diff --git a/[refs] b/[refs] index 718724a80566..29df577c054a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 43187902cbfafe73ede0144166b741fb0f7d04e1 +refs/heads/master: ba2bf2185121db74e075c703fbf986761733dd1d diff --git a/trunk/Documentation/HOWTO b/trunk/Documentation/HOWTO index 48123dba5e6a..8d51c148f721 100644 --- a/trunk/Documentation/HOWTO +++ b/trunk/Documentation/HOWTO @@ -30,7 +30,6 @@ are not a good substitute for a solid C education and/or years of experience, the following books are good for, if anything, reference: - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall] - "Practical C Programming" by Steve Oualline [O'Reilly] - - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] The kernel is written using GNU C and the GNU toolchain. While it adheres to the ISO C89 standard, it uses a number of extensions that are diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 2dc5e5da8f88..0ba6af02cdaf 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -274,7 +274,6 @@ Who: Venkatesh Pallipadi --------------------------- -<<<<<<< test:Documentation/feature-removal-schedule.txt What: ACPI hotkey driver (CONFIG_ACPI_HOTKEY) When: 2.6.21 Why: hotkey.c was an attempt to consolidate multiple drivers that use @@ -307,15 +306,8 @@ Why: The ACPI namespace is effectively the symbol list for the BIOS can be extracted and disassembled with acpidump and iasl as documented in the pmtools package here: http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils -Who: Len Brown - ---------------------------- -What: ACPI procfs interface -When: July 2007 -Why: After ACPI sysfs conversion, ACPI attributes will be duplicated - in sysfs and the ACPI procfs interface should be removed. -Who: Zhang Rui +Who: Len Brown --------------------------- @@ -333,10 +325,3 @@ Why: Unmaintained for years, superceded by JFFS2 for years. Who: Jeff Garzik --------------------------- - -What: sk98lin network driver -When: July 2007 -Why: In kernel tree version of driver is unmaintained. Sk98lin driver - replaced by the skge driver. -Who: Stephen Hemminger - diff --git a/trunk/Documentation/usb/proc_usb_info.txt b/trunk/Documentation/usb/proc_usb_info.txt index 077e9032d0cd..22c5331260ca 100644 --- a/trunk/Documentation/usb/proc_usb_info.txt +++ b/trunk/Documentation/usb/proc_usb_info.txt @@ -213,16 +213,15 @@ C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA Interface descriptor info (can be multiple per Config): -I:* If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss -| | | | | | | | |__Driver name -| | | | | | | | or "(none)" -| | | | | | | |__InterfaceProtocol -| | | | | | |__InterfaceSubClass -| | | | | |__InterfaceClass -| | | | |__NumberOfEndpoints -| | | |__AlternateSettingNumber -| | |__InterfaceNumber -| |__ "*" indicates the active altsetting (others are " ") +I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss +| | | | | | | |__Driver name +| | | | | | | or "(none)" +| | | | | | |__InterfaceProtocol +| | | | | |__InterfaceSubClass +| | | | |__InterfaceClass +| | | |__NumberOfEndpoints +| | |__AlternateSettingNumber +| |__InterfaceNumber |__Interface info tag A given interface may have one or more "alternate" settings. @@ -278,7 +277,7 @@ of the USB devices on a system's root hub. (See more below on how to do this.) The Interface lines can be used to determine what driver is -being used for each device, and which altsetting it activated. +being used for each device. The Configuration lines could be used to list maximum power (in milliamps) that a system's USB devices are using. diff --git a/trunk/Documentation/usb/usbmon.txt b/trunk/Documentation/usb/usbmon.txt index 0f6808abd612..e65ec828d7aa 100644 --- a/trunk/Documentation/usb/usbmon.txt +++ b/trunk/Documentation/usb/usbmon.txt @@ -77,7 +77,7 @@ that the file size is not excessive for your favourite editor. The '1t' type data consists of a stream of events, such as URB submission, URB callback, submission error. Every event is a text line, which consists -of whitespace separated words. The number or position of words may depend +of whitespace separated words. The number of position of words may depend on the event type, but there is a set of words, common for all types. Here is the list of words, from left to right: @@ -170,152 +170,4 @@ dd65f0e8 4128379808 C Bo:005:02 0 31 > * Raw binary format and API -The overall architecture of the API is about the same as the one above, -only the events are delivered in binary format. Each event is sent in -the following structure (its name is made up, so that we can refer to it): - -struct usbmon_packet { - u64 id; /* 0: URB ID - from submission to callback */ - unsigned char type; /* 8: Same as text; extensible. */ - unsigned char xfer_type; /* ISO (0), Intr, Control, Bulk (3) */ - unsigned char epnum; /* Endpoint number and transfer direction */ - unsigned char devnum; /* Device address */ - u16 busnum; /* 12: Bus number */ - char flag_setup; /* 14: Same as text */ - char flag_data; /* 15: Same as text; Binary zero is OK. */ - s64 ts_sec; /* 16: gettimeofday */ - s32 ts_usec; /* 24: gettimeofday */ - int status; /* 28: */ - unsigned int length; /* 32: Length of data (submitted or actual) */ - unsigned int len_cap; /* 36: Delivered length */ - unsigned char setup[8]; /* 40: Only for Control 'S' */ -}; /* 48 bytes total */ - -These events can be received from a character device by reading with read(2), -with an ioctl(2), or by accessing the buffer with mmap. - -The character device is usually called /dev/usbmonN, where N is the USB bus -number. Number zero (/dev/usbmon0) is special and means "all buses". -However, this feature is not implemented yet. Note that specific naming -policy is set by your Linux distribution. - -If you create /dev/usbmon0 by hand, make sure that it is owned by root -and has mode 0600. Otherwise, unpriviledged users will be able to snoop -keyboard traffic. - -The following ioctl calls are available, with MON_IOC_MAGIC 0x92: - - MON_IOCQ_URB_LEN, defined as _IO(MON_IOC_MAGIC, 1) - -This call returns the length of data in the next event. Note that majority of -events contain no data, so if this call returns zero, it does not mean that -no events are available. - - MON_IOCG_STATS, defined as _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats) - -The argument is a pointer to the following structure: - -struct mon_bin_stats { - u32 queued; - u32 dropped; -}; - -The member "queued" refers to the number of events currently queued in the -buffer (and not to the number of events processed since the last reset). - -The member "dropped" is the number of events lost since the last call -to MON_IOCG_STATS. - - MON_IOCT_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 4) - -This call sets the buffer size. The argument is the size in bytes. -The size may be rounded down to the next chunk (or page). If the requested -size is out of [unspecified] bounds for this kernel, the call fails with --EINVAL. - - MON_IOCQ_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 5) - -This call returns the current size of the buffer in bytes. - - MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg) - -This call waits for events to arrive if none were in the kernel buffer, -then returns the first event. Its argument is a pointer to the following -structure: - -struct mon_get_arg { - struct usbmon_packet *hdr; - void *data; - size_t alloc; /* Length of data (can be zero) */ -}; - -Before the call, hdr, data, and alloc should be filled. Upon return, the area -pointed by hdr contains the next event structure, and the data buffer contains -the data, if any. The event is removed from the kernel buffer. - - MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg) - -This ioctl is primarily used when the application accesses the buffer -with mmap(2). Its argument is a pointer to the following structure: - -struct mon_mfetch_arg { - uint32_t *offvec; /* Vector of events fetched */ - uint32_t nfetch; /* Number of events to fetch (out: fetched) */ - uint32_t nflush; /* Number of events to flush */ -}; - -The ioctl operates in 3 stages. - -First, it removes and discards up to nflush events from the kernel buffer. -The actual number of events discarded is returned in nflush. - -Second, it waits for an event to be present in the buffer, unless the pseudo- -device is open with O_NONBLOCK. - -Third, it extracts up to nfetch offsets into the mmap buffer, and stores -them into the offvec. The actual number of event offsets is stored into -the nfetch. - - MON_IOCH_MFLUSH, defined as _IO(MON_IOC_MAGIC, 8) - -This call removes a number of events from the kernel buffer. Its argument -is the number of events to remove. If the buffer contains fewer events -than requested, all events present are removed, and no error is reported. -This works when no events are available too. - - FIONBIO - -The ioctl FIONBIO may be implemented in the future, if there's a need. - -In addition to ioctl(2) and read(2), the special file of binary API can -be polled with select(2) and poll(2). But lseek(2) does not work. - -* Memory-mapped access of the kernel buffer for the binary API - -The basic idea is simple: - -To prepare, map the buffer by getting the current size, then using mmap(2). -Then, execute a loop similar to the one written in pseudo-code below: - - struct mon_mfetch_arg fetch; - struct usbmon_packet *hdr; - int nflush = 0; - for (;;) { - fetch.offvec = vec; // Has N 32-bit words - fetch.nfetch = N; // Or less than N - fetch.nflush = nflush; - ioctl(fd, MON_IOCX_MFETCH, &fetch); // Process errors, too - nflush = fetch.nfetch; // This many packets to flush when done - for (i = 0; i < nflush; i++) { - hdr = (struct ubsmon_packet *) &mmap_area[vec[i]]; - if (hdr->type == '@') // Filler packet - continue; - caddr_t data = &mmap_area[vec[i]] + 64; - process_packet(hdr, data); - } - } - -Thus, the main idea is to execute only one ioctl per N events. - -Although the buffer is circular, the returned headers and data do not cross -the end of the buffer, so the above pseudo-code does not need any gathering. +TBD diff --git a/trunk/Documentation/video-output.txt b/trunk/Documentation/video-output.txt deleted file mode 100644 index e517011be4f9..000000000000 --- a/trunk/Documentation/video-output.txt +++ /dev/null @@ -1,34 +0,0 @@ - - Video Output Switcher Control - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 2006 luming.yu@intel.com - -The output sysfs class driver provides an abstract video output layer that -can be used to hook platform specific methods to enable/disable video output -device through common sysfs interface. For example, on my IBM ThinkPad T42 -laptop, The ACPI video driver registered its output devices and read/write -method for 'state' with output sysfs class. The user interface under sysfs is: - -linux:/sys/class/video_output # tree . -. -|-- CRT0 -| |-- device -> ../../../devices/pci0000:00/0000:00:01.0 -| |-- state -| |-- subsystem -> ../../../class/video_output -| `-- uevent -|-- DVI0 -| |-- device -> ../../../devices/pci0000:00/0000:00:01.0 -| |-- state -| |-- subsystem -> ../../../class/video_output -| `-- uevent -|-- LCD0 -| |-- device -> ../../../devices/pci0000:00/0000:00:01.0 -| |-- state -| |-- subsystem -> ../../../class/video_output -| `-- uevent -`-- TV0 - |-- device -> ../../../devices/pci0000:00/0000:00:01.0 - |-- state - |-- subsystem -> ../../../class/video_output - `-- uevent - diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index fe35f3ac4cd3..16c0e15b5785 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -584,30 +584,12 @@ W: http://sourceforge.net/projects/acpi4asus W: http://xf.iksaif.net/acpi4asus S: Maintained -ASUS LAPTOP EXTRAS DRIVER -P: Corentin Chary -M: corentincj@iksaif.net -L: acpi4asus-user@lists.sourceforge.net -W: http://sourceforge.net/projects/acpi4asus -W: http://xf.iksaif.net/acpi4asus -S: Maintained - ATA OVER ETHERNET DRIVER P: Ed L. Cashin M: ecashin@coraid.com W: http://www.coraid.com/support/linux S: Supported -ATL1 ETHERNET DRIVER -P: Jay Cliburn -M: jcliburn@gmail.com -P: Chris Snook -M: csnook@redhat.com -L: atl1-devel@lists.sourceforge.net -W: http://sourceforge.net/projects/atl1 -W: http://atl1.sourceforge.net -S: Maintained - ATM P: Chas Williams M: chas@cmf.nrl.navy.mil @@ -2495,12 +2477,6 @@ L: orinoco-devel@lists.sourceforge.net W: http://www.nongnu.org/orinoco/ S: Maintained -PA SEMI ETHERNET DRIVER -P: Olof Johansson -M: olof@lixom.net -L: netdev@vger.kernel.org -S: Maintained - PARALLEL PORT SUPPORT P: Phil Blundell M: philb@gnu.org @@ -2670,7 +2646,7 @@ S: Supported PRISM54 WIRELESS DRIVER P: Prism54 Development Team -M: developers@islsm.org +M: prism54-private@prism54.org L: netdev@vger.kernel.org W: http://prism54.org S: Maintained diff --git a/trunk/arch/alpha/kernel/pci.c b/trunk/arch/alpha/kernel/pci.c index ab642a4f08de..3c10b9a1ddf5 100644 --- a/trunk/arch/alpha/kernel/pci.c +++ b/trunk/arch/alpha/kernel/pci.c @@ -575,7 +575,3 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr) EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); - -/* FIXME: Some boxes have multiple ISA bridges! */ -struct pci_dev *isa_bridge; -EXPORT_SYMBOL(isa_bridge); diff --git a/trunk/arch/i386/defconfig b/trunk/arch/i386/defconfig index bb0c376b62b3..5d80edfc61b7 100644 --- a/trunk/arch/i386/defconfig +++ b/trunk/arch/i386/defconfig @@ -466,8 +466,7 @@ CONFIG_FW_LOADER=y # # Plug and Play support # -CONFIG_PNP=y -CONFIG_PNPACPI=y +# CONFIG_PNP is not set # # Block devices diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index e94aff6888ca..cbcb2c27f48b 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -66,7 +66,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ - ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) + ((acpi_table_entry_header *)entry)->length < sizeof(*entry)) #define PREFIX "ACPI: " @@ -79,7 +79,7 @@ int acpi_ioapic; int acpi_strict; EXPORT_SYMBOL(acpi_strict); -u8 acpi_sci_flags __initdata; +acpi_interrupt_flags acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; int acpi_skip_timer_override __initdata; int acpi_use_timer_override __initdata; @@ -92,6 +92,11 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; #warning ACPI uses CMPXCHG, i486 and later hardware #endif +#define MAX_MADT_ENTRIES 256 +u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = + {[0 ... MAX_MADT_ENTRIES - 1] = 0xff }; +EXPORT_SYMBOL(x86_acpiid_to_apicid); + /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ @@ -161,26 +166,30 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) #ifdef CONFIG_PCI_MMCONFIG /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -struct acpi_mcfg_allocation *pci_mmcfg_config; +struct acpi_table_mcfg_config *pci_mmcfg_config; int pci_mmcfg_config_num; -int __init acpi_parse_mcfg(struct acpi_table_header *header) +int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) { struct acpi_table_mcfg *mcfg; unsigned long i; int config_size; - if (!header) + if (!phys_addr || !size) return -EINVAL; - mcfg = (struct acpi_table_mcfg *)header; + mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); + if (!mcfg) { + printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); + return -ENODEV; + } /* how many config structures do we have */ pci_mmcfg_config_num = 0; - i = header->length - sizeof(struct acpi_table_mcfg); - while (i >= sizeof(struct acpi_mcfg_allocation)) { + i = size - sizeof(struct acpi_table_mcfg); + while (i >= sizeof(struct acpi_table_mcfg_config)) { ++pci_mmcfg_config_num; - i -= sizeof(struct acpi_mcfg_allocation); + i -= sizeof(struct acpi_table_mcfg_config); }; if (pci_mmcfg_config_num == 0) { printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); @@ -195,9 +204,9 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header) return -ENOMEM; } - memcpy(pci_mmcfg_config, &mcfg[1], config_size); + memcpy(pci_mmcfg_config, &mcfg->config, config_size); for (i = 0; i < pci_mmcfg_config_num; ++i) { - if (pci_mmcfg_config[i].address > 0xFFFFFFFF) { + if (mcfg->config[i].base_reserved) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); kfree(pci_mmcfg_config); @@ -211,24 +220,24 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header) #endif /* CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC -static int __init acpi_parse_madt(struct acpi_table_header *table) +static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) { struct acpi_table_madt *madt = NULL; - if (!cpu_has_apic) + if (!phys_addr || !size || !cpu_has_apic) return -EINVAL; - madt = (struct acpi_table_madt *)table; + madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); if (!madt) { printk(KERN_WARNING PREFIX "Unable to map MADT\n"); return -ENODEV; } - if (madt->address) { - acpi_lapic_addr = (u64) madt->address; + if (madt->lapic_address) { + acpi_lapic_addr = (u64) madt->lapic_address; printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", - madt->address); + madt->lapic_address); } acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); @@ -237,17 +246,21 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) } static int __init -acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic *processor = NULL; + struct acpi_table_lapic *processor = NULL; - processor = (struct acpi_madt_local_apic *)header; + processor = (struct acpi_table_lapic *)header; if (BAD_MADT_ENTRY(processor, end)) return -EINVAL; acpi_table_print_madt_entry(header); + /* Record local apic id only when enabled */ + if (processor->flags.enabled) + x86_acpiid_to_apicid[processor->acpi_id] = processor->id; + /* * We need to register disabled CPU as well to permit * counting disabled CPUs. This allows us to size @@ -256,18 +269,18 @@ acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) * when we use CPU hotplug. */ mp_register_lapic(processor->id, /* APIC ID */ - processor->lapic_flags & ACPI_MADT_ENABLED); /* Enabled? */ + processor->flags.enabled); /* Enabled? */ return 0; } static int __init -acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, +acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic_override *lapic_addr_ovr = NULL; + struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; - lapic_addr_ovr = (struct acpi_madt_local_apic_override *)header; + lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header; if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) return -EINVAL; @@ -278,11 +291,11 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, } static int __init -acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic_nmi *lapic_nmi = NULL; + struct acpi_table_lapic_nmi *lapic_nmi = NULL; - lapic_nmi = (struct acpi_madt_local_apic_nmi *)header; + lapic_nmi = (struct acpi_table_lapic_nmi *)header; if (BAD_MADT_ENTRY(lapic_nmi, end)) return -EINVAL; @@ -300,11 +313,11 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e #ifdef CONFIG_X86_IO_APIC static int __init -acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_io_apic *ioapic = NULL; + struct acpi_table_ioapic *ioapic = NULL; - ioapic = (struct acpi_madt_io_apic *)header; + ioapic = (struct acpi_table_ioapic *)header; if (BAD_MADT_ENTRY(ioapic, end)) return -EINVAL; @@ -329,11 +342,11 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) polarity = 3; /* Command-line over-ride via acpi_sci= */ - if (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) - trigger = (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2; + if (acpi_sci_flags.trigger) + trigger = acpi_sci_flags.trigger; - if (acpi_sci_flags & ACPI_MADT_POLARITY_MASK) - polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK; + if (acpi_sci_flags.polarity) + polarity = acpi_sci_flags.polarity; /* * mp_config_acpi_legacy_irqs() already setup IRQs < 16 @@ -344,52 +357,51 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) /* * stash over-ride to indicate we've been here - * and for later update of acpi_gbl_FADT + * and for later update of acpi_fadt */ acpi_sci_override_gsi = gsi; return; } static int __init -acpi_parse_int_src_ovr(struct acpi_subtable_header * header, +acpi_parse_int_src_ovr(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_interrupt_override *intsrc = NULL; + struct acpi_table_int_src_ovr *intsrc = NULL; - intsrc = (struct acpi_madt_interrupt_override *)header; + intsrc = (struct acpi_table_int_src_ovr *)header; if (BAD_MADT_ENTRY(intsrc, end)) return -EINVAL; acpi_table_print_madt_entry(header); - if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) { + if (intsrc->bus_irq == acpi_fadt.sci_int) { acpi_sci_ioapic_setup(intsrc->global_irq, - intsrc->inti_flags & ACPI_MADT_POLARITY_MASK, - (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2); + intsrc->flags.polarity, + intsrc->flags.trigger); return 0; } if (acpi_skip_timer_override && - intsrc->source_irq == 0 && intsrc->global_irq == 2) { + intsrc->bus_irq == 0 && intsrc->global_irq == 2) { printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); return 0; } - mp_override_legacy_irq(intsrc->source_irq, - intsrc->inti_flags & ACPI_MADT_POLARITY_MASK, - (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2, - intsrc->global_irq); + mp_override_legacy_irq(intsrc->bus_irq, + intsrc->flags.polarity, + intsrc->flags.trigger, intsrc->global_irq); return 0; } static int __init -acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_nmi_source *nmi_src = NULL; + struct acpi_table_nmi_src *nmi_src = NULL; - nmi_src = (struct acpi_madt_nmi_source *)header; + nmi_src = (struct acpi_table_nmi_src *)header; if (BAD_MADT_ENTRY(nmi_src, end)) return -EINVAL; @@ -405,7 +417,7 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end /* * acpi_pic_sci_set_trigger() - * + * * use ELCR to set PIC-mode trigger type for SCI * * If a PIC-mode SCI is not recognized or gives spurious IRQ7's @@ -499,7 +511,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - struct acpi_madt_local_apic *lapic; + struct acpi_table_lapic *lapic; cpumask_t tmp_map, new_map; u8 physid; int cpu; @@ -517,10 +529,10 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) return -EINVAL; } - lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer; + lapic = (struct acpi_table_lapic *)obj->buffer.pointer; - if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC || - !(lapic->lapic_flags & ACPI_MADT_ENABLED)) { + if ((lapic->header.type != ACPI_MADT_LAPIC) || + (!lapic->flags.enabled)) { kfree(buffer.pointer); return -EINVAL; } @@ -532,7 +544,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) buffer.pointer = NULL; tmp_map = cpu_present_map; - mp_register_lapic(physid, lapic->lapic_flags & ACPI_MADT_ENABLED); + mp_register_lapic(physid, lapic->flags.enabled); /* * If mp_register_lapic successfully generates a new logical cpu @@ -554,6 +566,14 @@ EXPORT_SYMBOL(acpi_map_lsapic); int acpi_unmap_lsapic(int cpu) { + int i; + + for_each_possible_cpu(i) { + if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu]) { + x86_acpiid_to_apicid[i] = -1; + break; + } + } x86_cpu_to_apicid[cpu] = -1; cpu_clear(cpu, cpu_present_map); num_processors--; @@ -599,36 +619,42 @@ acpi_scan_rsdp(unsigned long start, unsigned long length) return 0; } -static int __init acpi_parse_sbf(struct acpi_table_header *table) +static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) { - struct acpi_table_boot *sb; + struct acpi_table_sbf *sb; + + if (!phys_addr || !size) + return -EINVAL; - sb = (struct acpi_table_boot *)table; + sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size); if (!sb) { printk(KERN_WARNING PREFIX "Unable to map SBF\n"); return -ENODEV; } - sbf_port = sb->cmos_index; /* Save CMOS port */ + sbf_port = sb->sbf_cmos; /* Save CMOS port */ return 0; } #ifdef CONFIG_HPET_TIMER -static int __init acpi_parse_hpet(struct acpi_table_header *table) +static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) { struct acpi_table_hpet *hpet_tbl; struct resource *hpet_res; resource_size_t res_start; - hpet_tbl = (struct acpi_table_hpet *)table; + if (!phys || !size) + return -EINVAL; + + hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size); if (!hpet_tbl) { printk(KERN_WARNING PREFIX "Unable to map HPET\n"); return -ENODEV; } - if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { + if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) { printk(KERN_WARNING PREFIX "HPET timers must be located in " "memory.\n"); return -1; @@ -641,28 +667,29 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table) hpet_res->name = (void *)&hpet_res[1]; hpet_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, - "HPET %u", hpet_tbl->sequence); + "HPET %u", hpet_tbl->number); hpet_res->end = (1 * 1024) - 1; } -#ifdef CONFIG_X86_64 - vxtime.hpet_address = hpet_tbl->address.address; +#ifdef CONFIG_X86_64 + vxtime.hpet_address = hpet_tbl->addr.addrl | + ((long)hpet_tbl->addr.addrh << 32); printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", - hpet_tbl->id, vxtime.hpet_address); + hpet_tbl->id, vxtime.hpet_address); res_start = vxtime.hpet_address; -#else /* X86 */ +#else /* X86 */ { extern unsigned long hpet_address; - hpet_address = hpet_tbl->address.address; + hpet_address = hpet_tbl->addr.addrl; printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", - hpet_tbl->id, hpet_address); + hpet_tbl->id, hpet_address); res_start = hpet_address; } -#endif /* X86 */ +#endif /* X86 */ if (hpet_res) { hpet_res->start = res_start; @@ -680,28 +707,42 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table) extern u32 pmtmr_ioport; #endif -static int __init acpi_parse_fadt(struct acpi_table_header *table) +static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) { + struct fadt_descriptor *fadt = NULL; + + fadt = (struct fadt_descriptor *)__acpi_map_table(phys, size); + if (!fadt) { + printk(KERN_WARNING PREFIX "Unable to map FADT\n"); + return 0; + } + /* initialize sci_int early for INT_SRC_OVR MADT parsing */ + acpi_fadt.sci_int = fadt->sci_int; + + /* initialize rev and apic_phys_dest_mode for x86_64 genapic */ + acpi_fadt.revision = fadt->revision; + acpi_fadt.force_apic_physical_destination_mode = + fadt->force_apic_physical_destination_mode; #ifdef CONFIG_X86_PM_TIMER /* detect the location of the ACPI PM Timer */ - if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) { + if (fadt->revision >= FADT2_REVISION_ID) { /* FADT rev. 2 */ - if (acpi_gbl_FADT.xpm_timer_block.space_id != + if (fadt->xpm_tmr_blk.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO) return 0; - pmtmr_ioport = acpi_gbl_FADT.xpm_timer_block.address; + pmtmr_ioport = fadt->xpm_tmr_blk.address; /* * "X" fields are optional extensions to the original V1.0 * fields, so we must selectively expand V1.0 fields if the * corresponding X field is zero. */ if (!pmtmr_ioport) - pmtmr_ioport = acpi_gbl_FADT.pm_timer_block; + pmtmr_ioport = fadt->V1_pm_tmr_blk; } else { /* FADT rev. 1 */ - pmtmr_ioport = acpi_gbl_FADT.pm_timer_block; + pmtmr_ioport = fadt->V1_pm_tmr_blk; } if (pmtmr_ioport) printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", @@ -743,13 +784,13 @@ static int __init acpi_parse_madt_lapic_entries(void) if (!cpu_has_apic) return -ENODEV; - /* + /* * Note that the LAPIC address is obtained from the MADT (32-bit value) * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). */ count = - acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, + acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); if (count < 0) { printk(KERN_ERR PREFIX @@ -759,7 +800,7 @@ static int __init acpi_parse_madt_lapic_entries(void) mp_register_lapic_address(acpi_lapic_addr); - count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, acpi_parse_lapic, + count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, MAX_APICS); if (!count) { printk(KERN_ERR PREFIX "No LAPIC entries present\n"); @@ -772,7 +813,7 @@ static int __init acpi_parse_madt_lapic_entries(void) } count = - acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0); + acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* TBD: Cleanup to allow fallback to MPS */ @@ -801,7 +842,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) return -ENODEV; } - if (!cpu_has_apic) + if (!cpu_has_apic) return -ENODEV; /* @@ -814,7 +855,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) } count = - acpi_table_parse_madt(ACPI_MADT_TYPE_IO_APIC, acpi_parse_ioapic, + acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); if (!count) { printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); @@ -825,7 +866,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) } count = - acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr, + acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); if (count < 0) { printk(KERN_ERR PREFIX @@ -839,13 +880,13 @@ static int __init acpi_parse_madt_ioapic_entries(void) * pretend we got one so we can set the SCI flags. */ if (!acpi_sci_override_gsi) - acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0); + acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); /* Fill in identity legacy mapings where no override */ mp_config_acpi_legacy_irqs(); count = - acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src, + acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); @@ -867,7 +908,7 @@ static void __init acpi_process_madt(void) #ifdef CONFIG_X86_LOCAL_APIC int count, error; - count = acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt); + count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); if (count >= 1) { /* @@ -1154,7 +1195,7 @@ int __init acpi_boot_table_init(void) if (acpi_disabled && !acpi_ht) return 1; - /* + /* * Initialize the ACPI boot-time table parser. */ error = acpi_table_init(); @@ -1163,7 +1204,7 @@ int __init acpi_boot_table_init(void) return error; } - acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); + acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); /* * blacklist may disable ACPI entirely @@ -1191,19 +1232,19 @@ int __init acpi_boot_init(void) if (acpi_disabled && !acpi_ht) return 1; - acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); + acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); /* * set sci_int and PM timer address */ - acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt); + acpi_table_parse(ACPI_FADT, acpi_parse_fadt); /* * Process the Multiple APIC Description Table (MADT), if present */ acpi_process_madt(); - acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); + acpi_table_parse(ACPI_HPET, acpi_parse_hpet); return 0; } @@ -1274,17 +1315,13 @@ static int __init setup_acpi_sci(char *s) if (!s) return -EINVAL; if (!strcmp(s, "edge")) - acpi_sci_flags = ACPI_MADT_TRIGGER_EDGE | - (acpi_sci_flags & ~ACPI_MADT_TRIGGER_MASK); + acpi_sci_flags.trigger = 1; else if (!strcmp(s, "level")) - acpi_sci_flags = ACPI_MADT_TRIGGER_LEVEL | - (acpi_sci_flags & ~ACPI_MADT_TRIGGER_MASK); + acpi_sci_flags.trigger = 3; else if (!strcmp(s, "high")) - acpi_sci_flags = ACPI_MADT_POLARITY_ACTIVE_HIGH | - (acpi_sci_flags & ~ACPI_MADT_POLARITY_MASK); + acpi_sci_flags.polarity = 1; else if (!strcmp(s, "low")) - acpi_sci_flags = ACPI_MADT_POLARITY_ACTIVE_LOW | - (acpi_sci_flags & ~ACPI_MADT_POLARITY_MASK); + acpi_sci_flags.polarity = 3; else return -EINVAL; return 0; diff --git a/trunk/arch/i386/kernel/acpi/earlyquirk.c b/trunk/arch/i386/kernel/acpi/earlyquirk.c index bf86f7662d8b..4b60af7f91dd 100644 --- a/trunk/arch/i386/kernel/acpi/earlyquirk.c +++ b/trunk/arch/i386/kernel/acpi/earlyquirk.c @@ -16,7 +16,7 @@ static int nvidia_hpet_detected __initdata; -static int __init nvidia_hpet_check(struct acpi_table_header *header) +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) { nvidia_hpet_detected = 1; return 0; @@ -30,7 +30,7 @@ static int __init check_bridge(int vendor, int device) is enabled. */ if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) { nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check); + acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { acpi_skip_timer_override = 1; printk(KERN_INFO "Nvidia board " diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c index a3db9332d652..e940e00b96c9 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -190,7 +190,7 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index) /* Invoke C3 */ inb(cx_address); /* Dummy op - must do something useless after P_LVL3 read */ - t = inl(acpi_gbl_FADT.xpm_timer_block.address); + t = inl(acpi_fadt.xpm_tmr_blk.address); } /* Disable bus ratio bit */ local_irq_disable(); @@ -250,7 +250,8 @@ static void longhaul_setstate(unsigned int clock_ratio_index) outb(3, 0x22); } else if ((pr != NULL) && pr->flags.bm_control) { /* Disable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, + ACPI_MTX_DO_NOT_LOCK); } switch (longhaul_version) { @@ -280,7 +281,8 @@ static void longhaul_setstate(unsigned int clock_ratio_index) case TYPE_POWERSAVER: if (longhaul_flags & USE_ACPI_C3) { /* Don't allow wakeup */ - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, + ACPI_MTX_DO_NOT_LOCK); do_powersaver(cx->address, clock_ratio_index); } else { do_powersaver(0, clock_ratio_index); @@ -293,7 +295,8 @@ static void longhaul_setstate(unsigned int clock_ratio_index) outb(0, 0x22); } else if ((pr != NULL) && pr->flags.bm_control) { /* Enable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, + ACPI_MTX_DO_NOT_LOCK); } outb(pic2_mask,0xA1); /* restore mask */ outb(pic1_mask,0x21); @@ -411,7 +414,7 @@ static int __init longhaul_get_ranges(void) highest_speed = calc_speed(maxmult); lowest_speed = calc_speed(minmult); dprintk ("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb, - print_speed(lowest_speed/1000), + print_speed(lowest_speed/1000), print_speed(highest_speed/1000)); if (lowest_speed == highest_speed) { @@ -495,7 +498,7 @@ static void __init longhaul_setup_voltagescaling(void) maxvid.mV/1000, maxvid.mV%1000, minvid.mV/1000, minvid.mV%1000, numvscales); - + j = 0; while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) { speed = longhaul_table[j].frequency; diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index 5592fa6e1fa1..6a3875f81a0a 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -2606,32 +2606,25 @@ static struct irq_chip msi_chip = { .retrigger = ioapic_retrigger_irq, }; -int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) +int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) { struct msi_msg msg; - int irq, ret; - irq = create_irq(); - if (irq < 0) - return irq; - - set_irq_msi(irq, desc); + int ret; ret = msi_compose_msg(dev, irq, &msg); - if (ret < 0) { - destroy_irq(irq); + if (ret < 0) return ret; - } write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return irq; + return 0; } void arch_teardown_msi_irq(unsigned int irq) { - destroy_irq(irq); + return; } #endif /* CONFIG_PCI_MSI */ diff --git a/trunk/arch/i386/kernel/mpparse.c b/trunk/arch/i386/kernel/mpparse.c index 4f5983c98669..49bff3596bff 100644 --- a/trunk/arch/i386/kernel/mpparse.c +++ b/trunk/arch/i386/kernel/mpparse.c @@ -1057,7 +1057,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) static int gsi_to_irq[MAX_GSI_NUM]; /* Don't set up the ACPI SCI because it's already set up */ - if (acpi_gbl_FADT.sci_interrupt == gsi) + if (acpi_fadt.sci_int == gsi) return gsi; ioapic = mp_find_ioapic(gsi); @@ -1114,7 +1114,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) /* * Don't assign IRQ used by ACPI SCI */ - if (gsi == acpi_gbl_FADT.sci_interrupt) + if (gsi == acpi_fadt.sci_int) gsi = pci_irq++; gsi_to_irq[irq] = gsi; } else { diff --git a/trunk/arch/i386/kernel/srat.c b/trunk/arch/i386/kernel/srat.c index 2a8713ec0f9a..f7e735c077c3 100644 --- a/trunk/arch/i386/kernel/srat.c +++ b/trunk/arch/i386/kernel/srat.c @@ -62,19 +62,19 @@ extern void * boot_ioremap(unsigned long, unsigned long); /* Identify CPU proximity domains */ static void __init parse_cpu_affinity_structure(char *p) { - struct acpi_srat_cpu_affinity *cpu_affinity = - (struct acpi_srat_cpu_affinity *) p; + struct acpi_table_processor_affinity *cpu_affinity = + (struct acpi_table_processor_affinity *) p; - if ((cpu_affinity->flags & ACPI_SRAT_CPU_ENABLED) == 0) + if (!cpu_affinity->flags.enabled) return; /* empty entry */ /* mark this node as "seen" in node bitmap */ - BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain_lo); + BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain); - apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain_lo; + apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain; printk("CPU 0x%02X in proximity domain 0x%02X\n", - cpu_affinity->apic_id, cpu_affinity->proximity_domain_lo); + cpu_affinity->apic_id, cpu_affinity->proximity_domain); } /* @@ -84,27 +84,28 @@ static void __init parse_cpu_affinity_structure(char *p) static void __init parse_memory_affinity_structure (char *sratp) { unsigned long long paddr, size; - unsigned long start_pfn, end_pfn; + unsigned long start_pfn, end_pfn; u8 pxm; struct node_memory_chunk_s *p, *q, *pend; - struct acpi_srat_mem_affinity *memory_affinity = - (struct acpi_srat_mem_affinity *) sratp; + struct acpi_table_memory_affinity *memory_affinity = + (struct acpi_table_memory_affinity *) sratp; - if ((memory_affinity->flags & ACPI_SRAT_MEM_ENABLED) == 0) + if (!memory_affinity->flags.enabled) return; /* empty entry */ - pxm = memory_affinity->proximity_domain & 0xff; - /* mark this node as "seen" in node bitmap */ - BMAP_SET(pxm_bitmap, pxm); + BMAP_SET(pxm_bitmap, memory_affinity->proximity_domain); /* calculate info for memory chunk structure */ - paddr = memory_affinity->base_address; - size = memory_affinity->length; - + paddr = memory_affinity->base_addr_hi; + paddr = (paddr << 32) | memory_affinity->base_addr_lo; + size = memory_affinity->length_hi; + size = (size << 32) | memory_affinity->length_lo; + start_pfn = paddr >> PAGE_SHIFT; end_pfn = (paddr + size) >> PAGE_SHIFT; - + + pxm = memory_affinity->proximity_domain; if (num_memory_chunks >= MAXCHUNKS) { printk("Too many mem chunks in SRAT. Ignoring %lld MBytes at %llx\n", @@ -131,8 +132,8 @@ static void __init parse_memory_affinity_structure (char *sratp) printk("Memory range 0x%lX to 0x%lX (type 0x%X) in proximity domain 0x%02X %s\n", start_pfn, end_pfn, memory_affinity->memory_type, - pxm, - ((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ? + memory_affinity->proximity_domain, + (memory_affinity->flags.hot_pluggable ? "enabled and removable" : "enabled" ) ); } @@ -184,10 +185,10 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) num_memory_chunks = 0; while (p < end) { switch (*p) { - case ACPI_SRAT_TYPE_CPU_AFFINITY: + case ACPI_SRAT_PROCESSOR_AFFINITY: parse_cpu_affinity_structure(p); break; - case ACPI_SRAT_TYPE_MEMORY_AFFINITY: + case ACPI_SRAT_MEMORY_AFFINITY: parse_memory_affinity_structure(p); break; default: @@ -261,30 +262,31 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) return 0; } -struct acpi_static_rsdt { - struct acpi_table_rsdt table; - u32 padding[7]; /* Allow for 7 more table entries */ -}; - int __init get_memcfg_from_srat(void) { struct acpi_table_header *header = NULL; struct acpi_table_rsdp *rsdp = NULL; struct acpi_table_rsdt *rsdt = NULL; - acpi_native_uint rsdp_address = 0; - struct acpi_static_rsdt saved_rsdt; + struct acpi_pointer *rsdp_address = NULL; + struct acpi_table_rsdt saved_rsdt; int tables = 0; int i = 0; - rsdp_address = acpi_find_rsdp(); - if (!rsdp_address) { + if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, + rsdp_address))) { printk("%s: System description tables not found\n", __FUNCTION__); goto out_err; } - printk("%s: assigning address to rsdp\n", __FUNCTION__); - rsdp = (struct acpi_table_rsdp *)(u32)rsdp_address; + if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) { + printk("%s: assigning address to rsdp\n", __FUNCTION__); + rsdp = (struct acpi_table_rsdp *) + (u32)rsdp_address->pointer.physical; + } else { + printk("%s: rsdp_address is not a physical pointer\n", __FUNCTION__); + goto out_err; + } if (!rsdp) { printk("%s: Didn't find ACPI root!\n", __FUNCTION__); goto out_err; @@ -293,13 +295,13 @@ int __init get_memcfg_from_srat(void) printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision, rsdp->oem_id); - if (strncmp(rsdp->signature, ACPI_SIG_RSDP,strlen(ACPI_SIG_RSDP))) { + if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) { printk(KERN_WARNING "%s: RSDP table signature incorrect\n", __FUNCTION__); goto out_err; } rsdt = (struct acpi_table_rsdt *) - boot_ioremap(rsdp->rsdt_physical_address, sizeof(struct acpi_table_rsdt)); + boot_ioremap(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt)); if (!rsdt) { printk(KERN_WARNING @@ -308,9 +310,9 @@ int __init get_memcfg_from_srat(void) goto out_err; } - header = &rsdt->header; + header = & rsdt->header; - if (strncmp(header->signature, ACPI_SIG_RSDT, strlen(ACPI_SIG_RSDT))) { + if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) { printk(KERN_WARNING "ACPI: RSDT signature incorrect\n"); goto out_err; } @@ -328,9 +330,9 @@ int __init get_memcfg_from_srat(void) memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt)); - if (saved_rsdt.table.header.length > sizeof(saved_rsdt)) { + if (saved_rsdt.header.length > sizeof(saved_rsdt)) { printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", - saved_rsdt.table.header.length); + saved_rsdt.header.length); goto out_err; } @@ -339,15 +341,15 @@ int __init get_memcfg_from_srat(void) for (i = 0; i < tables; i++) { /* Map in header, then map in full table length. */ header = (struct acpi_table_header *) - boot_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header)); + boot_ioremap(saved_rsdt.entry[i], sizeof(struct acpi_table_header)); if (!header) break; header = (struct acpi_table_header *) - boot_ioremap(saved_rsdt.table.table_offset_entry[i], header->length); + boot_ioremap(saved_rsdt.entry[i], header->length); if (!header) break; - if (strncmp((char *) &header->signature, ACPI_SIG_SRAT, 4)) + if (strncmp((char *) &header->signature, "SRAT", 4)) continue; /* we've found the srat table. don't need to look at any more tables */ diff --git a/trunk/arch/i386/mach-es7000/es7000.h b/trunk/arch/i386/mach-es7000/es7000.h index c8d5aa132fa0..80566ca4a80a 100644 --- a/trunk/arch/i386/mach-es7000/es7000.h +++ b/trunk/arch/i386/mach-es7000/es7000.h @@ -84,6 +84,15 @@ struct es7000_oem_table { }; #ifdef CONFIG_ACPI +struct acpi_table_sdt { + unsigned long pa; + unsigned long count; + struct { + unsigned long pa; + enum acpi_table_id id; + unsigned long size; + } entry[50]; +}; struct oem_table { struct acpi_table_header Header; diff --git a/trunk/arch/i386/mach-es7000/es7000plat.c b/trunk/arch/i386/mach-es7000/es7000plat.c index 9be6ceabf042..3d0fc853516d 100644 --- a/trunk/arch/i386/mach-es7000/es7000plat.c +++ b/trunk/arch/i386/mach-es7000/es7000plat.c @@ -160,14 +160,51 @@ parse_unisys_oem (char *oemptr) int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { - struct acpi_table_header *header = NULL; - int i = 0; - while (ACPI_SUCCESS(acpi_get_table("OEM1", i++, &header))) { - if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) { - struct oem_table *t = (struct oem_table *)header; - *oem_addr = (unsigned long)__acpi_map_table(t->OEMTableAddr, - t->OEMTableSize); - return 0; + struct acpi_table_rsdp *rsdp = NULL; + unsigned long rsdp_phys = 0; + struct acpi_table_header *header = NULL; + int i; + struct acpi_table_sdt sdt; + + rsdp_phys = acpi_find_rsdp(); + rsdp = __va(rsdp_phys); + if (rsdp->rsdt_address) { + struct acpi_table_rsdt *mapped_rsdt = NULL; + sdt.pa = rsdp->rsdt_address; + + header = (struct acpi_table_header *) + __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header)); + if (!header) + return -ENODEV; + + sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3; + mapped_rsdt = (struct acpi_table_rsdt *) + __acpi_map_table(sdt.pa, header->length); + if (!mapped_rsdt) + return -ENODEV; + + header = &mapped_rsdt->header; + + for (i = 0; i < sdt.count; i++) + sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i]; + }; + for (i = 0; i < sdt.count; i++) { + + header = (struct acpi_table_header *) + __acpi_map_table(sdt.entry[i].pa, + sizeof(struct acpi_table_header)); + if (!header) + continue; + if (!strncmp((char *) &header->signature, "OEM1", 4)) { + if (!strncmp((char *) &header->oem_id, "UNISYS", 6)) { + void *addr; + struct oem_table *t; + acpi_table_print(header, sdt.entry[i].pa); + t = (struct oem_table *) __acpi_map_table(sdt.entry[i].pa, header->length); + addr = (void *) __acpi_map_table(t->OEMTableAddr, t->OEMTableSize); + *oem_addr = (unsigned long) addr; + return 0; + } } } return -1; diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c index 5700220dcf5f..e2616a266e13 100644 --- a/trunk/arch/i386/pci/mmconfig.c +++ b/trunk/arch/i386/pci/mmconfig.c @@ -36,7 +36,7 @@ static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32); static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) { int cfg_num = -1; - struct acpi_mcfg_allocation *cfg; + struct acpi_table_mcfg_config *cfg; if (seg == 0 && bus < MAX_CHECK_BUS && test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots)) @@ -48,11 +48,11 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) break; } cfg = &pci_mmcfg_config[cfg_num]; - if (cfg->pci_segment != seg) + if (cfg->pci_segment_group_number != seg) continue; if ((cfg->start_bus_number <= bus) && (cfg->end_bus_number >= bus)) - return cfg->address; + return cfg->base_address; } /* Handle more broken MCFG tables on Asus etc. @@ -60,9 +60,9 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) this applies to all busses. */ cfg = &pci_mmcfg_config[0]; if (pci_mmcfg_config_num == 1 && - cfg->pci_segment == 0 && + cfg->pci_segment_group_number == 0 && (cfg->start_bus_number | cfg->end_bus_number) == 0) - return cfg->address; + return cfg->base_address; /* Fall back to type 0 */ return 0; @@ -125,7 +125,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, unsigned long flags; u32 base; - if ((bus > 255) || (devfn > 255) || (reg > 4095)) + if ((bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; base = get_base_addr(seg, bus, devfn); @@ -199,19 +199,19 @@ void __init pci_mmcfg_init(int type) if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; - acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); if ((pci_mmcfg_config_num == 0) || (pci_mmcfg_config == NULL) || - (pci_mmcfg_config[0].address == 0)) + (pci_mmcfg_config[0].base_address == 0)) return; /* Only do this check when type 1 works. If it doesn't work assume we run on a Mac and always use MCFG */ - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].address, - pci_mmcfg_config[0].address + MMCONFIG_APER_MIN, + if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { - printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %lx is not E820-reserved\n", - (unsigned long)pci_mmcfg_config[0].address); + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", + pci_mmcfg_config[0].base_address); printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); return; } diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 9197d7b361b3..29f05d4b68cd 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -55,7 +55,7 @@ #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ - ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) + ((acpi_table_entry_header *)entry)->length < sizeof(*entry)) #define PREFIX "ACPI: " @@ -67,11 +67,16 @@ EXPORT_SYMBOL(pm_power_off); unsigned int acpi_cpei_override; unsigned int acpi_cpei_phys_cpuid; +#define MAX_SAPICS 256 +u16 ia64_acpiid_to_sapicid[MAX_SAPICS] = {[0 ... MAX_SAPICS - 1] = -1 }; + +EXPORT_SYMBOL(ia64_acpiid_to_sapicid); + const char *acpi_get_sysname(void) { #ifdef CONFIG_IA64_GENERIC unsigned long rsdp_phys; - struct acpi_table_rsdp *rsdp; + struct acpi20_table_rsdp *rsdp; struct acpi_table_xsdt *xsdt; struct acpi_table_header *hdr; @@ -82,16 +87,16 @@ const char *acpi_get_sysname(void) return "dig"; } - rsdp = (struct acpi_table_rsdp *)__va(rsdp_phys); - if (strncmp(rsdp->signature, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)) { + rsdp = (struct acpi20_table_rsdp *)__va(rsdp_phys); + if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) { printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n"); return "dig"; } - xsdt = (struct acpi_table_xsdt *)__va(rsdp->xsdt_physical_address); + xsdt = (struct acpi_table_xsdt *)__va(rsdp->xsdt_address); hdr = &xsdt->header; - if (strncmp(hdr->signature, ACPI_SIG_XSDT, sizeof(ACPI_SIG_XSDT) - 1)) { + if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) { printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n"); return "dig"; @@ -164,12 +169,12 @@ struct acpi_table_madt *acpi_madt __initdata; static u8 has_8259; static int __init -acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, +acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic_override *lapic; + struct acpi_table_lapic_addr_ovr *lapic; - lapic = (struct acpi_madt_local_apic_override *)header; + lapic = (struct acpi_table_lapic_addr_ovr *)header; if (BAD_MADT_ENTRY(lapic, end)) return -EINVAL; @@ -182,19 +187,22 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, } static int __init -acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lsapic(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_sapic *lsapic; + struct acpi_table_lsapic *lsapic; - lsapic = (struct acpi_madt_local_sapic *)header; + lsapic = (struct acpi_table_lsapic *)header; - /*Skip BAD_MADT_ENTRY check, as lsapic size could vary */ + if (BAD_MADT_ENTRY(lsapic, end)) + return -EINVAL; - if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { + if (lsapic->flags.enabled) { #ifdef CONFIG_SMP smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid; #endif + ia64_acpiid_to_sapicid[lsapic->acpi_id] = + (lsapic->id << 8) | lsapic->eid; ++available_cpus; } @@ -203,11 +211,11 @@ acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end) } static int __init -acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic_nmi *lacpi_nmi; + struct acpi_table_lapic_nmi *lacpi_nmi; - lacpi_nmi = (struct acpi_madt_local_apic_nmi *)header; + lacpi_nmi = (struct acpi_table_lapic_nmi *)header; if (BAD_MADT_ENTRY(lacpi_nmi, end)) return -EINVAL; @@ -217,11 +225,11 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e } static int __init -acpi_parse_iosapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_iosapic(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_io_sapic *iosapic; + struct acpi_table_iosapic *iosapic; - iosapic = (struct acpi_madt_io_sapic *)header; + iosapic = (struct acpi_table_iosapic *)header; if (BAD_MADT_ENTRY(iosapic, end)) return -EINVAL; @@ -232,13 +240,13 @@ acpi_parse_iosapic(struct acpi_subtable_header * header, const unsigned long end static unsigned int __initdata acpi_madt_rev; static int __init -acpi_parse_plat_int_src(struct acpi_subtable_header * header, +acpi_parse_plat_int_src(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_interrupt_source *plintsrc; + struct acpi_table_plat_int_src *plintsrc; int vector; - plintsrc = (struct acpi_madt_interrupt_source *)header; + plintsrc = (struct acpi_table_plat_int_src *)header; if (BAD_MADT_ENTRY(plintsrc, end)) return -EINVAL; @@ -249,19 +257,19 @@ acpi_parse_plat_int_src(struct acpi_subtable_header * header, */ vector = iosapic_register_platform_intr(plintsrc->type, plintsrc->global_irq, - plintsrc->io_sapic_vector, + plintsrc->iosapic_vector, plintsrc->eid, plintsrc->id, - ((plintsrc->inti_flags & ACPI_MADT_POLARITY_MASK) == - ACPI_MADT_POLARITY_ACTIVE_HIGH) ? - IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, - ((plintsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) == - ACPI_MADT_TRIGGER_EDGE) ? - IOSAPIC_EDGE : IOSAPIC_LEVEL); + (plintsrc->flags.polarity == + 1) ? IOSAPIC_POL_HIGH : + IOSAPIC_POL_LOW, + (plintsrc->flags.trigger == + 1) ? IOSAPIC_EDGE : + IOSAPIC_LEVEL); platform_intr_list[plintsrc->type] = vector; if (acpi_madt_rev > 1) { - acpi_cpei_override = plintsrc->flags & ACPI_MADT_CPEI_OVERRIDE; + acpi_cpei_override = plintsrc->plint_flags.cpei_override_flag; } /* @@ -316,32 +324,30 @@ unsigned int get_cpei_target_cpu(void) } static int __init -acpi_parse_int_src_ovr(struct acpi_subtable_header * header, +acpi_parse_int_src_ovr(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_interrupt_override *p; + struct acpi_table_int_src_ovr *p; - p = (struct acpi_madt_interrupt_override *)header; + p = (struct acpi_table_int_src_ovr *)header; if (BAD_MADT_ENTRY(p, end)) return -EINVAL; - iosapic_override_isa_irq(p->source_irq, p->global_irq, - ((p->inti_flags & ACPI_MADT_POLARITY_MASK) == - ACPI_MADT_POLARITY_ACTIVE_HIGH) ? - IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, - ((p->inti_flags & ACPI_MADT_TRIGGER_MASK) == - ACPI_MADT_TRIGGER_EDGE) ? - IOSAPIC_EDGE : IOSAPIC_LEVEL); + iosapic_override_isa_irq(p->bus_irq, p->global_irq, + (p->flags.polarity == + 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + (p->flags.trigger == + 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); return 0; } static int __init -acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_nmi_source *nmi_src; + struct acpi_table_nmi_src *nmi_src; - nmi_src = (struct acpi_madt_nmi_source *)header; + nmi_src = (struct acpi_table_nmi_src *)header; if (BAD_MADT_ENTRY(nmi_src, end)) return -EINVAL; @@ -365,12 +371,12 @@ static void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) } } -static int __init acpi_parse_madt(struct acpi_table_header *table) +static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) { - if (!table) + if (!phys_addr || !size) return -EINVAL; - acpi_madt = (struct acpi_table_madt *)table; + acpi_madt = (struct acpi_table_madt *)__va(phys_addr); acpi_madt_rev = acpi_madt->header.revision; @@ -378,14 +384,14 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) #ifdef CONFIG_ITANIUM has_8259 = 1; /* Firmware on old Itanium systems is broken */ #else - has_8259 = acpi_madt->flags & ACPI_MADT_PCAT_COMPAT; + has_8259 = acpi_madt->flags.pcat_compat; #endif iosapic_system_init(has_8259); /* Get base address of IPI Message Block */ - if (acpi_madt->address) - ipi_base_addr = ioremap(acpi_madt->address, 0); + if (acpi_madt->lapic_address) + ipi_base_addr = ioremap(acpi_madt->lapic_address, 0); printk(KERN_INFO PREFIX "Local APIC address %p\n", ipi_base_addr); @@ -407,24 +413,23 @@ static u32 __devinitdata pxm_flag[PXM_FLAG_LEN]; #define pxm_bit_test(bit) (test_bit(bit,(void *)pxm_flag)) static struct acpi_table_slit __initdata *slit_table; -static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa) +static int get_processor_proximity_domain(struct acpi_table_processor_affinity *pa) { int pxm; - pxm = pa->proximity_domain_lo; + pxm = pa->proximity_domain; if (ia64_platform_is("sn2")) - pxm += pa->proximity_domain_hi[0] << 8; + pxm += pa->reserved[0] << 8; return pxm; } -static int get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma) +static int get_memory_proximity_domain(struct acpi_table_memory_affinity *ma) { int pxm; pxm = ma->proximity_domain; - if (!ia64_platform_is("sn2")) - pxm &= 0xff; - + if (ia64_platform_is("sn2")) + pxm += ma->reserved1[0] << 8; return pxm; } @@ -437,7 +442,7 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) u32 len; len = sizeof(struct acpi_table_header) + 8 - + slit->locality_count * slit->locality_count; + + slit->localities * slit->localities; if (slit->header.length != len) { printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", @@ -449,11 +454,11 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) } void __init -acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) +acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) { int pxm; - if (!(pa->flags & ACPI_SRAT_CPU_ENABLED)) + if (!pa->flags.enabled) return; pxm = get_processor_proximity_domain(pa); @@ -462,14 +467,14 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) pxm_bit_set(pxm); node_cpuid[srat_num_cpus].phys_id = - (pa->apic_id << 8) | (pa->local_sapic_eid); + (pa->apic_id << 8) | (pa->lsapic_eid); /* nid should be overridden as logical node id later */ node_cpuid[srat_num_cpus].nid = pxm; srat_num_cpus++; } void __init -acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) +acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) { unsigned long paddr, size; int pxm; @@ -478,11 +483,13 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) pxm = get_memory_proximity_domain(ma); /* fill node memory chunk structure */ - paddr = ma->base_address; - size = ma->length; + paddr = ma->base_addr_hi; + paddr = (paddr << 32) | ma->base_addr_lo; + size = ma->length_hi; + size = (size << 32) | ma->length_lo; /* Ignore disabled entries */ - if (!(ma->flags & ACPI_SRAT_MEM_ENABLED)) + if (!ma->flags.enabled) return; /* record this node in proximity bitmap */ @@ -553,16 +560,16 @@ void __init acpi_numa_arch_fixup(void) if (!slit_table) return; memset(numa_slit, -1, sizeof(numa_slit)); - for (i = 0; i < slit_table->locality_count; i++) { + for (i = 0; i < slit_table->localities; i++) { if (!pxm_bit_test(i)) continue; node_from = pxm_to_node(i); - for (j = 0; j < slit_table->locality_count; j++) { + for (j = 0; j < slit_table->localities; j++) { if (!pxm_bit_test(j)) continue; node_to = pxm_to_node(j); node_distance(node_from, node_to) = - slit_table->entry[i * slit_table->locality_count + j]; + slit_table->entry[i * slit_table->localities + j]; } } @@ -610,21 +617,21 @@ void acpi_unregister_gsi(u32 gsi) EXPORT_SYMBOL(acpi_unregister_gsi); -static int __init acpi_parse_fadt(struct acpi_table_header *table) +static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size) { struct acpi_table_header *fadt_header; - struct acpi_table_fadt *fadt; + struct fadt_descriptor *fadt; - if (!table) + if (!phys_addr || !size) return -EINVAL; - fadt_header = (struct acpi_table_header *)table; + fadt_header = (struct acpi_table_header *)__va(phys_addr); if (fadt_header->revision != 3) return -ENODEV; /* Only deal with ACPI 2.0 FADT */ - fadt = (struct acpi_table_fadt *)fadt_header; + fadt = (struct fadt_descriptor *)fadt_header; - acpi_register_gsi(fadt->sci_interrupt, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); + acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); return 0; } @@ -651,7 +658,7 @@ int __init acpi_boot_init(void) * information -- the successor to MPS tables. */ - if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt) < 1) { + if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) { printk(KERN_ERR PREFIX "Can't find MADT\n"); goto skip_madt; } @@ -659,40 +666,40 @@ int __init acpi_boot_init(void) /* Local APIC */ if (acpi_table_parse_madt - (ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, acpi_parse_lapic_addr_ovr, 0) < 0) + (ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, acpi_parse_lsapic, NR_CPUS) + if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, NR_CPUS) < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n"); - if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0) + if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* I/O APIC */ if (acpi_table_parse_madt - (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) + (ACPI_MADT_IOSAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n"); /* System-Level Interrupt Routing */ if (acpi_table_parse_madt - (ACPI_MADT_TYPE_INTERRUPT_SOURCE, acpi_parse_plat_int_src, + (ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src, ACPI_MAX_PLATFORM_INTERRUPTS) < 0) printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n"); if (acpi_table_parse_madt - (ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr, 0) < 0) + (ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, 0) < 0) printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src, 0) < 0) + if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, 0) < 0) printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); skip_madt: @@ -702,7 +709,7 @@ int __init acpi_boot_init(void) * gets interrupts such as power and sleep buttons. If it's not * on a Legacy interrupt, it needs to be setup. */ - if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt) < 1) + if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1) printk(KERN_ERR PREFIX "Can't find FADT\n"); #ifdef CONFIG_SMP @@ -835,7 +842,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - struct acpi_madt_local_sapic *lsapic; + struct acpi_table_lsapic *lsapic; cpumask_t tmp_map; long physid; int cpu; @@ -847,16 +854,16 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) return -EINVAL; obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER) - { + if (obj->type != ACPI_TYPE_BUFFER || + obj->buffer.length < sizeof(*lsapic)) { kfree(buffer.pointer); return -EINVAL; } - lsapic = (struct acpi_madt_local_sapic *)obj->buffer.pointer; + lsapic = (struct acpi_table_lsapic *)obj->buffer.pointer; - if ((lsapic->header.type != ACPI_MADT_TYPE_LOCAL_SAPIC) || - (!lsapic->lapic_flags & ACPI_MADT_ENABLED)) { + if ((lsapic->header.type != ACPI_MADT_LSAPIC) || + (!lsapic->flags.enabled)) { kfree(buffer.pointer); return -EINVAL; } @@ -876,6 +883,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) cpu_set(cpu, cpu_present_map); ia64_cpu_to_sapicid[cpu] = physid; + ia64_acpiid_to_sapicid[lsapic->acpi_id] = ia64_cpu_to_sapicid[cpu]; *pcpu = cpu; return (0); @@ -885,6 +893,14 @@ EXPORT_SYMBOL(acpi_map_lsapic); int acpi_unmap_lsapic(int cpu) { + int i; + + for (i = 0; i < MAX_SAPICS; i++) { + if (ia64_acpiid_to_sapicid[i] == ia64_cpu_to_sapicid[cpu]) { + ia64_acpiid_to_sapicid[i] = -1; + break; + } + } ia64_cpu_to_sapicid[cpu] = -1; cpu_clear(cpu, cpu_present_map); @@ -904,7 +920,7 @@ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - struct acpi_madt_io_sapic *iosapic; + struct acpi_table_iosapic *iosapic; unsigned int gsi_base; int pxm, node; @@ -922,9 +938,9 @@ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret) return AE_OK; } - iosapic = (struct acpi_madt_io_sapic *)obj->buffer.pointer; + iosapic = (struct acpi_table_iosapic *)obj->buffer.pointer; - if (iosapic->header.type != ACPI_MADT_TYPE_IO_SAPIC) { + if (iosapic->header.type != ACPI_MADT_IOSAPIC) { kfree(buffer.pointer); return AE_OK; } diff --git a/trunk/arch/ia64/kernel/msi_ia64.c b/trunk/arch/ia64/kernel/msi_ia64.c index 0d05450c91c4..822e59a1b822 100644 --- a/trunk/arch/ia64/kernel/msi_ia64.c +++ b/trunk/arch/ia64/kernel/msi_ia64.c @@ -64,17 +64,12 @@ static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask) } #endif /* CONFIG_SMP */ -int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) +int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) { struct msi_msg msg; unsigned long dest_phys_id; - unsigned int irq, vector; + unsigned int vector; - irq = create_irq(); - if (irq < 0) - return irq; - - set_irq_msi(irq, desc); dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); vector = irq; @@ -94,12 +89,12 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq); - return irq; + return 0; } void ia64_teardown_msi_irq(unsigned int irq) { - destroy_irq(irq); + return; /* no-op */ } static void ia64_ack_msi_irq(unsigned int irq) @@ -131,12 +126,12 @@ static struct irq_chip ia64_msi_chip = { }; -int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) +int arch_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) { if (platform_setup_msi_irq) - return platform_setup_msi_irq(pdev, desc); + return platform_setup_msi_irq(irq, pdev); - return ia64_setup_msi_irq(pdev, desc); + return ia64_setup_msi_irq(irq, pdev); } void arch_teardown_msi_irq(unsigned int irq) diff --git a/trunk/arch/ia64/sn/kernel/io_acpi_init.c b/trunk/arch/ia64/sn/kernel/io_acpi_init.c index 8c331ca6e5c9..cb96b4ea7df6 100644 --- a/trunk/arch/ia64/sn/kernel/io_acpi_init.c +++ b/trunk/arch/ia64/sn/kernel/io_acpi_init.c @@ -13,7 +13,6 @@ #include #include "xtalk/hubdev.h" #include -#include /* @@ -32,12 +31,6 @@ struct acpi_vendor_uuid sn_uuid = { 0xa2, 0x7c, 0x08, 0x00, 0x69, 0x13, 0xea, 0x51 }, }; -struct sn_pcidev_match { - u8 bus; - unsigned int devfn; - acpi_handle handle; -}; - /* * Perform the early IO init in PROM. */ @@ -126,11 +119,9 @@ sn_get_bussoft_ptr(struct pci_bus *bus) status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, &sn_uuid, &buffer); if (ACPI_FAILURE(status)) { - printk(KERN_ERR "%s: " - "acpi_get_vendor_resource() failed (0x%x) for: ", - __FUNCTION__, status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); + printk(KERN_ERR "get_acpi_pcibus_ptr: " + "get_acpi_bussoft_info() failed: %d\n", + status); return NULL; } resource = buffer.pointer; @@ -139,8 +130,8 @@ sn_get_bussoft_ptr(struct pci_bus *bus) if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != sizeof(struct pcibus_bussoft *)) { printk(KERN_ERR - "%s: Invalid vendor data length %d\n", - __FUNCTION__, vendor->byte_length); + "get_acpi_bussoft_ptr: Invalid vendor data " + "length %d\n", vendor->byte_length); kfree(buffer.pointer); return NULL; } @@ -152,254 +143,34 @@ sn_get_bussoft_ptr(struct pci_bus *bus) } /* - * sn_extract_device_info - Extract the pcidev_info and the sn_irq_info - * pointers from the vendor resource using the - * provided acpi handle, and copy the structures - * into the argument buffers. - */ -static int -sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info, - struct sn_irq_info **sn_irq_info) -{ - u64 addr; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - struct sn_irq_info *irq_info, *irq_info_prom; - struct pcidev_info *pcidev_ptr, *pcidev_prom_ptr; - struct acpi_resource *resource; - int ret = 0; - acpi_status status; - struct acpi_resource_vendor_typed *vendor; - - /* - * The pointer to this device's pcidev_info structure in - * the PROM, is in the vendor resource. - */ - status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, - &sn_uuid, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR - "%s: acpi_get_vendor_resource() failed (0x%x) for: ", - __FUNCTION__, status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); - return 1; - } - - resource = buffer.pointer; - vendor = &resource->data.vendor_typed; - if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != - sizeof(struct pci_devdev_info *)) { - printk(KERN_ERR - "%s: Invalid vendor data length: %d for: ", - __FUNCTION__, vendor->byte_length); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); - ret = 1; - goto exit; - } - - pcidev_ptr = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); - if (!pcidev_ptr) - panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__); - - memcpy(&addr, vendor->byte_data, sizeof(struct pcidev_info *)); - pcidev_prom_ptr = __va(addr); - memcpy(pcidev_ptr, pcidev_prom_ptr, sizeof(struct pcidev_info)); - - /* Get the IRQ info */ - irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (!irq_info) - panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__); - - if (pcidev_ptr->pdi_sn_irq_info) { - irq_info_prom = __va(pcidev_ptr->pdi_sn_irq_info); - memcpy(irq_info, irq_info_prom, sizeof(struct sn_irq_info)); - } - - *pcidev_info = pcidev_ptr; - *sn_irq_info = irq_info; - -exit: - kfree(buffer.pointer); - return ret; -} - -static unsigned int -get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle) -{ - unsigned long adr; - acpi_handle child; - unsigned int devfn; - int function; - acpi_handle parent; - int slot; - acpi_status status; - - /* - * Do an upward search to find the root bus device, and - * obtain the host devfn from the previous child device. - */ - child = device_handle; - while (child) { - status = acpi_get_parent(child, &parent); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR "%s: acpi_get_parent() failed " - "(0x%x) for: ", __FUNCTION__, status); - acpi_ns_print_node_pathname(child, NULL); - printk("\n"); - panic("%s: Unable to find host devfn\n", __FUNCTION__); - } - if (parent == rootbus_handle) - break; - child = parent; - } - if (!child) { - printk(KERN_ERR "%s: Unable to find root bus for: ", - __FUNCTION__); - acpi_ns_print_node_pathname(device_handle, NULL); - printk("\n"); - BUG(); - } - - status = acpi_evaluate_integer(child, METHOD_NAME__ADR, NULL, &adr); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: ", - __FUNCTION__, status); - acpi_ns_print_node_pathname(child, NULL); - printk("\n"); - panic("%s: Unable to find host devfn\n", __FUNCTION__); - } - - slot = (adr >> 16) & 0xffff; - function = adr & 0xffff; - devfn = PCI_DEVFN(slot, function); - return devfn; -} - -/* - * find_matching_device - Callback routine to find the ACPI device - * that matches up with our pci_dev device. - * Matching is done on bus number and devfn. - * To find the bus number for a particular - * ACPI device, we must look at the _BBN method - * of its parent. - */ -static acpi_status -find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - unsigned long bbn = -1; - unsigned long adr; - acpi_handle parent = NULL; - acpi_status status; - unsigned int devfn; - int function; - int slot; - struct sn_pcidev_match *info = context; - - status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, - &adr); - if (ACPI_SUCCESS(status)) { - status = acpi_get_parent(handle, &parent); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR - "%s: acpi_get_parent() failed (0x%x) for: ", - __FUNCTION__, status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); - return AE_OK; - } - status = acpi_evaluate_integer(parent, METHOD_NAME__BBN, - NULL, &bbn); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR - "%s: Failed to find _BBN in parent of: ", - __FUNCTION__); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); - return AE_OK; - } - - slot = (adr >> 16) & 0xffff; - function = adr & 0xffff; - devfn = PCI_DEVFN(slot, function); - if ((info->devfn == devfn) && (info->bus == bbn)) { - /* We have a match! */ - info->handle = handle; - return 1; - } - } - return AE_OK; -} - -/* - * sn_acpi_get_pcidev_info - Search ACPI namespace for the acpi - * device matching the specified pci_dev, - * and return the pcidev info and irq info. + * sn_acpi_bus_fixup */ -int -sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info, - struct sn_irq_info **sn_irq_info) +void +sn_acpi_bus_fixup(struct pci_bus *bus) { - unsigned int host_devfn; - struct sn_pcidev_match pcidev_match; - acpi_handle rootbus_handle; - unsigned long segment; - acpi_status status; + struct pci_dev *pci_dev = NULL; + struct pcibus_bussoft *prom_bussoft_ptr; + extern void sn_common_bus_fixup(struct pci_bus *, + struct pcibus_bussoft *); - rootbus_handle = PCI_CONTROLLER(dev)->acpi_handle; - status = acpi_evaluate_integer(rootbus_handle, METHOD_NAME__SEG, NULL, - &segment); - if (ACPI_SUCCESS(status)) { - if (segment != pci_domain_nr(dev)) { + if (!bus->parent) { /* If root bus */ + prom_bussoft_ptr = sn_get_bussoft_ptr(bus); + if (prom_bussoft_ptr == NULL) { printk(KERN_ERR - "%s: Segment number mismatch, 0x%lx vs 0x%x for: ", - __FUNCTION__, segment, pci_domain_nr(dev)); - acpi_ns_print_node_pathname(rootbus_handle, NULL); - printk("\n"); - return 1; + "sn_pci_fixup_bus: 0x%04x:0x%02x Unable to " + "obtain prom_bussoft_ptr\n", + pci_domain_nr(bus), bus->number); + return; } - } else { - printk(KERN_ERR "%s: Unable to get __SEG from: ", - __FUNCTION__); - acpi_ns_print_node_pathname(rootbus_handle, NULL); - printk("\n"); - return 1; + sn_common_bus_fixup(bus, prom_bussoft_ptr); } - - /* - * We want to search all devices in this segment/domain - * of the ACPI namespace for the matching ACPI device, - * which holds the pcidev_info pointer in its vendor resource. - */ - pcidev_match.bus = dev->bus->number; - pcidev_match.devfn = dev->devfn; - pcidev_match.handle = NULL; - - acpi_walk_namespace(ACPI_TYPE_DEVICE, rootbus_handle, ACPI_UINT32_MAX, - find_matching_device, &pcidev_match, NULL); - - if (!pcidev_match.handle) { - printk(KERN_ERR - "%s: Could not find matching ACPI device for %s.\n", - __FUNCTION__, pci_name(dev)); - return 1; + list_for_each_entry(pci_dev, &bus->devices, bus_list) { + sn_pci_fixup_slot(pci_dev); } - - if (sn_extract_device_info(pcidev_match.handle, pcidev_info, sn_irq_info)) - return 1; - - /* Build up the pcidev_info.pdi_slot_host_handle */ - host_devfn = get_host_devfn(pcidev_match.handle, rootbus_handle); - (*pcidev_info)->pdi_slot_host_handle = - ((unsigned long) pci_domain_nr(dev) << 40) | - /* bus == 0 */ - host_devfn; - return 0; } /* - * sn_acpi_slot_fixup - Obtain the pcidev_info and sn_irq_info. - * Perform any SN specific slot fixup. + * sn_acpi_slot_fixup - Perform any SN specific slot fixup. * At present there does not appear to be * any generic way to handle a ROM image * that has been shadowed by the PROM, so @@ -408,18 +179,11 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info, */ void -sn_acpi_slot_fixup(struct pci_dev *dev) +sn_acpi_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) { void __iomem *addr; - struct pcidev_info *pcidev_info = NULL; - struct sn_irq_info *sn_irq_info = NULL; size_t size; - if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) { - panic("%s: Failure obtaining pcidev_info for %s\n", - __FUNCTION__, pci_name(dev)); - } - if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) { /* * A valid ROM image exists and has been shadowed by the @@ -436,11 +200,8 @@ sn_acpi_slot_fixup(struct pci_dev *dev) (unsigned long) addr + size; dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY; } - sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); } -EXPORT_SYMBOL(sn_acpi_slot_fixup); - static struct acpi_driver acpi_sn_hubdev_driver = { .name = "SGI HUBDEV Driver", .ids = "SGIHUB,SGITIO", @@ -450,33 +211,6 @@ static struct acpi_driver acpi_sn_hubdev_driver = { }; -/* - * sn_acpi_bus_fixup - Perform SN specific setup of software structs - * (pcibus_bussoft, pcidev_info) and hardware - * registers, for the specified bus and devices under it. - */ -void -sn_acpi_bus_fixup(struct pci_bus *bus) -{ - struct pci_dev *pci_dev = NULL; - struct pcibus_bussoft *prom_bussoft_ptr; - - if (!bus->parent) { /* If root bus */ - prom_bussoft_ptr = sn_get_bussoft_ptr(bus); - if (prom_bussoft_ptr == NULL) { - printk(KERN_ERR - "%s: 0x%04x:0x%02x Unable to " - "obtain prom_bussoft_ptr\n", - __FUNCTION__, pci_domain_nr(bus), bus->number); - return; - } - sn_common_bus_fixup(bus, prom_bussoft_ptr); - } - list_for_each_entry(pci_dev, &bus->devices, bus_list) { - sn_acpi_slot_fixup(pci_dev); - } -} - /* * sn_io_acpi_init - PROM has ACPI support for IO, defining at a minimum the * nodes and root buses in the DSDT. As a result, bus scanning diff --git a/trunk/arch/ia64/sn/kernel/io_common.c b/trunk/arch/ia64/sn/kernel/io_common.c index d48bcd83253c..d4dd8f4b6b8d 100644 --- a/trunk/arch/ia64/sn/kernel/io_common.c +++ b/trunk/arch/ia64/sn/kernel/io_common.c @@ -26,10 +26,14 @@ #include #include #include -#include "acpi/acglobal.h" extern void sn_init_cpei_timer(void); extern void register_sn_procfs(void); +extern void sn_acpi_bus_fixup(struct pci_bus *); +extern void sn_bus_fixup(struct pci_bus *); +extern void sn_acpi_slot_fixup(struct pci_dev *, struct pcidev_info *); +extern void sn_more_slot_fixup(struct pci_dev *, struct pcidev_info *); +extern void sn_legacy_pci_window_fixup(struct pci_controller *, u64, u64); extern void sn_io_acpi_init(void); extern void sn_io_init(void); @@ -44,9 +48,6 @@ struct sysdata_el { int sn_ioif_inited; /* SN I/O infrastructure initialized? */ -int sn_acpi_rev; /* SN ACPI revision */ -EXPORT_SYMBOL_GPL(sn_acpi_rev); - struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ /* @@ -97,6 +98,25 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, return ret_stuff.status; } +/* + * Retrieve the pci device information given the bus and device|function number. + */ +static inline u64 +sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, + u64 sn_irq_info) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, + (u64) segment, (u64) bus_number, (u64) devfn, + (u64) pci_dev, + sn_irq_info, 0, 0); + return ret_stuff.v0; +} + /* * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified * device. @@ -229,25 +249,50 @@ void sn_pci_unfixup_slot(struct pci_dev *dev) } /* - * sn_pci_fixup_slot() + * sn_pci_fixup_slot() - This routine sets up a slot's resources consistent + * with the Linux PCI abstraction layer. Resources + * acquired from our PCI provider include PIO maps + * to BAR space and interrupt objects. */ -void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *pcidev_info, - struct sn_irq_info *sn_irq_info) +void sn_pci_fixup_slot(struct pci_dev *dev) { int segment = pci_domain_nr(dev->bus); + int status = 0; struct pcibus_bussoft *bs; - struct pci_bus *host_pci_bus; - struct pci_dev *host_pci_dev; - unsigned int bus_no, devfn; + struct pci_bus *host_pci_bus; + struct pci_dev *host_pci_dev; + struct pcidev_info *pcidev_info; + struct sn_irq_info *sn_irq_info; + unsigned int bus_no, devfn; pci_dev_get(dev); /* for the sysdata pointer */ + pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); + if (!pcidev_info) + BUG(); /* Cannot afford to run out of memory */ + + sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); + if (!sn_irq_info) + BUG(); /* Cannot afford to run out of memory */ + + /* Call to retrieve pci device information needed by kernel. */ + status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, + dev->devfn, + (u64) __pa(pcidev_info), + (u64) __pa(sn_irq_info)); + if (status) + BUG(); /* Cannot get platform pci device information */ /* Add pcidev_info to list in pci_controller.platform_data */ list_add_tail(&pcidev_info->pdi_list, &(SN_PLATFORM_DATA(dev->bus)->pcidev_info)); + + if (SN_ACPI_BASE_SUPPORT()) + sn_acpi_slot_fixup(dev, pcidev_info); + else + sn_more_slot_fixup(dev, pcidev_info); /* * Using the PROMs values for the PCI host bus, get the Linux - * PCI host_pci_dev struct and set up host bus linkages + * PCI host_pci_dev struct and set up host bus linkages */ bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff; @@ -444,6 +489,11 @@ void sn_generate_path(struct pci_bus *pci_bus, char *address) sprintf(address, "%s^%d", address, geo_slot(geoid)); } +/* + * sn_pci_fixup_bus() - Perform SN specific setup of software structs + * (pcibus_bussoft, pcidev_info) and hardware + * registers, for the specified bus and devices under it. + */ void __devinit sn_pci_fixup_bus(struct pci_bus *bus) { @@ -469,15 +519,6 @@ sn_io_early_init(void) if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; - /* we set the acpi revision to that of the DSDT table OEM rev. */ - { - struct acpi_table_header *header = NULL; - - acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header); - BUG_ON(header == NULL); - sn_acpi_rev = header->oem_revision; - } - /* * prime sn_pci_provider[]. Individial provider init routines will * override their respective default entries. @@ -503,12 +544,8 @@ sn_io_early_init(void) register_sn_procfs(); #endif - { - struct acpi_table_header *header; - (void)acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header); - printk(KERN_INFO "ACPI DSDT OEM Rev 0x%x\n", - header->oem_revision); - } + printk(KERN_INFO "ACPI DSDT OEM Rev 0x%x\n", + acpi_gbl_DSDT->oem_revision); if (SN_ACPI_BASE_SUPPORT()) sn_io_acpi_init(); else @@ -568,6 +605,7 @@ sn_io_late_init(void) fs_initcall(sn_io_late_init); +EXPORT_SYMBOL(sn_pci_fixup_slot); EXPORT_SYMBOL(sn_pci_unfixup_slot); EXPORT_SYMBOL(sn_bus_store_sysdata); EXPORT_SYMBOL(sn_bus_free_sysdata); diff --git a/trunk/arch/ia64/sn/kernel/io_init.c b/trunk/arch/ia64/sn/kernel/io_init.c index 600be3ebae05..9ad843e0383b 100644 --- a/trunk/arch/ia64/sn/kernel/io_init.c +++ b/trunk/arch/ia64/sn/kernel/io_init.c @@ -56,25 +56,6 @@ static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) return ret_stuff.v0; } -/* - * Retrieve the pci device information given the bus and device|function number. - */ -static inline u64 -sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, - u64 sn_irq_info) -{ - struct ia64_sal_retval ret_stuff; - ret_stuff.status = 0; - ret_stuff.v0 = 0; - - SAL_CALL_NOLOCK(ret_stuff, - (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, - (u64) segment, (u64) bus_number, (u64) devfn, - (u64) pci_dev, - sn_irq_info, 0, 0); - return ret_stuff.v0; -} - /* * sn_fixup_ionodes() - This routine initializes the HUB data structure for @@ -191,40 +172,18 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, } /* - * sn_io_slot_fixup() - We are not running with an ACPI capable PROM, + * sn_more_slot_fixup() - We are not running with an ACPI capable PROM, * and need to convert the pci_dev->resource * 'start' and 'end' addresses to mapped addresses, * and setup the pci_controller->window array entries. */ void -sn_io_slot_fixup(struct pci_dev *dev) +sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) { unsigned int count = 0; int idx; s64 pci_addrs[PCI_ROM_RESOURCE + 1]; unsigned long addr, end, size, start; - struct pcidev_info *pcidev_info; - struct sn_irq_info *sn_irq_info; - int status; - - pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); - if (!pcidev_info) - panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__); - - sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (!sn_irq_info) - panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__); - - /* Call to retrieve pci device information needed by kernel. */ - status = sal_get_pcidev_info((u64) pci_domain_nr(dev), - (u64) dev->bus->number, - dev->devfn, - (u64) __pa(pcidev_info), - (u64) __pa(sn_irq_info)); - - if (status) - BUG(); /* Cannot get platform pci device information */ - /* Copy over PIO Mapped Addresses */ for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { @@ -260,12 +219,8 @@ sn_io_slot_fixup(struct pci_dev *dev) */ if (count > 0) sn_pci_window_fixup(dev, count, pci_addrs); - - sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); } -EXPORT_SYMBOL(sn_io_slot_fixup); - /* * sn_pci_controller_fixup() - This routine sets up a bus's resources * consistent with the Linux PCI abstraction layer. @@ -317,6 +272,9 @@ sn_bus_fixup(struct pci_bus *bus) { struct pci_dev *pci_dev = NULL; struct pcibus_bussoft *prom_bussoft_ptr; + extern void sn_common_bus_fixup(struct pci_bus *, + struct pcibus_bussoft *); + if (!bus->parent) { /* If root bus */ prom_bussoft_ptr = PCI_CONTROLLER(bus)->platform_data; @@ -333,7 +291,7 @@ sn_bus_fixup(struct pci_bus *bus) prom_bussoft_ptr->bs_legacy_mem); } list_for_each_entry(pci_dev, &bus->devices, bus_list) { - sn_io_slot_fixup(pci_dev); + sn_pci_fixup_slot(pci_dev); } } diff --git a/trunk/arch/ia64/sn/kernel/iomv.c b/trunk/arch/ia64/sn/kernel/iomv.c index ab7e2fd40798..4aa4f301d56d 100644 --- a/trunk/arch/ia64/sn/kernel/iomv.c +++ b/trunk/arch/ia64/sn/kernel/iomv.c @@ -1,4 +1,4 @@ -/* +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -26,10 +26,9 @@ * @port: port to convert * * Legacy in/out instructions are converted to ld/st instructions - * on IA64. This routine will convert a port number into a valid + * on IA64. This routine will convert a port number into a valid * SN i/o address. Used by sn_in*() and sn_out*(). */ - void *sn_io_addr(unsigned long port) { if (!IS_RUNNING_ON_SIMULATOR()) { diff --git a/trunk/arch/ia64/sn/kernel/msi_sn.c b/trunk/arch/ia64/sn/kernel/msi_sn.c index ea3dc38d73fd..b3a435fd70fb 100644 --- a/trunk/arch/ia64/sn/kernel/msi_sn.c +++ b/trunk/arch/ia64/sn/kernel/msi_sn.c @@ -59,12 +59,13 @@ void sn_teardown_msi_irq(unsigned int irq) sn_intr_free(nasid, widget, sn_irq_info); sn_msi_info[irq].sn_irq_info = NULL; - destroy_irq(irq); + return; } -int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) +int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) { struct msi_msg msg; + struct msi_desc *entry; int widget; int status; nasid_t nasid; @@ -72,8 +73,8 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) struct sn_irq_info *sn_irq_info; struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); - int irq; + entry = get_irq_data(irq); if (!entry->msi_attrib.is_64) return -EINVAL; @@ -83,11 +84,6 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) if (provider == NULL || provider->dma_map_consistent == NULL) return -EINVAL; - irq = create_irq(); - if (irq < 0) - return irq; - - set_irq_msi(irq, entry); /* * Set up the vector plumbing. Let the prom (via sn_intr_alloc) * decide which cpu to direct this msi at by default. @@ -99,15 +95,12 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) SWIN_WIDGETNUM(bussoft->bs_base); sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (! sn_irq_info) { - destroy_irq(irq); + if (! sn_irq_info) return -ENOMEM; - } status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1); if (status) { kfree(sn_irq_info); - destroy_irq(irq); return -ENOMEM; } @@ -128,7 +121,6 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) if (! bus_addr) { sn_intr_free(nasid, widget, sn_irq_info); kfree(sn_irq_info); - destroy_irq(irq); return -ENOMEM; } @@ -147,7 +139,7 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); - return irq; + return 0; } #ifdef CONFIG_SMP diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 04a8256017eb..6846dc9b432d 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -20,8 +20,7 @@ #include "xtalk/hubdev.h" int -sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp, - char **ssdt) +sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) { struct ia64_sal_retval ret_stuff; u64 busnum; @@ -33,8 +32,7 @@ sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp, segment = soft->pbi_buscommon.bs_persist_segment; busnum = soft->pbi_buscommon.bs_persist_busnum; SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment, - busnum, (u64) device, (u64) resp, (u64)ia64_tpa(ssdt), - 0, 0); + busnum, (u64) device, (u64) resp, 0, 0, 0); return (int)ret_stuff.v0; } diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index f08e80a0bf0a..d6abe495c6b0 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -173,11 +173,6 @@ config PPC_86xx help The Freescale E600 SoCs have 74xx cores. -config PPC_8xx - bool "Freescale 8xx" - select FSL_SOC - select 8xx - config 40x bool "AMCC 40x" select PPC_DCR_NATIVE @@ -186,6 +181,8 @@ config 44x bool "AMCC 44x" select PPC_DCR_NATIVE +config 8xx + bool "Freescale 8xx" config E200 bool "Freescale e200" @@ -213,10 +210,6 @@ config POWER4 config 6xx bool -# this is temp to handle compat with arch=ppc -config 8xx - bool - # this is temp to handle compat with arch=ppc config 83xx bool @@ -436,21 +429,6 @@ config PPC_MPC52xx bool default n -config PPC_MPC5200 - bool - select PPC_MPC52xx - default n - -config PPC_MPC5200_BUGFIX - bool "MPC5200 (L25R) bugfix support" - depends on PPC_MPC5200 - default n - help - Enable workarounds for original MPC5200 errata. This is not required - for MPC5200B based boards. - - It is safe to say 'Y' here - config PPC_EFIKA bool "bPlan Efika 5k2. MPC5200B based computer" depends on PPC_MULTIPLATFORM && PPC32 @@ -463,7 +441,7 @@ config PPC_EFIKA config PPC_LITE5200 bool "Freescale Lite5200 Eval Board" depends on PPC_MULTIPLATFORM && PPC32 - select PPC_MPC5200 + select PPC_MPC52xx default n config PPC_PMAC @@ -506,7 +484,6 @@ config PPC_MAPLE select PPC_970_NAP select PPC_NATIVE select PPC_RTAS - select MMIO_NVRAM select ATA_NONSTANDARD if ATA default n help @@ -552,11 +529,6 @@ config PPC_PS3 bool "Sony PS3 (incomplete)" depends on PPC_MULTIPLATFORM && PPC64 select PPC_CELL - select USB_ARCH_HAS_OHCI - select USB_OHCI_LITTLE_ENDIAN - select USB_OHCI_BIG_ENDIAN_MMIO - select USB_ARCH_HAS_EHCI - select USB_EHCI_BIG_ENDIAN_MMIO help This option enables support for the Sony PS3 game console and other platforms using the PS3 hypervisor. @@ -564,16 +536,6 @@ config PPC_PS3 enabling this will not result in a bootable kernel on a PS3 system. -config PPC_CELLEB - bool "Toshiba's Cell Reference Set 'Celleb' Architecture" - depends on PPC_MULTIPLATFORM && PPC64 - select PPC_CELL - select PPC_OF_PLATFORM_PCI - select HAS_TXX9_SERIAL - select PPC_UDBG_BEAT - select USB_OHCI_BIG_ENDIAN_MMIO - select USB_EHCI_BIG_ENDIAN_MMIO - config PPC_NATIVE bool depends on PPC_MULTIPLATFORM @@ -587,11 +549,6 @@ config UDBG_RTAS_CONSOLE depends on PPC_RTAS default n -config PPC_UDBG_BEAT - bool "BEAT based debug console" - depends on PPC_CELLEB - default n - config XICS depends on PPC_PSERIES bool @@ -745,7 +702,6 @@ source arch/powerpc/platforms/86xx/Kconfig source arch/powerpc/platforms/8xx/Kconfig source arch/powerpc/platforms/cell/Kconfig source arch/powerpc/platforms/ps3/Kconfig -source arch/powerpc/platforms/pasemi/Kconfig menu "Kernel options" @@ -768,7 +724,7 @@ config FORCE_MAX_ZONEORDER config MATH_EMULATION bool "Math emulation" - depends on 4xx || 8xx || E200 || PPC_MPC832x || E500 + depends on 4xx || 8xx || E200 || PPC_83xx || E500 ---help--- Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the @@ -1226,7 +1182,7 @@ source "arch/powerpc/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on !BOOKE && !4xx && KALLSYMS && EXPERIMENTAL && MODULES + depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index d39d13327e6d..f0e51edde022 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -4,14 +4,14 @@ source "lib/Kconfig.debug" config DEBUG_STACKOVERFLOW bool "Check for stack overflows" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && PPC64 help This option will cause messages to be printed if free stack space drops below a certain limit. config DEBUG_STACK_USAGE bool "Stack utilization instrumentation" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && PPC64 help Enables the display of the minimum amount of free stack which each task has ever had available in the sysrq-T and sysrq-P debug output. @@ -185,20 +185,6 @@ config PPC_EARLY_DEBUG_ISERIES Select this to enable early debugging for legacy iSeries. You need to hit "Ctrl-x Ctrl-x" to see the messages on the console. -config PPC_EARLY_DEBUG_PAS_REALMODE - bool "PA Semi real mode" - depends on PPC_PASEMI - help - Select this to enable early debugging for PA Semi. - Output will be on UART0. - -config PPC_EARLY_DEBUG_BEAT - bool "Beat HV Console" - depends on PPC_CELLEB - select PPC_UDBG_BEAT - help - Select this to enable early debugging for Celleb with Beat. - endchoice endmenu diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index dc779407de14..98392fb5f581 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -162,7 +162,6 @@ image-$(CONFIG_PPC_PSERIES) += zImage.pseries image-$(CONFIG_PPC_MAPLE) += zImage.pseries image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries image-$(CONFIG_PPC_PS3) += zImage.ps3 -image-$(CONFIG_PPC_CELLEB) += zImage.pseries image-$(CONFIG_PPC_CHRP) += zImage.chrp image-$(CONFIG_PPC_EFIKA) += zImage.chrp image-$(CONFIG_PPC_PMAC) += zImage.pmac diff --git a/trunk/arch/powerpc/boot/dts/mpc8272ads.dts b/trunk/arch/powerpc/boot/dts/mpc8272ads.dts index 26b44f7513dc..34efdd028c4f 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8272ads.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8272ads.dts @@ -53,20 +53,13 @@ reg = <00000000 4000000 f4500000 00000020>; }; - chosen { - name = "chosen"; - linux,platform = <0>; - interrupt-controller = <10c00>; - linux,phandle = <400>; - }; - soc8272@f0000000 { #address-cells = <1>; #size-cells = <1>; #interrupt-cells = <2>; device_type = "soc"; - ranges = <00000000 f0000000 00053000>; - reg = ; + ranges = < 0 0 2 00000000 f0000000 00053000>; + reg = ; mdio@0 { device_type = "mdio"; @@ -78,7 +71,7 @@ ethernet-phy@0 { linux,phandle = <2452000>; interrupt-parent = <10c00>; - interrupts = <17 4>; + interrupts = <19 1>; reg = <0>; bitbang = [ 12 12 13 02 02 01 ]; device_type = "ethernet-phy"; @@ -86,7 +79,7 @@ ethernet-phy@1 { linux,phandle = <2452001>; interrupt-parent = <10c00>; - interrupts = <17 4>; + interrupts = <19 1>; bitbang = [ 12 12 13 02 02 01 ]; reg = <3>; device_type = "ethernet-phy"; @@ -97,7 +90,7 @@ #address-cells = <1>; #size-cells = <0>; device_type = "network"; - device-id = <1>; + device-id = <2>; compatible = "fs_enet"; model = "FCC"; reg = <11300 20 8400 100 11380 30>; @@ -111,7 +104,7 @@ ethernet@25000 { device_type = "network"; - device-id = <2>; + device-id = <3>; compatible = "fs_enet"; model = "FCC"; reg = <11320 20 8500 100 113b0 30>; @@ -130,8 +123,8 @@ #interrupt-cells = <2>; device_type = "cpm"; model = "CPM2"; - ranges = <00000000 00000000 20000>; - reg = <0 20000>; + ranges = <00000000 00000000 3ffff>; + reg = <10d80 3280>; command-proc = <119c0>; brg-frequency = <17D7840>; cpm_clk = ; @@ -140,7 +133,7 @@ device_type = "serial"; compatible = "cpm_uart"; model = "SCC"; - device-id = <1>; + device-id = <2>; reg = <11a00 20 8000 100>; current-speed = <1c200>; interrupts = <28 2>; @@ -154,7 +147,7 @@ device_type = "serial"; compatible = "cpm_uart"; model = "SCC"; - device-id = <4>; + device-id = <5>; reg = <11a60 20 8300 100>; current-speed = <1c200>; interrupts = <2b 2>; @@ -188,24 +181,24 @@ interrupt-map = < /* IDSEL 0x16 */ - b000 0 0 1 f8200000 40 8 - b000 0 0 2 f8200000 41 8 - b000 0 0 3 f8200000 42 8 - b000 0 0 4 f8200000 43 8 + b000 0 0 1 f8200000 40 0 + b000 0 0 2 f8200000 41 0 + b000 0 0 3 f8200000 42 0 + b000 0 0 4 f8200000 43 0 /* IDSEL 0x17 */ - b800 0 0 1 f8200000 43 8 - b800 0 0 2 f8200000 40 8 - b800 0 0 3 f8200000 41 8 - b800 0 0 4 f8200000 42 8 + b800 0 0 1 f8200000 43 0 + b800 0 0 2 f8200000 40 0 + b800 0 0 3 f8200000 41 0 + b800 0 0 4 f8200000 42 0 /* IDSEL 0x18 */ - c000 0 0 1 f8200000 42 8 - c000 0 0 2 f8200000 43 8 - c000 0 0 3 f8200000 40 8 - c000 0 0 4 f8200000 41 8>; + c000 0 0 1 f8200000 42 0 + c000 0 0 2 f8200000 43 0 + c000 0 0 3 f8200000 40 0 + c000 0 0 4 f8200000 41 0>; interrupt-parent = <10c00>; - interrupts = <14 8>; + interrupts = <14 3>; bus-range = <0 0>; ranges = <02000000 0 80000000 80000000 0 40000000 01000000 0 00000000 f6000000 0 02000000>; @@ -217,7 +210,7 @@ model = "SEC2"; compatible = "talitos"; reg = <30000 10000>; - interrupts = ; + interrupts = ; interrupt-parent = <10c00>; num-channels = <4>; channel-fifo-len = <18>; diff --git a/trunk/arch/powerpc/boot/dts/mpc8323emds.dts b/trunk/arch/powerpc/boot/dts/mpc8323emds.dts deleted file mode 100644 index fa7ef24d205b..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc8323emds.dts +++ /dev/null @@ -1,345 +0,0 @@ -/* - * MPC8323E EMDS Device Tree Source - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -/ { - model = "MPC8323EMDS"; - compatible = "MPC83xx"; - #address-cells = <1>; - #size-cells = <1>; - linux,phandle = <100>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - linux,phandle = <200>; - - PowerPC,8323@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; // 32 bytes - i-cache-line-size = <20>; // 32 bytes - d-cache-size = <4000>; // L1, 16K - i-cache-size = <4000>; // L1, 16K - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - 32-bit; - linux,phandle = <201>; - linux,boot-cpu; - }; - }; - - memory { - device_type = "memory"; - linux,phandle = <300>; - reg = <00000000 08000000>; - }; - - bcsr@f8000000 { - device_type = "board-control"; - reg = ; - }; - - soc8323@e0000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - ranges = <0 e0000000 00100000>; - reg = ; - bus-frequency = <7DE2900>; - - wdt@200 { - device_type = "watchdog"; - compatible = "mpc83xx_wdt"; - reg = <200 100>; - }; - - i2c@3000 { - device_type = "i2c"; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; - interrupt-parent = <700>; - dfsrr; - }; - - serial@4500 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; - clock-frequency = <0>; - interrupts = <9 8>; - interrupt-parent = <700>; - }; - - serial@4600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; - clock-frequency = <0>; - interrupts = ; - interrupt-parent = <700>; - }; - - crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; - reg = <30000 7000>; - interrupts = ; - interrupt-parent = <700>; - /* Rev. 2.2 */ - num-channels = <1>; - channel-fifo-len = <18>; - exec-units-mask = <0000004c>; - descriptor-types-mask = <0122003f>; - }; - - pci@8500 { - linux,phandle = <8500>; - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x11 AD17 */ - 8800 0 0 1 700 14 8 - 8800 0 0 2 700 15 8 - 8800 0 0 3 700 16 8 - 8800 0 0 4 700 17 8 - - /* IDSEL 0x12 AD18 */ - 9000 0 0 1 700 16 8 - 9000 0 0 2 700 17 8 - 9000 0 0 3 700 14 8 - 9000 0 0 4 700 15 8 - - /* IDSEL 0x13 AD19 */ - 9800 0 0 1 700 17 8 - 9800 0 0 2 700 14 8 - 9800 0 0 3 700 15 8 - 9800 0 0 4 700 16 8 - - /* IDSEL 0x15 AD21*/ - a800 0 0 1 700 14 8 - a800 0 0 2 700 15 8 - a800 0 0 3 700 16 8 - a800 0 0 4 700 17 8 - - /* IDSEL 0x16 AD22*/ - b000 0 0 1 700 17 8 - b000 0 0 2 700 14 8 - b000 0 0 3 700 15 8 - b000 0 0 4 700 16 8 - - /* IDSEL 0x17 AD23*/ - b800 0 0 1 700 16 8 - b800 0 0 2 700 17 8 - b800 0 0 3 700 14 8 - b800 0 0 4 700 15 8 - - /* IDSEL 0x18 AD24*/ - c000 0 0 1 700 15 8 - c000 0 0 2 700 16 8 - c000 0 0 3 700 17 8 - c000 0 0 4 700 14 8>; - interrupt-parent = <700>; - interrupts = <42 8>; - bus-range = <0 0>; - ranges = <02000000 0 a0000000 90000000 0 10000000 - 42000000 0 80000000 80000000 0 10000000 - 01000000 0 00000000 d0000000 0 00100000>; - clock-frequency = <0>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <8500 100>; - compatible = "83xx"; - device_type = "pci"; - }; - - pic@700 { - linux,phandle = <700>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <700 100>; - built-in; - device_type = "ipic"; - }; - - par_io@1400 { - reg = <1400 100>; - device_type = "par_io"; - num-ports = <7>; - - ucc_pin@03 { - linux,phandle = <140003>; - pio-map = < - /* port pin dir open_drain assignment has_irq */ - 3 4 3 0 2 0 /* MDIO */ - 3 5 1 0 2 0 /* MDC */ - 0 d 2 0 1 0 /* RX_CLK (CLK9) */ - 3 18 2 0 1 0 /* TX_CLK (CLK10) */ - 1 1 1 0 1 0 /* TxD1 */ - 1 0 1 0 1 0 /* TxD0 */ - 1 1 1 0 1 0 /* TxD1 */ - 1 2 1 0 1 0 /* TxD2 */ - 1 3 1 0 1 0 /* TxD3 */ - 1 4 2 0 1 0 /* RxD0 */ - 1 5 2 0 1 0 /* RxD1 */ - 1 6 2 0 1 0 /* RxD2 */ - 1 7 2 0 1 0 /* RxD3 */ - 1 8 2 0 1 0 /* RX_ER */ - 1 9 1 0 1 0 /* TX_ER */ - 1 a 2 0 1 0 /* RX_DV */ - 1 b 2 0 1 0 /* COL */ - 1 c 1 0 1 0 /* TX_EN */ - 1 d 2 0 1 0>;/* CRS */ - }; - ucc_pin@04 { - linux,phandle = <140004>; - pio-map = < - /* port pin dir open_drain assignment has_irq */ - 3 1f 2 0 1 0 /* RX_CLK (CLK7) */ - 3 6 2 0 1 0 /* TX_CLK (CLK8) */ - 1 12 1 0 1 0 /* TxD0 */ - 1 13 1 0 1 0 /* TxD1 */ - 1 14 1 0 1 0 /* TxD2 */ - 1 15 1 0 1 0 /* TxD3 */ - 1 16 2 0 1 0 /* RxD0 */ - 1 17 2 0 1 0 /* RxD1 */ - 1 18 2 0 1 0 /* RxD2 */ - 1 19 2 0 1 0 /* RxD3 */ - 1 1a 2 0 1 0 /* RX_ER */ - 1 1b 1 0 1 0 /* TX_ER */ - 1 1c 2 0 1 0 /* RX_DV */ - 1 1d 2 0 1 0 /* COL */ - 1 1e 1 0 1 0 /* TX_EN */ - 1 1f 2 0 1 0>;/* CRS */ - }; - }; - }; - - qe@e0100000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "qe"; - model = "QE"; - ranges = <0 e0100000 00100000>; - reg = ; - brg-frequency = <0>; - bus-frequency = ; - - muram@10000 { - device_type = "muram"; - ranges = <0 00010000 00004000>; - - data-only@0 { - reg = <0 4000>; - }; - }; - - spi@4c0 { - device_type = "spi"; - compatible = "fsl_spi"; - reg = <4c0 40>; - interrupts = <2>; - interrupt-parent = <80>; - mode = "cpu"; - }; - - spi@500 { - device_type = "spi"; - compatible = "fsl_spi"; - reg = <500 40>; - interrupts = <1>; - interrupt-parent = <80>; - mode = "cpu"; - }; - - usb@6c0 { - device_type = "usb"; - compatible = "qe_udc"; - reg = <6c0 40 8B00 100>; - interrupts = ; - interrupt-parent = <80>; - mode = "slave"; - }; - - ucc@2200 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; - device-id = <3>; - reg = <2200 200>; - interrupts = <22>; - interrupt-parent = <80>; - mac-address = [ 00 04 9f 00 23 23 ]; - rx-clock = <19>; - tx-clock = <1a>; - phy-handle = <212003>; - pio-handle = <140003>; - }; - - ucc@3200 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; - device-id = <4>; - reg = <3000 200>; - interrupts = <23>; - interrupt-parent = <80>; - mac-address = [ 00 11 22 33 44 55 ]; - rx-clock = <17>; - tx-clock = <18>; - phy-handle = <212004>; - pio-handle = <140004>; - }; - - mdio@2320 { - #address-cells = <1>; - #size-cells = <0>; - reg = <2320 18>; - device_type = "mdio"; - compatible = "ucc_geth_phy"; - - ethernet-phy@03 { - linux,phandle = <212003>; - interrupt-parent = <700>; - interrupts = <11 2>; - reg = <3>; - device_type = "ethernet-phy"; - interface = <3>; //ENET_100_MII - }; - ethernet-phy@04 { - linux,phandle = <212004>; - interrupt-parent = <700>; - interrupts = <12 2>; - reg = <4>; - device_type = "ethernet-phy"; - interface = <3>; - }; - }; - - qeic@80 { - linux,phandle = <80>; - interrupt-controller; - device_type = "qeic"; - #address-cells = <0>; - #interrupt-cells = <1>; - reg = <80 80>; - built-in; - big-endian; - interrupts = <20 8 21 8>; //high:32 low:33 - interrupt-parent = <700>; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc8560ads.dts b/trunk/arch/powerpc/boot/dts/mpc8560ads.dts index 119bd5d3a834..2b168486aeba 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8560ads.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8560ads.dts @@ -200,7 +200,7 @@ a800 0 0 4 40000 31 1>; interrupt-parent = <40000>; - interrupts = <8 0>; + interrupts = <42 0>; bus-range = <0 0>; ranges = <02000000 0 80000000 80000000 0 20000000 01000000 0 00000000 e2000000 0 01000000>; @@ -250,7 +250,7 @@ rx-clock = <1>; tx-clock = <1>; current-speed = <1c200>; - interrupts = <28 8>; + interrupts = <64 1>; interrupt-parent = <90c00>; }; @@ -264,7 +264,7 @@ rx-clock = <2>; tx-clock = <2>; current-speed = <1c200>; - interrupts = <29 8>; + interrupts = <65 1>; interrupt-parent = <90c00>; }; @@ -278,7 +278,7 @@ clock-setup = ; rx-clock = <15>; tx-clock = <16>; - interrupts = <21 8>; + interrupts = <5d 1>; interrupt-parent = <90c00>; phy-handle = <2452002>; }; @@ -293,7 +293,7 @@ clock-setup = ; rx-clock = <17>; tx-clock = <18>; - interrupts = <22 8>; + interrupts = <5e 1>; interrupt-parent = <90c00>; phy-handle = <2452003>; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc866ads.dts b/trunk/arch/powerpc/boot/dts/mpc866ads.dts deleted file mode 100644 index 5d4005239b83..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc866ads.dts +++ /dev/null @@ -1,162 +0,0 @@ -/* - * MPC866 ADS Device Tree Source - * - * Copyright 2006 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -/ { - model = "MPC866ADS"; - compatible = "mpc8xx"; - #address-cells = <1>; - #size-cells = <1>; - linux,phandle = <100>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - linux,phandle = <200>; - - PowerPC,866@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; // 32 bytes - i-cache-line-size = <20>; // 32 bytes - d-cache-size = <2000>; // L1, 8K - i-cache-size = <4000>; // L1, 16K - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - 32-bit; - interrupts = ; // decrementer interrupt - interrupt-parent = ; - linux,phandle = <201>; - linux,boot-cpu; - }; - }; - - memory { - device_type = "memory"; - linux,phandle = <300>; - reg = <00000000 800000>; - }; - - soc866@ff000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - ranges = <0 ff000000 00100000>; - reg = ; - bus-frequency = <0>; - mdio@e80 { - device_type = "mdio"; - compatible = "fs_enet"; - reg = ; - linux,phandle = ; - #address-cells = <1>; - #size-cells = <0>; - ethernet-phy@f { - linux,phandle = ; - reg = ; - device_type = "ethernet-phy"; - }; - }; - - fec@e00 { - device_type = "network"; - compatible = "fs_enet"; - model = "FEC"; - device-id = <1>; - reg = ; - mac-address = [ 00 00 0C 00 01 FD ]; - interrupts = <3 1>; - interrupt-parent = ; - phy-handle = ; - }; - - pic@ff000000 { - linux,phandle = ; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0 24>; - built-in; - device_type = "mpc8xx-pic"; - compatible = "CPM"; - }; - - cpm@ff000000 { - linux,phandle = ; - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "cpm"; - model = "CPM"; - ranges = <0 0 4000>; - reg = <860 f0>; - command-proc = <9c0>; - brg-frequency = <0>; - interrupts = <0 2>; // cpm error interrupt - interrupt-parent = <930>; - - pic@930 { - linux,phandle = <930>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - interrupts = <5 2 0 2>; - interrupt-parent = ; - reg = <930 20>; - built-in; - device_type = "cpm-pic"; - compatible = "CPM"; - }; - - smc@a80 { - device_type = "serial"; - compatible = "cpm_uart"; - model = "SMC"; - device-id = <1>; - reg = ; - clock-setup = <00ffffff 0>; - rx-clock = <1>; - tx-clock = <1>; - current-speed = <0>; - interrupts = <4 3>; - interrupt-parent = <930>; - }; - - smc@a90 { - device_type = "serial"; - compatible = "cpm_uart"; - model = "SMC"; - device-id = <2>; - reg = ; - clock-setup = ; - rx-clock = <2>; - tx-clock = <2>; - current-speed = <0>; - interrupts = <3 3>; - interrupt-parent = <930>; - }; - - scc@a00 { - device_type = "network"; - compatible = "fs_enet"; - model = "SCC"; - device-id = <1>; - reg = ; - mac-address = [ 00 00 0C 00 03 FD ]; - interrupts = <1e 3>; - interrupt-parent = <930>; - }; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc885ads.dts b/trunk/arch/powerpc/boot/dts/mpc885ads.dts deleted file mode 100644 index cf1a19f962c5..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc885ads.dts +++ /dev/null @@ -1,185 +0,0 @@ -/* - * MPC885 ADS Device Tree Source - * - * Copyright 2006 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -/ { - model = "MPC885ADS"; - compatible = "mpc8xx"; - #address-cells = <1>; - #size-cells = <1>; - linux,phandle = <100>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - linux,phandle = <200>; - - PowerPC,885@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; // 32 bytes - i-cache-line-size = <20>; // 32 bytes - d-cache-size = <2000>; // L1, 8K - i-cache-size = <2000>; // L1, 8K - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - 32-bit; - interrupts = ; // decrementer interrupt - interrupt-parent = ; - linux,phandle = <201>; - linux,boot-cpu; - }; - }; - - memory { - device_type = "memory"; - linux,phandle = <300>; - reg = <00000000 800000>; - }; - - soc885@ff000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - ranges = <0 ff000000 00100000>; - reg = ; - bus-frequency = <0>; - mdio@e80 { - device_type = "mdio"; - compatible = "fs_enet"; - reg = ; - linux,phandle = ; - #address-cells = <1>; - #size-cells = <0>; - ethernet-phy@0 { - linux,phandle = ; - reg = <0>; - device_type = "ethernet-phy"; - }; - ethernet-phy@1 { - linux,phandle = ; - reg = <1>; - device_type = "ethernet-phy"; - }; - ethernet-phy@2 { - linux,phandle = ; - reg = <2>; - device_type = "ethernet-phy"; - }; - }; - - fec@e00 { - device_type = "network"; - compatible = "fs_enet"; - model = "FEC"; - device-id = <1>; - reg = ; - mac-address = [ 00 00 0C 00 01 FD ]; - interrupts = <3 1>; - interrupt-parent = ; - phy-handle = ; - }; - - fec@1e00 { - device_type = "network"; - compatible = "fs_enet"; - model = "FEC"; - device-id = <2>; - reg = <1e00 188>; - mac-address = [ 00 00 0C 00 02 FD ]; - interrupts = <7 1>; - interrupt-parent = ; - phy-handle = ; - }; - - pic@ff000000 { - linux,phandle = ; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0 24>; - built-in; - device_type = "mpc8xx-pic"; - compatible = "CPM"; - }; - - cpm@ff000000 { - linux,phandle = ; - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "cpm"; - model = "CPM"; - ranges = <0 0 4000>; - reg = <860 f0>; - command-proc = <9c0>; - brg-frequency = <0>; - interrupts = <0 2>; // cpm error interrupt - interrupt-parent = <930>; - - pic@930 { - linux,phandle = <930>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - interrupts = <5 2 0 2>; - interrupt-parent = ; - reg = <930 20>; - built-in; - device_type = "cpm-pic"; - compatible = "CPM"; - }; - - smc@a80 { - device_type = "serial"; - compatible = "cpm_uart"; - model = "SMC"; - device-id = <1>; - reg = ; - clock-setup = <00ffffff 0>; - rx-clock = <1>; - tx-clock = <1>; - current-speed = <0>; - interrupts = <4 3>; - interrupt-parent = <930>; - }; - - smc@a90 { - device_type = "serial"; - compatible = "cpm_uart"; - model = "SMC"; - device-id = <2>; - reg = ; - clock-setup = ; - rx-clock = <2>; - tx-clock = <2>; - current-speed = <0>; - interrupts = <3 3>; - interrupt-parent = <930>; - }; - - scc@a40 { - device_type = "network"; - compatible = "fs_enet"; - model = "SCC"; - device-id = <3>; - reg = ; - mac-address = [ 00 00 0C 00 03 FD ]; - interrupts = <1c 3>; - interrupt-parent = <930>; - phy-handle = ; - }; - }; - }; -}; diff --git a/trunk/arch/powerpc/configs/celleb_defconfig b/trunk/arch/powerpc/configs/celleb_defconfig deleted file mode 100644 index a1fe97197ead..000000000000 --- a/trunk/arch/powerpc/configs/celleb_defconfig +++ /dev/null @@ -1,1408 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc4 -# Thu Jan 11 20:55:33 2007 -# -CONFIG_PPC64=y -CONFIG_64BIT=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_IRQ_PER_CPU=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_ARCH_HAS_ILOG2_U64=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_COMPAT=y -CONFIG_SYSVIPC_COMPAT=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -# CONFIG_PPC_UDBG_16550 is not set -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -# CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -# CONFIG_POWER4_ONLY is not set -CONFIG_POWER3=y -CONFIG_POWER4=y -CONFIG_PPC_FPU=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_PPC_OF_PLATFORM_PCI=y -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -CONFIG_VIRT_CPU_ACCOUNTING=y -CONFIG_SMP=y -CONFIG_NR_CPUS=4 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_CPUSETS is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -# CONFIG_EMBEDDED is not set -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Platform support -# -CONFIG_PPC_MULTIPLATFORM=y -# CONFIG_EMBEDDED6xx is not set -# CONFIG_APUS is not set -# CONFIG_PPC_PSERIES is not set -# CONFIG_PPC_ISERIES is not set -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_PMAC is not set -# CONFIG_PPC_MAPLE is not set -# CONFIG_PPC_PASEMI is not set -CONFIG_PPC_CELL=y -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PPC_IBM_CELL_BLADE is not set -# CONFIG_PPC_PS3 is not set -CONFIG_PPC_CELLEB=y -CONFIG_PPC_UDBG_BEAT=y -# CONFIG_U3_DART is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_WANT_EARLY_SERIAL is not set -# CONFIG_MPIC is not set - -# -# Cell Broadband Engine options -# -CONFIG_SPU_FS=y -CONFIG_SPU_BASE=y -# CONFIG_CBE_RAS is not set - -# -# Kernel options -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_PREEMPT_BKL=y -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -CONFIG_FORCE_MAX_ZONEORDER=13 -# CONFIG_IOMMU_VMERGE is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_KEXEC=y -# CONFIG_CRASH_DUMP is not set -# CONFIG_IRQ_ALL_CPUS is not set -CONFIG_NUMA=y -CONFIG_NODES_SHIFT=4 -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -# CONFIG_FLATMEM_MANUAL is not set -# CONFIG_DISCONTIGMEM_MANUAL is not set -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM=y -CONFIG_NEED_MULTIPLE_NODES=y -CONFIG_HAVE_MEMORY_PRESENT=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_MEMORY_HOTPLUG=y -CONFIG_MEMORY_HOTPLUG_SPARSE=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y -CONFIG_RESOURCES_64BIT=y -CONFIG_ARCH_MEMORY_PROBE=y -CONFIG_NODES_SPAN_OTHER_NODES=y -# CONFIG_PPC_64K_PAGES is not set -# CONFIG_SCHED_SMT is not set -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_INDIRECT_PCI is not set -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set -CONFIG_KERNEL_START=0xc000000000000000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -# CONFIG_IPV6_MIP6 is not set -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NF_CONNTRACK_ENABLED is not set -# CONFIG_NETFILTER_XTABLES is not set - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_QUEUE=m - -# -# IPv6: Netfilter Configuration (EXPERIMENTAL) -# -# CONFIG_IP6_NF_QUEUE is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -CONFIG_BLK_DEV_IDECD=m -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SL82C105 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_BLK_DEV_IDE_CELLEB=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=m -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_SCSI_PROC_FS is not set - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=m -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=m -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=m -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -# CONFIG_MD_RAID10 is not set -# CONFIG_MD_RAID456 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_MD_FAULTY is not set -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -# CONFIG_DM_MULTIPATH_EMC is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_SPIDER_NET=y -# CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_COMPUTONE is not set -# CONFIG_ROCKETPORT is not set -# CONFIG_CYCLADES is not set -# CONFIG_DIGIEPCA is not set -# CONFIG_MOXA_INTELLIO is not set -# CONFIG_MOXA_SMARTIO is not set -# CONFIG_MOXA_SMARTIO_NEW is not set -# CONFIG_ISI is not set -# CONFIG_SYNCLINK is not set -# CONFIG_SYNCLINKMP is not set -# CONFIG_SYNCLINK_GT is not set -# CONFIG_N_HDLC is not set -# CONFIG_SPECIALIX is not set -# CONFIG_SX is not set -# CONFIG_RIO is not set -# CONFIG_STALDRV is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_TXX9=y -CONFIG_HAS_TXX9_SERIAL=y -CONFIG_SERIAL_TXX9_CONSOLE=y -# CONFIG_SERIAL_TXX9_STDSERIAL is not set -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_HVC_DRIVER=y -CONFIG_HVC_BEAT=y - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -# CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_HANGCHECK_TIMER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=y -# CONFIG_I2C_CHARDEV is not set - -# -# I2C Algorithms -# -CONFIG_I2C_ALGOBIT=y -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB is not set -# CONFIG_FB_IBM_GXT4500 is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_MULTITHREAD_PROBE is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=m -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=m -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -CONFIG_USB_HIDDEV=y -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT2_FS_XIP=y -CONFIG_FS_XIP=y -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -CONFIG_NFS_V3_ACL=y -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=m -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -# CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m -CONFIG_NFS_ACL_SUPPORT=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -CONFIG_EFI_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=m -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y - -# -# Instrumentation Support -# -# CONFIG_PROFILING is not set -# CONFIG_KPROBES is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=15 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_RWSEMS is not set -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_FORCED_INLINING is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUGGER=y -CONFIG_XMON=y -CONFIG_XMON_DEFAULT=y -CONFIG_XMON_DISASSEMBLY=y -CONFIG_IRQSTACKS=y -# CONFIG_BOOTX_TEXT is not set -CONFIG_PPC_EARLY_DEBUG=y -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set -CONFIG_PPC_EARLY_DEBUG_BEAT=y - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_TEST=m - -# -# Hardware crypto devices -# diff --git a/trunk/arch/powerpc/configs/mpc8272_ads_defconfig b/trunk/arch/powerpc/configs/mpc8272_ads_defconfig deleted file mode 100644 index 2af45025082f..000000000000 --- a/trunk/arch/powerpc/configs/mpc8272_ads_defconfig +++ /dev/null @@ -1,848 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc5 -# Fri Jul 14 20:36:35 2006 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_IRQ_PER_CPU=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -# CONFIG_PPC_UDBG_16550 is not set -# CONFIG_GENERIC_TBSYNC is not set -# CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -# CONFIG_CLASSIC32 is not set -# CONFIG_PPC_52xx is not set -CONFIG_PPC_82xx=y -# CONFIG_PPC_83xx is not set -# CONFIG_PPC_85xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -CONFIG_6xx=y -CONFIG_PPC_FPU=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_SMP is not set - -# -# Code maturity level options -# -# CONFIG_EXPERIMENTAL is not set -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="powerpc8272" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_EXTRA_PASS=y -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_PQ2ADS=y -CONFIG_8260=y -CONFIG_8272=y -CONFIG_CPM2=y -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_EMBEDDEDBOOT=y - -# -# Platform support -# -CONFIG_ADS8272=y - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -# CONFIG_PC_KEYBOARD is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -# CONFIG_PPC_I8259 is not set -CONFIG_FSL_SOC=y -# CONFIG_PCI is not set -# CONFIG_PCI_DOMAINS is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00400000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_IPV6_TUNNEL is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_XTABLES is not set - -# -# IP: Netfilter Configuration -# -# CONFIG_IP_NF_CONNTRACK is not set -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_IDE_GENERIC is not set -# CONFIG_IDE_ARM is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=y - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -CONFIG_DAVICOM_PHY=y -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_FS_ENET=y -# CONFIG_FS_ENET_HAS_SCC is not set -CONFIG_FS_ENET_HAS_FCC=y - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -CONFIG_PPP=y -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=y -CONFIG_PPP_SYNC_TTY=y -CONFIG_PPP_DEFLATE=y -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_SLIP is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_CPM=y -CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_SERIAL_CPM_SCC1=y -# CONFIG_SERIAL_CPM_SCC2 is not set -# CONFIG_SERIAL_CPM_SCC3 is not set -CONFIG_SERIAL_CPM_SCC4=y -# CONFIG_SERIAL_CPM_SMC1 is not set -# CONFIG_SERIAL_CPM_SMC2 is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG_FILES is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA2XX is not set -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_AT91 is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -# CONFIG_USB_GADGET_DUALSPEED is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_XFS_FS=y -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_HFSPLUS_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_NFS_V3_ACL=y -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SMB_FS=y -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=y - -# -# Library routines -# -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_DEBUGGER is not set -# CONFIG_KGDB_CONSOLE is not set -CONFIG_BDI_SWITCH=y -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/powerpc/configs/mpc832xemds_defconfig b/trunk/arch/powerpc/configs/mpc832xemds_defconfig deleted file mode 100644 index e1b36de6b38c..000000000000 --- a/trunk/arch/powerpc/configs/mpc832xemds_defconfig +++ /dev/null @@ -1,1083 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc5 -# Tue Jan 30 14:27:25 2007 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_IRQ_PER_CPU=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_PPC_UDBG_16550=y -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -CONFIG_DEFAULT_UIMAGE=y - -# -# Processor support -# -# CONFIG_CLASSIC32 is not set -# CONFIG_PPC_82xx is not set -CONFIG_PPC_83xx=y -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_86xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -CONFIG_6xx=y -CONFIG_83xx=y -CONFIG_PPC_FPU=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_SMP is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -# CONFIG_KALLSYMS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_QUICC_ENGINE=y -CONFIG_PPC_GEN550=y -# CONFIG_WANT_EARLY_SERIAL is not set - -# -# Platform support -# -CONFIG_MPC832x_MDS=y -# CONFIG_MPC834x_SYS is not set -# CONFIG_MPC834x_ITX is not set -# CONFIG_MPC8360E_PB is not set -CONFIG_PPC_MPC832x=y -# CONFIG_MPIC is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_MATH_EMULATION=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCIEPORTBUS is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -# CONFIG_BLK_DEV_SD is not set -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_GIANFAR is not set -CONFIG_UCC_GETH=y -# CONFIG_UGETH_NAPI is not set -# CONFIG_UGETH_MAGIC_PACKET is not set -# CONFIG_UGETH_FILTERING is not set -# CONFIG_UGETH_TX_ON_DEMOND is not set -# CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_83xx_WDT=y - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_M41T00 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB is not set -# CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# QE Options -# -CONFIG_UCC_SLOW=y -CONFIG_UCC_FAST=y -CONFIG_UCC=y - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y - -# -# Instrumentation Support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_SERIAL_TEXT_DEBUG is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_MANAGER=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/powerpc/configs/mpc834x_itx_defconfig b/trunk/arch/powerpc/configs/mpc834x_itx_defconfig index 7902806429f8..45757b613702 100644 --- a/trunk/arch/powerpc/configs/mpc834x_itx_defconfig +++ b/trunk/arch/powerpc/configs/mpc834x_itx_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.20-rc5 -# Fri Jan 26 00:19:02 2007 +# Mon Jan 22 22:23:43 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -149,6 +149,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +CONFIG_MATH_EMULATION=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y @@ -323,7 +324,6 @@ CONFIG_MTD=y # User Modules And Translation Layers # CONFIG_MTD_CHAR=y -# CONFIG_MTD_BLKDEVS is not set # CONFIG_MTD_BLOCK is not set # CONFIG_MTD_BLOCK_RO is not set # CONFIG_FTL is not set @@ -366,7 +366,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_MTD_PHYSMAP_START=0xfe000000 CONFIG_MTD_PHYSMAP_LEN=0x1000000 CONFIG_MTD_PHYSMAP_BANKWIDTH=2 -# CONFIG_MTD_PHYSMAP_OF is not set # CONFIG_MTD_PLATRAM is not set # @@ -391,7 +390,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # NAND Flash Device Drivers # # CONFIG_MTD_NAND is not set -# CONFIG_MTD_NAND_CAFE is not set # # OneNAND Flash Device Drivers @@ -1013,6 +1011,7 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # diff --git a/trunk/arch/powerpc/configs/mpc834x_mds_defconfig b/trunk/arch/powerpc/configs/mpc834x_mds_defconfig index 9eaed3a36983..c24db58be457 100644 --- a/trunk/arch/powerpc/configs/mpc834x_mds_defconfig +++ b/trunk/arch/powerpc/configs/mpc834x_mds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.20-rc5 -# Fri Jan 26 00:19:27 2007 +# Mon Jan 22 22:24:10 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -149,6 +149,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +CONFIG_MATH_EMULATION=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y diff --git a/trunk/arch/powerpc/configs/mpc8360emds_defconfig b/trunk/arch/powerpc/configs/mpc8360emds_defconfig index bbe38ccc3d86..58e6795dbfe5 100644 --- a/trunk/arch/powerpc/configs/mpc8360emds_defconfig +++ b/trunk/arch/powerpc/configs/mpc8360emds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.20-rc5 -# Fri Jan 26 00:19:45 2007 +# Mon Jan 22 22:24:40 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -150,6 +150,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +CONFIG_MATH_EMULATION=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y diff --git a/trunk/arch/powerpc/configs/mpc866_ads_defconfig b/trunk/arch/powerpc/configs/mpc866_ads_defconfig deleted file mode 100644 index 539d9e3d3668..000000000000 --- a/trunk/arch/powerpc/configs/mpc866_ads_defconfig +++ /dev/null @@ -1,829 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc6 -# Fri Nov 24 21:13:55 2006 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_IRQ_PER_CPU=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -# CONFIG_PPC_UDBG_16550 is not set -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -# CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -# CONFIG_CLASSIC32 is not set -# CONFIG_PPC_52xx is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PPC_83xx is not set -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_86xx is not set -CONFIG_PPC_8xx=y -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_8xx=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_NOT_COHERENT_CACHE=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set -CONFIG_PRINTK=y -# CONFIG_BUG is not set -CONFIG_ELF_CORE=y -# CONFIG_BASE_FULL is not set -CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -CONFIG_SHMEM=y -CONFIG_SLAB=y -# CONFIG_VM_EVENT_COUNTERS is not set -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_EMBEDDEDBOOT=y -# CONFIG_MPIC is not set - -# -# Platform support -# -CONFIG_CPM1=y -# CONFIG_MPC8XXFADS is not set -CONFIG_MPC86XADS=y -# CONFIG_MPC885ADS is not set - -# -# MPC8xx CPM Options -# - -# -# Generic MPC8xx Options -# -CONFIG_8xx_COPYBACK=y -CONFIG_8xx_CPU6=y -CONFIG_NO_UCODE_PATCH=y -# CONFIG_USB_SOF_UCODE_PATCH is not set -# CONFIG_I2C_SPI_UCODE_PATCH is not set -# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_MATH_EMULATION=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SECCOMP is not set -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -CONFIG_FSL_SOC=y -# CONFIG_PCI is not set -# CONFIG_PCI_DOMAINS is not set -# CONFIG_PCI_QSPAN is not set - -# -# PCCARD (PCMCIA/CardBus) support -# - -# -# PCI Hotplug Support -# - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_CONSISTENT_START=0xff100000 -CONFIG_CONSISTENT_SIZE=0x00200000 -CONFIG_BOOT_LOAD=0x00400000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -CONFIG_FIXED_PHY=y -CONFIG_FIXED_MII_10_FDX=y -CONFIG_FIXED_MII_100_FDX=y - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_FEC_8XX is not set -CONFIG_FS_ENET=y -CONFIG_FS_ENET_HAS_SCC=y -CONFIG_FS_ENET_HAS_FEC=y - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_CPM=y -CONFIG_SERIAL_CPM_CONSOLE=y -# CONFIG_SERIAL_CPM_SCC1 is not set -# CONFIG_SERIAL_CPM_SCC2 is not set -# CONFIG_SERIAL_CPM_SCC3 is not set -# CONFIG_SERIAL_CPM_SCC4 is not set -CONFIG_SERIAL_CPM_SMC1=y -CONFIG_SERIAL_CPM_SMC2=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -# CONFIG_EXT2_FS_POSIX_ACL is not set -# CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Library routines -# -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y - -# -# Instrumentation Support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_FS is not set -# CONFIG_UNWIND_INFO is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set diff --git a/trunk/arch/powerpc/configs/mpc885_ads_defconfig b/trunk/arch/powerpc/configs/mpc885_ads_defconfig deleted file mode 100644 index e2c17d8da4fc..000000000000 --- a/trunk/arch/powerpc/configs/mpc885_ads_defconfig +++ /dev/null @@ -1,827 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc4 -# Fri Nov 10 21:30:40 2006 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_IRQ_PER_CPU=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -# CONFIG_PPC_UDBG_16550 is not set -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -# CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -# CONFIG_CLASSIC32 is not set -# CONFIG_PPC_52xx is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PPC_83xx is not set -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_86xx is not set -CONFIG_PPC_8xx=y -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_8xx=y -CONFIG_NOT_COHERENT_CACHE=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set -CONFIG_PRINTK=y -# CONFIG_BUG is not set -CONFIG_ELF_CORE=y -# CONFIG_BASE_FULL is not set -CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -CONFIG_SHMEM=y -CONFIG_SLAB=y -# CONFIG_VM_EVENT_COUNTERS is not set -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_EMBEDDEDBOOT=y -# CONFIG_MPIC is not set - -# -# Platform support -# -CONFIG_CPM1=y -# CONFIG_MPC8XXFADS is not set -# CONFIG_MPC86XADS is not set -CONFIG_MPC885ADS=y - -# -# MPC8xx CPM Options -# - -# -# Generic MPC8xx Options -# -CONFIG_8xx_COPYBACK=y -# CONFIG_8xx_CPU6 is not set -CONFIG_NO_UCODE_PATCH=y -# CONFIG_USB_SOF_UCODE_PATCH is not set -# CONFIG_I2C_SPI_UCODE_PATCH is not set -# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_MATH_EMULATION=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SECCOMP is not set -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -CONFIG_FSL_SOC=y -# CONFIG_PCI is not set -# CONFIG_PCI_DOMAINS is not set -# CONFIG_PCI_QSPAN is not set - -# -# PCCARD (PCMCIA/CardBus) support -# - -# -# PCI Hotplug Support -# - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_CONSISTENT_START=0xff100000 -CONFIG_CONSISTENT_SIZE=0x00200000 -CONFIG_BOOT_LOAD=0x00400000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -CONFIG_DAVICOM_PHY=y -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -CONFIG_FIXED_PHY=y -CONFIG_FIXED_MII_10_FDX=y -# CONFIG_FIXED_MII_100_FDX is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_FEC_8XX is not set -CONFIG_FS_ENET=y -CONFIG_FS_ENET_HAS_SCC=y -CONFIG_FS_ENET_HAS_FEC=y - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_CPM=y -CONFIG_SERIAL_CPM_CONSOLE=y -# CONFIG_SERIAL_CPM_SCC1 is not set -# CONFIG_SERIAL_CPM_SCC2 is not set -# CONFIG_SERIAL_CPM_SCC3 is not set -# CONFIG_SERIAL_CPM_SCC4 is not set -CONFIG_SERIAL_CPM_SMC1=y -CONFIG_SERIAL_CPM_SMC2=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -# CONFIG_EXT2_FS_POSIX_ACL is not set -# CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Library routines -# -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y - -# -# Instrumentation Support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_FS is not set -# CONFIG_UNWIND_INFO is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set diff --git a/trunk/arch/powerpc/configs/pasemi_defconfig b/trunk/arch/powerpc/configs/pasemi_defconfig deleted file mode 100644 index 97a57e996663..000000000000 --- a/trunk/arch/powerpc/configs/pasemi_defconfig +++ /dev/null @@ -1,1722 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc6 -# Thu Feb 1 22:54:15 2007 -# -CONFIG_PPC64=y -CONFIG_64BIT=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_IRQ_PER_CPU=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_ARCH_HAS_ILOG2_U64=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_COMPAT=y -CONFIG_SYSVIPC_COMPAT=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_PPC_UDBG_16550=y -CONFIG_GENERIC_TBSYNC=y -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -# CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -CONFIG_POWER4_ONLY=y -CONFIG_POWER4=y -CONFIG_PPC_FPU=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -# CONFIG_PPC_OF_PLATFORM_PCI is not set -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -# CONFIG_VIRT_CPU_ACCOUNTING is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_CPUSETS is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -# CONFIG_EMBEDDED is not set -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set -CONFIG_STOP_MACHINE=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Platform support -# -CONFIG_PPC_MULTIPLATFORM=y -# CONFIG_EMBEDDED6xx is not set -# CONFIG_APUS is not set -CONFIG_PPC_PSERIES=y -# CONFIG_PPC_ISERIES is not set -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_PMAC is not set -# CONFIG_PPC_MAPLE is not set -CONFIG_PPC_PASEMI=y -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PPC_IBM_CELL_BLADE is not set -# CONFIG_PPC_PS3 is not set -CONFIG_PPC_NATIVE=y -# CONFIG_UDBG_RTAS_CONSOLE is not set -CONFIG_XICS=y -# CONFIG_U3_DART is not set -CONFIG_PPC_RTAS=y -CONFIG_RTAS_ERROR_LOGGING=y -CONFIG_RTAS_PROC=y -# CONFIG_RTAS_FLASH is not set -# CONFIG_MMIO_NVRAM is not set -CONFIG_IBMVIO=y -# CONFIG_IBMEBUS is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_MPIC=y - -# -# PA Semi PWRficient options -# -CONFIG_PPC_PASEMI_IOMMU=y - -# -# Kernel options -# -CONFIG_HZ_100=y -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=100 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_PREEMPT_BKL=y -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_FORCE_MAX_ZONEORDER=13 -CONFIG_IOMMU_VMERGE=y -# CONFIG_HOTPLUG_CPU is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set -# CONFIG_IRQ_ALL_CPUS is not set -# CONFIG_PPC_SPLPAR is not set -CONFIG_EEH=y -# CONFIG_SCANLOG is not set -# CONFIG_LPARCFG is not set -# CONFIG_NUMA is not set -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y -# CONFIG_PPC_64K_PAGES is not set -# CONFIG_SCHED_SMT is not set -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SECCOMP is not set -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -CONFIG_PPC_I8259=y -# CONFIG_PPC_INDIRECT_PCI is not set -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=y -CONFIG_PCMCIA_DEBUG=y -CONFIG_PCMCIA=y -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y -CONFIG_CARDBUS=y - -# -# PC-card bridges -# -# CONFIG_YENTA is not set -# CONFIG_PD6729 is not set -# CONFIG_I82092 is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set -CONFIG_KERNEL_START=0xc000000000000000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=y -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=y -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -# CONFIG_MTD_PARTITIONS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -CONFIG_MTD_SLRAM=y -CONFIG_MTD_PHRAM=y -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_NAND_CAFE is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=16384 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_BLK_DEV_IDECS is not set -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -CONFIG_BLK_DEV_IDESCSI=y -CONFIG_IDE_TASK_IOCTL=y - -# -# IDE chipset support/bugfixes -# -# CONFIG_IDE_GENERIC is not set -# CONFIG_BLK_DEV_IDEPCI is not set -# CONFIG_IDE_ARM is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -CONFIG_CHR_DEV_OSST=y -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=y -CONFIG_CHR_DEV_SCH=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -CONFIG_BLK_DEV_3W_XXXX_RAID=y -CONFIG_SCSI_3W_9XXX=y -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_IBMVSCSI is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set - -# -# PCMCIA SCSI adapter support -# -# CONFIG_PCMCIA_FDOMAIN is not set -# CONFIG_PCMCIA_QLOGIC is not set -# CONFIG_PCMCIA_SYM53C500 is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -# CONFIG_SATA_AHCI is not set -CONFIG_SATA_SVW=y -# CONFIG_ATA_PIIX is not set -CONFIG_SATA_MV=y -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -CONFIG_SATA_SIL=y -CONFIG_SATA_SIL24=y -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -CONFIG_ATA_GENERIC=y -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PCMCIA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -CONFIG_IEEE1394=y - -# -# Subsystem Options -# -# CONFIG_IEEE1394_VERBOSEDEBUG is not set -# CONFIG_IEEE1394_OUI_DB is not set -# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set -# CONFIG_IEEE1394_EXPORT_FULL_API is not set - -# -# Device Drivers -# -CONFIG_IEEE1394_PCILYNX=y -CONFIG_IEEE1394_OHCI1394=y - -# -# Protocol Drivers -# -# CONFIG_IEEE1394_VIDEO1394 is not set -CONFIG_IEEE1394_SBP2=y -# CONFIG_IEEE1394_ETH1394 is not set -# CONFIG_IEEE1394_DV1394 is not set -CONFIG_IEEE1394_RAWIO=y - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_IBMVETH=y -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -CONFIG_EEPRO100=y -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -CONFIG_E1000=y -CONFIG_E1000_NAPI=y -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -CONFIG_TIGON3=y -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# PCMCIA network device support -# -# CONFIG_NET_PCMCIA is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=y -# CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -# CONFIG_MOUSE_PS2 is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -# CONFIG_SERIAL_8250_CS is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_ICOM is not set -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=4 -CONFIG_HVC_DRIVER=y -CONFIG_HVC_CONSOLE=y -CONFIG_HVC_RTAS=y -# CONFIG_HVCS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -CONFIG_GEN_RTC=y -CONFIG_GEN_RTC_X=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_CARDMAN_4000 is not set -# CONFIG_CARDMAN_4040 is not set -CONFIG_RAW_DRIVER=y -CONFIG_MAX_RAW_DEVS=256 -# CONFIG_HANGCHECK_TIMER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_ALGOPCF=y -CONFIG_I2C_ALGOPCA=y - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -CONFIG_SENSORS_EEPROM=y -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -CONFIG_I2C_DEBUG_BUS=y -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -CONFIG_HWMON_VID=y -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -CONFIG_SENSORS_LM85=y -# CONFIG_SENSORS_LM87 is not set -CONFIG_SENSORS_LM90=y -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -CONFIG_FIRMWARE_EDID=y -CONFIG_FB=y -CONFIG_FB_DDC=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_MACMODES=y -# CONFIG_FB_BACKLIGHT is not set -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_TILEBLITTING=y -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_OF is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -CONFIG_FB_VGA16=y -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_NVIDIA=y -CONFIG_FB_NVIDIA_I2C=y -CONFIG_FB_RIVA=y -CONFIG_FB_RIVA_I2C=y -# CONFIG_FB_RIVA_DEBUG is not set -CONFIG_FB_MATROX=y -CONFIG_FB_MATROX_MILLENIUM=y -CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G=y -CONFIG_FB_MATROX_I2C=y -CONFIG_FB_MATROX_MAVEN=y -CONFIG_FB_MATROX_MULTIHEAD=y -CONFIG_FB_RADEON=y -CONFIG_FB_RADEON_I2C=y -# CONFIG_FB_RADEON_DEBUG is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -CONFIG_VGACON_SOFT_SCROLLBACK=y -CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64 -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Logo configuration -# -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_MONO=y -CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_HWDEP=y -CONFIG_SND_RAWMIDI=y -CONFIG_SND_SEQUENCER=y -# CONFIG_SND_SEQ_DUMMY is not set -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_SND_PCM_OSS_PLUGINS=y -CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# PCI devices -# -# CONFIG_SND_AD1889 is not set -# CONFIG_SND_ALS300 is not set -# CONFIG_SND_ALS4000 is not set -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_CS4281 is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_DARLA20 is not set -# CONFIG_SND_GINA20 is not set -# CONFIG_SND_LAYLA20 is not set -# CONFIG_SND_DARLA24 is not set -# CONFIG_SND_GINA24 is not set -# CONFIG_SND_LAYLA24 is not set -# CONFIG_SND_MONA is not set -# CONFIG_SND_MIA is not set -# CONFIG_SND_ECHO3G is not set -# CONFIG_SND_INDIGO is not set -# CONFIG_SND_INDIGOIO is not set -# CONFIG_SND_INDIGODJ is not set -# CONFIG_SND_EMU10K1 is not set -# CONFIG_SND_EMU10K1X is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_HDA_INTEL is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -# CONFIG_SND_INTEL8X0 is not set -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_PCXHR is not set -# CONFIG_SND_RIPTIDE is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_TRIDENT is not set -# CONFIG_SND_VIA82XX is not set -# CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VX222 is not set -# CONFIG_SND_YMFPCI is not set - -# -# ALSA PowerMac devices -# - -# -# USB devices -# -CONFIG_SND_USB_AUDIO=y -CONFIG_SND_USB_USX2Y=y - -# -# PCMCIA devices -# -# CONFIG_SND_VXPOCKET is not set -# CONFIG_SND_PDAUDIOCF is not set - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set - -# -# HID Devices -# -CONFIG_HID=y - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_UHCI_HCD=y -CONFIG_USB_SL811_HCD=y -# CONFIG_USB_SL811_CS is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -CONFIG_USB_LIBUSUAL=y - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_X1205 is not set -CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -# CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=y -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y - -# -# Instrumentation Support -# -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -# CONFIG_KPROBES is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=17 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUGGER=y -CONFIG_XMON=y -CONFIG_XMON_DEFAULT=y -CONFIG_XMON_DISASSEMBLY=y -# CONFIG_IRQSTACKS is not set -CONFIG_BOOTX_TEXT=y -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=y -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/powerpc/configs/ps3_defconfig b/trunk/arch/powerpc/configs/ps3_defconfig index ec644b34a082..32560876c3dc 100644 --- a/trunk/arch/powerpc/configs/ps3_defconfig +++ b/trunk/arch/powerpc/configs/ps3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc6 -# Thu Jan 25 13:35:34 2007 +# Linux kernel version: 2.6.20-rc5 +# Mon Jan 22 22:29:11 2007 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -70,10 +70,10 @@ CONFIG_SYSVIPC=y CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y -# CONFIG_EMBEDDED is not set -CONFIG_SYSCTL_SYSCALL=y +CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_EXTRA_PASS=y @@ -160,7 +160,7 @@ CONFIG_SPU_BASE=y # PS3 Platform Options # CONFIG_PS3_HTAB_SIZE=20 -# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_DYNAMIC_DMA=y CONFIG_PS3_USE_LPAR_ADDR=y CONFIG_PS3_VUART=y @@ -207,7 +207,7 @@ CONFIG_PPC_64K_PAGES=y # CONFIG_SCHED_SMT is not set CONFIG_PROC_DEVICETREE=y CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="root=/dev/sda1 ip=dhcp" +CONFIG_CMDLINE="root=/dev/nfs rw ip=dhcp" # CONFIG_PM is not set # CONFIG_SECCOMP is not set CONFIG_ISA_DMA_API=y @@ -240,8 +240,7 @@ CONFIG_NET=y # Networking options # # CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y +# CONFIG_PACKET is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -354,7 +353,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set @@ -382,11 +380,10 @@ CONFIG_SCSI_PROC_FS=y # # SCSI support type (disk, tape, CD-ROM) # -CONFIG_BLK_DEV_SD=y +# CONFIG_BLK_DEV_SD is not set # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SR is not set # CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set @@ -459,7 +456,6 @@ CONFIG_NETDEVICES=y # Ethernet (10 or 100Mbit) # # CONFIG_NET_ETHERNET is not set -CONFIG_MII=y # # Ethernet (1000 Mbit) @@ -508,13 +504,10 @@ CONFIG_INPUT=y # # Userland interfaces # -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # @@ -605,7 +598,6 @@ CONFIG_GEN_RTC=y # Digital Video Broadcasting Devices # # CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set # # Graphics support @@ -634,141 +626,14 @@ CONFIG_HID=y # # USB support # -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -CONFIG_USB_DEBUG=y - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_HCD_PPC_OF is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -CONFIG_USB_USBNET_MII=y -CONFIG_USB_USBNET=y -CONFIG_USB_NET_CDCETHER=y -# CONFIG_USB_NET_GL620A is not set -# CONFIG_USB_NET_NET1080 is not set -# CONFIG_USB_NET_PLUSB is not set -CONFIG_USB_NET_MCS7830=y -# CONFIG_USB_NET_RNDIS_HOST is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_ZAURUS is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set - -# -# USB DSL modem support -# - # # USB Gadget Support # @@ -826,14 +691,8 @@ CONFIG_USB_MON=y # File systems # # CONFIG_EXT2_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT3_FS is not set # CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -853,20 +712,14 @@ CONFIG_DNOTIFY=y # # CD-ROM/DVD Filesystems # -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=y -CONFIG_UDF_NLS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set # # DOS/FAT/NT Filesystems # -CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_VFAT_FS is not set # CONFIG_NTFS_FS is not set # @@ -932,46 +785,7 @@ CONFIG_MSDOS_PARTITION=y # # Native Language Support # -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +# CONFIG_NLS is not set # # Distributed Lock Manager @@ -981,10 +795,9 @@ CONFIG_NLS_ISO8859_1=y # # Library routines # -CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set -CONFIG_CRC32=y +# CONFIG_CRC32 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_IOMAP_COPY=y @@ -1008,23 +821,22 @@ CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_SLAB_LEAK is not set +# CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_RWSEMS=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set CONFIG_DEBUG_LIST=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set -CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUGGER is not set CONFIG_IRQSTACKS=y diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index 8120d428ebfd..d2ded19e4064 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -17,7 +17,6 @@ obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o cpu_setup_ppc970.o \ - cpu_setup_pa6t.o \ firmware.o sysfs.o nvram_64.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o diff --git a/trunk/arch/powerpc/kernel/cpu_setup_pa6t.S b/trunk/arch/powerpc/kernel/cpu_setup_pa6t.S deleted file mode 100644 index 4047be25c4d2..000000000000 --- a/trunk/arch/powerpc/kernel/cpu_setup_pa6t.S +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2006-2007 PA Semi, Inc - * - * Maintained by: Olof Johansson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -/* Right now, restore and setup are the same thing */ -_GLOBAL(__restore_cpu_pa6t) -_GLOBAL(__setup_cpu_pa6t) - /* Do nothing if not running in HV mode */ - mfmsr r0 - rldicl. r0,r0,4,63 - beqlr - - mfspr r0,SPRN_HID5 - ori r0,r0,0x30 - mtspr SPRN_HID5,r0 - - mfspr r0,SPRN_LPCR - ori r0,r0,0x7000 - mtspr SPRN_LPCR,r0 - - blr diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index dd17dffbf058..b742013bb9da 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -43,8 +43,6 @@ extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); #ifdef CONFIG_PPC64 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_pa6t(unsigned long offset, struct cpu_spec* spec); -extern void __restore_cpu_pa6t(unsigned long offset, struct cpu_spec* spec); extern void __restore_cpu_ppc970(void); #endif /* CONFIG_PPC64 */ @@ -88,7 +86,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/power3", .oprofile_type = PPC_OPROFILE_RS64, .platform = "power3", @@ -102,7 +99,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/power3", .oprofile_type = PPC_OPROFILE_RS64, .platform = "power3", @@ -116,7 +112,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/rs64", .oprofile_type = PPC_OPROFILE_RS64, .platform = "rs64", @@ -130,7 +125,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/rs64", .oprofile_type = PPC_OPROFILE_RS64, .platform = "rs64", @@ -144,7 +138,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/rs64", .oprofile_type = PPC_OPROFILE_RS64, .platform = "rs64", @@ -158,7 +151,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/rs64", .oprofile_type = PPC_OPROFILE_RS64, .platform = "rs64", @@ -172,7 +164,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/power4", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "power4", @@ -186,7 +177,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/power4", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "power4", @@ -201,7 +191,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", @@ -218,7 +207,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", @@ -251,7 +239,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, @@ -266,7 +253,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 6, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/power5", .oprofile_type = PPC_OPROFILE_POWER4, /* SIHV / SIPR bits are implemented on POWER4+ (GQ) @@ -285,7 +271,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 6, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/power5+", .oprofile_type = PPC_OPROFILE_POWER4, .oprofile_mmcra_sihv = MMCRA_SIHV, @@ -336,7 +321,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 6, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/power6", .oprofile_type = PPC_OPROFILE_POWER4, .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, @@ -356,7 +340,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/cell-be", .oprofile_type = PPC_OPROFILE_CELL, .platform = "ppc-cell-be", @@ -370,9 +353,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 64, .dcache_bsize = 64, .num_pmcs = 6, - .pmc_type = PPC_PMC_PA6T, - .cpu_setup = __setup_cpu_pa6t, - .cpu_restore = __restore_cpu_pa6t, .platform = "pa6t", }, { /* default match */ @@ -384,7 +364,6 @@ static struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 6, - .pmc_type = PPC_PMC_IBM, .platform = "power4", } #endif /* CONFIG_PPC64 */ diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 2b66d53dcc55..2551c0884afc 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -172,18 +172,13 @@ syscall_error_cont: stdcx. r0,0,r1 /* to clear the reservation */ andi. r6,r8,MSR_PR ld r4,_LINK(r1) - /* - * Clear RI before restoring r13. If we are returning to - * userspace and we take an exception after restoring r13, - * we end up corrupting the userspace r13 value. - */ - li r12,MSR_RI - andc r11,r10,r12 - mtmsrd r11,1 /* clear MSR.RI */ beq- 1f ACCOUNT_CPU_USER_EXIT(r11, r12) ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ 1: ld r2,GPR2(r1) + li r12,MSR_RI + andc r11,r10,r12 + mtmsrd r11,1 /* clear MSR.RI */ ld r1,GPR1(r1) mtlr r4 mtcr r5 @@ -493,44 +488,42 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif stb r5,PACASOFTIRQEN(r13) - /* extract EE bit and use it to restore paca->hard_enabled */ ld r3,_MSR(r1) - rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ - stb r4,PACAHARDIRQEN(r13) - - ld r4,_CTR(r1) - ld r0,_LINK(r1) - mtctr r4 - mtlr r0 - ld r4,_XER(r1) - mtspr SPRN_XER,r4 - - REST_8GPRS(5, r1) - andi. r0,r3,MSR_RI beq- unrecov_restore - stdcx. r0,0,r1 /* to clear the reservation */ + /* extract EE bit and use it to restore paca->hard_enabled */ + rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ + stb r4,PACAHARDIRQEN(r13) - /* - * Clear RI before restoring r13. If we are returning to - * userspace and we take an exception after restoring r13, - * we end up corrupting the userspace r13 value. - */ - mfmsr r4 - andc r4,r4,r0 /* r0 contains MSR_RI here */ - mtmsrd r4,1 + andi. r0,r3,MSR_PR /* * r13 is our per cpu area, only restore it if we are returning to * userspace */ - andi. r0,r3,MSR_PR beq 1f - ACCOUNT_CPU_USER_EXIT(r2, r4) + ACCOUNT_CPU_USER_EXIT(r3, r4) REST_GPR(13, r1) 1: - mtspr SPRN_SRR1,r3 + ld r3,_CTR(r1) + ld r0,_LINK(r1) + mtctr r3 + mtlr r0 + ld r3,_XER(r1) + mtspr SPRN_XER,r3 + + REST_8GPRS(5, r1) + + stdcx. r0,0,r1 /* to clear the reservation */ + + mfmsr r0 + li r2, MSR_RI + andc r0,r0,r2 + mtmsrd r0,1 + + ld r0,_MSR(r1) + mtspr SPRN_SRR1,r0 ld r2,_CCR(r1) mtcrf 0xFF,r2 diff --git a/trunk/arch/powerpc/kernel/head_32.S b/trunk/arch/powerpc/kernel/head_32.S index c897203198b1..9417cf5b4b7e 100644 --- a/trunk/arch/powerpc/kernel/head_32.S +++ b/trunk/arch/powerpc/kernel/head_32.S @@ -344,7 +344,12 @@ i##n: \ /* System reset */ /* core99 pmac starts the seconary here by changing the vector, and putting it back to what it was (unknown_exception) when done. */ +#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP) + . = 0x100 + b __secondary_start_gemini +#else EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) +#endif /* Machine check */ /* diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index 97cedcd6c9b4..71b1fe58e9e4 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -613,7 +613,7 @@ system_call_pSeries: /*** pSeries interrupt support ***/ /* moved from 0xf00 */ - STD_EXCEPTION_PSERIES(., performance_monitor) + MASKABLE_EXCEPTION_PSERIES(., performance_monitor) /* * An interrupt came in while soft-disabled; clear EE in SRR1, diff --git a/trunk/arch/powerpc/kernel/iomap.c b/trunk/arch/powerpc/kernel/iomap.c index 601ef79a5916..c68113371050 100644 --- a/trunk/arch/powerpc/kernel/iomap.c +++ b/trunk/arch/powerpc/kernel/iomap.c @@ -12,23 +12,23 @@ * Here comes the ppc64 implementation of the IOMAP * interfaces. */ -unsigned int ioread8(void __iomem *addr) +unsigned int fastcall ioread8(void __iomem *addr) { return readb(addr); } -unsigned int ioread16(void __iomem *addr) +unsigned int fastcall ioread16(void __iomem *addr) { return readw(addr); } -unsigned int ioread16be(void __iomem *addr) +unsigned int fastcall ioread16be(void __iomem *addr) { return in_be16(addr); } -unsigned int ioread32(void __iomem *addr) +unsigned int fastcall ioread32(void __iomem *addr) { return readl(addr); } -unsigned int ioread32be(void __iomem *addr) +unsigned int fastcall ioread32be(void __iomem *addr) { return in_be32(addr); } @@ -38,23 +38,23 @@ EXPORT_SYMBOL(ioread16be); EXPORT_SYMBOL(ioread32); EXPORT_SYMBOL(ioread32be); -void iowrite8(u8 val, void __iomem *addr) +void fastcall iowrite8(u8 val, void __iomem *addr) { writeb(val, addr); } -void iowrite16(u16 val, void __iomem *addr) +void fastcall iowrite16(u16 val, void __iomem *addr) { writew(val, addr); } -void iowrite16be(u16 val, void __iomem *addr) +void fastcall iowrite16be(u16 val, void __iomem *addr) { out_be16(addr, val); } -void iowrite32(u32 val, void __iomem *addr) +void fastcall iowrite32(u32 val, void __iomem *addr) { writel(val, addr); } -void iowrite32be(u32 val, void __iomem *addr) +void fastcall iowrite32be(u32 val, void __iomem *addr) { out_be32(addr, val); } diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 919fbf568495..0bd8c7665834 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -281,10 +281,10 @@ void do_IRQ(struct pt_regs *regs) /* * Every platform is required to implement ppc_md.get_irq. - * This function will either return an irq number or NO_IRQ to + * This function will either return an irq number or -1 to * indicate there are no more pending. - * The value NO_IRQ_IGNORE is for buggy hardware and means that this - * IRQ has already been handled. -- Tom + * The value -2 is for buggy hardware and means that this IRQ + * has already been handled. -- Tom */ irq = ppc_md.get_irq(); @@ -604,8 +604,6 @@ unsigned int irq_create_mapping(struct irq_host *host, */ virq = irq_find_mapping(host, hwirq); if (virq != IRQ_NONE) { - if (host->ops->remap) - host->ops->remap(host, virq, hwirq); pr_debug("irq: -> existing mapping on virq %d\n", virq); return virq; } diff --git a/trunk/arch/powerpc/kernel/kprobes.c b/trunk/arch/powerpc/kernel/kprobes.c index dd2886f97e98..4657563f8813 100644 --- a/trunk/arch/powerpc/kernel/kprobes.c +++ b/trunk/arch/powerpc/kernel/kprobes.c @@ -46,8 +46,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) if ((unsigned long)p->addr & 0x03) { printk("Attempt to register kprobe at an unaligned address\n"); ret = -EINVAL; - } else if (IS_MTMSRD(insn) || IS_RFID(insn) || IS_RFI(insn)) { - printk("Cannot register a kprobe on rfi/rfid or mtmsr[d]\n"); + } else if (IS_MTMSRD(insn) || IS_RFID(insn)) { + printk("Cannot register a kprobe on rfid or mtmsrd\n"); ret = -EINVAL; } @@ -483,12 +483,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs)); /* setup return addr to the jprobe handler routine */ -#ifdef CONFIG_PPC64 regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry); regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); -#else - regs->nip = (unsigned long)jp->entry; -#endif return 1; } diff --git a/trunk/arch/powerpc/kernel/lparcfg.c b/trunk/arch/powerpc/kernel/lparcfg.c index 0de5a08cf9b0..41c05dcd68f4 100644 --- a/trunk/arch/powerpc/kernel/lparcfg.c +++ b/trunk/arch/powerpc/kernel/lparcfg.c @@ -439,10 +439,6 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf, ssize_t retval = -ENOMEM; - if (!firmware_has_feature(FW_FEATURE_SPLPAR) || - firmware_has_feature(FW_FEATURE_ISERIES)) - return -EINVAL; - kbuf = kmalloc(count, GFP_KERNEL); if (!kbuf) goto out; @@ -521,7 +517,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) static ssize_t lparcfg_write(struct file *file, const char __user * buf, size_t count, loff_t * off) { - return -EINVAL; + return count; } #endif /* CONFIG_PPC_PSERIES */ @@ -574,7 +570,6 @@ static int lparcfg_open(struct inode *inode, struct file *file) struct file_operations lparcfg_fops = { .owner = THIS_MODULE, .read = seq_read, - .write = lparcfg_write, .open = lparcfg_open, .release = single_release, }; @@ -586,8 +581,10 @@ int __init lparcfg_init(void) /* Allow writing if we have FW_FEATURE_SPLPAR */ if (firmware_has_feature(FW_FEATURE_SPLPAR) && - !firmware_has_feature(FW_FEATURE_ISERIES)) + !firmware_has_feature(FW_FEATURE_ISERIES)) { + lparcfg_fops.write = lparcfg_write; mode |= S_IWUSR; + } ent = create_proc_entry("ppc64/lparcfg", mode, NULL); if (ent) { diff --git a/trunk/arch/powerpc/kernel/misc_64.S b/trunk/arch/powerpc/kernel/misc_64.S index 519861da0423..21fd2c662a99 100644 --- a/trunk/arch/powerpc/kernel/misc_64.S +++ b/trunk/arch/powerpc/kernel/misc_64.S @@ -311,46 +311,6 @@ _GLOBAL(real_writeb) blr #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ -#ifdef CONFIG_PPC_PASEMI - -/* No support in all binutils for these yet, so use defines */ -#define LBZCIX(RT,RA,RB) .long (0x7c0006aa|(RT<<21)|(RA<<16)|(RB << 11)) -#define STBCIX(RS,RA,RB) .long (0x7c0007aa|(RS<<21)|(RA<<16)|(RB << 11)) - - -_GLOBAL(real_205_readb) - mfmsr r7 - ori r0,r7,MSR_DR - xori r0,r0,MSR_DR - sync - mtmsrd r0 - sync - isync - LBZCIX(r3,0,r3) - isync - mtmsrd r7 - sync - isync - blr - -_GLOBAL(real_205_writeb) - mfmsr r7 - ori r0,r7,MSR_DR - xori r0,r0,MSR_DR - sync - mtmsrd r0 - sync - isync - STBCIX(r3,0,r4) - isync - mtmsrd r7 - sync - isync - blr - -#endif /* CONFIG_PPC_PASEMI */ - - #ifdef CONFIG_CPU_FREQ_PMAC64 /* * SCOM access functions for 970 (FX only for now) diff --git a/trunk/arch/powerpc/kernel/module_32.c b/trunk/arch/powerpc/kernel/module_32.c index 07a89a398639..8339fd609de0 100644 --- a/trunk/arch/powerpc/kernel/module_32.c +++ b/trunk/arch/powerpc/kernel/module_32.c @@ -224,12 +224,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, /* Low half of the symbol */ *(uint16_t *)location = value; break; - - case R_PPC_ADDR16_HI: - /* Higher half of the symbol */ - *(uint16_t *)location = (value >> 16); - break; - + case R_PPC_ADDR16_HA: /* Sign-adjusted lower 16 bits: PPC ELF ABI says: (((x >> 16) + ((x & 0x8000) ? 1 : 0))) & 0xFFFF. diff --git a/trunk/arch/powerpc/kernel/pci_32.c b/trunk/arch/powerpc/kernel/pci_32.c index d8ef2e100505..c54f3639c5ad 100644 --- a/trunk/arch/powerpc/kernel/pci_32.c +++ b/trunk/arch/powerpc/kernel/pci_32.c @@ -1450,6 +1450,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev) return -1; } pci_dev->irq = virq; + pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); return 0; } diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 7e97d71a5f8f..01f18c683407 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -381,6 +381,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, pci_device_add(dev, bus); + /* XXX pci_scan_msi_device(dev); */ + return dev; } EXPORT_SYMBOL(of_create_pci_dev); @@ -1323,6 +1325,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev) DBG(" -> mapped to linux irq %d\n", virq); pci_dev->irq = virq; + pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); return 0; } diff --git a/trunk/arch/powerpc/kernel/pmc.c b/trunk/arch/powerpc/kernel/pmc.c index 24d7b7c99bb9..3d8f6f44641e 100644 --- a/trunk/arch/powerpc/kernel/pmc.c +++ b/trunk/arch/powerpc/kernel/pmc.c @@ -17,25 +17,40 @@ #include #include -#include #include -#ifndef MMCR0_PMA0 -#define MMCR0_PMA0 0 -#endif - +#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) static void dummy_perf(struct pt_regs *regs) { -#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) - mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE); + unsigned int pmgc0 = mfpmr(PMRN_PMGC0); + + pmgc0 &= ~PMGC0_PMIE; + mtpmr(PMRN_PMGC0, pmgc0); +} #elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) - if (cur_cpu_spec->pmc_type == PPC_PMC_IBM) - mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~(MMCR0_PMXE|MMCR0_PMA0)); -#else - mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMXE); + +#ifndef MMCR0_PMAO +#define MMCR0_PMAO 0 #endif + +/* Ensure exceptions are disabled */ +static void dummy_perf(struct pt_regs *regs) +{ + unsigned int mmcr0 = mfspr(SPRN_MMCR0); + + mmcr0 &= ~(MMCR0_PMXE|MMCR0_PMAO); + mtspr(SPRN_MMCR0, mmcr0); } +#else +/* Ensure exceptions are disabled */ +static void dummy_perf(struct pt_regs *regs) +{ + unsigned int mmcr0 = mfspr(SPRN_MMCR0); + mmcr0 &= ~(MMCR0_PMXE); + mtspr(SPRN_MMCR0, mmcr0); +} +#endif static DEFINE_SPINLOCK(pmc_owner_lock); static void *pmc_owner_caller; /* mostly for debugging */ diff --git a/trunk/arch/powerpc/kernel/ppc_ksyms.c b/trunk/arch/powerpc/kernel/ppc_ksyms.c index ecee596d28f6..95776b6af4e2 100644 --- a/trunk/arch/powerpc/kernel/ppc_ksyms.c +++ b/trunk/arch/powerpc/kernel/ppc_ksyms.c @@ -44,7 +44,6 @@ #include #include #include -#include #ifdef CONFIG_8xx #include diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 3be52d693eca..1fc732a552db 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -1221,7 +1221,8 @@ struct device_node *of_find_node_by_name(struct device_node *from, if (np->name != NULL && strcasecmp(np->name, name) == 0 && of_node_get(np)) break; - of_node_put(from); + if (from) + of_node_put(from); read_unlock(&devtree_lock); return np; } @@ -1249,7 +1250,8 @@ struct device_node *of_find_node_by_type(struct device_node *from, if (np->type != 0 && strcasecmp(np->type, type) == 0 && of_node_get(np)) break; - of_node_put(from); + if (from) + of_node_put(from); read_unlock(&devtree_lock); return np; } @@ -1283,7 +1285,8 @@ struct device_node *of_find_compatible_node(struct device_node *from, if (device_is_compatible(np, compatible) && of_node_get(np)) break; } - of_node_put(from); + if (from) + of_node_put(from); read_unlock(&devtree_lock); return np; } @@ -1326,7 +1329,8 @@ struct device_node *of_find_node_by_phandle(phandle handle) for (np = allnodes; np != 0; np = np->allnext) if (np->linux_phandle == handle) break; - of_node_get(np); + if (np) + of_node_get(np); read_unlock(&devtree_lock); return np; } @@ -1349,7 +1353,8 @@ struct device_node *of_find_all_nodes(struct device_node *prev) for (; np != 0; np = np->allnext) if (of_node_get(np)) break; - of_node_put(prev); + if (prev) + of_node_put(prev); read_unlock(&devtree_lock); return np; } @@ -1394,7 +1399,8 @@ struct device_node *of_get_next_child(const struct device_node *node, for (; next != 0; next = next->sibling) if (of_node_get(next)) break; - of_node_put(prev); + if (prev) + of_node_put(prev); read_unlock(&devtree_lock); return next; } diff --git a/trunk/arch/powerpc/kernel/ptrace.c b/trunk/arch/powerpc/kernel/ptrace.c index cc44c7b975aa..975102a020d9 100644 --- a/trunk/arch/powerpc/kernel/ptrace.c +++ b/trunk/arch/powerpc/kernel/ptrace.c @@ -532,22 +532,16 @@ void do_syscall_trace_enter(struct pt_regs *regs) && (current->ptrace & PT_PTRACED)) do_syscall_trace(); - if (unlikely(current->audit_context)) { -#ifdef CONFIG_PPC64 - if (!test_thread_flag(TIF_32BIT)) - audit_syscall_entry(AUDIT_ARCH_PPC64, - regs->gpr[0], - regs->gpr[3], regs->gpr[4], - regs->gpr[5], regs->gpr[6]); - else + if (unlikely(current->audit_context)) + audit_syscall_entry( +#ifdef CONFIG_PPC32 + AUDIT_ARCH_PPC, +#else + test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64, #endif - audit_syscall_entry(AUDIT_ARCH_PPC, - regs->gpr[0], - regs->gpr[3] & 0xffffffff, - regs->gpr[4] & 0xffffffff, - regs->gpr[5] & 0xffffffff, - regs->gpr[6] & 0xffffffff); - } + regs->gpr[0], + regs->gpr[3], regs->gpr[4], + regs->gpr[5], regs->gpr[6]); } void do_syscall_trace_leave(struct pt_regs *regs) diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index 6a19fa40dcee..61c65d19ef06 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -65,7 +65,6 @@ int have_of = 1; #ifdef CONFIG_VGA_CONSOLE unsigned long vgacon_remap_base; -EXPORT_SYMBOL(vgacon_remap_base); #endif /* diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c index d57818aea081..400ab2b946e7 100644 --- a/trunk/arch/powerpc/kernel/sysfs.c +++ b/trunk/arch/powerpc/kernel/sysfs.c @@ -169,11 +169,6 @@ static ssize_t __attribute_used__ \ return count; \ } - -/* Let's define all possible registers, we'll only hook up the ones - * that are implemented on the current processor - */ - SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); @@ -189,87 +184,55 @@ SYSFS_PMCSETUP(purr, SPRN_PURR); SYSFS_PMCSETUP(spurr, SPRN_SPURR); SYSFS_PMCSETUP(dscr, SPRN_DSCR); -SYSFS_PMCSETUP(pa6t_pmc0, PA6T_SPRN_PMC0); -SYSFS_PMCSETUP(pa6t_pmc1, PA6T_SPRN_PMC1); -SYSFS_PMCSETUP(pa6t_pmc2, PA6T_SPRN_PMC2); -SYSFS_PMCSETUP(pa6t_pmc3, PA6T_SPRN_PMC3); -SYSFS_PMCSETUP(pa6t_pmc4, PA6T_SPRN_PMC4); -SYSFS_PMCSETUP(pa6t_pmc5, PA6T_SPRN_PMC5); - - +static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0); +static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1); static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); +static SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1); +static SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2); +static SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3); +static SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4); +static SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5); +static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6); +static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7); +static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8); +static SYSDEV_ATTR(purr, 0600, show_purr, NULL); static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); -static SYSDEV_ATTR(purr, 0600, show_purr, store_purr); - -static struct sysdev_attribute ibm_common_attrs[] = { - _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), - _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), -}; - -static struct sysdev_attribute ibm_pmc_attrs[] = { - _SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1), - _SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2), - _SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3), - _SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4), - _SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5), - _SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6), - _SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7), - _SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8), -}; - -static struct sysdev_attribute pa6t_attrs[] = { - _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), - _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), - _SYSDEV_ATTR(pmc0, 0600, show_pa6t_pmc0, store_pa6t_pmc0), - _SYSDEV_ATTR(pmc1, 0600, show_pa6t_pmc1, store_pa6t_pmc1), - _SYSDEV_ATTR(pmc2, 0600, show_pa6t_pmc2, store_pa6t_pmc2), - _SYSDEV_ATTR(pmc3, 0600, show_pa6t_pmc3, store_pa6t_pmc3), - _SYSDEV_ATTR(pmc4, 0600, show_pa6t_pmc4, store_pa6t_pmc4), - _SYSDEV_ATTR(pmc5, 0600, show_pa6t_pmc5, store_pa6t_pmc5), -}; - static void register_cpu_online(unsigned int cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); struct sys_device *s = &c->sysdev; - struct sysdev_attribute *attrs, *pmc_attrs; - int i, nattrs; if (!firmware_has_feature(FW_FEATURE_ISERIES) && cpu_has_feature(CPU_FTR_SMT)) sysdev_create_file(s, &attr_smt_snooze_delay); /* PMC stuff */ - switch (cur_cpu_spec->pmc_type) { - case PPC_PMC_IBM: - attrs = ibm_common_attrs; - nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); - pmc_attrs = ibm_pmc_attrs; - break; - case PPC_PMC_PA6T: - /* PA Semi starts counting at PMC0 */ - attrs = pa6t_attrs; - nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); - pmc_attrs = NULL; - break; - default: - attrs = NULL; - nattrs = 0; - pmc_attrs = NULL; - } - - for (i = 0; i < nattrs; i++) - sysdev_create_file(s, &attrs[i]); - if (pmc_attrs) - for (i = 0; i < cur_cpu_spec->num_pmcs; i++) - sysdev_create_file(s, &pmc_attrs[i]); + sysdev_create_file(s, &attr_mmcr0); + sysdev_create_file(s, &attr_mmcr1); if (cpu_has_feature(CPU_FTR_MMCRA)) sysdev_create_file(s, &attr_mmcra); + if (cur_cpu_spec->num_pmcs >= 1) + sysdev_create_file(s, &attr_pmc1); + if (cur_cpu_spec->num_pmcs >= 2) + sysdev_create_file(s, &attr_pmc2); + if (cur_cpu_spec->num_pmcs >= 3) + sysdev_create_file(s, &attr_pmc3); + if (cur_cpu_spec->num_pmcs >= 4) + sysdev_create_file(s, &attr_pmc4); + if (cur_cpu_spec->num_pmcs >= 5) + sysdev_create_file(s, &attr_pmc5); + if (cur_cpu_spec->num_pmcs >= 6) + sysdev_create_file(s, &attr_pmc6); + if (cur_cpu_spec->num_pmcs >= 7) + sysdev_create_file(s, &attr_pmc7); + if (cur_cpu_spec->num_pmcs >= 8) + sysdev_create_file(s, &attr_pmc8); + if (cpu_has_feature(CPU_FTR_PURR)) sysdev_create_file(s, &attr_purr); @@ -285,8 +248,6 @@ static void unregister_cpu_online(unsigned int cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); struct sys_device *s = &c->sysdev; - struct sysdev_attribute *attrs, *pmc_attrs; - int i, nattrs; BUG_ON(!c->hotpluggable); @@ -295,34 +256,30 @@ static void unregister_cpu_online(unsigned int cpu) sysdev_remove_file(s, &attr_smt_snooze_delay); /* PMC stuff */ - switch (cur_cpu_spec->pmc_type) { - case PPC_PMC_IBM: - attrs = ibm_common_attrs; - nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); - pmc_attrs = ibm_pmc_attrs; - break; - case PPC_PMC_PA6T: - /* PA Semi starts counting at PMC0 */ - attrs = pa6t_attrs; - nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); - pmc_attrs = NULL; - break; - default: - attrs = NULL; - nattrs = 0; - pmc_attrs = NULL; - } - for (i = 0; i < nattrs; i++) - sysdev_remove_file(s, &attrs[i]); - - if (pmc_attrs) - for (i = 0; i < cur_cpu_spec->num_pmcs; i++) - sysdev_remove_file(s, &pmc_attrs[i]); + sysdev_remove_file(s, &attr_mmcr0); + sysdev_remove_file(s, &attr_mmcr1); if (cpu_has_feature(CPU_FTR_MMCRA)) sysdev_remove_file(s, &attr_mmcra); + if (cur_cpu_spec->num_pmcs >= 1) + sysdev_remove_file(s, &attr_pmc1); + if (cur_cpu_spec->num_pmcs >= 2) + sysdev_remove_file(s, &attr_pmc2); + if (cur_cpu_spec->num_pmcs >= 3) + sysdev_remove_file(s, &attr_pmc3); + if (cur_cpu_spec->num_pmcs >= 4) + sysdev_remove_file(s, &attr_pmc4); + if (cur_cpu_spec->num_pmcs >= 5) + sysdev_remove_file(s, &attr_pmc5); + if (cur_cpu_spec->num_pmcs >= 6) + sysdev_remove_file(s, &attr_pmc6); + if (cur_cpu_spec->num_pmcs >= 7) + sysdev_remove_file(s, &attr_pmc7); + if (cur_cpu_spec->num_pmcs >= 8) + sysdev_remove_file(s, &attr_pmc8); + if (cpu_has_feature(CPU_FTR_PURR)) sysdev_remove_file(s, &attr_purr); diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index dcc6f159fd94..535f50665647 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -174,7 +174,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) * generate the same exception over and over again and we get * nowhere. Better to kill it and let the kernel panic. */ - if (is_init(current)) { + if (current->pid == 1) { __sighandler_t handler; spin_lock_irq(¤t->sighand->siglock); @@ -535,40 +535,34 @@ static void emulate_single_step(struct pt_regs *regs) } } -static inline int __parse_fpscr(unsigned long fpscr) +static void parse_fpe(struct pt_regs *regs) { - int ret = 0; + int code = 0; + unsigned long fpscr; + + flush_fp_to_thread(current); + + fpscr = current->thread.fpscr.val; /* Invalid operation */ if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) - ret = FPE_FLTINV; + code = FPE_FLTINV; /* Overflow */ else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX)) - ret = FPE_FLTOVF; + code = FPE_FLTOVF; /* Underflow */ else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX)) - ret = FPE_FLTUND; + code = FPE_FLTUND; /* Divide by zero */ else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX)) - ret = FPE_FLTDIV; + code = FPE_FLTDIV; /* Inexact result */ else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX)) - ret = FPE_FLTRES; - - return ret; -} - -static void parse_fpe(struct pt_regs *regs) -{ - int code = 0; - - flush_fp_to_thread(current); - - code = __parse_fpscr(current->thread.fpscr.val); + code = FPE_FLTRES; _exception(SIGFPE, regs, code, regs->nip); } @@ -745,7 +739,20 @@ void __kprobes program_check_exception(struct pt_regs *regs) extern int do_mathemu(struct pt_regs *regs); /* We can now get here via a FP Unavailable exception if the core - * has no FPU, in that case the reason flags will be 0 */ + * has no FPU, in that case no reason flags will be set */ +#ifdef CONFIG_MATH_EMULATION + /* (reason & REASON_ILLEGAL) would be the obvious thing here, + * but there seems to be a hardware bug on the 405GP (RevD) + * that means ESR is sometimes set incorrectly - either to + * ESR_DST (!?) or 0. In the process of chasing this with the + * hardware people - not sure if it can happen on any illegal + * instruction or only on FP instructions, whether there is a + * pattern to occurences etc. -dgibson 31/Mar/2003 */ + if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) { + emulate_single_step(regs); + return; + } +#endif /* CONFIG_MATH_EMULATION */ if (reason & REASON_FP) { /* IEEE FP exception */ @@ -771,31 +778,6 @@ void __kprobes program_check_exception(struct pt_regs *regs) local_irq_enable(); -#ifdef CONFIG_MATH_EMULATION - /* (reason & REASON_ILLEGAL) would be the obvious thing here, - * but there seems to be a hardware bug on the 405GP (RevD) - * that means ESR is sometimes set incorrectly - either to - * ESR_DST (!?) or 0. In the process of chasing this with the - * hardware people - not sure if it can happen on any illegal - * instruction or only on FP instructions, whether there is a - * pattern to occurences etc. -dgibson 31/Mar/2003 */ - switch (do_mathemu(regs)) { - case 0: - emulate_single_step(regs); - return; - case 1: { - int code = 0; - code = __parse_fpscr(current->thread.fpscr.val); - _exception(SIGFPE, regs, code, regs->nip); - return; - } - case -EFAULT: - _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); - return; - } - /* fall through on any other errors */ -#endif /* CONFIG_MATH_EMULATION */ - /* Try to emulate it if we should. */ if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { switch (emulate_instruction(regs)) { @@ -909,39 +891,18 @@ void SoftwareEmulation(struct pt_regs *regs) #ifdef CONFIG_MATH_EMULATION errcode = do_mathemu(regs); - - switch (errcode) { - case 0: - emulate_single_step(regs); - return; - case 1: { - int code = 0; - code = __parse_fpscr(current->thread.fpscr.val); - _exception(SIGFPE, regs, code, regs->nip); - return; - } - case -EFAULT: - _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); - return; - default: - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - return; - } - #else errcode = Soft_emulate_8xx(regs); - switch (errcode) { - case 0: - emulate_single_step(regs); - return; - case 1: - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - return; - case -EFAULT: - _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); - return; - } #endif + if (errcode) { + if (errcode > 0) + _exception(SIGFPE, regs, 0, 0); + else if (errcode == -EFAULT) + _exception(SIGSEGV, regs, 0, 0); + else + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); + } else + emulate_single_step(regs); } #endif /* CONFIG_8xx */ diff --git a/trunk/arch/powerpc/kernel/udbg.c b/trunk/arch/powerpc/kernel/udbg.c index 8f5afdbad0d5..5730906b23d5 100644 --- a/trunk/arch/powerpc/kernel/udbg.c +++ b/trunk/arch/powerpc/kernel/udbg.c @@ -45,10 +45,6 @@ void __init udbg_early_init(void) #elif defined(CONFIG_PPC_EARLY_DEBUG_ISERIES) /* For iSeries - hit Ctrl-x Ctrl-x to see the output */ udbg_init_iseries(); -#elif defined(CONFIG_PPC_EARLY_DEBUG_BEAT) - udbg_init_debug_beat(); -#elif defined(CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE) - udbg_init_pas_realmode(); #endif } diff --git a/trunk/arch/powerpc/kernel/udbg_16550.c b/trunk/arch/powerpc/kernel/udbg_16550.c index e738f93b42fe..2d17f2b8eda7 100644 --- a/trunk/arch/powerpc/kernel/udbg_16550.c +++ b/trunk/arch/powerpc/kernel/udbg_16550.c @@ -14,8 +14,6 @@ extern u8 real_readb(volatile u8 __iomem *addr); extern void real_writeb(u8 data, volatile u8 __iomem *addr); -extern u8 real_205_readb(volatile u8 __iomem *addr); -extern void real_205_writeb(u8 data, volatile u8 __iomem *addr); struct NS16550 { /* this struct must be packed */ @@ -169,25 +167,3 @@ void __init udbg_init_maple_realmode(void) udbg_getc_poll = NULL; } #endif /* CONFIG_PPC_MAPLE */ - -#ifdef CONFIG_PPC_PASEMI -void udbg_pas_real_putc(char c) -{ - if (udbg_comport) { - while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0) - /* wait for idle */; - real_205_writeb(c, &udbg_comport->thr); eieio(); - if (c == '\n') - udbg_pas_real_putc('\r'); - } -} - -void udbg_init_pas_realmode(void) -{ - udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8; - - udbg_putc = udbg_pas_real_putc; - udbg_getc = NULL; - udbg_getc_poll = NULL; -} -#endif /* CONFIG_PPC_MAPLE */ diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c index 2968ffeafdb6..a80f8f1d2e5d 100644 --- a/trunk/arch/powerpc/kernel/vio.c +++ b/trunk/arch/powerpc/kernel/vio.c @@ -199,8 +199,10 @@ EXPORT_SYMBOL(vio_unregister_driver); /* vio_dev refcount hit 0 */ static void __devinit vio_dev_release(struct device *dev) { - /* XXX should free TCE table */ - of_node_put(dev->archdata.of_node); + if (dev->archdata.of_node) { + /* XXX should free TCE table */ + of_node_put(dev->archdata.of_node); + } kfree(to_vio_dev(dev)); } diff --git a/trunk/arch/powerpc/lib/Makefile b/trunk/arch/powerpc/lib/Makefile index 4b1ba49fbd9e..a0360ae10d0c 100644 --- a/trunk/arch/powerpc/lib/Makefile +++ b/trunk/arch/powerpc/lib/Makefile @@ -16,15 +16,13 @@ obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ strcase.o obj-$(CONFIG_QUICC_ENGINE) += rheap.o obj-$(CONFIG_XMON) += sstep.o -obj-$(CONFIG_KPROBES) += sstep.o -obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o +obj-$(CONFIG_DEBUG_KERNEL) += sstep.o endif # Temporary hack until we have migrated to asm-powerpc ifeq ($(CONFIG_PPC_MERGE),y) -obj-$(CONFIG_8xx) += rheap.o obj-$(CONFIG_CPM2) += rheap.o endif diff --git a/trunk/arch/powerpc/lib/rheap.c b/trunk/arch/powerpc/lib/rheap.c index 6c5c5dd183ee..57bf991ccd6e 100644 --- a/trunk/arch/powerpc/lib/rheap.c +++ b/trunk/arch/powerpc/lib/rheap.c @@ -14,7 +14,6 @@ */ #include #include -#include #include #include @@ -86,8 +85,7 @@ static int grow(rh_info_t * info, int max_blocks) info->flags &= ~RHIF_STATIC_BLOCK; /* add all new blocks to the free list */ - blk = block + info->max_blocks - new_blocks; - for (i = 0; i < new_blocks; i++, blk++) + for (i = 0, blk = block + info->max_blocks; i < new_blocks; i++, blk++) list_add(&blk->list, &info->empty_list); return 0; @@ -672,7 +670,7 @@ void rh_dump(rh_info_t * info) int maxnr; int i, nr; - maxnr = ARRAY_SIZE(st); + maxnr = sizeof(st) / sizeof(st[0]); printk(KERN_INFO "info @0x%p (%d slots empty / %d max)\n", diff --git a/trunk/arch/powerpc/mm/hugetlbpage.c b/trunk/arch/powerpc/mm/hugetlbpage.c index 8c77c791f87e..1bb20d841080 100644 --- a/trunk/arch/powerpc/mm/hugetlbpage.c +++ b/trunk/arch/powerpc/mm/hugetlbpage.c @@ -1014,6 +1014,7 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access, /* Primary is full, try the secondary */ if (unlikely(slot == -1)) { + new_pte |= _PAGE_F_SECOND; hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, @@ -1032,7 +1033,7 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access, if (unlikely(slot == -2)) panic("hash_huge_page: pte_insert failed\n"); - new_pte |= (slot << 12) & (_PAGE_F_SECOND | _PAGE_F_GIX); + new_pte |= (slot << 12) & _PAGE_F_GIX; } /* diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 77b4637097e9..d1c0758c5611 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -61,6 +61,10 @@ unsigned long memory_limit; extern void hash_preload(struct mm_struct *mm, unsigned long ea, unsigned long access, unsigned long trap); +/* + * This is called by /dev/mem to know if a given address has to + * be mapped non-cacheable or not + */ int page_is_ram(unsigned long pfn) { unsigned long paddr = (pfn << PAGE_SHIFT); @@ -486,19 +490,19 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, !cpu_has_feature(CPU_FTR_NOEXECUTE) && pfn_valid(pfn)) { struct page *page = pfn_to_page(pfn); -#ifdef CONFIG_8xx - /* On 8xx, cache control instructions (particularly - * "dcbst" from flush_dcache_icache) fault as write - * operation if there is an unpopulated TLB entry - * for the address in question. To workaround that, - * we invalidate the TLB here, thus avoiding dcbst - * misbehaviour. - */ - _tlbie(address); -#endif if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) { if (vma->vm_mm == current->active_mm) { +#ifdef CONFIG_8xx + /* On 8xx, cache control instructions (particularly + * "dcbst" from flush_dcache_icache) fault as write + * operation if there is an unpopulated TLB entry + * for the address in question. To workaround that, + * we invalidate the TLB here, thus avoiding dcbst + * misbehaviour. + */ + _tlbie(address); +#endif __flush_dcache_icache((void *) address); } else flush_dcache_icache_page(page); diff --git a/trunk/arch/powerpc/mm/pgtable_32.c b/trunk/arch/powerpc/mm/pgtable_32.c index bd02272bcb0f..1891dbeeb8e9 100644 --- a/trunk/arch/powerpc/mm/pgtable_32.c +++ b/trunk/arch/powerpc/mm/pgtable_32.c @@ -294,8 +294,11 @@ void __init mapin_ram(void) } } +/* is x a power of 2? */ +#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) + /* is x a power of 4? */ -#define is_power_of_4(x) is_power_of_2(x) && (ffs(x) & 1)) +#define is_power_of_4(x) ((x) != 0 && (((x) & (x-1)) == 0) && (ffs(x) & 1)) /* * Set up a mapping for a block of I/O. diff --git a/trunk/arch/powerpc/oprofile/common.c b/trunk/arch/powerpc/oprofile/common.c index fbd62eacfdf4..b6d82390b6a6 100644 --- a/trunk/arch/powerpc/oprofile/common.c +++ b/trunk/arch/powerpc/oprofile/common.c @@ -149,8 +149,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) #ifdef CONFIG_PPC64 #ifdef CONFIG_PPC_CELL_NATIVE case PPC_OPROFILE_CELL: - if (firmware_has_feature(FW_FEATURE_LPAR)) - return -ENODEV; model = &op_model_cell; break; #endif diff --git a/trunk/arch/powerpc/oprofile/op_model_7450.c b/trunk/arch/powerpc/oprofile/op_model_7450.c index 5d1bbaf35ccb..f481c0ed5e67 100644 --- a/trunk/arch/powerpc/oprofile/op_model_7450.c +++ b/trunk/arch/powerpc/oprofile/op_model_7450.c @@ -137,9 +137,9 @@ static void fsl7450_start(struct op_counter_config *ctr) for (i = 0; i < NUM_CTRS; ++i) { if (ctr[i].enabled) - classic_ctr_write(i, reset_value[i]); + ctr_write(i, reset_value[i]); else - classic_ctr_write(i, 0); + ctr_write(i, 0); } /* Clear the freeze bit, and enable the interrupt. @@ -179,13 +179,13 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs, is_kernel = is_kernel_addr(pc); for (i = 0; i < NUM_CTRS; ++i) { - val = classic_ctr_read(i); + val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { oprofile_add_ext_sample(pc, regs, i, is_kernel); - classic_ctr_write(i, reset_value[i]); + ctr_write(i, reset_value[i]); } else { - classic_ctr_write(i, 0); + ctr_write(i, 0); } } } diff --git a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c index 2267eb8c661b..0b3c31f5209e 100644 --- a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c +++ b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c @@ -32,87 +32,6 @@ static unsigned long reset_value[OP_MAX_COUNTER]; static int num_counters; static int oprofile_running; -static inline u32 get_pmlca(int ctr) -{ - u32 pmlca; - - switch (ctr) { - case 0: - pmlca = mfpmr(PMRN_PMLCA0); - break; - case 1: - pmlca = mfpmr(PMRN_PMLCA1); - break; - case 2: - pmlca = mfpmr(PMRN_PMLCA2); - break; - case 3: - pmlca = mfpmr(PMRN_PMLCA3); - break; - default: - panic("Bad ctr number\n"); - } - - return pmlca; -} - -static inline void set_pmlca(int ctr, u32 pmlca) -{ - switch (ctr) { - case 0: - mtpmr(PMRN_PMLCA0, pmlca); - break; - case 1: - mtpmr(PMRN_PMLCA1, pmlca); - break; - case 2: - mtpmr(PMRN_PMLCA2, pmlca); - break; - case 3: - mtpmr(PMRN_PMLCA3, pmlca); - break; - default: - panic("Bad ctr number\n"); - } -} - -static inline unsigned int ctr_read(unsigned int i) -{ - switch(i) { - case 0: - return mfpmr(PMRN_PMC0); - case 1: - return mfpmr(PMRN_PMC1); - case 2: - return mfpmr(PMRN_PMC2); - case 3: - return mfpmr(PMRN_PMC3); - default: - return 0; - } -} - -static inline void ctr_write(unsigned int i, unsigned int val) -{ - switch(i) { - case 0: - mtpmr(PMRN_PMC0, val); - break; - case 1: - mtpmr(PMRN_PMC1, val); - break; - case 2: - mtpmr(PMRN_PMC2, val); - break; - case 3: - mtpmr(PMRN_PMC3, val); - break; - default: - break; - } -} - - static void init_pmc_stop(int ctr) { u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | diff --git a/trunk/arch/powerpc/oprofile/op_model_power4.c b/trunk/arch/powerpc/oprofile/op_model_power4.c index fe597a154d4f..356709d515b9 100644 --- a/trunk/arch/powerpc/oprofile/op_model_power4.c +++ b/trunk/arch/powerpc/oprofile/op_model_power4.c @@ -121,9 +121,9 @@ static void power4_start(struct op_counter_config *ctr) for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) { if (ctr[i].enabled) { - classic_ctr_write(i, reset_value[i]); + ctr_write(i, reset_value[i]); } else { - classic_ctr_write(i, 0); + ctr_write(i, 0); } } @@ -254,13 +254,13 @@ static void power4_handle_interrupt(struct pt_regs *regs, mtmsrd(mfmsr() | MSR_PMM); for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) { - val = classic_ctr_read(i); + val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { oprofile_add_ext_sample(pc, regs, i, is_kernel); - classic_ctr_write(i, reset_value[i]); + ctr_write(i, reset_value[i]); } else { - classic_ctr_write(i, 0); + ctr_write(i, 0); } } } diff --git a/trunk/arch/powerpc/oprofile/op_model_rs64.c b/trunk/arch/powerpc/oprofile/op_model_rs64.c index c731acbfb2a5..19c5ee089bc9 100644 --- a/trunk/arch/powerpc/oprofile/op_model_rs64.c +++ b/trunk/arch/powerpc/oprofile/op_model_rs64.c @@ -137,10 +137,10 @@ static void rs64_start(struct op_counter_config *ctr) for (i = 0; i < num_counters; ++i) { if (ctr[i].enabled) { - classic_ctr_write(i, reset_value[i]); + ctr_write(i, reset_value[i]); ctrl_write(i, ctr[i].event); } else { - classic_ctr_write(i, 0); + ctr_write(i, 0); } } @@ -186,13 +186,13 @@ static void rs64_handle_interrupt(struct pt_regs *regs, mtmsrd(mfmsr() | MSR_PMM); for (i = 0; i < num_counters; ++i) { - val = classic_ctr_read(i); + val = ctr_read(i); if (val < 0) { if (ctr[i].enabled) { oprofile_add_ext_sample(pc, regs, i, is_kernel); - classic_ctr_write(i, reset_value[i]); + ctr_write(i, reset_value[i]); } else { - classic_ctr_write(i, 0); + ctr_write(i, 0); } } } diff --git a/trunk/arch/powerpc/platforms/52xx/Makefile b/trunk/arch/powerpc/platforms/52xx/Makefile index 795b713ec9ee..a46184a0c750 100644 --- a/trunk/arch/powerpc/platforms/52xx/Makefile +++ b/trunk/arch/powerpc/platforms/52xx/Makefile @@ -3,7 +3,6 @@ # ifeq ($(CONFIG_PPC_MERGE),y) obj-y += mpc52xx_pic.o mpc52xx_common.o -obj-$(CONFIG_PCI) += mpc52xx_pci.o endif obj-$(CONFIG_PPC_EFIKA) += efika-setup.o efika-pci.o diff --git a/trunk/arch/powerpc/platforms/52xx/lite5200.c b/trunk/arch/powerpc/platforms/52xx/lite5200.c index cdb16bfa6ca6..0f21bab33f6c 100644 --- a/trunk/arch/powerpc/platforms/52xx/lite5200.c +++ b/trunk/arch/powerpc/platforms/52xx/lite5200.c @@ -107,12 +107,6 @@ static void __init lite52xx_setup_arch(void) mpc52xx_setup_cpu(); /* Generic */ lite52xx_setup_cpu(); /* Platorm specific */ -#ifdef CONFIG_PCI - np = of_find_node_by_type(np, "pci"); - if (np) - mpc52xx_add_bridge(np); -#endif - #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) ROOT_DEV = Root_RAM0; diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c deleted file mode 100644 index faf161bdbc1c..000000000000 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * PCI code for the Freescale MPC52xx embedded CPU. - * - * Copyright (C) 2006 Secret Lab Technologies Ltd. - * Grant Likely - * Copyright (C) 2004 Sylvain Munaut - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include - - -/* ======================================================================== */ -/* PCI windows config */ -/* ======================================================================== */ - -#define MPC52xx_PCI_TARGET_IO 0xf0000000 -#define MPC52xx_PCI_TARGET_MEM 0x00000000 - - -/* ======================================================================== */ -/* Structures mapping & Defines for PCI Unit */ -/* ======================================================================== */ - -#define MPC52xx_PCI_GSCR_BM 0x40000000 -#define MPC52xx_PCI_GSCR_PE 0x20000000 -#define MPC52xx_PCI_GSCR_SE 0x10000000 -#define MPC52xx_PCI_GSCR_XLB2PCI_MASK 0x07000000 -#define MPC52xx_PCI_GSCR_XLB2PCI_SHIFT 24 -#define MPC52xx_PCI_GSCR_IPG2PCI_MASK 0x00070000 -#define MPC52xx_PCI_GSCR_IPG2PCI_SHIFT 16 -#define MPC52xx_PCI_GSCR_BME 0x00004000 -#define MPC52xx_PCI_GSCR_PEE 0x00002000 -#define MPC52xx_PCI_GSCR_SEE 0x00001000 -#define MPC52xx_PCI_GSCR_PR 0x00000001 - - -#define MPC52xx_PCI_IWBTAR_TRANSLATION(proc_ad,pci_ad,size) \ - ( ( (proc_ad) & 0xff000000 ) | \ - ( (((size) - 1) >> 8) & 0x00ff0000 ) | \ - ( ((pci_ad) >> 16) & 0x0000ff00 ) ) - -#define MPC52xx_PCI_IWCR_PACK(win0,win1,win2) (((win0) << 24) | \ - ((win1) << 16) | \ - ((win2) << 8)) - -#define MPC52xx_PCI_IWCR_DISABLE 0x0 -#define MPC52xx_PCI_IWCR_ENABLE 0x1 -#define MPC52xx_PCI_IWCR_READ 0x0 -#define MPC52xx_PCI_IWCR_READ_LINE 0x2 -#define MPC52xx_PCI_IWCR_READ_MULTI 0x4 -#define MPC52xx_PCI_IWCR_MEM 0x0 -#define MPC52xx_PCI_IWCR_IO 0x8 - -#define MPC52xx_PCI_TCR_P 0x01000000 -#define MPC52xx_PCI_TCR_LD 0x00010000 - -#define MPC52xx_PCI_TBATR_DISABLE 0x0 -#define MPC52xx_PCI_TBATR_ENABLE 0x1 - -struct mpc52xx_pci { - u32 idr; /* PCI + 0x00 */ - u32 scr; /* PCI + 0x04 */ - u32 ccrir; /* PCI + 0x08 */ - u32 cr1; /* PCI + 0x0C */ - u32 bar0; /* PCI + 0x10 */ - u32 bar1; /* PCI + 0x14 */ - u8 reserved1[16]; /* PCI + 0x18 */ - u32 ccpr; /* PCI + 0x28 */ - u32 sid; /* PCI + 0x2C */ - u32 erbar; /* PCI + 0x30 */ - u32 cpr; /* PCI + 0x34 */ - u8 reserved2[4]; /* PCI + 0x38 */ - u32 cr2; /* PCI + 0x3C */ - u8 reserved3[32]; /* PCI + 0x40 */ - u32 gscr; /* PCI + 0x60 */ - u32 tbatr0; /* PCI + 0x64 */ - u32 tbatr1; /* PCI + 0x68 */ - u32 tcr; /* PCI + 0x6C */ - u32 iw0btar; /* PCI + 0x70 */ - u32 iw1btar; /* PCI + 0x74 */ - u32 iw2btar; /* PCI + 0x78 */ - u8 reserved4[4]; /* PCI + 0x7C */ - u32 iwcr; /* PCI + 0x80 */ - u32 icr; /* PCI + 0x84 */ - u32 isr; /* PCI + 0x88 */ - u32 arb; /* PCI + 0x8C */ - u8 reserved5[104]; /* PCI + 0x90 */ - u32 car; /* PCI + 0xF8 */ - u8 reserved6[4]; /* PCI + 0xFC */ -}; - - -/* ======================================================================== */ -/* PCI configuration acess */ -/* ======================================================================== */ - -static int -mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - struct pci_controller *hose = bus->sysdata; - u32 value; - - if (ppc_md.pci_exclude_device) - if (ppc_md.pci_exclude_device(bus->number, devfn)) - return PCIBIOS_DEVICE_NOT_FOUND; - - out_be32(hose->cfg_addr, - (1 << 31) | - ((bus->number - hose->bus_offset) << 16) | - (devfn << 8) | - (offset & 0xfc)); - mb(); - -#if defined(CONFIG_PPC_MPC5200_BUGFIX) - if (bus->number != hose->bus_offset) { - /* workaround for the bug 435 of the MPC5200 (L25R); - * Don't do 32 bits config access during type-1 cycles */ - switch (len) { - case 1: - value = in_8(((u8 __iomem *)hose->cfg_data) + - (offset & 3)); - break; - case 2: - value = in_le16(((u16 __iomem *)hose->cfg_data) + - ((offset>>1) & 1)); - break; - - default: - value = in_le16((u16 __iomem *)hose->cfg_data) | - (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16); - break; - } - } - else -#endif - { - value = in_le32(hose->cfg_data); - - if (len != 4) { - value >>= ((offset & 0x3) << 3); - value &= 0xffffffff >> (32 - (len << 3)); - } - } - - *val = value; - - out_be32(hose->cfg_addr, 0); - mb(); - - return PCIBIOS_SUCCESSFUL; -} - -static int -mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose = bus->sysdata; - u32 value, mask; - - if (ppc_md.pci_exclude_device) - if (ppc_md.pci_exclude_device(bus->number, devfn)) - return PCIBIOS_DEVICE_NOT_FOUND; - - out_be32(hose->cfg_addr, - (1 << 31) | - ((bus->number - hose->bus_offset) << 16) | - (devfn << 8) | - (offset & 0xfc)); - mb(); - -#if defined(CONFIG_PPC_MPC5200_BUGFIX) - if (bus->number != hose->bus_offset) { - /* workaround for the bug 435 of the MPC5200 (L25R); - * Don't do 32 bits config access during type-1 cycles */ - switch (len) { - case 1: - out_8(((u8 __iomem *)hose->cfg_data) + - (offset & 3), val); - break; - case 2: - out_le16(((u16 __iomem *)hose->cfg_data) + - ((offset>>1) & 1), val); - break; - - default: - out_le16((u16 __iomem *)hose->cfg_data, - (u16)val); - out_le16(((u16 __iomem *)hose->cfg_data) + 1, - (u16)(val>>16)); - break; - } - } - else -#endif - { - if (len != 4) { - value = in_le32(hose->cfg_data); - - offset = (offset & 0x3) << 3; - mask = (0xffffffff >> (32 - (len << 3))); - mask <<= offset; - - value &= ~mask; - val = value | ((val << offset) & mask); - } - - out_le32(hose->cfg_data, val); - } - mb(); - - out_be32(hose->cfg_addr, 0); - mb(); - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops mpc52xx_pci_ops = { - .read = mpc52xx_pci_read_config, - .write = mpc52xx_pci_write_config -}; - - -/* ======================================================================== */ -/* PCI setup */ -/* ======================================================================== */ - -static void __init -mpc52xx_pci_setup(struct pci_controller *hose, - struct mpc52xx_pci __iomem *pci_regs) -{ - struct resource *res; - u32 tmp; - int iwcr0 = 0, iwcr1 = 0, iwcr2 = 0; - - pr_debug("mpc52xx_pci_setup(hose=%p, pci_regs=%p)\n", hose, pci_regs); - - /* pci_process_bridge_OF_ranges() found all our addresses for us; - * now store them in the right places */ - hose->cfg_addr = &pci_regs->car; - hose->cfg_data = hose->io_base_virt; - - /* Control regs */ - tmp = in_be32(&pci_regs->scr); - tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - out_be32(&pci_regs->scr, tmp); - - /* Memory windows */ - res = &hose->mem_resources[0]; - if (res->flags) { - pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n", - res->start, res->end, res->flags); - out_be32(&pci_regs->iw0btar, - MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start, - res->end - res->start + 1)); - iwcr0 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM; - if (res->flags & IORESOURCE_PREFETCH) - iwcr0 |= MPC52xx_PCI_IWCR_READ_MULTI; - else - iwcr0 |= MPC52xx_PCI_IWCR_READ; - } - - res = &hose->mem_resources[1]; - if (res->flags) { - pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n", - res->start, res->end, res->flags); - out_be32(&pci_regs->iw1btar, - MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start, - res->end - res->start + 1)); - iwcr1 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM; - if (res->flags & IORESOURCE_PREFETCH) - iwcr1 |= MPC52xx_PCI_IWCR_READ_MULTI; - else - iwcr1 |= MPC52xx_PCI_IWCR_READ; - } - - /* IO resources */ - res = &hose->io_resource; - if (!res) { - printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__); - return; - } - pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} " - ".io_base_phys=0x%p\n", - res->start, res->end, res->flags, (void*)hose->io_base_phys); - out_be32(&pci_regs->iw2btar, - MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys, - res->start, - res->end - res->start + 1)); - iwcr2 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_IO; - - /* Set all the IWCR fields at once; they're in the same reg */ - out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2)); - - out_be32(&pci_regs->tbatr0, - MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO ); - out_be32(&pci_regs->tbatr1, - MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM ); - - out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD); - - tmp = in_be32(&pci_regs->gscr); -#if 0 - /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */ - /* Not necessary and can be a bad thing if for example the bootloader - is displaying a splash screen or ... Just left here for - documentation purpose if anyone need it */ - out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR); - udelay(50); -#endif - - /* Make sure the PCI bridge is out of reset */ - out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR); -} - -static void -mpc52xx_pci_fixup_resources(struct pci_dev *dev) -{ - int i; - - pr_debug("mpc52xx_pci_fixup_resources() %.4x:%.4x\n", - dev->vendor, dev->device); - - /* We don't rely on boot loader for PCI and resets all - devices */ - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - struct resource *res = &dev->resource[i]; - if (res->end > res->start) { /* Only valid resources */ - res->end -= res->start; - res->start = 0; - res->flags |= IORESOURCE_UNSET; - } - } - - /* The PCI Host bridge of MPC52xx has a prefetch memory resource - fixed to 1Gb. Doesn't fit in the resource system so we remove it */ - if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) && - ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200 - || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) { - struct resource *res = &dev->resource[1]; - res->start = res->end = res->flags = 0; - } -} - -int __init -mpc52xx_add_bridge(struct device_node *node) -{ - int len; - struct mpc52xx_pci __iomem *pci_regs; - struct pci_controller *hose; - const int *bus_range; - struct resource rsrc; - - pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name); - - pci_assign_all_buses = 1; - - if (of_address_to_resource(node, 0, &rsrc) != 0) { - printk(KERN_ERR "Can't get %s resources\n", node->full_name); - return -EINVAL; - } - - bus_range = get_property(node, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get %s bus-range, assume bus 0\n", - node->full_name); - bus_range = NULL; - } - - /* There are some PCI quirks on the 52xx, register the hook to - * fix them. */ - ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources; - - /* Alloc and initialize the pci controller. Values in the device - * tree are needed to configure the 52xx PCI controller. Rather - * than parse the tree here, let pci_process_bridge_OF_ranges() - * do it for us and extract the values after the fact */ - hose = pcibios_alloc_controller(); - if (!hose) - return -ENOMEM; - - hose->arch_data = node; - hose->set_cfg_type = 1; - - hose->first_busno = bus_range ? bus_range[0] : 0; - hose->last_busno = bus_range ? bus_range[1] : 0xff; - - hose->bus_offset = 0; - hose->ops = &mpc52xx_pci_ops; - - pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1); - if (!pci_regs) - return -ENOMEM; - - pci_process_bridge_OF_ranges(hose, node, 1); - - /* Finish setting up PCI using values obtained by - * pci_proces_bridge_OF_ranges */ - mpc52xx_pci_setup(hose, pci_regs); - - return 0; -} diff --git a/trunk/arch/powerpc/platforms/82xx/mpc82xx.c b/trunk/arch/powerpc/platforms/82xx/mpc82xx.c index 74e7892cdfcf..0f5b30dc60da 100644 --- a/trunk/arch/powerpc/platforms/82xx/mpc82xx.c +++ b/trunk/arch/powerpc/platforms/82xx/mpc82xx.c @@ -50,7 +50,7 @@ #include #include -#include "pq2ads.h" +#include "pq2ads_pd.h" static int __init get_freq(char *name, unsigned long *val) { diff --git a/trunk/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/trunk/arch/powerpc/platforms/82xx/mpc82xx_ads.c index 7334c1a15b90..ea880f1f0dcd 100644 --- a/trunk/arch/powerpc/platforms/82xx/mpc82xx_ads.c +++ b/trunk/arch/powerpc/platforms/82xx/mpc82xx_ads.c @@ -51,7 +51,7 @@ #include #include <../sysdev/cpm2_pic.h> -#include "pq2ads.h" +#include "pq2ads_pd.h" #ifdef CONFIG_PCI static uint pci_clk_frq; diff --git a/trunk/arch/powerpc/platforms/82xx/pq2ads.h b/trunk/arch/powerpc/platforms/82xx/pq2ads.h index 5b5cca6c8c88..fb2f92bcd770 100644 --- a/trunk/arch/powerpc/platforms/82xx/pq2ads.h +++ b/trunk/arch/powerpc/platforms/82xx/pq2ads.h @@ -22,7 +22,6 @@ #ifndef __MACH_ADS8260_DEFS #define __MACH_ADS8260_DEFS -#include #include /* For our show_cpuinfo hooks. */ @@ -47,12 +46,12 @@ #define BCSR1_RS232_EN1 ((uint)0x02000000) /* 0 ==enable */ #define BCSR1_RS232_EN2 ((uint)0x01000000) /* 0 ==enable */ #define BCSR3_FETHIEN2 ((uint)0x10000000) /* 0 == enable*/ -#define BCSR3_FETH2_RST ((uint)0x80000000) /* 0 == reset */ +#define BCSR3_FETH2_RS ((uint)0x80000000) /* 0 == reset */ /* cpm serial driver works with constants below */ #define SIU_INT_SMC1 ((uint)0x04+CPM_IRQ_OFFSET) -#define SIU_INT_SMC2 ((uint)0x05+CPM_IRQ_OFFSET) +#define SIU_INT_SMC2i ((uint)0x05+CPM_IRQ_OFFSET) #define SIU_INT_SCC1 ((uint)0x28+CPM_IRQ_OFFSET) #define SIU_INT_SCC2 ((uint)0x29+CPM_IRQ_OFFSET) #define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET) diff --git a/trunk/arch/powerpc/platforms/83xx/misc.c b/trunk/arch/powerpc/platforms/83xx/misc.c index f01806c940e1..f0c6df61faa9 100644 --- a/trunk/arch/powerpc/platforms/83xx/misc.c +++ b/trunk/arch/powerpc/platforms/83xx/misc.c @@ -18,36 +18,23 @@ #include "mpc83xx.h" -static __be32 __iomem *restart_reg_base; - -static int __init mpc83xx_restart_init(void) -{ - /* map reset restart_reg_baseister space */ - restart_reg_base = ioremap(get_immrbase() + 0x900, 0xff); - - return 0; -} - -arch_initcall(mpc83xx_restart_init); - void mpc83xx_restart(char *cmd) { #define RST_OFFSET 0x00000900 #define RST_PROT_REG 0x00000018 #define RST_CTRL_REG 0x0000001c + __be32 __iomem *reg; - local_irq_disable(); + /* map reset register space */ + reg = ioremap(get_immrbase() + 0x900, 0xff); - if (restart_reg_base) { - /* enable software reset "RSTE" */ - out_be32(restart_reg_base + (RST_PROT_REG >> 2), 0x52535445); + local_irq_disable(); - /* set software hard reset */ - out_be32(restart_reg_base + (RST_CTRL_REG >> 2), 0x2); - } else { - printk (KERN_EMERG "Error: Restart registers not mapped, spinning!\n"); - } + /* enable software reset "RSTE" */ + out_be32(reg + (RST_PROT_REG >> 2), 0x52535445); + /* set software hard reset */ + out_be32(reg + (RST_CTRL_REG >> 2), 0x2); for (;;) ; } diff --git a/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c b/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c index 3ecb55f8a6e2..4d471190be8d 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -154,7 +153,7 @@ static int __init mpc832x_declare_of_platform_devices(void) } device_initcall(mpc832x_declare_of_platform_devices); -static void __init mpc832x_sys_init_IRQ(void) +void __init mpc832x_sys_init_IRQ(void) { struct device_node *np; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c b/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c index 2446dea9407e..314c42ac6048 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -81,7 +81,7 @@ static void __init mpc834x_itx_setup_arch(void) #endif } -static void __init mpc834x_itx_init_IRQ(void) +void __init mpc834x_itx_init_IRQ(void) { struct device_node *np; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c b/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c index f30393f0b832..80b735a414d9 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c @@ -79,7 +79,7 @@ static void __init mpc834x_sys_setup_arch(void) #endif } -static void __init mpc834x_sys_init_IRQ(void) +void __init mpc834x_sys_init_IRQ(void) { struct device_node *np; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/trunk/arch/powerpc/platforms/83xx/mpc8360e_pb.c index ccce2f9f283d..53b92a904e8e 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc8360e_pb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc8360e_pb.c @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -159,7 +158,7 @@ static int __init mpc8360_declare_of_platform_devices(void) } device_initcall(mpc8360_declare_of_platform_devices); -static void __init mpc8360_sys_init_IRQ(void) +void __init mpc8360_sys_init_IRQ(void) { struct device_node *np; diff --git a/trunk/arch/powerpc/platforms/86xx/Kconfig b/trunk/arch/powerpc/platforms/86xx/Kconfig index 0c70944d0e37..d1ecc0f9ab58 100644 --- a/trunk/arch/powerpc/platforms/86xx/Kconfig +++ b/trunk/arch/powerpc/platforms/86xx/Kconfig @@ -8,7 +8,6 @@ choice config MPC8641_HPCN bool "Freescale MPC8641 HPCN" select PPC_I8259 - select DEFAULT_UIMAGE help This option enables support for the MPC8641 HPCN board. diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c index 7ef0c6854799..bb7fb41933ad 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c @@ -65,6 +65,7 @@ smp_86xx_kick_cpu(int nr) pr_debug("smp_86xx_kick_cpu: kick CPU #%d\n", nr); local_irq_save(flags); + local_irq_disable(); /* Save reset vector */ save_vector = *vector; diff --git a/trunk/arch/powerpc/platforms/8xx/Kconfig b/trunk/arch/powerpc/platforms/8xx/Kconfig index beea6834bb7e..c8c0ba3cf8e8 100644 --- a/trunk/arch/powerpc/platforms/8xx/Kconfig +++ b/trunk/arch/powerpc/platforms/8xx/Kconfig @@ -1,16 +1,105 @@ -menu "Platform support" - depends on PPC_8xx - config FADS bool -config CPM1 - bool - choice prompt "8xx Machine Type" depends on 8xx - default MPC885ADS + default RPXLITE + +config RPXLITE + bool "RPX-Lite" + ---help--- + Single-board computers based around the PowerPC MPC8xx chips and + intended for embedded applications. The following types are + supported: + + RPX-Lite: + Embedded Planet RPX Lite. PC104 form-factor SBC based on the MPC823. + + RPX-Classic: + Embedded Planet RPX Classic Low-fat. Credit-card-size SBC based on + the MPC 860 + + BSE-IP: + Bright Star Engineering ip-Engine. + + TQM823L: + TQM850L: + TQM855L: + TQM860L: + MPC8xx based family of mini modules, half credit card size, + up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports, + 2 x CAN bus interface, ... + Manufacturer: TQ Components, www.tq-group.de + Date of Release: October (?) 1999 + End of Life: not yet :-) + URL: + - module: + - starter kit: + - images: + + FPS850L: + FingerPrint Sensor System (based on TQM850L) + Manufacturer: IKENDI AG, + Date of Release: November 1999 + End of life: end 2000 ? + URL: see TQM850L + + IVMS8: + MPC860 based board used in the "Integrated Voice Mail System", + Small Version (8 voice channels) + Manufacturer: Speech Design, + Date of Release: December 2000 (?) + End of life: - + URL: + + IVML24: + MPC860 based board used in the "Integrated Voice Mail System", + Large Version (24 voice channels) + Manufacturer: Speech Design, + Date of Release: March 2001 (?) + End of life: - + URL: + + HERMES: + Hermes-Pro ISDN/LAN router with integrated 8 x hub + Manufacturer: Multidata Gesellschaft fur Datentechnik und Informatik + + Date of Release: 2000 (?) + End of life: - + URL: + + IP860: + VMEBus IP (Industry Pack) carrier board with MPC860 + Manufacturer: MicroSys GmbH, + Date of Release: ? + End of life: - + URL: + + PCU_E: + PCU = Peripheral Controller Unit, Extended + Manufacturer: Siemens AG, ICN (Information and Communication Networks) + + Date of Release: April 2001 + End of life: August 2001 + URL: n. a. + +config RPXCLASSIC + bool "RPX-Classic" + help + The RPX-Classic is a single-board computer based on the Motorola + MPC860. It features 16MB of DRAM and a variable amount of flash, + I2C EEPROM, thermal monitoring, a PCMCIA slot, a DIP switch and two + LEDs. Variants with Ethernet ports exist. Say Y here to support it + directly. + +config BSEIP + bool "BSE-IP" + help + Say Y here to support the Bright Star Engineering ipEngine SBC. + This is a credit-card-sized device featuring a MPC823 processor, + 26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video + controller, and two RS232 ports. config MPC8XXFADS bool "FADS" @@ -18,58 +107,110 @@ config MPC8XXFADS config MPC86XADS bool "MPC86XADS" - select CPM1 help MPC86x Application Development System by Freescale Semiconductor. The MPC86xADS is meant to serve as a platform for s/w and h/w development around the MPC86X processor families. + select FADS config MPC885ADS bool "MPC885ADS" - select CPM1 help Freescale Semiconductor MPC885 Application Development System (ADS). Also known as DUET. The MPC885ADS is meant to serve as a platform for s/w and h/w development around the MPC885 processor family. -endchoice +config TQM823L + bool "TQM823L" + help + Say Y here to support the TQM823L, one of an MPC8xx-based family of + mini SBCs (half credit-card size) from TQ Components first released + in late 1999. Technical references are at + , and + , and an image at + . -menu "Freescale Ethernet driver platform-specific options" - depends on (FS_ENET && MPC885ADS) - - config MPC8xx_SECOND_ETH - bool "Second Ethernet channel" - depends on MPC885ADS - default y - help - This enables support for second Ethernet on MPC885ADS and MPC86xADS boards. - The latter will use SCC1, for 885ADS you can select it below. - - choice - prompt "Second Ethernet channel" - depends on MPC8xx_SECOND_ETH - default MPC8xx_SECOND_ETH_FEC2 - - config MPC8xx_SECOND_ETH_FEC2 - bool "FEC2" - depends on MPC885ADS - help - Enable FEC2 to serve as 2-nd Ethernet channel. Note that SMC2 - (often 2-nd UART) will not work if this is enabled. - - config MPC8xx_SECOND_ETH_SCC3 - bool "SCC3" - depends on MPC885ADS - help - Enable SCC3 to serve as 2-nd Ethernet channel. Note that SMC1 - (often 1-nd UART) will not work if this is enabled. - - endchoice +config TQM850L + bool "TQM850L" + help + Say Y here to support the TQM850L, one of an MPC8xx-based family of + mini SBCs (half credit-card size) from TQ Components first released + in late 1999. Technical references are at + , and + , and an image at + . -endmenu +config TQM855L + bool "TQM855L" + help + Say Y here to support the TQM855L, one of an MPC8xx-based family of + mini SBCs (half credit-card size) from TQ Components first released + in late 1999. Technical references are at + , and + , and an image at + . -endmenu +config TQM860L + bool "TQM860L" + help + Say Y here to support the TQM860L, one of an MPC8xx-based family of + mini SBCs (half credit-card size) from TQ Components first released + in late 1999. Technical references are at + , and + , and an image at + . + +config FPS850L + bool "FPS850L" + +config IVMS8 + bool "IVMS8" + help + Say Y here to support the Integrated Voice-Mail Small 8-channel SBC + from Speech Design, released March 2001. The manufacturer's website + is at . + +config IVML24 + bool "IVML24" + help + Say Y here to support the Integrated Voice-Mail Large 24-channel SBC + from Speech Design, released March 2001. The manufacturer's website + is at . + +config HERMES_PRO + bool "HERMES" + +config IP860 + bool "IP860" + +config LWMON + bool "LWMON" + +config PCU_E + bool "PCU_E" + +config CCM + bool "CCM" + +config LANTEC + bool "LANTEC" + +config MBX + bool "MBX" + help + MBX is a line of Motorola single-board computer based around the + MPC821 and MPC860 processors, and intended for embedded-controller + applications. Say Y here to support these boards directly. + +config WINCEPT + bool "WinCept" + help + The Wincept 100/110 is a Motorola single-board computer based on the + MPC821 PowerPC, introduced in 1998 and designed to be used in + thin-client machines. Say Y to support it directly. + +endchoice # # MPC8xx Communication options @@ -78,6 +219,79 @@ endmenu menu "MPC8xx CPM Options" depends on 8xx +config SCC_ENET + bool "CPM SCC Ethernet" + depends on NET_ETHERNET + help + Enable Ethernet support via the Motorola MPC8xx serial + communications controller. + +choice + prompt "SCC used for Ethernet" + depends on SCC_ENET + default SCC1_ENET + +config SCC1_ENET + bool "SCC1" + help + Use MPC8xx serial communications controller 1 to drive Ethernet + (default). + +config SCC2_ENET + bool "SCC2" + help + Use MPC8xx serial communications controller 2 to drive Ethernet. + +config SCC3_ENET + bool "SCC3" + help + Use MPC8xx serial communications controller 3 to drive Ethernet. + +endchoice + +config FEC_ENET + bool "860T FEC Ethernet" + depends on NET_ETHERNET + help + Enable Ethernet support via the Fast Ethernet Controller (FCC) on + the Motorola MPC8260. + +config USE_MDIO + bool "Use MDIO for PHY configuration" + depends on FEC_ENET + help + On some boards the hardware configuration of the ethernet PHY can be + used without any software interaction over the MDIO interface, so + all MII code can be omitted. Say N here if unsure or if you don't + need link status reports. + +config FEC_AM79C874 + bool "Support AMD79C874 PHY" + depends on USE_MDIO + +config FEC_LXT970 + bool "Support LXT970 PHY" + depends on USE_MDIO + +config FEC_LXT971 + bool "Support LXT971 PHY" + depends on USE_MDIO + +config FEC_QS6612 + bool "Support QS6612 PHY" + depends on USE_MDIO + +config ENET_BIG_BUFFERS + bool "Use Big CPM Ethernet Buffers" + depends on SCC_ENET || FEC_ENET + help + Allocate large buffers for MPC8xx Ethernet. Increases throughput + and decreases the likelihood of dropped packets, but costs memory. + +config HTDMSOUND + bool "Embedded Planet HIOX Audio" + depends on SOUND=y + # This doesn't really belong here, but it is convenient to ask # 8xx specific questions. comment "Generic MPC8xx Options" diff --git a/trunk/arch/powerpc/platforms/8xx/Makefile b/trunk/arch/powerpc/platforms/8xx/Makefile deleted file mode 100644 index 5e2dae3afd2f..000000000000 --- a/trunk/arch/powerpc/platforms/8xx/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for the PowerPC 8xx linux kernel. -# -obj-$(CONFIG_PPC_8xx) += m8xx_setup.o -obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o -obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o diff --git a/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c b/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c deleted file mode 100644 index 9ed7125f0150..000000000000 --- a/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 1995 Linus Torvalds - * Adapted from 'alpha' version by Gary Thomas - * Modified by Cort Dougan (cort@cs.nmt.edu) - * Modified for MBX using prep/chrp/pmac functions by Dan (dmalek@jlc.net) - * Further modified for generic 8xx by Dan. - */ - -/* - * bootup setup stuff.. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdev/mpc8xx_pic.h" - -void m8xx_calibrate_decr(void); -extern void m8xx_wdt_handler_install(bd_t *bp); -extern int cpm_pic_init(void); -extern int cpm_get_irq(void); - -/* A place holder for time base interrupts, if they are ever enabled. */ -irqreturn_t timebase_interrupt(int irq, void * dev) -{ - printk ("timebase_interrupt()\n"); - - return IRQ_HANDLED; -} - -static struct irqaction tbint_irqaction = { - .handler = timebase_interrupt, - .mask = CPU_MASK_NONE, - .name = "tbint", -}; - -/* per-board overridable init_internal_rtc() function. */ -void __init __attribute__ ((weak)) -init_internal_rtc(void) -{ - sit8xx_t *sys_tmr = (sit8xx_t *) immr_map(im_sit); - - /* Disable the RTC one second and alarm interrupts. */ - clrbits16(&sys_tmr->sit_rtcsc, (RTCSC_SIE | RTCSC_ALE)); - - /* Enable the RTC */ - setbits16(&sys_tmr->sit_rtcsc, (RTCSC_RTF | RTCSC_RTE)); - immr_unmap(sys_tmr); -} - -static int __init get_freq(char *name, unsigned long *val) -{ - struct device_node *cpu; - unsigned int *fp; - int found = 0; - - /* The cpu node should have timebase and clock frequency properties */ - cpu = of_find_node_by_type(NULL, "cpu"); - - if (cpu) { - fp = (unsigned int *)get_property(cpu, name, NULL); - if (fp) { - found = 1; - *val = *fp++; - } - - of_node_put(cpu); - } - - return found; -} - -/* The decrementer counts at the system (internal) clock frequency divided by - * sixteen, or external oscillator divided by four. We force the processor - * to use system clock divided by sixteen. - */ -void __init mpc8xx_calibrate_decr(void) -{ - struct device_node *cpu; - cark8xx_t *clk_r1; - car8xx_t *clk_r2; - sitk8xx_t *sys_tmr1; - sit8xx_t *sys_tmr2; - int irq, virq; - - clk_r1 = (cark8xx_t *) immr_map(im_clkrstk); - - /* Unlock the SCCR. */ - out_be32(&clk_r1->cark_sccrk, ~KAPWR_KEY); - out_be32(&clk_r1->cark_sccrk, KAPWR_KEY); - immr_unmap(clk_r1); - - /* Force all 8xx processors to use divide by 16 processor clock. */ - clk_r2 = (car8xx_t *) immr_map(im_clkrst); - setbits32(&clk_r2->car_sccr, 0x02000000); - immr_unmap(clk_r2); - - /* Processor frequency is MHz. - */ - ppc_tb_freq = 50000000; - if (!get_freq("bus-frequency", &ppc_tb_freq)) { - printk(KERN_ERR "WARNING: Estimating decrementer frequency " - "(not found)\n"); - } - ppc_tb_freq /= 16; - ppc_proc_freq = 50000000; - if (!get_freq("clock-frequency", &ppc_proc_freq)) - printk(KERN_ERR "WARNING: Estimating processor frequency" - "(not found)\n"); - - printk("Decrementer Frequency = 0x%lx\n", ppc_tb_freq); - - /* Perform some more timer/timebase initialization. This used - * to be done elsewhere, but other changes caused it to get - * called more than once....that is a bad thing. - * - * First, unlock all of the registers we are going to modify. - * To protect them from corruption during power down, registers - * that are maintained by keep alive power are "locked". To - * modify these registers we have to write the key value to - * the key location associated with the register. - * Some boards power up with these unlocked, while others - * are locked. Writing anything (including the unlock code?) - * to the unlocked registers will lock them again. So, here - * we guarantee the registers are locked, then we unlock them - * for our use. - */ - sys_tmr1 = (sitk8xx_t *) immr_map(im_sitk); - out_be32(&sys_tmr1->sitk_tbscrk, ~KAPWR_KEY); - out_be32(&sys_tmr1->sitk_rtcsck, ~KAPWR_KEY); - out_be32(&sys_tmr1->sitk_tbk, ~KAPWR_KEY); - out_be32(&sys_tmr1->sitk_tbscrk, KAPWR_KEY); - out_be32(&sys_tmr1->sitk_rtcsck, KAPWR_KEY); - out_be32(&sys_tmr1->sitk_tbk, KAPWR_KEY); - immr_unmap(sys_tmr1); - - init_internal_rtc(); - - /* Enabling the decrementer also enables the timebase interrupts - * (or from the other point of view, to get decrementer interrupts - * we have to enable the timebase). The decrementer interrupt - * is wired into the vector table, nothing to do here for that. - */ - cpu = of_find_node_by_type(NULL, "cpu"); - virq= irq_of_parse_and_map(cpu, 0); - irq = irq_map[virq].hwirq; - - sys_tmr2 = (sit8xx_t *) immr_map(im_sit); - out_be16(&sys_tmr2->sit_tbscr, ((1 << (7 - (irq/2))) << 8) | - (TBSCR_TBF | TBSCR_TBE)); - immr_unmap(sys_tmr2); - - if (setup_irq(virq, &tbint_irqaction)) - panic("Could not allocate timer IRQ!"); - -#ifdef CONFIG_8xx_WDT - /* Install watchdog timer handler early because it might be - * already enabled by the bootloader - */ - m8xx_wdt_handler_install(binfo); -#endif -} - -/* The RTC on the MPC8xx is an internal register. - * We want to protect this during power down, so we need to unlock, - * modify, and re-lock. - */ - -int mpc8xx_set_rtc_time(struct rtc_time *tm) -{ - sitk8xx_t *sys_tmr1; - sit8xx_t *sys_tmr2; - int time; - - sys_tmr1 = (sitk8xx_t *) immr_map(im_sitk); - sys_tmr2 = (sit8xx_t *) immr_map(im_sit); - time = mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - out_be32(&sys_tmr1->sitk_rtck, KAPWR_KEY); - out_be32(&sys_tmr2->sit_rtc, time); - out_be32(&sys_tmr1->sitk_rtck, ~KAPWR_KEY); - - immr_unmap(sys_tmr2); - immr_unmap(sys_tmr1); - return 0; -} - -void mpc8xx_get_rtc_time(struct rtc_time *tm) -{ - unsigned long data; - sit8xx_t *sys_tmr = (sit8xx_t *) immr_map(im_sit); - - /* Get time from the RTC. */ - data = in_be32(&sys_tmr->sit_rtc); - to_tm(data, tm); - tm->tm_year -= 1900; - tm->tm_mon -= 1; - immr_unmap(sys_tmr); - return; -} - -void mpc8xx_restart(char *cmd) -{ - __volatile__ unsigned char dummy; - car8xx_t * clk_r = (car8xx_t *) immr_map(im_clkrst); - - - local_irq_disable(); - - setbits32(&clk_r->car_plprcr, 0x00000080); - /* Clear the ME bit in MSR to cause checkstop on machine check - */ - mtmsr(mfmsr() & ~0x1000); - - dummy = in_8(&clk_r->res[0]); - printk("Restart failed\n"); - while(1); -} - -void mpc8xx_show_cpuinfo(struct seq_file *m) -{ - struct device_node *root; - uint memsize = total_memory; - const char *model = ""; - - seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); - - root = of_find_node_by_path("/"); - if (root) - model = get_property(root, "model", NULL); - seq_printf(m, "Machine\t\t: %s\n", model); - of_node_put(root); - - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -} - -static void cpm_cascade(unsigned int irq, struct irq_desc *desc) -{ - int cascade_irq; - - if ((cascade_irq = cpm_get_irq()) >= 0) { - struct irq_desc *cdesc = irq_desc + cascade_irq; - - generic_handle_irq(cascade_irq); - cdesc->chip->eoi(cascade_irq); - } - desc->chip->eoi(irq); -} - -/* Initialize the internal interrupt controller. The number of - * interrupts supported can vary with the processor type, and the - * 82xx family can have up to 64. - * External interrupts can be either edge or level triggered, and - * need to be initialized by the appropriate driver. - */ -void __init m8xx_pic_init(void) -{ - int irq; - - if (mpc8xx_pic_init()) { - printk(KERN_ERR "Failed interrupt 8xx controller initialization\n"); - return; - } - - irq = cpm_pic_init(); - if (irq != NO_IRQ) - set_irq_chained_handler(irq, cpm_cascade); -} diff --git a/trunk/arch/powerpc/platforms/8xx/mpc86xads.h b/trunk/arch/powerpc/platforms/8xx/mpc86xads.h deleted file mode 100644 index b5d19dd0619c..000000000000 --- a/trunk/arch/powerpc/platforms/8xx/mpc86xads.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * A collection of structures, addresses, and values associated with - * the Freescale MPC86xADS board. - * Copied from the FADS stuff. - * - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * 2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is licensed - * "as is" without any warranty of any kind, whether express or implied. - */ - -#ifdef __KERNEL__ -#ifndef __ASM_MPC86XADS_H__ -#define __ASM_MPC86XADS_H__ - -#include -#include - -/* U-Boot maps BCSR to 0xff080000 */ -#define BCSR_ADDR ((uint)0xff080000) -#define BCSR_SIZE ((uint)32) -#define BCSR0 ((uint)(BCSR_ADDR + 0x00)) -#define BCSR1 ((uint)(BCSR_ADDR + 0x04)) -#define BCSR2 ((uint)(BCSR_ADDR + 0x08)) -#define BCSR3 ((uint)(BCSR_ADDR + 0x0c)) -#define BCSR4 ((uint)(BCSR_ADDR + 0x10)) - -#define CFG_PHYDEV_ADDR ((uint)0xff0a0000) -#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300)) - -#define IMAP_ADDR (get_immrbase()) -#define IMAP_SIZE ((uint)(64 * 1024)) - -#define MPC8xx_CPM_OFFSET (0x9c0) -#define CPM_MAP_ADDR (get_immrbase() + MPC8xx_CPM_OFFSET) -#define CPM_IRQ_OFFSET 16 // for compability with cpm_uart driver - -#define PCMCIA_MEM_ADDR (uint)0xff020000) -#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) - -/* Bits of interest in the BCSRs. - */ -#define BCSR1_ETHEN ((uint)0x20000000) -#define BCSR1_IRDAEN ((uint)0x10000000) -#define BCSR1_RS232EN_1 ((uint)0x01000000) -#define BCSR1_PCCEN ((uint)0x00800000) -#define BCSR1_PCCVCC0 ((uint)0x00400000) -#define BCSR1_PCCVPP0 ((uint)0x00200000) -#define BCSR1_PCCVPP1 ((uint)0x00100000) -#define BCSR1_PCCVPP_MASK (BCSR1_PCCVPP0 | BCSR1_PCCVPP1) -#define BCSR1_RS232EN_2 ((uint)0x00040000) -#define BCSR1_PCCVCC1 ((uint)0x00010000) -#define BCSR1_PCCVCC_MASK (BCSR1_PCCVCC0 | BCSR1_PCCVCC1) - -#define BCSR4_ETH10_RST ((uint)0x80000000) /* 10Base-T PHY reset*/ -#define BCSR4_USB_LO_SPD ((uint)0x04000000) -#define BCSR4_USB_VCC ((uint)0x02000000) -#define BCSR4_USB_FULL_SPD ((uint)0x00040000) -#define BCSR4_USB_EN ((uint)0x00020000) - -#define BCSR5_MII2_EN 0x40 -#define BCSR5_MII2_RST 0x20 -#define BCSR5_T1_RST 0x10 -#define BCSR5_ATM155_RST 0x08 -#define BCSR5_ATM25_RST 0x04 -#define BCSR5_MII1_EN 0x02 -#define BCSR5_MII1_RST 0x01 - -/* Interrupt level assignments */ -#define PHY_INTERRUPT SIU_IRQ7 /* PHY link change interrupt */ -#define SIU_INT_FEC1 SIU_LEVEL1 /* FEC1 interrupt */ -#define FEC_INTERRUPT SIU_INT_FEC1 /* FEC interrupt */ - -/* We don't use the 8259 */ -#define NR_8259_INTS 0 - -/* CPM Ethernet through SCC1 */ -#define PA_ENET_RXD ((ushort)0x0001) -#define PA_ENET_TXD ((ushort)0x0002) -#define PA_ENET_TCLK ((ushort)0x0100) -#define PA_ENET_RCLK ((ushort)0x0200) -#define PB_ENET_TENA ((uint)0x00001000) -#define PC_ENET_CLSN ((ushort)0x0010) -#define PC_ENET_RENA ((ushort)0x0020) - -/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to - * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. - */ -#define SICR_ENET_MASK ((uint)0x000000ff) -#define SICR_ENET_CLKRT ((uint)0x0000002c) - -#endif /* __ASM_MPC86XADS_H__ */ -#endif /* __KERNEL__ */ diff --git a/trunk/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/trunk/arch/powerpc/platforms/8xx/mpc86xads_setup.c deleted file mode 100644 index ef52ce701b0e..000000000000 --- a/trunk/arch/powerpc/platforms/8xx/mpc86xads_setup.c +++ /dev/null @@ -1,301 +0,0 @@ -/*arch/ppc/platforms/mpc86xads-setup.c - * - * Platform setup for the Freescale mpc86xads board - * - * Vitaly Bordug - * - * Copyright 2005 MontaVista Software Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void cpm_reset(void); -extern void mpc8xx_show_cpuinfo(struct seq_file*); -extern void mpc8xx_restart(char *cmd); -extern void mpc8xx_calibrate_decr(void); -extern int mpc8xx_set_rtc_time(struct rtc_time *tm); -extern void mpc8xx_get_rtc_time(struct rtc_time *tm); -extern void m8xx_pic_init(void); -extern unsigned int mpc8xx_get_irq(void); - -static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi); -static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi); -static void init_scc1_ioports(struct fs_platform_info* ptr); - -void __init mpc86xads_board_setup(void) -{ - cpm8xx_t *cp; - unsigned int *bcsr_io; - u8 tmpval8; - - bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); - cp = (cpm8xx_t *)immr_map(im_cpm); - - if (bcsr_io == NULL) { - printk(KERN_CRIT "Could not remap BCSR\n"); - return; - } -#ifdef CONFIG_SERIAL_CPM_SMC1 - clrbits32(bcsr_io, BCSR1_RS232EN_1); - clrbits32(&cp->cp_simode, 0xe0000000 >> 17); /* brg1 */ - tmpval8 = in_8(&(cp->cp_smc[0].smc_smcm)) | (SMCM_RX | SMCM_TX); - out_8(&(cp->cp_smc[0].smc_smcm), tmpval8); - clrbits16(&cp->cp_smc[0].smc_smcmr, SMCMR_REN | SMCMR_TEN); -#else - setbits32(bcsr_io,BCSR1_RS232EN_1); - out_be16(&cp->cp_smc[0].smc_smcmr, 0); - out_8(&cp->cp_smc[0].smc_smce, 0); -#endif - -#ifdef CONFIG_SERIAL_CPM_SMC2 - clrbits32(bcsr_io,BCSR1_RS232EN_2); - clrbits32(&cp->cp_simode, 0xe0000000 >> 1); - setbits32(&cp->cp_simode, 0x20000000 >> 1); /* brg2 */ - tmpval8 = in_8(&(cp->cp_smc[1].smc_smcm)) | (SMCM_RX | SMCM_TX); - out_8(&(cp->cp_smc[1].smc_smcm), tmpval8); - clrbits16(&cp->cp_smc[1].smc_smcmr, SMCMR_REN | SMCMR_TEN); - - init_smc2_uart_ioports(0); -#else - setbits32(bcsr_io,BCSR1_RS232EN_2); - out_be16(&cp->cp_smc[1].smc_smcmr, 0); - out_8(&cp->cp_smc[1].smc_smce, 0); -#endif - immr_unmap(cp); - iounmap(bcsr_io); -} - - -static void init_fec1_ioports(struct fs_platform_info* ptr) -{ - iop8xx_t *io_port = (iop8xx_t *)immr_map(im_ioport); - - /* configure FEC1 pins */ - - setbits16(&io_port->iop_pdpar, 0x1fff); - setbits16(&io_port->iop_pddir, 0x1fff); - - immr_unmap(io_port); -} - -void init_fec_ioports(struct fs_platform_info *fpi) -{ - int fec_no = fs_get_fec_index(fpi->fs_no); - - switch (fec_no) { - case 0: - init_fec1_ioports(fpi); - break; - default: - printk(KERN_ERR "init_fec_ioports: invalid FEC number\n"); - return; - } -} - -static void init_scc1_ioports(struct fs_platform_info* fpi) -{ - unsigned *bcsr_io; - iop8xx_t *io_port; - cpm8xx_t *cp; - - bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE); - io_port = (iop8xx_t *)immr_map(im_ioport); - cp = (cpm8xx_t *)immr_map(im_cpm); - - if (bcsr_io == NULL) { - printk(KERN_CRIT "Could not remap BCSR\n"); - return; - } - - /* Configure port A pins for Txd and Rxd. - */ - setbits16(&io_port->iop_papar, PA_ENET_RXD | PA_ENET_TXD); - clrbits16(&io_port->iop_padir, PA_ENET_RXD | PA_ENET_TXD); - clrbits16(&io_port->iop_paodr, PA_ENET_TXD); - - /* Configure port C pins to enable CLSN and RENA. - */ - clrbits16(&io_port->iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA); - clrbits16(&io_port->iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA); - setbits16(&io_port->iop_pcso, PC_ENET_CLSN | PC_ENET_RENA); - - /* Configure port A for TCLK and RCLK. - */ - setbits16(&io_port->iop_papar, PA_ENET_TCLK | PA_ENET_RCLK); - clrbits16(&io_port->iop_padir, PA_ENET_TCLK | PA_ENET_RCLK); - clrbits32(&cp->cp_pbpar, PB_ENET_TENA); - clrbits32(&cp->cp_pbdir, PB_ENET_TENA); - - /* Configure Serial Interface clock routing. - * First, clear all SCC bits to zero, then set the ones we want. - */ - clrbits32(&cp->cp_sicr, SICR_ENET_MASK); - setbits32(&cp->cp_sicr, SICR_ENET_CLKRT); - - /* In the original SCC enet driver the following code is placed at - the end of the initialization */ - setbits32(&cp->cp_pbpar, PB_ENET_TENA); - setbits32(&cp->cp_pbdir, PB_ENET_TENA); - - clrbits32(bcsr_io+1, BCSR1_ETHEN); - iounmap(bcsr_io); - immr_unmap(cp); - immr_unmap(io_port); -} - -void init_scc_ioports(struct fs_platform_info *fpi) -{ - int scc_no = fs_get_scc_index(fpi->fs_no); - - switch (scc_no) { - case 0: - init_scc1_ioports(fpi); - break; - default: - printk(KERN_ERR "init_scc_ioports: invalid SCC number\n"); - return; - } -} - - - -static void init_smc1_uart_ioports(struct fs_uart_platform_info* ptr) -{ - unsigned *bcsr_io; - cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm); - - setbits32(&cp->cp_pbpar, 0x000000c0); - clrbits32(&cp->cp_pbdir, 0x000000c0); - clrbits16(&cp->cp_pbodr, 0x00c0); - immr_unmap(cp); - - bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); - - if (bcsr_io == NULL) { - printk(KERN_CRIT "Could not remap BCSR1\n"); - return; - } - clrbits32(bcsr_io,BCSR1_RS232EN_1); - iounmap(bcsr_io); -} - -static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi) -{ - unsigned *bcsr_io; - cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm); - - setbits32(&cp->cp_pbpar, 0x00000c00); - clrbits32(&cp->cp_pbdir, 0x00000c00); - clrbits16(&cp->cp_pbodr, 0x0c00); - immr_unmap(cp); - - bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); - - if (bcsr_io == NULL) { - printk(KERN_CRIT "Could not remap BCSR1\n"); - return; - } - clrbits32(bcsr_io,BCSR1_RS232EN_2); - iounmap(bcsr_io); -} - -void init_smc_ioports(struct fs_uart_platform_info *data) -{ - int smc_no = fs_uart_id_fsid2smc(data->fs_no); - - switch (smc_no) { - case 0: - init_smc1_uart_ioports(data); - data->brg = data->clk_rx; - break; - case 1: - init_smc2_uart_ioports(data); - data->brg = data->clk_rx; - break; - default: - printk(KERN_ERR "init_scc_ioports: invalid SCC number\n"); - return; - } -} - -int platform_device_skip(char *model, int id) -{ - return 0; -} - -static void __init mpc86xads_setup_arch(void) -{ - struct device_node *cpu; - - cpu = of_find_node_by_type(NULL, "cpu"); - if (cpu != 0) { - const unsigned int *fp; - - fp = get_property(cpu, "clock-frequency", NULL); - if (fp != 0) - loops_per_jiffy = *fp / HZ; - else - loops_per_jiffy = 50000000 / HZ; - of_node_put(cpu); - } - - cpm_reset(); - - mpc86xads_board_setup(); - - ROOT_DEV = Root_NFS; -} - -static int __init mpc86xads_probe(void) -{ - char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), - "model", NULL); - if (model == NULL) - return 0; - if (strcmp(model, "MPC866ADS")) - return 0; - - return 1; -} - -define_machine(mpc86x_ads) { - .name = "MPC86x ADS", - .probe = mpc86xads_probe, - .setup_arch = mpc86xads_setup_arch, - .init_IRQ = m8xx_pic_init, - .show_cpuinfo = mpc8xx_show_cpuinfo, - .get_irq = mpc8xx_get_irq, - .restart = mpc8xx_restart, - .calibrate_decr = mpc8xx_calibrate_decr, - .set_rtc_time = mpc8xx_set_rtc_time, - .get_rtc_time = mpc8xx_get_rtc_time, -}; diff --git a/trunk/arch/powerpc/platforms/8xx/mpc885ads.h b/trunk/arch/powerpc/platforms/8xx/mpc885ads.h deleted file mode 100644 index 30cbebfe84c5..000000000000 --- a/trunk/arch/powerpc/platforms/8xx/mpc885ads.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * A collection of structures, addresses, and values associated with - * the Freescale MPC885ADS board. - * Copied from the FADS stuff. - * - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * 2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is licensed - * "as is" without any warranty of any kind, whether express or implied. - */ - -#ifdef __KERNEL__ -#ifndef __ASM_MPC885ADS_H__ -#define __ASM_MPC885ADS_H__ - -#include -#include - -/* U-Boot maps BCSR to 0xff080000 */ -#define BCSR_ADDR ((uint)0xff080000) -#define BCSR_SIZE ((uint)32) -#define BCSR0 ((uint)(BCSR_ADDR + 0x00)) -#define BCSR1 ((uint)(BCSR_ADDR + 0x04)) -#define BCSR2 ((uint)(BCSR_ADDR + 0x08)) -#define BCSR3 ((uint)(BCSR_ADDR + 0x0c)) -#define BCSR4 ((uint)(BCSR_ADDR + 0x10)) - -#define CFG_PHYDEV_ADDR ((uint)0xff0a0000) -#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300)) - -#define IMAP_ADDR (get_immrbase()) -#define IMAP_SIZE ((uint)(64 * 1024)) - -#define MPC8xx_CPM_OFFSET (0x9c0) -#define CPM_MAP_ADDR (get_immrbase() + MPC8xx_CPM_OFFSET) -#define CPM_IRQ_OFFSET 16 // for compability with cpm_uart driver - -#define PCMCIA_MEM_ADDR (uint)0xff020000) -#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) - -/* Bits of interest in the BCSRs. - */ -#define BCSR1_ETHEN ((uint)0x20000000) -#define BCSR1_IRDAEN ((uint)0x10000000) -#define BCSR1_RS232EN_1 ((uint)0x01000000) -#define BCSR1_PCCEN ((uint)0x00800000) -#define BCSR1_PCCVCC0 ((uint)0x00400000) -#define BCSR1_PCCVPP0 ((uint)0x00200000) -#define BCSR1_PCCVPP1 ((uint)0x00100000) -#define BCSR1_PCCVPP_MASK (BCSR1_PCCVPP0 | BCSR1_PCCVPP1) -#define BCSR1_RS232EN_2 ((uint)0x00040000) -#define BCSR1_PCCVCC1 ((uint)0x00010000) -#define BCSR1_PCCVCC_MASK (BCSR1_PCCVCC0 | BCSR1_PCCVCC1) - -#define BCSR4_ETH10_RST ((uint)0x80000000) /* 10Base-T PHY reset*/ -#define BCSR4_USB_LO_SPD ((uint)0x04000000) -#define BCSR4_USB_VCC ((uint)0x02000000) -#define BCSR4_USB_FULL_SPD ((uint)0x00040000) -#define BCSR4_USB_EN ((uint)0x00020000) - -#define BCSR5_MII2_EN 0x40 -#define BCSR5_MII2_RST 0x20 -#define BCSR5_T1_RST 0x10 -#define BCSR5_ATM155_RST 0x08 -#define BCSR5_ATM25_RST 0x04 -#define BCSR5_MII1_EN 0x02 -#define BCSR5_MII1_RST 0x01 - -/* Interrupt level assignments */ -#define PHY_INTERRUPT SIU_IRQ7 /* PHY link change interrupt */ -#define SIU_INT_FEC1 SIU_LEVEL1 /* FEC1 interrupt */ -#define SIU_INT_FEC2 SIU_LEVEL3 /* FEC2 interrupt */ -#define FEC_INTERRUPT SIU_INT_FEC1 /* FEC interrupt */ - -/* We don't use the 8259 */ -#define NR_8259_INTS 0 - -/* CPM Ethernet through SCC3 */ -#define PA_ENET_RXD ((ushort)0x0040) -#define PA_ENET_TXD ((ushort)0x0080) -#define PE_ENET_TCLK ((uint)0x00004000) -#define PE_ENET_RCLK ((uint)0x00008000) -#define PE_ENET_TENA ((uint)0x00000010) -#define PC_ENET_CLSN ((ushort)0x0400) -#define PC_ENET_RENA ((ushort)0x0800) - -/* Control bits in the SICR to route TCLK (CLK5) and RCLK (CLK6) to - * SCC3. Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero */ -#define SICR_ENET_MASK ((uint)0x00ff0000) -#define SICR_ENET_CLKRT ((uint)0x002c0000) - -#endif /* __ASM_MPC885ADS_H__ */ -#endif /* __KERNEL__ */ diff --git a/trunk/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/trunk/arch/powerpc/platforms/8xx/mpc885ads_setup.c deleted file mode 100644 index c5fefdf66c0a..000000000000 --- a/trunk/arch/powerpc/platforms/8xx/mpc885ads_setup.c +++ /dev/null @@ -1,387 +0,0 @@ -/*arch/ppc/platforms/mpc885ads-setup.c - * - * Platform setup for the Freescale mpc885ads board - * - * Vitaly Bordug - * - * Copyright 2005 MontaVista Software Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void cpm_reset(void); -extern void mpc8xx_show_cpuinfo(struct seq_file*); -extern void mpc8xx_restart(char *cmd); -extern void mpc8xx_calibrate_decr(void); -extern int mpc8xx_set_rtc_time(struct rtc_time *tm); -extern void mpc8xx_get_rtc_time(struct rtc_time *tm); -extern void m8xx_pic_init(void); -extern unsigned int mpc8xx_get_irq(void); - -static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi); -static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi); -static void init_scc3_ioports(struct fs_platform_info* ptr); - -void __init mpc885ads_board_setup(void) -{ - cpm8xx_t *cp; - unsigned int *bcsr_io; - u8 tmpval8; - -#ifdef CONFIG_FS_ENET - iop8xx_t *io_port; -#endif - - bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); - cp = (cpm8xx_t *)immr_map(im_cpm); - - if (bcsr_io == NULL) { - printk(KERN_CRIT "Could not remap BCSR\n"); - return; - } -#ifdef CONFIG_SERIAL_CPM_SMC1 - clrbits32(bcsr_io, BCSR1_RS232EN_1); - clrbits32(&cp->cp_simode, 0xe0000000 >> 17); /* brg1 */ - tmpval8 = in_8(&(cp->cp_smc[0].smc_smcm)) | (SMCM_RX | SMCM_TX); - out_8(&(cp->cp_smc[0].smc_smcm), tmpval8); - clrbits16(&cp->cp_smc[0].smc_smcmr, SMCMR_REN | SMCMR_TEN); /* brg1 */ -#else - setbits32(bcsr_io,BCSR1_RS232EN_1); - out_be16(&cp->cp_smc[0].smc_smcmr, 0); - out_8(&cp->cp_smc[0].smc_smce, 0); -#endif - -#ifdef CONFIG_SERIAL_CPM_SMC2 - clrbits32(bcsr_io,BCSR1_RS232EN_2); - clrbits32(&cp->cp_simode, 0xe0000000 >> 1); - setbits32(&cp->cp_simode, 0x20000000 >> 1); /* brg2 */ - tmpval8 = in_8(&(cp->cp_smc[1].smc_smcm)) | (SMCM_RX | SMCM_TX); - out_8(&(cp->cp_smc[1].smc_smcm), tmpval8); - clrbits16(&cp->cp_smc[1].smc_smcmr, SMCMR_REN | SMCMR_TEN); - - init_smc2_uart_ioports(0); -#else - setbits32(bcsr_io,BCSR1_RS232EN_2); - out_be16(&cp->cp_smc[1].smc_smcmr, 0); - out_8(&cp->cp_smc[1].smc_smce, 0); -#endif - immr_unmap(cp); - iounmap(bcsr_io); - -#ifdef CONFIG_FS_ENET - /* use MDC for MII (common) */ - io_port = (iop8xx_t*)immr_map(im_ioport); - setbits16(&io_port->iop_pdpar, 0x0080); - clrbits16(&io_port->iop_pddir, 0x0080); - - bcsr_io = ioremap(BCSR5, sizeof(unsigned long)); - clrbits32(bcsr_io,BCSR5_MII1_EN); - clrbits32(bcsr_io,BCSR5_MII1_RST); -#ifndef CONFIG_FC_ENET_HAS_SCC - clrbits32(bcsr_io,BCSR5_MII2_EN); - clrbits32(bcsr_io,BCSR5_MII2_RST); - -#endif - iounmap(bcsr_io); - immr_unmap(io_port); - -#endif -} - - -static void init_fec1_ioports(struct fs_platform_info* ptr) -{ - cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm); - iop8xx_t *io_port = (iop8xx_t *)immr_map(im_ioport); - - /* configure FEC1 pins */ - setbits16(&io_port->iop_papar, 0xf830); - setbits16(&io_port->iop_padir, 0x0830); - clrbits16(&io_port->iop_padir, 0xf000); - - setbits32(&cp->cp_pbpar, 0x00001001); - clrbits32(&cp->cp_pbdir, 0x00001001); - - setbits16(&io_port->iop_pcpar, 0x000c); - clrbits16(&io_port->iop_pcdir, 0x000c); - - setbits32(&cp->cp_pepar, 0x00000003); - setbits32(&cp->cp_pedir, 0x00000003); - clrbits32(&cp->cp_peso, 0x00000003); - clrbits32(&cp->cp_cptr, 0x00000100); - - immr_unmap(io_port); - immr_unmap(cp); -} - - -static void init_fec2_ioports(struct fs_platform_info* ptr) -{ - cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm); - iop8xx_t *io_port = (iop8xx_t *)immr_map(im_ioport); - - /* configure FEC2 pins */ - setbits32(&cp->cp_pepar, 0x0003fffc); - setbits32(&cp->cp_pedir, 0x0003fffc); - clrbits32(&cp->cp_peso, 0x000087fc); - setbits32(&cp->cp_peso, 0x00037800); - clrbits32(&cp->cp_cptr, 0x00000080); - - immr_unmap(io_port); - immr_unmap(cp); -} - -void init_fec_ioports(struct fs_platform_info *fpi) -{ - int fec_no = fs_get_fec_index(fpi->fs_no); - - switch (fec_no) { - case 0: - init_fec1_ioports(fpi); - break; - case 1: - init_fec2_ioports(fpi); - break; - default: - printk(KERN_ERR "init_fec_ioports: invalid FEC number\n"); - return; - } -} - -static void init_scc3_ioports(struct fs_platform_info* fpi) -{ - unsigned *bcsr_io; - iop8xx_t *io_port; - cpm8xx_t *cp; - - bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE); - io_port = (iop8xx_t *)immr_map(im_ioport); - cp = (cpm8xx_t *)immr_map(im_cpm); - - if (bcsr_io == NULL) { - printk(KERN_CRIT "Could not remap BCSR\n"); - return; - } - - /* Enable the PHY. - */ - clrbits32(bcsr_io+4, BCSR4_ETH10_RST); - udelay(1000); - setbits32(bcsr_io+4, BCSR4_ETH10_RST); - /* Configure port A pins for Txd and Rxd. - */ - setbits16(&io_port->iop_papar, PA_ENET_RXD | PA_ENET_TXD); - clrbits16(&io_port->iop_padir, PA_ENET_RXD | PA_ENET_TXD); - - /* Configure port C pins to enable CLSN and RENA. - */ - clrbits16(&io_port->iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA); - clrbits16(&io_port->iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA); - setbits16(&io_port->iop_pcso, PC_ENET_CLSN | PC_ENET_RENA); - - /* Configure port E for TCLK and RCLK. - */ - setbits32(&cp->cp_pepar, PE_ENET_TCLK | PE_ENET_RCLK); - clrbits32(&cp->cp_pepar, PE_ENET_TENA); - clrbits32(&cp->cp_pedir, - PE_ENET_TCLK | PE_ENET_RCLK | PE_ENET_TENA); - clrbits32(&cp->cp_peso, PE_ENET_TCLK | PE_ENET_RCLK); - setbits32(&cp->cp_peso, PE_ENET_TENA); - - /* Configure Serial Interface clock routing. - * First, clear all SCC bits to zero, then set the ones we want. - */ - clrbits32(&cp->cp_sicr, SICR_ENET_MASK); - setbits32(&cp->cp_sicr, SICR_ENET_CLKRT); - - /* Disable Rx and Tx. SMC1 sshould be stopped if SCC3 eternet are used. - */ - clrbits16(&cp->cp_smc[0].smc_smcmr, SMCMR_REN | SMCMR_TEN); - /* On the MPC885ADS SCC ethernet PHY is initialized in the full duplex mode - * by H/W setting after reset. SCC ethernet controller support only half duplex. - * This discrepancy of modes causes a lot of carrier lost errors. - */ - - /* In the original SCC enet driver the following code is placed at - the end of the initialization */ - setbits32(&cp->cp_pepar, PE_ENET_TENA); - clrbits32(&cp->cp_pedir, PE_ENET_TENA); - setbits32(&cp->cp_peso, PE_ENET_TENA); - - setbits32(bcsr_io+4, BCSR1_ETHEN); - iounmap(bcsr_io); - immr_unmap(io_port); - immr_unmap(cp); -} - -void init_scc_ioports(struct fs_platform_info *fpi) -{ - int scc_no = fs_get_scc_index(fpi->fs_no); - - switch (scc_no) { - case 2: - init_scc3_ioports(fpi); - break; - default: - printk(KERN_ERR "init_scc_ioports: invalid SCC number\n"); - return; - } -} - - - -static void init_smc1_uart_ioports(struct fs_uart_platform_info* ptr) -{ - unsigned *bcsr_io; - cpm8xx_t *cp; - - cp = (cpm8xx_t *)immr_map(im_cpm); - setbits32(&cp->cp_pepar, 0x000000c0); - clrbits32(&cp->cp_pedir, 0x000000c0); - clrbits32(&cp->cp_peso, 0x00000040); - setbits32(&cp->cp_peso, 0x00000080); - immr_unmap(cp); - - bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); - - if (bcsr_io == NULL) { - printk(KERN_CRIT "Could not remap BCSR1\n"); - return; - } - clrbits32(bcsr_io,BCSR1_RS232EN_1); - iounmap(bcsr_io); -} - -static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi) -{ - unsigned *bcsr_io; - cpm8xx_t *cp; - - cp = (cpm8xx_t *)immr_map(im_cpm); - setbits32(&cp->cp_pepar, 0x00000c00); - clrbits32(&cp->cp_pedir, 0x00000c00); - clrbits32(&cp->cp_peso, 0x00000400); - setbits32(&cp->cp_peso, 0x00000800); - immr_unmap(cp); - - bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); - - if (bcsr_io == NULL) { - printk(KERN_CRIT "Could not remap BCSR1\n"); - return; - } - clrbits32(bcsr_io,BCSR1_RS232EN_2); - iounmap(bcsr_io); -} - -void init_smc_ioports(struct fs_uart_platform_info *data) -{ - int smc_no = fs_uart_id_fsid2smc(data->fs_no); - - switch (smc_no) { - case 0: - init_smc1_uart_ioports(data); - data->brg = data->clk_rx; - break; - case 1: - init_smc2_uart_ioports(data); - data->brg = data->clk_rx; - break; - default: - printk(KERN_ERR "init_scc_ioports: invalid SCC number\n"); - return; - } -} - -int platform_device_skip(char *model, int id) -{ -#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3 - const char *dev = "FEC"; - int n = 2; -#else - const char *dev = "SCC"; - int n = 3; -#endif - - if (!strcmp(model, dev) && n == id) - return 1; - - return 0; -} - -static void __init mpc885ads_setup_arch(void) -{ - struct device_node *cpu; - - cpu = of_find_node_by_type(NULL, "cpu"); - if (cpu != 0) { - const unsigned int *fp; - - fp = get_property(cpu, "clock-frequency", NULL); - if (fp != 0) - loops_per_jiffy = *fp / HZ; - else - loops_per_jiffy = 50000000 / HZ; - of_node_put(cpu); - } - - cpm_reset(); - - mpc885ads_board_setup(); - - ROOT_DEV = Root_NFS; -} - -static int __init mpc885ads_probe(void) -{ - char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), - "model", NULL); - if (model == NULL) - return 0; - if (strcmp(model, "MPC885ADS")) - return 0; - - return 1; -} - -define_machine(mpc885_ads) { - .name = "MPC885 ADS", - .probe = mpc885ads_probe, - .setup_arch = mpc885ads_setup_arch, - .init_IRQ = m8xx_pic_init, - .show_cpuinfo = mpc8xx_show_cpuinfo, - .get_irq = mpc8xx_get_irq, - .restart = mpc8xx_restart, - .calibrate_decr = mpc8xx_calibrate_decr, - .set_rtc_time = mpc8xx_set_rtc_time, - .get_rtc_time = mpc8xx_get_rtc_time, -}; diff --git a/trunk/arch/powerpc/platforms/Makefile b/trunk/arch/powerpc/platforms/Makefile index 65e612315b9b..507d1b98f270 100644 --- a/trunk/arch/powerpc/platforms/Makefile +++ b/trunk/arch/powerpc/platforms/Makefile @@ -8,8 +8,6 @@ endif obj-$(CONFIG_PPC_MPC52xx) += 52xx/ obj-$(CONFIG_PPC_CHRP) += chrp/ obj-$(CONFIG_4xx) += 4xx/ -obj-$(CONFIG_PPC_8xx) += 8xx/ -obj-$(CONFIG_PPC_82xx) += 82xx/ obj-$(CONFIG_PPC_83xx) += 83xx/ obj-$(CONFIG_PPC_85xx) += 85xx/ obj-$(CONFIG_PPC_86xx) += 86xx/ @@ -19,5 +17,4 @@ obj-$(CONFIG_PPC_MAPLE) += maple/ obj-$(CONFIG_PPC_PASEMI) += pasemi/ obj-$(CONFIG_PPC_CELL) += cell/ obj-$(CONFIG_PPC_PS3) += ps3/ -obj-$(CONFIG_PPC_CELLEB) += celleb/ obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ diff --git a/trunk/arch/powerpc/platforms/cell/Makefile b/trunk/arch/powerpc/platforms/cell/Makefile index 869af89df6ff..f90e8337796c 100644 --- a/trunk/arch/powerpc/platforms/cell/Makefile +++ b/trunk/arch/powerpc/platforms/cell/Makefile @@ -14,12 +14,7 @@ endif spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o spu-priv1-$(CONFIG_PPC_CELL_NATIVE) += spu_priv1_mmio.o -spu-manage-$(CONFIG_PPC_CELLEB) += spu_manage.o -spu-manage-$(CONFIG_PPC_CELL_NATIVE) += spu_manage.o - obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ spu_coredump.o \ $(spufs-modular-m) \ - $(spu-priv1-y) \ - $(spu-manage-y) \ - spufs/ + $(spu-priv1-y) spufs/ diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c index c43999a10deb..bd7bffc3ddd0 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ b/trunk/arch/powerpc/platforms/cell/spu_base.c @@ -170,11 +170,9 @@ int spu_irq_class_0_bottom(struct spu *spu) { unsigned long stat, mask; - unsigned long flags; spu->class_0_pending = 0; - spin_lock_irqsave(&spu->register_lock, flags); mask = spu_int_mask_get(spu, 0); stat = spu_int_stat_get(spu, 0); @@ -190,7 +188,6 @@ spu_irq_class_0_bottom(struct spu *spu) __spu_trap_error(spu); spu_int_stat_clear(spu, 0, stat); - spin_unlock_irqrestore(&spu->register_lock, flags); return (stat & 0x7) ? -EIO : 0; } diff --git a/trunk/arch/powerpc/platforms/cell/spu_manage.c b/trunk/arch/powerpc/platforms/cell/spu_manage.c deleted file mode 100644 index d8b39fe39cdd..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spu_manage.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * spu management operations for of based platforms - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 - * Copyright 2006 Sony Corp. - * (C) Copyright 2007 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "interrupt.h" - -struct device_node *spu_devnode(struct spu *spu) -{ - return spu->devnode; -} - -EXPORT_SYMBOL_GPL(spu_devnode); - -static u64 __init find_spu_unit_number(struct device_node *spe) -{ - const unsigned int *prop; - int proplen; - prop = get_property(spe, "unit-id", &proplen); - if (proplen == 4) - return (u64)*prop; - - prop = get_property(spe, "reg", &proplen); - if (proplen == 4) - return (u64)*prop; - - return 0; -} - -static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, - const char *prop) -{ - const struct address_prop { - unsigned long address; - unsigned int len; - } __attribute__((packed)) *p; - int proplen; - - unsigned long start_pfn, nr_pages; - struct pglist_data *pgdata; - struct zone *zone; - int ret; - - p = get_property(spe, prop, &proplen); - WARN_ON(proplen != sizeof (*p)); - - start_pfn = p->address >> PAGE_SHIFT; - nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; - - pgdata = NODE_DATA(spu->node); - zone = pgdata->node_zones; - - ret = __add_pages(zone, start_pfn, nr_pages); - - return ret; -} - -static void __iomem * __init map_spe_prop(struct spu *spu, - struct device_node *n, const char *name) -{ - const struct address_prop { - unsigned long address; - unsigned int len; - } __attribute__((packed)) *prop; - - const void *p; - int proplen; - void __iomem *ret = NULL; - int err = 0; - - p = get_property(n, name, &proplen); - if (proplen != sizeof (struct address_prop)) - return NULL; - - prop = p; - - err = cell_spuprop_present(spu, n, name); - if (err && (err != -EEXIST)) - goto out; - - ret = ioremap(prop->address, prop->len); - - out: - return ret; -} - -static void spu_unmap(struct spu *spu) -{ - if (!firmware_has_feature(FW_FEATURE_LPAR)) - iounmap(spu->priv1); - iounmap(spu->priv2); - iounmap(spu->problem); - iounmap((__force u8 __iomem *)spu->local_store); -} - -static int __init spu_map_interrupts_old(struct spu *spu, - struct device_node *np) -{ - unsigned int isrc; - const u32 *tmp; - int nid; - - /* Get the interrupt source unit from the device-tree */ - tmp = get_property(np, "isrc", NULL); - if (!tmp) - return -ENODEV; - isrc = tmp[0]; - - tmp = get_property(np->parent->parent, "node-id", NULL); - if (!tmp) { - printk(KERN_WARNING "%s: can't find node-id\n", __FUNCTION__); - nid = spu->node; - } else - nid = tmp[0]; - - /* Add the node number */ - isrc |= nid << IIC_IRQ_NODE_SHIFT; - - /* Now map interrupts of all 3 classes */ - spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc); - spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc); - spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc); - - /* Right now, we only fail if class 2 failed */ - return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; -} - -static int __init spu_map_device_old(struct spu *spu) -{ - struct device_node *node = spu->devnode; - const char *prop; - int ret; - - ret = -ENODEV; - spu->name = get_property(node, "name", NULL); - if (!spu->name) - goto out; - - prop = get_property(node, "local-store", NULL); - if (!prop) - goto out; - spu->local_store_phys = *(unsigned long *)prop; - - /* we use local store as ram, not io memory */ - spu->local_store = (void __force *) - map_spe_prop(spu, node, "local-store"); - if (!spu->local_store) - goto out; - - prop = get_property(node, "problem", NULL); - if (!prop) - goto out_unmap; - spu->problem_phys = *(unsigned long *)prop; - - spu->problem = map_spe_prop(spu, node, "problem"); - if (!spu->problem) - goto out_unmap; - - spu->priv2 = map_spe_prop(spu, node, "priv2"); - if (!spu->priv2) - goto out_unmap; - - if (!firmware_has_feature(FW_FEATURE_LPAR)) { - spu->priv1 = map_spe_prop(spu, node, "priv1"); - if (!spu->priv1) - goto out_unmap; - } - - ret = 0; - goto out; - -out_unmap: - spu_unmap(spu); -out: - return ret; -} - -static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) -{ - struct of_irq oirq; - int ret; - int i; - - for (i=0; i < 3; i++) { - ret = of_irq_map_one(np, i, &oirq); - if (ret) { - pr_debug("spu_new: failed to get irq %d\n", i); - goto err; - } - ret = -EINVAL; - pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], - oirq.controller->full_name); - spu->irqs[i] = irq_create_of_mapping(oirq.controller, - oirq.specifier, oirq.size); - if (spu->irqs[i] == NO_IRQ) { - pr_debug("spu_new: failed to map it !\n"); - goto err; - } - } - return 0; - -err: - pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, - spu->name); - for (; i >= 0; i--) { - if (spu->irqs[i] != NO_IRQ) - irq_dispose_mapping(spu->irqs[i]); - } - return ret; -} - -static int spu_map_resource(struct spu *spu, int nr, - void __iomem** virt, unsigned long *phys) -{ - struct device_node *np = spu->devnode; - unsigned long start_pfn, nr_pages; - struct pglist_data *pgdata; - struct zone *zone; - struct resource resource = { }; - unsigned long len; - int ret; - - ret = of_address_to_resource(np, nr, &resource); - if (ret) - goto out; - - if (phys) - *phys = resource.start; - len = resource.end - resource.start + 1; - *virt = ioremap(resource.start, len); - if (!*virt) - ret = -EINVAL; - - start_pfn = resource.start >> PAGE_SHIFT; - nr_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; - - pgdata = NODE_DATA(spu->node); - zone = pgdata->node_zones; - - ret = __add_pages(zone, start_pfn, nr_pages); - -out: - return ret; -} - -static int __init spu_map_device(struct spu *spu) -{ - struct device_node *np = spu->devnode; - int ret = -ENODEV; - - spu->name = get_property(np, "name", NULL); - if (!spu->name) - goto out; - - ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store, - &spu->local_store_phys); - if (ret) { - pr_debug("spu_new: failed to map %s resource 0\n", - np->full_name); - goto out; - } - ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem, - &spu->problem_phys); - if (ret) { - pr_debug("spu_new: failed to map %s resource 1\n", - np->full_name); - goto out_unmap; - } - ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL); - if (ret) { - pr_debug("spu_new: failed to map %s resource 2\n", - np->full_name); - goto out_unmap; - } - if (!firmware_has_feature(FW_FEATURE_LPAR)) - ret = spu_map_resource(spu, 3, - (void __iomem**)&spu->priv1, NULL); - if (ret) { - pr_debug("spu_new: failed to map %s resource 3\n", - np->full_name); - goto out_unmap; - } - pr_debug("spu_new: %s maps:\n", np->full_name); - pr_debug(" local store : 0x%016lx -> 0x%p\n", - spu->local_store_phys, spu->local_store); - pr_debug(" problem state : 0x%016lx -> 0x%p\n", - spu->problem_phys, spu->problem); - pr_debug(" priv2 : 0x%p\n", spu->priv2); - pr_debug(" priv1 : 0x%p\n", spu->priv1); - - return 0; - -out_unmap: - spu_unmap(spu); -out: - pr_debug("failed to map spe %s: %d\n", spu->name, ret); - return ret; -} - -static int __init of_enumerate_spus(int (*fn)(void *data)) -{ - int ret; - struct device_node *node; - - ret = -ENODEV; - for (node = of_find_node_by_type(NULL, "spe"); - node; node = of_find_node_by_type(node, "spe")) { - ret = fn(node); - if (ret) { - printk(KERN_WARNING "%s: Error initializing %s\n", - __FUNCTION__, node->name); - break; - } - } - return ret; -} - -static int __init of_create_spu(struct spu *spu, void *data) -{ - int ret; - struct device_node *spe = (struct device_node *)data; - static int legacy_map = 0, legacy_irq = 0; - - spu->devnode = of_node_get(spe); - spu->spe_id = find_spu_unit_number(spe); - - spu->node = of_node_to_nid(spe); - if (spu->node >= MAX_NUMNODES) { - printk(KERN_WARNING "SPE %s on node %d ignored," - " node number too big\n", spe->full_name, spu->node); - printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); - ret = -ENODEV; - goto out; - } - - ret = spu_map_device(spu); - if (ret) { - if (!legacy_map) { - legacy_map = 1; - printk(KERN_WARNING "%s: Legacy device tree found, " - "trying to map old style\n", __FUNCTION__); - } - ret = spu_map_device_old(spu); - if (ret) { - printk(KERN_ERR "Unable to map %s\n", - spu->name); - goto out; - } - } - - ret = spu_map_interrupts(spu, spe); - if (ret) { - if (!legacy_irq) { - legacy_irq = 1; - printk(KERN_WARNING "%s: Legacy device tree found, " - "trying old style irq\n", __FUNCTION__); - } - ret = spu_map_interrupts_old(spu, spe); - if (ret) { - printk(KERN_ERR "%s: could not map interrupts", - spu->name); - goto out_unmap; - } - } - - pr_debug("Using SPE %s %p %p %p %p %d\n", spu->name, - spu->local_store, spu->problem, spu->priv1, - spu->priv2, spu->number); - goto out; - -out_unmap: - spu_unmap(spu); -out: - return ret; -} - -static int of_destroy_spu(struct spu *spu) -{ - spu_unmap(spu); - of_node_put(spu->devnode); - return 0; -} - -const struct spu_management_ops spu_management_of_ops = { - .enumerate_spus = of_enumerate_spus, - .create_spu = of_create_spu, - .destroy_spu = of_destroy_spu, -}; diff --git a/trunk/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/trunk/arch/powerpc/platforms/cell/spu_priv1_mmio.c index 67fa7247b80a..910a926b61a2 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ b/trunk/arch/powerpc/platforms/cell/spu_priv1_mmio.c @@ -37,112 +37,490 @@ #include "interrupt.h" #include "spu_priv1_mmio.h" +static DEFINE_MUTEX(add_spumem_mutex); + +struct spu_pdata { + struct device_node *devnode; + struct spu_priv1 __iomem *priv1; +}; + +static struct spu_pdata *spu_get_pdata(struct spu *spu) +{ + BUG_ON(!spu->pdata); + return spu->pdata; +} + +struct device_node *spu_devnode(struct spu *spu) +{ + return spu_get_pdata(spu)->devnode; +} + +EXPORT_SYMBOL_GPL(spu_devnode); + +static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, + const char *prop) +{ + const struct address_prop { + unsigned long address; + unsigned int len; + } __attribute__((packed)) *p; + int proplen; + + unsigned long start_pfn, nr_pages; + struct pglist_data *pgdata; + struct zone *zone; + int ret; + + p = get_property(spe, prop, &proplen); + WARN_ON(proplen != sizeof (*p)); + + start_pfn = p->address >> PAGE_SHIFT; + nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; + + pgdata = NODE_DATA(spu->node); + zone = pgdata->node_zones; + + /* XXX rethink locking here */ + mutex_lock(&add_spumem_mutex); + ret = __add_pages(zone, start_pfn, nr_pages); + mutex_unlock(&add_spumem_mutex); + + return ret; +} + +static void __iomem * __init map_spe_prop(struct spu *spu, + struct device_node *n, const char *name) +{ + const struct address_prop { + unsigned long address; + unsigned int len; + } __attribute__((packed)) *prop; + + const void *p; + int proplen; + void __iomem *ret = NULL; + int err = 0; + + p = get_property(n, name, &proplen); + if (proplen != sizeof (struct address_prop)) + return NULL; + + prop = p; + + err = cell_spuprop_present(spu, n, name); + if (err && (err != -EEXIST)) + goto out; + + ret = ioremap(prop->address, prop->len); + + out: + return ret; +} + +static void spu_unmap(struct spu *spu) +{ + iounmap(spu->priv2); + iounmap(spu_get_pdata(spu)->priv1); + iounmap(spu->problem); + iounmap((__force u8 __iomem *)spu->local_store); +} + +static int __init spu_map_interrupts_old(struct spu *spu, + struct device_node *np) +{ + unsigned int isrc; + const u32 *tmp; + int nid; + + /* Get the interrupt source unit from the device-tree */ + tmp = get_property(np, "isrc", NULL); + if (!tmp) + return -ENODEV; + isrc = tmp[0]; + + tmp = get_property(np->parent->parent, "node-id", NULL); + if (!tmp) { + printk(KERN_WARNING "%s: can't find node-id\n", __FUNCTION__); + nid = spu->node; + } else + nid = tmp[0]; + + /* Add the node number */ + isrc |= nid << IIC_IRQ_NODE_SHIFT; + + /* Now map interrupts of all 3 classes */ + spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc); + spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc); + spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc); + + /* Right now, we only fail if class 2 failed */ + return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; +} + +static int __init spu_map_device_old(struct spu *spu, struct device_node *node) +{ + const char *prop; + int ret; + + ret = -ENODEV; + spu->name = get_property(node, "name", NULL); + if (!spu->name) + goto out; + + prop = get_property(node, "local-store", NULL); + if (!prop) + goto out; + spu->local_store_phys = *(unsigned long *)prop; + + /* we use local store as ram, not io memory */ + spu->local_store = (void __force *) + map_spe_prop(spu, node, "local-store"); + if (!spu->local_store) + goto out; + + prop = get_property(node, "problem", NULL); + if (!prop) + goto out_unmap; + spu->problem_phys = *(unsigned long *)prop; + + spu->problem= map_spe_prop(spu, node, "problem"); + if (!spu->problem) + goto out_unmap; + + spu_get_pdata(spu)->priv1= map_spe_prop(spu, node, "priv1"); + + spu->priv2= map_spe_prop(spu, node, "priv2"); + if (!spu->priv2) + goto out_unmap; + ret = 0; + goto out; + +out_unmap: + spu_unmap(spu); +out: + return ret; +} + +static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) +{ + struct of_irq oirq; + int ret; + int i; + + for (i=0; i < 3; i++) { + ret = of_irq_map_one(np, i, &oirq); + if (ret) { + pr_debug("spu_new: failed to get irq %d\n", i); + goto err; + } + ret = -EINVAL; + pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], + oirq.controller->full_name); + spu->irqs[i] = irq_create_of_mapping(oirq.controller, + oirq.specifier, oirq.size); + if (spu->irqs[i] == NO_IRQ) { + pr_debug("spu_new: failed to map it !\n"); + goto err; + } + } + return 0; + +err: + pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, + spu->name); + for (; i >= 0; i--) { + if (spu->irqs[i] != NO_IRQ) + irq_dispose_mapping(spu->irqs[i]); + } + return ret; +} + +static int spu_map_resource(struct spu *spu, int nr, + void __iomem** virt, unsigned long *phys) +{ + struct device_node *np = spu_get_pdata(spu)->devnode; + unsigned long start_pfn, nr_pages; + struct pglist_data *pgdata; + struct zone *zone; + struct resource resource = { }; + unsigned long len; + int ret; + + ret = of_address_to_resource(np, nr, &resource); + if (ret) + goto out; + + if (phys) + *phys = resource.start; + len = resource.end - resource.start + 1; + *virt = ioremap(resource.start, len); + if (!*virt) + ret = -EINVAL; + + start_pfn = resource.start >> PAGE_SHIFT; + nr_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; + + pgdata = NODE_DATA(spu->node); + zone = pgdata->node_zones; + + /* XXX rethink locking here */ + mutex_lock(&add_spumem_mutex); + ret = __add_pages(zone, start_pfn, nr_pages); + mutex_unlock(&add_spumem_mutex); + +out: + return ret; +} + +static int __init spu_map_device(struct spu *spu) +{ + struct device_node *np = spu_get_pdata(spu)->devnode; + int ret = -ENODEV; + + spu->name = get_property(np, "name", NULL); + if (!spu->name) + goto out; + + ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store, + &spu->local_store_phys); + if (ret) { + pr_debug("spu_new: failed to map %s resource 0\n", + np->full_name); + goto out; + } + ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem, + &spu->problem_phys); + if (ret) { + pr_debug("spu_new: failed to map %s resource 1\n", + np->full_name); + goto out_unmap; + } + ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL); + if (ret) { + pr_debug("spu_new: failed to map %s resource 2\n", + np->full_name); + goto out_unmap; + } + if (!firmware_has_feature(FW_FEATURE_LPAR)) + ret = spu_map_resource(spu, 3, + (void __iomem**)&spu_get_pdata(spu)->priv1, NULL); + if (ret) { + pr_debug("spu_new: failed to map %s resource 3\n", + np->full_name); + goto out_unmap; + } + pr_debug("spu_new: %s maps:\n", np->full_name); + pr_debug(" local store : 0x%016lx -> 0x%p\n", + spu->local_store_phys, spu->local_store); + pr_debug(" problem state : 0x%016lx -> 0x%p\n", + spu->problem_phys, spu->problem); + pr_debug(" priv2 : 0x%p\n", spu->priv2); + pr_debug(" priv1 : 0x%p\n", + spu_get_pdata(spu)->priv1); + + return 0; + +out_unmap: + spu_unmap(spu); +out: + pr_debug("failed to map spe %s: %d\n", spu->name, ret); + return ret; +} + +static int __init of_enumerate_spus(int (*fn)(void *data)) +{ + int ret; + struct device_node *node; + + ret = -ENODEV; + for (node = of_find_node_by_type(NULL, "spe"); + node; node = of_find_node_by_type(node, "spe")) { + ret = fn(node); + if (ret) { + printk(KERN_WARNING "%s: Error initializing %s\n", + __FUNCTION__, node->name); + break; + } + } + return ret; +} + +static int __init of_create_spu(struct spu *spu, void *data) +{ + int ret; + struct device_node *spe = (struct device_node *)data; + + spu->pdata = kzalloc(sizeof(struct spu_pdata), + GFP_KERNEL); + if (!spu->pdata) { + ret = -ENOMEM; + goto out; + } + spu_get_pdata(spu)->devnode = of_node_get(spe); + + spu->node = of_node_to_nid(spe); + if (spu->node >= MAX_NUMNODES) { + printk(KERN_WARNING "SPE %s on node %d ignored," + " node number too big\n", spe->full_name, spu->node); + printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); + ret = -ENODEV; + goto out_free; + } + + ret = spu_map_device(spu); + /* try old method */ + if (ret) + ret = spu_map_device_old(spu, spe); + if (ret) + goto out_free; + + ret = spu_map_interrupts(spu, spe); + if (ret) + ret = spu_map_interrupts_old(spu, spe); + if (ret) + goto out_unmap; + + pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", spu->name, + spu->local_store, spu->problem, spu_get_pdata(spu)->priv1, + spu->priv2, spu->number); + goto out; + +out_unmap: + spu_unmap(spu); +out_free: + kfree(spu->pdata); + spu->pdata = NULL; +out: + return ret; +} + +static int of_destroy_spu(struct spu *spu) +{ + spu_unmap(spu); + of_node_put(spu_get_pdata(spu)->devnode); + kfree(spu->pdata); + spu->pdata = NULL; + return 0; +} + +const struct spu_management_ops spu_management_of_ops = { + .enumerate_spus = of_enumerate_spus, + .create_spu = of_create_spu, + .destroy_spu = of_destroy_spu, +}; + static void int_mask_and(struct spu *spu, int class, u64 mask) { u64 old_mask; - old_mask = in_be64(&spu->priv1->int_mask_RW[class]); - out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); + old_mask = in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]); + out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], + old_mask & mask); } static void int_mask_or(struct spu *spu, int class, u64 mask) { u64 old_mask; - old_mask = in_be64(&spu->priv1->int_mask_RW[class]); - out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); + old_mask = in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]); + out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], + old_mask | mask); } static void int_mask_set(struct spu *spu, int class, u64 mask) { - out_be64(&spu->priv1->int_mask_RW[class], mask); + out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], mask); } static u64 int_mask_get(struct spu *spu, int class) { - return in_be64(&spu->priv1->int_mask_RW[class]); + return in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]); } static void int_stat_clear(struct spu *spu, int class, u64 stat) { - out_be64(&spu->priv1->int_stat_RW[class], stat); + out_be64(&spu_get_pdata(spu)->priv1->int_stat_RW[class], stat); } static u64 int_stat_get(struct spu *spu, int class) { - return in_be64(&spu->priv1->int_stat_RW[class]); + return in_be64(&spu_get_pdata(spu)->priv1->int_stat_RW[class]); } static void cpu_affinity_set(struct spu *spu, int cpu) { u64 target = iic_get_target_id(cpu); u64 route = target << 48 | target << 32 | target << 16; - out_be64(&spu->priv1->int_route_RW, route); + out_be64(&spu_get_pdata(spu)->priv1->int_route_RW, route); } static u64 mfc_dar_get(struct spu *spu) { - return in_be64(&spu->priv1->mfc_dar_RW); + return in_be64(&spu_get_pdata(spu)->priv1->mfc_dar_RW); } static u64 mfc_dsisr_get(struct spu *spu) { - return in_be64(&spu->priv1->mfc_dsisr_RW); + return in_be64(&spu_get_pdata(spu)->priv1->mfc_dsisr_RW); } static void mfc_dsisr_set(struct spu *spu, u64 dsisr) { - out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); + out_be64(&spu_get_pdata(spu)->priv1->mfc_dsisr_RW, dsisr); } static void mfc_sdr_setup(struct spu *spu) { - out_be64(&spu->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); + out_be64(&spu_get_pdata(spu)->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); } static void mfc_sr1_set(struct spu *spu, u64 sr1) { - out_be64(&spu->priv1->mfc_sr1_RW, sr1); + out_be64(&spu_get_pdata(spu)->priv1->mfc_sr1_RW, sr1); } static u64 mfc_sr1_get(struct spu *spu) { - return in_be64(&spu->priv1->mfc_sr1_RW); + return in_be64(&spu_get_pdata(spu)->priv1->mfc_sr1_RW); } static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id) { - out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); + out_be64(&spu_get_pdata(spu)->priv1->mfc_tclass_id_RW, tclass_id); } static u64 mfc_tclass_id_get(struct spu *spu) { - return in_be64(&spu->priv1->mfc_tclass_id_RW); + return in_be64(&spu_get_pdata(spu)->priv1->mfc_tclass_id_RW); } static void tlb_invalidate(struct spu *spu) { - out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); + out_be64(&spu_get_pdata(spu)->priv1->tlb_invalidate_entry_W, 0ul); } static void resource_allocation_groupID_set(struct spu *spu, u64 id) { - out_be64(&spu->priv1->resource_allocation_groupID_RW, id); + out_be64(&spu_get_pdata(spu)->priv1->resource_allocation_groupID_RW, + id); } static u64 resource_allocation_groupID_get(struct spu *spu) { - return in_be64(&spu->priv1->resource_allocation_groupID_RW); + return in_be64( + &spu_get_pdata(spu)->priv1->resource_allocation_groupID_RW); } static void resource_allocation_enable_set(struct spu *spu, u64 enable) { - out_be64(&spu->priv1->resource_allocation_enable_RW, enable); + out_be64(&spu_get_pdata(spu)->priv1->resource_allocation_enable_RW, + enable); } static u64 resource_allocation_enable_get(struct spu *spu) { - return in_be64(&spu->priv1->resource_allocation_enable_RW); + return in_be64( + &spu_get_pdata(spu)->priv1->resource_allocation_enable_RW); } const struct spu_priv1_ops spu_priv1_mmio_ops = diff --git a/trunk/arch/powerpc/platforms/celleb/Makefile b/trunk/arch/powerpc/platforms/celleb/Makefile deleted file mode 100644 index 3baf658ac543..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -obj-y += interrupt.o iommu.o setup.o \ - htab.o beat.o pci.o \ - scc_epci.o hvCall.o - -obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_PPC_UDBG_BEAT) += udbg_beat.o -obj-$(CONFIG_USB) += scc_uhc.o -obj-$(CONFIG_HAS_TXX9_SERIAL) += scc_sio.o -obj-$(CONFIG_SPU_BASE) += spu_priv1.o diff --git a/trunk/arch/powerpc/platforms/celleb/beat.c b/trunk/arch/powerpc/platforms/celleb/beat.c deleted file mode 100644 index 99341ce8a697..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/beat.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Simple routines for Celleb/Beat - * - * (C) Copyright 2006-2007 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include - -#include -#include - -#include "beat_wrapper.h" -#include "beat.h" - -void beat_restart(char *cmd) -{ - beat_shutdown_logical_partition(1); -} - -void beat_power_off(void) -{ - beat_shutdown_logical_partition(0); -} - -u64 beat_halt_code = 0x1000000000000000UL; - -void beat_halt(void) -{ - beat_shutdown_logical_partition(beat_halt_code); -} - -int beat_set_rtc_time(struct rtc_time *rtc_time) -{ - u64 tim; - tim = mktime(rtc_time->tm_year+1900, - rtc_time->tm_mon+1, rtc_time->tm_mday, - rtc_time->tm_hour, rtc_time->tm_min, rtc_time->tm_sec); - if (beat_rtc_write(tim)) - return -1; - return 0; -} - -void beat_get_rtc_time(struct rtc_time *rtc_time) -{ - u64 tim; - - if (beat_rtc_read(&tim)) - tim = 0; - to_tm(tim, rtc_time); - rtc_time->tm_year -= 1900; - rtc_time->tm_mon -= 1; -} - -#define BEAT_NVRAM_SIZE 4096 - -ssize_t beat_nvram_read(char *buf, size_t count, loff_t *index) -{ - unsigned int i; - unsigned long len; - char *p = buf; - - if (*index >= BEAT_NVRAM_SIZE) - return -ENODEV; - i = *index; - if (i + count > BEAT_NVRAM_SIZE) - count = BEAT_NVRAM_SIZE - i; - - for (; count != 0; count -= len) { - len = count; - if (len > BEAT_NVRW_CNT) - len = BEAT_NVRW_CNT; - if (beat_eeprom_read(i, len, p)) { - return -EIO; - } - - p += len; - i += len; - } - *index = i; - return p - buf; -} - -ssize_t beat_nvram_write(char *buf, size_t count, loff_t *index) -{ - unsigned int i; - unsigned long len; - char *p = buf; - - if (*index >= BEAT_NVRAM_SIZE) - return -ENODEV; - i = *index; - if (i + count > BEAT_NVRAM_SIZE) - count = BEAT_NVRAM_SIZE - i; - - for (; count != 0; count -= len) { - len = count; - if (len > BEAT_NVRW_CNT) - len = BEAT_NVRW_CNT; - if (beat_eeprom_write(i, len, p)) { - return -EIO; - } - - p += len; - i += len; - } - *index = i; - return p - buf; -} - -ssize_t beat_nvram_get_size(void) -{ - return BEAT_NVRAM_SIZE; -} - -int beat_set_xdabr(unsigned long dabr) -{ - if (beat_set_dabr(dabr, DABRX_KERNEL | DABRX_USER)) - return -1; - return 0; -} - -int64_t beat_get_term_char(u64 vterm, u64 *len, u64 *t1, u64 *t2) -{ - u64 db[2]; - s64 ret; - - ret = beat_get_characters_from_console(vterm, len, (u8*)db); - if (ret == 0) { - *t1 = db[0]; - *t2 = db[1]; - } - return ret; -} - -int64_t beat_put_term_char(u64 vterm, u64 len, u64 t1, u64 t2) -{ - u64 db[2]; - - db[0] = t1; - db[1] = t2; - return beat_put_characters_to_console(vterm, len, (u8*)db); -} - -EXPORT_SYMBOL(beat_get_term_char); -EXPORT_SYMBOL(beat_put_term_char); -EXPORT_SYMBOL(beat_halt_code); diff --git a/trunk/arch/powerpc/platforms/celleb/beat.h b/trunk/arch/powerpc/platforms/celleb/beat.h deleted file mode 100644 index 2b16bf3bee89..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/beat.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Guest OS Interfaces. - * - * (C) Copyright 2006 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef _CELLEB_BEAT_H -#define _CELLEB_BEAT_H - -#define DABRX_KERNEL (1UL<<1) -#define DABRX_USER (1UL<<0) - -int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*); -int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t); -int64_t beat_repository_encode(int, const char *, uint64_t[4]); -void beat_restart(char *); -void beat_power_off(void); -void beat_halt(void); -int beat_set_rtc_time(struct rtc_time *); -void beat_get_rtc_time(struct rtc_time *); -ssize_t beat_nvram_get_size(void); -ssize_t beat_nvram_read(char *, size_t, loff_t *); -ssize_t beat_nvram_write(char *, size_t, loff_t *); -int beat_set_xdabr(unsigned long); - -#endif /* _CELLEB_BEAT_H */ diff --git a/trunk/arch/powerpc/platforms/celleb/beat_syscall.h b/trunk/arch/powerpc/platforms/celleb/beat_syscall.h deleted file mode 100644 index 14e16974773f..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/beat_syscall.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Beat hypervisor call numbers - * - * (C) Copyright 2004-2007 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef BEAT_BEAT_syscall_H -#define BEAT_BEAT_syscall_H - -#ifdef __ASSEMBLY__ -#define __BEAT_ADD_VENDOR_ID(__x, __v) ((__v)<<60|(__x)) -#else -#define __BEAT_ADD_VENDOR_ID(__x, __v) ((u64)(__v)<<60|(__x)) -#endif -#define HV_allocate_memory __BEAT_ADD_VENDOR_ID(0, 0) -#define HV_construct_virtual_address_space __BEAT_ADD_VENDOR_ID(2, 0) -#define HV_destruct_virtual_address_space __BEAT_ADD_VENDOR_ID(10, 0) -#define HV_get_virtual_address_space_id_of_ppe __BEAT_ADD_VENDOR_ID(4, 0) -#define HV_query_logical_partition_address_region_info \ - __BEAT_ADD_VENDOR_ID(6, 0) -#define HV_release_memory __BEAT_ADD_VENDOR_ID(13, 0) -#define HV_select_virtual_address_space __BEAT_ADD_VENDOR_ID(7, 0) -#define HV_load_range_registers __BEAT_ADD_VENDOR_ID(68, 0) -#define HV_set_ppe_l2cache_rmt_entry __BEAT_ADD_VENDOR_ID(70, 0) -#define HV_set_ppe_tlb_rmt_entry __BEAT_ADD_VENDOR_ID(71, 0) -#define HV_set_spe_tlb_rmt_entry __BEAT_ADD_VENDOR_ID(72, 0) -#define HV_get_io_address_translation_fault_info __BEAT_ADD_VENDOR_ID(14, 0) -#define HV_get_iopte __BEAT_ADD_VENDOR_ID(16, 0) -#define HV_preload_iopt_cache __BEAT_ADD_VENDOR_ID(17, 0) -#define HV_put_iopte __BEAT_ADD_VENDOR_ID(15, 0) -#define HV_connect_event_ports __BEAT_ADD_VENDOR_ID(21, 0) -#define HV_construct_event_receive_port __BEAT_ADD_VENDOR_ID(18, 0) -#define HV_destruct_event_receive_port __BEAT_ADD_VENDOR_ID(19, 0) -#define HV_destruct_event_send_port __BEAT_ADD_VENDOR_ID(22, 0) -#define HV_get_state_of_event_send_port __BEAT_ADD_VENDOR_ID(25, 0) -#define HV_request_to_connect_event_ports __BEAT_ADD_VENDOR_ID(20, 0) -#define HV_send_event_externally __BEAT_ADD_VENDOR_ID(23, 0) -#define HV_send_event_locally __BEAT_ADD_VENDOR_ID(24, 0) -#define HV_construct_and_connect_irq_plug __BEAT_ADD_VENDOR_ID(28, 0) -#define HV_destruct_irq_plug __BEAT_ADD_VENDOR_ID(29, 0) -#define HV_detect_pending_interrupts __BEAT_ADD_VENDOR_ID(26, 0) -#define HV_end_of_interrupt __BEAT_ADD_VENDOR_ID(27, 0) -#define HV_assign_control_signal_notification_port __BEAT_ADD_VENDOR_ID(45, 0) -#define HV_end_of_control_signal_processing __BEAT_ADD_VENDOR_ID(48, 0) -#define HV_get_control_signal __BEAT_ADD_VENDOR_ID(46, 0) -#define HV_set_irq_mask_for_spe __BEAT_ADD_VENDOR_ID(61, 0) -#define HV_shutdown_logical_partition __BEAT_ADD_VENDOR_ID(44, 0) -#define HV_connect_message_ports __BEAT_ADD_VENDOR_ID(35, 0) -#define HV_destruct_message_port __BEAT_ADD_VENDOR_ID(36, 0) -#define HV_receive_message __BEAT_ADD_VENDOR_ID(37, 0) -#define HV_get_message_port_info __BEAT_ADD_VENDOR_ID(34, 0) -#define HV_request_to_connect_message_ports __BEAT_ADD_VENDOR_ID(33, 0) -#define HV_send_message __BEAT_ADD_VENDOR_ID(32, 0) -#define HV_get_logical_ppe_id __BEAT_ADD_VENDOR_ID(69, 0) -#define HV_pause __BEAT_ADD_VENDOR_ID(9, 0) -#define HV_destruct_shared_memory_handle __BEAT_ADD_VENDOR_ID(51, 0) -#define HV_get_shared_memory_info __BEAT_ADD_VENDOR_ID(52, 0) -#define HV_permit_sharing_memory __BEAT_ADD_VENDOR_ID(50, 0) -#define HV_request_to_attach_shared_memory __BEAT_ADD_VENDOR_ID(49, 0) -#define HV_enable_logical_spe_execution __BEAT_ADD_VENDOR_ID(55, 0) -#define HV_construct_logical_spe __BEAT_ADD_VENDOR_ID(53, 0) -#define HV_disable_logical_spe_execution __BEAT_ADD_VENDOR_ID(56, 0) -#define HV_destruct_logical_spe __BEAT_ADD_VENDOR_ID(54, 0) -#define HV_sense_spe_execution_status __BEAT_ADD_VENDOR_ID(58, 0) -#define HV_insert_htab_entry __BEAT_ADD_VENDOR_ID(101, 0) -#define HV_read_htab_entries __BEAT_ADD_VENDOR_ID(95, 0) -#define HV_write_htab_entry __BEAT_ADD_VENDOR_ID(94, 0) -#define HV_assign_io_address_translation_fault_port \ - __BEAT_ADD_VENDOR_ID(100, 0) -#define HV_set_interrupt_mask __BEAT_ADD_VENDOR_ID(73, 0) -#define HV_get_logical_partition_id __BEAT_ADD_VENDOR_ID(74, 0) -#define HV_create_repository_node2 __BEAT_ADD_VENDOR_ID(90, 0) -#define HV_create_repository_node __BEAT_ADD_VENDOR_ID(90, 0) /* alias */ -#define HV_get_repository_node_value2 __BEAT_ADD_VENDOR_ID(91, 0) -#define HV_get_repository_node_value __BEAT_ADD_VENDOR_ID(91, 0) /* alias */ -#define HV_modify_repository_node_value2 __BEAT_ADD_VENDOR_ID(92, 0) -#define HV_modify_repository_node_value __BEAT_ADD_VENDOR_ID(92, 0) /* alias */ -#define HV_remove_repository_node2 __BEAT_ADD_VENDOR_ID(93, 0) -#define HV_remove_repository_node __BEAT_ADD_VENDOR_ID(93, 0) /* alias */ -#define HV_cancel_shared_memory __BEAT_ADD_VENDOR_ID(104, 0) -#define HV_clear_interrupt_status_of_spe __BEAT_ADD_VENDOR_ID(206, 0) -#define HV_construct_spe_irq_outlet __BEAT_ADD_VENDOR_ID(80, 0) -#define HV_destruct_spe_irq_outlet __BEAT_ADD_VENDOR_ID(81, 0) -#define HV_disconnect_ipspc_service __BEAT_ADD_VENDOR_ID(88, 0) -#define HV_execute_ipspc_command __BEAT_ADD_VENDOR_ID(86, 0) -#define HV_get_interrupt_status_of_spe __BEAT_ADD_VENDOR_ID(205, 0) -#define HV_get_spe_privileged_state_1_registers __BEAT_ADD_VENDOR_ID(208, 0) -#define HV_permit_use_of_ipspc_service __BEAT_ADD_VENDOR_ID(85, 0) -#define HV_reinitialize_logical_spe __BEAT_ADD_VENDOR_ID(82, 0) -#define HV_request_ipspc_service __BEAT_ADD_VENDOR_ID(84, 0) -#define HV_stop_ipspc_command __BEAT_ADD_VENDOR_ID(87, 0) -#define HV_set_spe_privileged_state_1_registers __BEAT_ADD_VENDOR_ID(204, 0) -#define HV_get_status_of_ipspc_service __BEAT_ADD_VENDOR_ID(203, 0) -#define HV_put_characters_to_console __BEAT_ADD_VENDOR_ID(0x101, 1) -#define HV_get_characters_from_console __BEAT_ADD_VENDOR_ID(0x102, 1) -#define HV_get_base_clock __BEAT_ADD_VENDOR_ID(0x111, 1) -#define HV_set_base_clock __BEAT_ADD_VENDOR_ID(0x112, 1) -#define HV_get_frame_cycle __BEAT_ADD_VENDOR_ID(0x114, 1) -#define HV_disable_console __BEAT_ADD_VENDOR_ID(0x115, 1) -#define HV_disable_all_console __BEAT_ADD_VENDOR_ID(0x116, 1) -#define HV_oneshot_timer __BEAT_ADD_VENDOR_ID(0x117, 1) -#define HV_set_dabr __BEAT_ADD_VENDOR_ID(0x118, 1) -#define HV_get_dabr __BEAT_ADD_VENDOR_ID(0x119, 1) -#define HV_start_hv_stats __BEAT_ADD_VENDOR_ID(0x21c, 1) -#define HV_stop_hv_stats __BEAT_ADD_VENDOR_ID(0x21d, 1) -#define HV_get_hv_stats __BEAT_ADD_VENDOR_ID(0x21e, 1) -#define HV_get_hv_error_stats __BEAT_ADD_VENDOR_ID(0x221, 1) -#define HV_get_stats __BEAT_ADD_VENDOR_ID(0x224, 1) -#define HV_get_heap_stats __BEAT_ADD_VENDOR_ID(0x225, 1) -#define HV_get_memory_stats __BEAT_ADD_VENDOR_ID(0x227, 1) -#define HV_get_memory_detail __BEAT_ADD_VENDOR_ID(0x228, 1) -#define HV_set_priority_of_irq_outlet __BEAT_ADD_VENDOR_ID(0x122, 1) -#define HV_get_physical_spe_by_reservation_id __BEAT_ADD_VENDOR_ID(0x128, 1) -#define HV_get_spe_context __BEAT_ADD_VENDOR_ID(0x129, 1) -#define HV_set_spe_context __BEAT_ADD_VENDOR_ID(0x12a, 1) -#define HV_downcount_of_interrupt __BEAT_ADD_VENDOR_ID(0x12e, 1) -#define HV_peek_spe_context __BEAT_ADD_VENDOR_ID(0x12f, 1) -#define HV_read_bpa_register __BEAT_ADD_VENDOR_ID(0x131, 1) -#define HV_write_bpa_register __BEAT_ADD_VENDOR_ID(0x132, 1) -#define HV_map_context_table_of_spe __BEAT_ADD_VENDOR_ID(0x137, 1) -#define HV_get_slb_for_logical_spe __BEAT_ADD_VENDOR_ID(0x138, 1) -#define HV_set_slb_for_logical_spe __BEAT_ADD_VENDOR_ID(0x139, 1) -#define HV_init_pm __BEAT_ADD_VENDOR_ID(0x150, 1) -#define HV_set_pm_signal __BEAT_ADD_VENDOR_ID(0x151, 1) -#define HV_get_pm_signal __BEAT_ADD_VENDOR_ID(0x152, 1) -#define HV_set_pm_config __BEAT_ADD_VENDOR_ID(0x153, 1) -#define HV_get_pm_config __BEAT_ADD_VENDOR_ID(0x154, 1) -#define HV_get_inner_trace_data __BEAT_ADD_VENDOR_ID(0x155, 1) -#define HV_set_ext_trace_buffer __BEAT_ADD_VENDOR_ID(0x156, 1) -#define HV_get_ext_trace_buffer __BEAT_ADD_VENDOR_ID(0x157, 1) -#define HV_set_pm_interrupt __BEAT_ADD_VENDOR_ID(0x158, 1) -#define HV_get_pm_interrupt __BEAT_ADD_VENDOR_ID(0x159, 1) -#define HV_kick_pm __BEAT_ADD_VENDOR_ID(0x160, 1) -#define HV_construct_pm_context __BEAT_ADD_VENDOR_ID(0x164, 1) -#define HV_destruct_pm_context __BEAT_ADD_VENDOR_ID(0x165, 1) -#define HV_be_slow __BEAT_ADD_VENDOR_ID(0x170, 1) -#define HV_assign_ipspc_server_connection_status_notification_port \ - __BEAT_ADD_VENDOR_ID(0x173, 1) -#define HV_get_raid_of_physical_spe __BEAT_ADD_VENDOR_ID(0x174, 1) -#define HV_set_physical_spe_to_rag __BEAT_ADD_VENDOR_ID(0x175, 1) -#define HV_release_physical_spe_from_rag __BEAT_ADD_VENDOR_ID(0x176, 1) -#define HV_rtc_read __BEAT_ADD_VENDOR_ID(0x190, 1) -#define HV_rtc_write __BEAT_ADD_VENDOR_ID(0x191, 1) -#define HV_eeprom_read __BEAT_ADD_VENDOR_ID(0x192, 1) -#define HV_eeprom_write __BEAT_ADD_VENDOR_ID(0x193, 1) -#endif diff --git a/trunk/arch/powerpc/platforms/celleb/beat_wrapper.h b/trunk/arch/powerpc/platforms/celleb/beat_wrapper.h deleted file mode 100644 index 76ea0a6a9011..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/beat_wrapper.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Beat hypervisor call I/F - * - * (C) Copyright 2007 TOSHIBA CORPORATION - * - * This code is based on arch/powerpc/platforms/pseries/plpar_wrapper.h. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef BEAT_HCALL -#include "beat_syscall.h" - -/* defined in hvCall.S */ -extern s64 beat_hcall_norets(u64 opcode, ...); -extern s64 beat_hcall_norets8(u64 opcode, u64 arg1, u64 arg2, u64 arg3, - u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8); -extern s64 beat_hcall1(u64 opcode, u64 retbuf[1], ...); -extern s64 beat_hcall2(u64 opcode, u64 retbuf[2], ...); -extern s64 beat_hcall3(u64 opcode, u64 retbuf[3], ...); -extern s64 beat_hcall4(u64 opcode, u64 retbuf[4], ...); -extern s64 beat_hcall5(u64 opcode, u64 retbuf[5], ...); -extern s64 beat_hcall6(u64 opcode, u64 retbuf[6], ...); - -static inline s64 beat_downcount_of_interrupt(u64 plug_id) -{ - return beat_hcall_norets(HV_downcount_of_interrupt, plug_id); -} - -static inline s64 beat_set_interrupt_mask(u64 index, - u64 val0, u64 val1, u64 val2, u64 val3) -{ - return beat_hcall_norets(HV_set_interrupt_mask, index, - val0, val1, val2, val3); -} - -static inline s64 beat_destruct_irq_plug(u64 plug_id) -{ - return beat_hcall_norets(HV_destruct_irq_plug, plug_id); -} - -static inline s64 beat_construct_and_connect_irq_plug(u64 plug_id, - u64 outlet_id) -{ - return beat_hcall_norets(HV_construct_and_connect_irq_plug, plug_id, - outlet_id); -} - -static inline s64 beat_detect_pending_interrupts(u64 index, u64 *retbuf) -{ - return beat_hcall4(HV_detect_pending_interrupts, retbuf, index); -} - -static inline s64 beat_pause(u64 style) -{ - return beat_hcall_norets(HV_pause, style); -} - -static inline s64 beat_read_htab_entries(u64 htab_id, u64 index, u64 *retbuf) -{ - return beat_hcall5(HV_read_htab_entries, retbuf, htab_id, index); -} - -static inline s64 beat_insert_htab_entry(u64 htab_id, u64 group, - u64 bitmask, u64 hpte_v, u64 hpte_r, u64 *slot) -{ - u64 dummy[3]; - s64 ret; - - ret = beat_hcall3(HV_insert_htab_entry, dummy, htab_id, group, - bitmask, hpte_v, hpte_r); - *slot = dummy[0]; - return ret; -} - -static inline s64 beat_write_htab_entry(u64 htab_id, u64 slot, - u64 hpte_v, u64 hpte_r, u64 mask_v, u64 mask_r, - u64 *ret_v, u64 *ret_r) -{ - u64 dummy[2]; - s64 ret; - - ret = beat_hcall2(HV_write_htab_entry, dummy, htab_id, slot, - hpte_v, hpte_r, mask_v, mask_r); - *ret_v = dummy[0]; - *ret_r = dummy[1]; - return ret; -} - -static inline void beat_shutdown_logical_partition(u64 code) -{ - (void)beat_hcall_norets(HV_shutdown_logical_partition, code); -} - -static inline s64 beat_rtc_write(u64 time_from_epoch) -{ - return beat_hcall_norets(HV_rtc_write, time_from_epoch); -} - -static inline s64 beat_rtc_read(u64 *time_from_epoch) -{ - u64 dummy[1]; - s64 ret; - - ret = beat_hcall1(HV_rtc_read, dummy); - *time_from_epoch = dummy[0]; - return ret; -} - -#define BEAT_NVRW_CNT (sizeof(u64) * 6) - -static inline s64 beat_eeprom_write(u64 index, u64 length, u8 *buffer) -{ - u64 b[6]; - - if (length > BEAT_NVRW_CNT) - return -1; - memcpy(b, buffer, sizeof(b)); - return beat_hcall_norets8(HV_eeprom_write, index, length, - b[0], b[1], b[2], b[3], b[4], b[5]); -} - -static inline s64 beat_eeprom_read(u64 index, u64 length, u8 *buffer) -{ - u64 b[6]; - s64 ret; - - if (length > BEAT_NVRW_CNT) - return -1; - ret = beat_hcall6(HV_eeprom_read, b, index, length); - memcpy(buffer, b, length); - return ret; -} - -static inline s64 beat_set_dabr(u64 value, u64 style) -{ - return beat_hcall_norets(HV_set_dabr, value, style); -} - -static inline s64 beat_get_characters_from_console(u64 termno, u64 *len, - u8 *buffer) -{ - u64 dummy[3]; - s64 ret; - - ret = beat_hcall3(HV_get_characters_from_console, dummy, termno, len); - *len = dummy[0]; - memcpy(buffer, dummy + 1, *len); - return ret; -} - -static inline s64 beat_put_characters_to_console(u64 termno, u64 len, - u8 *buffer) -{ - u64 b[2]; - - memcpy(b, buffer, len); - return beat_hcall_norets(HV_put_characters_to_console, termno, len, b[0], b[1]); -} - -static inline s64 beat_get_spe_privileged_state_1_registers( - u64 id, u64 offsetof, u64 *value) -{ - u64 dummy[1]; - s64 ret; - - ret = beat_hcall1(HV_get_spe_privileged_state_1_registers, dummy, id, - offsetof); - *value = dummy[0]; - return ret; -} - -static inline s64 beat_set_irq_mask_for_spe(u64 id, u64 class, u64 mask) -{ - return beat_hcall_norets(HV_set_irq_mask_for_spe, id, class, mask); -} - -static inline s64 beat_clear_interrupt_status_of_spe(u64 id, u64 class, - u64 mask) -{ - return beat_hcall_norets(HV_clear_interrupt_status_of_spe, - id, class, mask); -} - -static inline s64 beat_set_spe_privileged_state_1_registers( - u64 id, u64 offsetof, u64 value) -{ - return beat_hcall_norets(HV_set_spe_privileged_state_1_registers, - id, offsetof, value); -} - -static inline s64 beat_get_interrupt_status_of_spe(u64 id, u64 class, u64 *val) -{ - u64 dummy[1]; - s64 ret; - - ret = beat_hcall1(HV_get_interrupt_status_of_spe, dummy, id, class); - *val = dummy[0]; - return ret; -} - -static inline s64 beat_put_iopte(u64 ioas_id, u64 io_addr, u64 real_addr, - u64 ioid, u64 flags) -{ - return beat_hcall_norets(HV_put_iopte, ioas_id, io_addr, real_addr, - ioid, flags); -} - -#endif diff --git a/trunk/arch/powerpc/platforms/celleb/htab.c b/trunk/arch/powerpc/platforms/celleb/htab.c deleted file mode 100644 index ffa7c2c2030d..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/htab.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * "Cell Reference Set" HTAB support. - * - * (C) Copyright 2006-2007 TOSHIBA CORPORATION - * - * This code is based on arch/powerpc/platforms/pseries/lpar.c: - * Copyright (C) 2001 Todd Inglett, IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#undef DEBUG_LOW - -#include -#include - -#include -#include -#include -#include -#include - -#include "beat_wrapper.h" - -#ifdef DEBUG_LOW -#define DBG_LOW(fmt...) do { udbg_printf(fmt); } while(0) -#else -#define DBG_LOW(fmt...) do { } while(0) -#endif - -static DEFINE_SPINLOCK(beat_htab_lock); - -static inline unsigned int beat_read_mask(unsigned hpte_group) -{ - unsigned long hpte_v[5]; - unsigned long rmask = 0; - - beat_read_htab_entries(0, hpte_group + 0, hpte_v); - if (!(hpte_v[0] & HPTE_V_BOLTED)) - rmask |= 0x8000; - if (!(hpte_v[1] & HPTE_V_BOLTED)) - rmask |= 0x4000; - if (!(hpte_v[2] & HPTE_V_BOLTED)) - rmask |= 0x2000; - if (!(hpte_v[3] & HPTE_V_BOLTED)) - rmask |= 0x1000; - beat_read_htab_entries(0, hpte_group + 4, hpte_v); - if (!(hpte_v[0] & HPTE_V_BOLTED)) - rmask |= 0x0800; - if (!(hpte_v[1] & HPTE_V_BOLTED)) - rmask |= 0x0400; - if (!(hpte_v[2] & HPTE_V_BOLTED)) - rmask |= 0x0200; - if (!(hpte_v[3] & HPTE_V_BOLTED)) - rmask |= 0x0100; - hpte_group = ~hpte_group & (htab_hash_mask * HPTES_PER_GROUP); - beat_read_htab_entries(0, hpte_group + 0, hpte_v); - if (!(hpte_v[0] & HPTE_V_BOLTED)) - rmask |= 0x80; - if (!(hpte_v[1] & HPTE_V_BOLTED)) - rmask |= 0x40; - if (!(hpte_v[2] & HPTE_V_BOLTED)) - rmask |= 0x20; - if (!(hpte_v[3] & HPTE_V_BOLTED)) - rmask |= 0x10; - beat_read_htab_entries(0, hpte_group + 4, hpte_v); - if (!(hpte_v[0] & HPTE_V_BOLTED)) - rmask |= 0x08; - if (!(hpte_v[1] & HPTE_V_BOLTED)) - rmask |= 0x04; - if (!(hpte_v[2] & HPTE_V_BOLTED)) - rmask |= 0x02; - if (!(hpte_v[3] & HPTE_V_BOLTED)) - rmask |= 0x01; - return rmask; -} - -static long beat_lpar_hpte_insert(unsigned long hpte_group, - unsigned long va, unsigned long pa, - unsigned long rflags, unsigned long vflags, - int psize) -{ - unsigned long lpar_rc; - unsigned long slot; - unsigned long hpte_v, hpte_r; - unsigned long flags; - - /* same as iseries */ - if (vflags & HPTE_V_SECONDARY) - return -1; - - if (!(vflags & HPTE_V_BOLTED)) - DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " - "rflags=%lx, vflags=%lx, psize=%d)\n", - hpte_group, va, pa, rflags, vflags, psize); - - hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID; - hpte_r = hpte_encode_r(pa, psize) | rflags; - - if (!(vflags & HPTE_V_BOLTED)) - DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); - - if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) - hpte_r &= ~_PAGE_COHERENT; - - spin_lock_irqsave(&beat_htab_lock, flags); - if ((lpar_rc = beat_read_mask(hpte_group)) == 0) { - if (!(vflags & HPTE_V_BOLTED)) - DBG_LOW(" full\n"); - spin_unlock_irqrestore(&beat_htab_lock, flags); - return -1; - } - - lpar_rc = beat_insert_htab_entry(0, hpte_group, lpar_rc << 48, - hpte_v, hpte_r, &slot); - spin_unlock_irqrestore(&beat_htab_lock, flags); - - /* - * Since we try and ioremap PHBs we don't own, the pte insert - * will fail. However we must catch the failure in hash_page - * or we will loop forever, so return -2 in this case. - */ - if (unlikely(lpar_rc != 0)) { - if (!(vflags & HPTE_V_BOLTED)) - DBG_LOW(" lpar err %lx\n", lpar_rc); - return -2; - } - if (!(vflags & HPTE_V_BOLTED)) - DBG_LOW(" -> slot: %lx\n", slot); - - /* We have to pass down the secondary bucket bit here as well */ - return (slot ^ hpte_group) & 15; -} - -static long beat_lpar_hpte_remove(unsigned long hpte_group) -{ - DBG_LOW("hpte_remove(group=%lx)\n", hpte_group); - return -1; -} - -static unsigned long beat_lpar_hpte_getword0(unsigned long slot) -{ - unsigned long dword0, dword[5]; - unsigned long lpar_rc; - - lpar_rc = beat_read_htab_entries(0, slot & ~3UL, dword); - - dword0 = dword[slot&3]; - - BUG_ON(lpar_rc != 0); - - return dword0; -} - -static void beat_lpar_hptab_clear(void) -{ - unsigned long size_bytes = 1UL << ppc64_pft_size; - unsigned long hpte_count = size_bytes >> 4; - int i; - unsigned long dummy0, dummy1; - - /* TODO: Use bulk call */ - for (i = 0; i < hpte_count; i++) - beat_write_htab_entry(0, i, 0, 0, -1UL, -1UL, &dummy0, &dummy1); -} - -/* - * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and - * the low 3 bits of flags happen to line up. So no transform is needed. - * We can probably optimize here and assume the high bits of newpp are - * already zero. For now I am paranoid. - */ -static long beat_lpar_hpte_updatepp(unsigned long slot, - unsigned long newpp, - unsigned long va, - int psize, int local) -{ - unsigned long lpar_rc; - unsigned long dummy0, dummy1, want_v; - unsigned long flags; - - want_v = hpte_encode_v(va, psize); - - DBG_LOW(" update: " - "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", - want_v & HPTE_V_AVPN, slot, psize, newpp); - - spin_lock_irqsave(&beat_htab_lock, flags); - dummy0 = beat_lpar_hpte_getword0(slot); - if ((dummy0 & ~0x7FUL) != (want_v & ~0x7FUL)) { - DBG_LOW("not found !\n"); - spin_unlock_irqrestore(&beat_htab_lock, flags); - return -1; - } - - lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, &dummy0, - &dummy1); - spin_unlock_irqrestore(&beat_htab_lock, flags); - if (lpar_rc != 0 || dummy0 == 0) { - DBG_LOW("not found !\n"); - return -1; - } - - DBG_LOW("ok %lx %lx\n", dummy0, dummy1); - - BUG_ON(lpar_rc != 0); - - return 0; -} - -static long beat_lpar_hpte_find(unsigned long va, int psize) -{ - unsigned long hash; - unsigned long i, j; - long slot; - unsigned long want_v, hpte_v; - - hash = hpt_hash(va, mmu_psize_defs[psize].shift); - want_v = hpte_encode_v(va, psize); - - for (j = 0; j < 2; j++) { - slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; - for (i = 0; i < HPTES_PER_GROUP; i++) { - hpte_v = beat_lpar_hpte_getword0(slot); - - if (HPTE_V_COMPARE(hpte_v, want_v) - && (hpte_v & HPTE_V_VALID) - && (!!(hpte_v & HPTE_V_SECONDARY) == j)) { - /* HPTE matches */ - if (j) - slot = -slot; - return slot; - } - ++slot; - } - hash = ~hash; - } - - return -1; -} - -static void beat_lpar_hpte_updateboltedpp(unsigned long newpp, - unsigned long ea, - int psize) -{ - unsigned long lpar_rc, slot, vsid, va, dummy0, dummy1; - unsigned long flags; - - vsid = get_kernel_vsid(ea); - va = (vsid << 28) | (ea & 0x0fffffff); - - spin_lock_irqsave(&beat_htab_lock, flags); - slot = beat_lpar_hpte_find(va, psize); - BUG_ON(slot == -1); - - lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, - &dummy0, &dummy1); - spin_unlock_irqrestore(&beat_htab_lock, flags); - - BUG_ON(lpar_rc != 0); -} - -static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va, - int psize, int local) -{ - unsigned long want_v; - unsigned long lpar_rc; - unsigned long dummy1, dummy2; - unsigned long flags; - - DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", - slot, va, psize, local); - want_v = hpte_encode_v(va, psize); - - spin_lock_irqsave(&beat_htab_lock, flags); - dummy1 = beat_lpar_hpte_getword0(slot); - - if ((dummy1 & ~0x7FUL) != (want_v & ~0x7FUL)) { - DBG_LOW("not found !\n"); - spin_unlock_irqrestore(&beat_htab_lock, flags); - return; - } - - lpar_rc = beat_write_htab_entry(0, slot, 0, 0, HPTE_V_VALID, 0, - &dummy1, &dummy2); - spin_unlock_irqrestore(&beat_htab_lock, flags); - - BUG_ON(lpar_rc != 0); -} - -void __init hpte_init_beat(void) -{ - ppc_md.hpte_invalidate = beat_lpar_hpte_invalidate; - ppc_md.hpte_updatepp = beat_lpar_hpte_updatepp; - ppc_md.hpte_updateboltedpp = beat_lpar_hpte_updateboltedpp; - ppc_md.hpte_insert = beat_lpar_hpte_insert; - ppc_md.hpte_remove = beat_lpar_hpte_remove; - ppc_md.hpte_clear_all = beat_lpar_hptab_clear; -} diff --git a/trunk/arch/powerpc/platforms/celleb/hvCall.S b/trunk/arch/powerpc/platforms/celleb/hvCall.S deleted file mode 100644 index 74c817448948..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/hvCall.S +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Beat hypervisor call I/F - * - * (C) Copyright 2007 TOSHIBA CORPORATION - * - * This code is based on arch/powerpc/platforms/pseries/hvCall.S. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#define STK_PARM(i) (48 + ((i)-3)*8) - -/* Not implemented on Beat, now */ -#define HCALL_INST_PRECALL -#define HCALL_INST_POSTCALL - - .text - -#define HVSC .long 0x44000022 - -/* Note: takes only 7 input parameters at maximum */ -_GLOBAL(beat_hcall_norets) - HMT_MEDIUM - - mfcr r0 - stw r0,8(r1) - - HCALL_INST_PRECALL - - mr r11,r3 - mr r3,r4 - mr r4,r5 - mr r5,r6 - mr r6,r7 - mr r7,r8 - mr r8,r9 - - HVSC /* invoke the hypervisor */ - - HCALL_INST_POSTCALL - - lwz r0,8(r1) - mtcrf 0xff,r0 - - blr /* return r3 = status */ - -/* Note: takes 8 input parameters at maximum */ -_GLOBAL(beat_hcall_norets8) - HMT_MEDIUM - - mfcr r0 - stw r0,8(r1) - - HCALL_INST_PRECALL - - mr r11,r3 - mr r3,r4 - mr r4,r5 - mr r5,r6 - mr r6,r7 - mr r7,r8 - mr r8,r9 - ld r10,STK_PARM(r10)(r1) - - HVSC /* invoke the hypervisor */ - - HCALL_INST_POSTCALL - - lwz r0,8(r1) - mtcrf 0xff,r0 - - blr /* return r3 = status */ - -/* Note: takes only 6 input parameters, 1 output parameters at maximum */ -_GLOBAL(beat_hcall1) - HMT_MEDIUM - - mfcr r0 - stw r0,8(r1) - - HCALL_INST_PRECALL - - std r4,STK_PARM(r4)(r1) /* save ret buffer */ - - mr r11,r3 - mr r3,r5 - mr r4,r6 - mr r5,r7 - mr r6,r8 - mr r7,r9 - mr r8,r10 - - HVSC /* invoke the hypervisor */ - - HCALL_INST_POSTCALL - - ld r12,STK_PARM(r4)(r1) - std r4, 0(r12) - - lwz r0,8(r1) - mtcrf 0xff,r0 - - blr /* return r3 = status */ - -/* Note: takes only 6 input parameters, 2 output parameters at maximum */ -_GLOBAL(beat_hcall2) - HMT_MEDIUM - - mfcr r0 - stw r0,8(r1) - - HCALL_INST_PRECALL - - std r4,STK_PARM(r4)(r1) /* save ret buffer */ - - mr r11,r3 - mr r3,r5 - mr r4,r6 - mr r5,r7 - mr r6,r8 - mr r7,r9 - mr r8,r10 - - HVSC /* invoke the hypervisor */ - - HCALL_INST_POSTCALL - - ld r12,STK_PARM(r4)(r1) - std r4, 0(r12) - std r5, 8(r12) - - lwz r0,8(r1) - mtcrf 0xff,r0 - - blr /* return r3 = status */ - -/* Note: takes only 6 input parameters, 3 output parameters at maximum */ -_GLOBAL(beat_hcall3) - HMT_MEDIUM - - mfcr r0 - stw r0,8(r1) - - HCALL_INST_PRECALL - - std r4,STK_PARM(r4)(r1) /* save ret buffer */ - - mr r11,r3 - mr r3,r5 - mr r4,r6 - mr r5,r7 - mr r6,r8 - mr r7,r9 - mr r8,r10 - - HVSC /* invoke the hypervisor */ - - HCALL_INST_POSTCALL - - ld r12,STK_PARM(r4)(r1) - std r4, 0(r12) - std r5, 8(r12) - std r6, 16(r12) - - lwz r0,8(r1) - mtcrf 0xff,r0 - - blr /* return r3 = status */ - -/* Note: takes only 6 input parameters, 4 output parameters at maximum */ -_GLOBAL(beat_hcall4) - HMT_MEDIUM - - mfcr r0 - stw r0,8(r1) - - HCALL_INST_PRECALL - - std r4,STK_PARM(r4)(r1) /* save ret buffer */ - - mr r11,r3 - mr r3,r5 - mr r4,r6 - mr r5,r7 - mr r6,r8 - mr r7,r9 - mr r8,r10 - - HVSC /* invoke the hypervisor */ - - HCALL_INST_POSTCALL - - ld r12,STK_PARM(r4)(r1) - std r4, 0(r12) - std r5, 8(r12) - std r6, 16(r12) - std r7, 24(r12) - - lwz r0,8(r1) - mtcrf 0xff,r0 - - blr /* return r3 = status */ - -/* Note: takes only 6 input parameters, 5 output parameters at maximum */ -_GLOBAL(beat_hcall5) - HMT_MEDIUM - - mfcr r0 - stw r0,8(r1) - - HCALL_INST_PRECALL - - std r4,STK_PARM(r4)(r1) /* save ret buffer */ - - mr r11,r3 - mr r3,r5 - mr r4,r6 - mr r5,r7 - mr r6,r8 - mr r7,r9 - mr r8,r10 - - HVSC /* invoke the hypervisor */ - - HCALL_INST_POSTCALL - - ld r12,STK_PARM(r4)(r1) - std r4, 0(r12) - std r5, 8(r12) - std r6, 16(r12) - std r7, 24(r12) - std r8, 32(r12) - - lwz r0,8(r1) - mtcrf 0xff,r0 - - blr /* return r3 = status */ - -/* Note: takes only 6 input parameters, 6 output parameters at maximum */ -_GLOBAL(beat_hcall6) - HMT_MEDIUM - - mfcr r0 - stw r0,8(r1) - - HCALL_INST_PRECALL - - std r4,STK_PARM(r4)(r1) /* save ret buffer */ - - mr r11,r3 - mr r3,r5 - mr r4,r6 - mr r5,r7 - mr r6,r8 - mr r7,r9 - mr r8,r10 - - HVSC /* invoke the hypervisor */ - - HCALL_INST_POSTCALL - - ld r12,STK_PARM(r4)(r1) - std r4, 0(r12) - std r5, 8(r12) - std r6, 16(r12) - std r7, 24(r12) - std r8, 32(r12) - std r9, 40(r12) - - lwz r0,8(r1) - mtcrf 0xff,r0 - - blr /* return r3 = status */ diff --git a/trunk/arch/powerpc/platforms/celleb/interrupt.c b/trunk/arch/powerpc/platforms/celleb/interrupt.c deleted file mode 100644 index 98e6665681d3..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/interrupt.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Celleb/Beat Interrupt controller - * - * (C) Copyright 2006-2007 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include - -#include - -#include "interrupt.h" -#include "beat_wrapper.h" - -#define MAX_IRQS NR_IRQS -static DEFINE_SPINLOCK(beatic_irq_mask_lock); -static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64]; -static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64]; - -static struct irq_host *beatic_host = NULL; - -/* - * In this implementation, "virq" == "IRQ plug number", - * "(irq_hw_number_t)hwirq" == "IRQ outlet number". - */ - -/* assumption: locked */ -static inline void beatic_update_irq_mask(unsigned int irq_plug) -{ - int off; - unsigned long masks[4]; - - off = (irq_plug / 256) * 4; - masks[0] = beatic_irq_mask_enable[off + 0] - & beatic_irq_mask_ack[off + 0]; - masks[1] = beatic_irq_mask_enable[off + 1] - & beatic_irq_mask_ack[off + 1]; - masks[2] = beatic_irq_mask_enable[off + 2] - & beatic_irq_mask_ack[off + 2]; - masks[3] = beatic_irq_mask_enable[off + 3] - & beatic_irq_mask_ack[off + 3]; - if (beat_set_interrupt_mask(irq_plug&~255UL, - masks[0], masks[1], masks[2], masks[3]) != 0) - panic("Failed to set mask IRQ!"); -} - -static void beatic_mask_irq(unsigned int irq_plug) -{ - unsigned long flags; - - spin_lock_irqsave(&beatic_irq_mask_lock, flags); - beatic_irq_mask_enable[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64))); - beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); -} - -static void beatic_unmask_irq(unsigned int irq_plug) -{ - unsigned long flags; - - spin_lock_irqsave(&beatic_irq_mask_lock, flags); - beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); - beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); -} - -static void beatic_ack_irq(unsigned int irq_plug) -{ - unsigned long flags; - - spin_lock_irqsave(&beatic_irq_mask_lock, flags); - beatic_irq_mask_ack[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64))); - beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); -} - -static void beatic_end_irq(unsigned int irq_plug) -{ - s64 err; - unsigned long flags; - - if ((err = beat_downcount_of_interrupt(irq_plug)) != 0) { - if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */ - panic("Failed to downcount IRQ! Error = %16lx", err); - - printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug); - } - spin_lock_irqsave(&beatic_irq_mask_lock, flags); - beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); - beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); -} - -static struct irq_chip beatic_pic = { - .typename = " CELL-BEAT ", - .unmask = beatic_unmask_irq, - .mask = beatic_mask_irq, - .eoi = beatic_end_irq, -}; - -/* - * Dispose binding hardware IRQ number (hw) and Virtuql IRQ number (virq), - * update flags. - * - * Note that the number (virq) is already assigned at upper layer. - */ -static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq) -{ - beat_destruct_irq_plug(virq); -} - -/* - * Create or update binding hardware IRQ number (hw) and Virtuql - * IRQ number (virq). This is called only once for a given mapping. - * - * Note that the number (virq) is already assigned at upper layer. - */ -static int beatic_pic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct irq_desc *desc = get_irq_desc(virq); - int64_t err; - - if ((err = beat_construct_and_connect_irq_plug(virq, hw)) < 0) - return -EIO; - - desc->status |= IRQ_LEVEL; - set_irq_chip_and_handler(virq, &beatic_pic, handle_fasteoi_irq); - return 0; -} - -/* - * Update binding hardware IRQ number (hw) and Virtuql - * IRQ number (virq). This is called only once for a given mapping. - */ -static void beatic_pic_host_remap(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) -{ - beat_construct_and_connect_irq_plug(virq, hw); -} - -/* - * Translate device-tree interrupt spec to irq_hw_number_t style (ulong), - * to pass away to irq_create_mapping(). - * - * Called from irq_create_of_mapping() only. - * Note: We have only 1 entry to translate. - */ -static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct, - u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, - unsigned int *out_flags) -{ - u64 *intspec2 = (u64 *)intspec; - - *out_hwirq = *intspec2; - *out_flags |= IRQ_TYPE_LEVEL_LOW; - return 0; -} - -static struct irq_host_ops beatic_pic_host_ops = { - .map = beatic_pic_host_map, - .remap = beatic_pic_host_remap, - .unmap = beatic_pic_host_unmap, - .xlate = beatic_pic_host_xlate, -}; - -/* - * Get an IRQ number - * Note: returns VIRQ - */ -static inline unsigned int beatic_get_irq_plug(void) -{ - int i; - uint64_t pending[4], ub; - - for (i = 0; i < MAX_IRQS; i += 256) { - beat_detect_pending_interrupts(i, pending); - __asm__ ("cntlzd %0,%1":"=r"(ub): - "r"(pending[0] & beatic_irq_mask_enable[i/64+0] - & beatic_irq_mask_ack[i/64+0])); - if (ub != 64) - return i + ub + 0; - __asm__ ("cntlzd %0,%1":"=r"(ub): - "r"(pending[1] & beatic_irq_mask_enable[i/64+1] - & beatic_irq_mask_ack[i/64+1])); - if (ub != 64) - return i + ub + 64; - __asm__ ("cntlzd %0,%1":"=r"(ub): - "r"(pending[2] & beatic_irq_mask_enable[i/64+2] - & beatic_irq_mask_ack[i/64+2])); - if (ub != 64) - return i + ub + 128; - __asm__ ("cntlzd %0,%1":"=r"(ub): - "r"(pending[3] & beatic_irq_mask_enable[i/64+3] - & beatic_irq_mask_ack[i/64+3])); - if (ub != 64) - return i + ub + 192; - } - - return NO_IRQ; -} -unsigned int beatic_get_irq(void) -{ - unsigned int ret; - - ret = beatic_get_irq_plug(); - if (ret != NO_IRQ) - beatic_ack_irq(ret); - return ret; -} - -/* - */ -void __init beatic_init_IRQ(void) -{ - int i; - - memset(beatic_irq_mask_enable, 0, sizeof(beatic_irq_mask_enable)); - memset(beatic_irq_mask_ack, 255, sizeof(beatic_irq_mask_ack)); - for (i = 0; i < MAX_IRQS; i += 256) - beat_set_interrupt_mask(i, 0L, 0L, 0L, 0L); - - /* Set out get_irq function */ - ppc_md.get_irq = beatic_get_irq; - - /* Allocate an irq host */ - beatic_host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, - &beatic_pic_host_ops, - 0); - BUG_ON(beatic_host == NULL); - irq_set_default_host(beatic_host); -} - -#ifdef CONFIG_SMP - -/* Nullified to compile with SMP mode */ -void beatic_setup_cpu(int cpu) -{ -} - -void beatic_cause_IPI(int cpu, int mesg) -{ -} - -void beatic_request_IPIs(void) -{ -} -#endif /* CONFIG_SMP */ - -void beatic_deinit_IRQ(void) -{ - int i; - - for (i = 1; i < NR_IRQS; i++) - beat_destruct_irq_plug(i); -} diff --git a/trunk/arch/powerpc/platforms/celleb/interrupt.h b/trunk/arch/powerpc/platforms/celleb/interrupt.h deleted file mode 100644 index b470fd0051f1..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/interrupt.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Celleb/Beat Interrupt controller - * - * (C) Copyright 2006 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef ASM_BEAT_PIC_H -#define ASM_BEAT_PIC_H -#ifdef __KERNEL__ - -extern void beatic_init_IRQ(void); -extern unsigned int beatic_get_irq(void); -extern void beatic_cause_IPI(int cpu, int mesg); -extern void beatic_request_IPIs(void); -extern void beatic_setup_cpu(int); -extern void beatic_deinit_IRQ(void); - -#endif -#endif /* ASM_BEAT_PIC_H */ diff --git a/trunk/arch/powerpc/platforms/celleb/iommu.c b/trunk/arch/powerpc/platforms/celleb/iommu.c deleted file mode 100644 index f63b94c65353..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/iommu.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Support for IOMMU on Celleb platform. - * - * (C) Copyright 2006-2007 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include - -#include - -#include "beat_wrapper.h" - -#define DMA_FLAGS 0xf800000000000000UL /* r/w permitted, coherency required, - strongest order */ - -static int __init find_dma_window(u64 *io_space_id, u64 *ioid, - u64 *base, u64 *size, u64 *io_page_size) -{ - struct device_node *dn; - const unsigned long *dma_window; - - for_each_node_by_type(dn, "ioif") { - dma_window = get_property(dn, "toshiba,dma-window", NULL); - if (dma_window) { - *io_space_id = (dma_window[0] >> 32) & 0xffffffffUL; - *ioid = dma_window[0] & 0x7ffUL; - *base = dma_window[1]; - *size = dma_window[2]; - *io_page_size = 1 << dma_window[3]; - of_node_put(dn); - return 1; - } - } - return 0; -} - -static void __init celleb_init_direct_mapping(void) -{ - u64 lpar_addr, io_addr; - u64 io_space_id, ioid, dma_base, dma_size, io_page_size; - - if (!find_dma_window(&io_space_id, &ioid, &dma_base, &dma_size, - &io_page_size)) { - pr_info("No dma window found !\n"); - return; - } - - for (lpar_addr = 0; lpar_addr < dma_size; lpar_addr += io_page_size) { - io_addr = lpar_addr + dma_base; - (void)beat_put_iopte(io_space_id, io_addr, lpar_addr, - ioid, DMA_FLAGS); - } - - dma_direct_offset = dma_base; -} - -static int celleb_of_bus_notify(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct device *dev = data; - - /* We are only intereted in device addition */ - if (action != BUS_NOTIFY_ADD_DEVICE) - return 0; - - dev->archdata.dma_ops = pci_dma_ops; - - return 0; -} - -static struct notifier_block celleb_of_bus_notifier = { - .notifier_call = celleb_of_bus_notify -}; - -static int __init celleb_init_iommu(void) -{ - if (!machine_is(celleb)) - return -ENODEV; - - celleb_init_direct_mapping(); - pci_dma_ops = &dma_direct_ops; - bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier); - - return 0; -} - -arch_initcall(celleb_init_iommu); diff --git a/trunk/arch/powerpc/platforms/celleb/pci.c b/trunk/arch/powerpc/platforms/celleb/pci.c deleted file mode 100644 index 867f83a7d0c9..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/pci.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * Support for PCI on Celleb platform. - * - * (C) Copyright 2006-2007 TOSHIBA CORPORATION - * - * This code is based on arch/powerpc/kernel/rtas_pci.c: - * Copyright (C) 2001 Dave Engebretsen, IBM Corporation - * Copyright (C) 2003 Anton Blanchard , IBM - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "pci.h" -#include "interrupt.h" - -#define MAX_PCI_DEVICES 32 -#define MAX_PCI_FUNCTIONS 8 -#define MAX_PCI_BASE_ADDRS 3 /* use 64 bit address */ - -/* definition for fake pci configuration area for GbE, .... ,and etc. */ - -struct celleb_pci_resource { - struct resource r[MAX_PCI_BASE_ADDRS]; -}; - -struct celleb_pci_private { - unsigned char *fake_config[MAX_PCI_DEVICES][MAX_PCI_FUNCTIONS]; - struct celleb_pci_resource *res[MAX_PCI_DEVICES][MAX_PCI_FUNCTIONS]; -}; - -static inline u8 celleb_fake_config_readb(void *addr) -{ - u8 *p = addr; - return *p; -} - -static inline u16 celleb_fake_config_readw(void *addr) -{ - u16 *p = addr; - return le16_to_cpu(*p); -} - -static inline u32 celleb_fake_config_readl(void *addr) -{ - u32 *p = addr; - return le32_to_cpu(*p); -} - -static inline void celleb_fake_config_writeb(u32 val, void *addr) -{ - u8 *p = addr; - *p = val; -} - -static inline void celleb_fake_config_writew(u32 val, void *addr) -{ - u16 val16; - u16 *p = addr; - val16 = cpu_to_le16(val); - *p = val16; -} - -static inline void celleb_fake_config_writel(u32 val, void *addr) -{ - u32 val32; - u32 *p = addr; - val32 = cpu_to_le32(val); - *p = val32; -} - -static unsigned char *get_fake_config_start(struct pci_controller *hose, - int devno, int fn) -{ - struct celleb_pci_private *private = hose->private_data; - - if (private == NULL) - return NULL; - - return private->fake_config[devno][fn]; -} - -static struct celleb_pci_resource *get_resource_start( - struct pci_controller *hose, - int devno, int fn) -{ - struct celleb_pci_private *private = hose->private_data; - - if (private == NULL) - return NULL; - - return private->res[devno][fn]; -} - - -static void celleb_config_read_fake(unsigned char *config, int where, - int size, u32 *val) -{ - char *p = config + where; - - switch (size) { - case 1: - *val = celleb_fake_config_readb(p); - break; - case 2: - *val = celleb_fake_config_readw(p); - break; - case 4: - *val = celleb_fake_config_readl(p); - break; - } - - return; -} - -static void celleb_config_write_fake(unsigned char *config, int where, - int size, u32 val) -{ - char *p = config + where; - - switch (size) { - case 1: - celleb_fake_config_writeb(val, p); - break; - case 2: - celleb_fake_config_writew(val, p); - break; - case 4: - celleb_fake_config_writel(val, p); - break; - } - return; -} - -static int celleb_fake_pci_read_config(struct pci_bus *bus, - unsigned int devfn, int where, int size, u32 *val) -{ - char *config; - struct device_node *node; - struct pci_controller *hose; - unsigned int devno = devfn >> 3; - unsigned int fn = devfn & 0x7; - - /* allignment check */ - BUG_ON(where % size); - - pr_debug(" fake read: bus=0x%x, ", bus->number); - node = (struct device_node *)bus->sysdata; - hose = pci_find_hose_for_OF_device(node); - config = get_fake_config_start(hose, devno, fn); - - pr_debug("devno=0x%x, where=0x%x, size=0x%x, ", devno, where, size); - if (!config) { - pr_debug("failed\n"); - return PCIBIOS_DEVICE_NOT_FOUND; - } - - celleb_config_read_fake(config, where, size, val); - pr_debug("val=0x%x\n", *val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int celleb_fake_pci_write_config(struct pci_bus *bus, - unsigned int devfn, int where, int size, u32 val) -{ - char *config; - struct device_node *node; - struct pci_controller *hose; - struct celleb_pci_resource *res; - unsigned int devno = devfn >> 3; - unsigned int fn = devfn & 0x7; - - /* allignment check */ - BUG_ON(where % size); - - node = (struct device_node *)bus->sysdata; - hose = pci_find_hose_for_OF_device(node); - config = get_fake_config_start(hose, devno, fn); - - if (!config) - return PCIBIOS_DEVICE_NOT_FOUND; - - if (val == ~0) { - int i = (where - PCI_BASE_ADDRESS_0) >> 3; - - switch (where) { - case PCI_BASE_ADDRESS_0: - case PCI_BASE_ADDRESS_2: - if (size != 4) - return PCIBIOS_DEVICE_NOT_FOUND; - res = get_resource_start(hose, devno, fn); - if (!res) - return PCIBIOS_DEVICE_NOT_FOUND; - celleb_config_write_fake(config, where, size, - (res->r[i].end - res->r[i].start)); - return PCIBIOS_SUCCESSFUL; - case PCI_BASE_ADDRESS_1: - case PCI_BASE_ADDRESS_3: - case PCI_BASE_ADDRESS_4: - case PCI_BASE_ADDRESS_5: - break; - default: - break; - } - } - - celleb_config_write_fake(config, where, size, val); - pr_debug(" fake write: where=%x, size=%d, val=%x\n", - where, size, val); - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops celleb_fake_pci_ops = { - celleb_fake_pci_read_config, - celleb_fake_pci_write_config -}; - -static inline void celleb_setup_pci_base_addrs(struct pci_controller *hose, - unsigned int devno, unsigned int fn, - unsigned int num_base_addr) -{ - u32 val; - unsigned char *config; - struct celleb_pci_resource *res; - - config = get_fake_config_start(hose, devno, fn); - res = get_resource_start(hose, devno, fn); - - if (!config || !res) - return; - - switch (num_base_addr) { - case 3: - val = (res->r[2].start & 0xfffffff0) - | PCI_BASE_ADDRESS_MEM_TYPE_64; - celleb_config_write_fake(config, PCI_BASE_ADDRESS_4, 4, val); - val = res->r[2].start >> 32; - celleb_config_write_fake(config, PCI_BASE_ADDRESS_5, 4, val); - /* FALLTHROUGH */ - case 2: - val = (res->r[1].start & 0xfffffff0) - | PCI_BASE_ADDRESS_MEM_TYPE_64; - celleb_config_write_fake(config, PCI_BASE_ADDRESS_2, 4, val); - val = res->r[1].start >> 32; - celleb_config_write_fake(config, PCI_BASE_ADDRESS_3, 4, val); - /* FALLTHROUGH */ - case 1: - val = (res->r[0].start & 0xfffffff0) - | PCI_BASE_ADDRESS_MEM_TYPE_64; - celleb_config_write_fake(config, PCI_BASE_ADDRESS_0, 4, val); - val = res->r[0].start >> 32; - celleb_config_write_fake(config, PCI_BASE_ADDRESS_1, 4, val); - break; - } - - val = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - celleb_config_write_fake(config, PCI_COMMAND, 2, val); -} - -static int __devinit celleb_setup_fake_pci_device(struct device_node *node, - struct pci_controller *hose) -{ - unsigned int rlen; - int num_base_addr = 0; - u32 val; - const u32 *wi0, *wi1, *wi2, *wi3, *wi4; - unsigned int devno, fn; - struct celleb_pci_private *private = hose->private_data; - unsigned char **config = NULL; - struct celleb_pci_resource **res = NULL; - const char *name; - const unsigned long *li; - int size, result; - - if (private == NULL) { - printk(KERN_ERR "PCI: " - "memory space for pci controller is not assigned\n"); - goto error; - } - - name = get_property(node, "model", &rlen); - if (!name) { - printk(KERN_ERR "PCI: model property not found.\n"); - goto error; - } - - wi4 = get_property(node, "reg", &rlen); - if (wi4 == NULL) - goto error; - - devno = ((wi4[0] >> 8) & 0xff) >> 3; - fn = (wi4[0] >> 8) & 0x7; - - pr_debug("PCI: celleb_setup_fake_pci() %s devno=%x fn=%x\n", name, - devno, fn); - - size = 256; - config = &private->fake_config[devno][fn]; - if (mem_init_done) - *config = kzalloc(size, GFP_KERNEL); - else - *config = alloc_bootmem(size); - if (*config == NULL) { - printk(KERN_ERR "PCI: " - "not enough memory for fake configuration space\n"); - goto error; - } - pr_debug("PCI: fake config area assigned 0x%016lx\n", - (unsigned long)*config); - - size = sizeof(struct celleb_pci_resource); - res = &private->res[devno][fn]; - if (mem_init_done) - *res = kzalloc(size, GFP_KERNEL); - else - *res = alloc_bootmem(size); - if (*res == NULL) { - printk(KERN_ERR - "PCI: not enough memory for resource data space\n"); - goto error; - } - pr_debug("PCI: res assigned 0x%016lx\n", (unsigned long)*res); - - wi0 = get_property(node, "device-id", NULL); - wi1 = get_property(node, "vendor-id", NULL); - wi2 = get_property(node, "class-code", NULL); - wi3 = get_property(node, "revision-id", NULL); - - celleb_config_write_fake(*config, PCI_DEVICE_ID, 2, wi0[0] & 0xffff); - celleb_config_write_fake(*config, PCI_VENDOR_ID, 2, wi1[0] & 0xffff); - pr_debug("class-code = 0x%08x\n", wi2[0]); - - celleb_config_write_fake(*config, PCI_CLASS_PROG, 1, wi2[0] & 0xff); - celleb_config_write_fake(*config, PCI_CLASS_DEVICE, 2, - (wi2[0] >> 8) & 0xffff); - celleb_config_write_fake(*config, PCI_REVISION_ID, 1, wi3[0]); - - while (num_base_addr < MAX_PCI_BASE_ADDRS) { - result = of_address_to_resource(node, - num_base_addr, &(*res)->r[num_base_addr]); - if (result) - break; - num_base_addr++; - } - - celleb_setup_pci_base_addrs(hose, devno, fn, num_base_addr); - - li = get_property(node, "interrupts", &rlen); - val = li[0]; - celleb_config_write_fake(*config, PCI_INTERRUPT_PIN, 1, 1); - celleb_config_write_fake(*config, PCI_INTERRUPT_LINE, 1, val); - -#ifdef DEBUG - pr_debug("PCI: %s irq=%ld\n", name, li[0]); - for (i = 0; i < 6; i++) { - celleb_config_read_fake(*config, - PCI_BASE_ADDRESS_0 + 0x4 * i, 4, - &val); - pr_debug("PCI: %s fn=%d base_address_%d=0x%x\n", - name, fn, i, val); - } -#endif - - celleb_config_write_fake(*config, PCI_HEADER_TYPE, 1, - PCI_HEADER_TYPE_NORMAL); - - return 0; - -error: - if (mem_init_done) { - if (config && *config) - kfree(*config); - if (res && *res) - kfree(*res); - - } else { - if (config && *config) { - size = 256; - free_bootmem((unsigned long)(*config), size); - } - if (res && *res) { - size = sizeof(struct celleb_pci_resource); - free_bootmem((unsigned long)(*res), size); - } - } - - return 1; -} - -static int __devinit phb_set_bus_ranges(struct device_node *dev, - struct pci_controller *phb) -{ - const int *bus_range; - unsigned int len; - - bus_range = get_property(dev, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) - return 1; - - phb->first_busno = bus_range[0]; - phb->last_busno = bus_range[1]; - - return 0; -} - -static void __devinit celleb_alloc_private_mem(struct pci_controller *hose) -{ - if (mem_init_done) - hose->private_data = - kzalloc(sizeof(struct celleb_pci_private), GFP_KERNEL); - else - hose->private_data = - alloc_bootmem(sizeof(struct celleb_pci_private)); -} - -int __devinit celleb_setup_phb(struct pci_controller *phb) -{ - const char *name; - struct device_node *dev = phb->arch_data; - struct device_node *node; - unsigned int rlen; - - name = get_property(dev, "name", &rlen); - if (!name) - return 1; - - pr_debug("PCI: celleb_setup_phb() %s\n", name); - phb_set_bus_ranges(dev, phb); - - if (strcmp(name, "epci") == 0) { - phb->ops = &celleb_epci_ops; - return celleb_setup_epci(dev, phb); - - } else if (strcmp(name, "pci-pseudo") == 0) { - phb->ops = &celleb_fake_pci_ops; - celleb_alloc_private_mem(phb); - for (node = of_get_next_child(dev, NULL); - node != NULL; node = of_get_next_child(dev, node)) - celleb_setup_fake_pci_device(node, phb); - - } else - return 1; - - return 0; -} - -int celleb_pci_probe_mode(struct pci_bus *bus) -{ - return PCI_PROBE_DEVTREE; -} diff --git a/trunk/arch/powerpc/platforms/celleb/pci.h b/trunk/arch/powerpc/platforms/celleb/pci.h deleted file mode 100644 index 5340e348e297..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/pci.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * pci prototypes for Celleb platform - * - * (C) Copyright 2006-2007 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef _CELLEB_PCI_H -#define _CELLEB_PCI_H - -#include - -#include -#include - -extern int celleb_setup_phb(struct pci_controller *); -extern int celleb_pci_probe_mode(struct pci_bus *); - -extern struct pci_ops celleb_epci_ops; -extern int celleb_setup_epci(struct device_node *, struct pci_controller *); - -#endif /* _CELLEB_PCI_H */ diff --git a/trunk/arch/powerpc/platforms/celleb/scc.h b/trunk/arch/powerpc/platforms/celleb/scc.h deleted file mode 100644 index e9ce8a7c1882..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/scc.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * SCC (Super Companion Chip) definitions - * - * (C) Copyright 2004-2006 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef _CELLEB_SCC_H -#define _CELLEB_SCC_H - -#define PCI_VENDOR_ID_TOSHIBA_2 0x102f -#define PCI_DEVICE_ID_TOSHIBA_SCC_PCIEXC_BRIDGE 0x01b0 -#define PCI_DEVICE_ID_TOSHIBA_SCC_EPCI_BRIDGE 0x01b1 -#define PCI_DEVICE_ID_TOSHIBA_SCC_BRIDGE 0x01b2 -#define PCI_DEVICE_ID_TOSHIBA_SCC_GBE 0x01b3 -#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 -#define PCI_DEVICE_ID_TOSHIBA_SCC_USB2 0x01b5 -#define PCI_DEVICE_ID_TOSHIBA_SCC_USB 0x01b6 -#define PCI_DEVICE_ID_TOSHIBA_SCC_ENCDEC 0x01b7 - -#define SCC_EPCI_REG 0x0000d000 - -/* EPCI registers */ -#define SCC_EPCI_CNF10_REG 0x010 -#define SCC_EPCI_CNF14_REG 0x014 -#define SCC_EPCI_CNF18_REG 0x018 -#define SCC_EPCI_PVBAT 0x100 -#define SCC_EPCI_VPMBAT 0x104 -#define SCC_EPCI_VPIBAT 0x108 -#define SCC_EPCI_VCSR 0x110 -#define SCC_EPCI_VIENAB 0x114 -#define SCC_EPCI_VISTAT 0x118 -#define SCC_EPCI_VRDCOUNT 0x124 -#define SCC_EPCI_BAM0 0x12c -#define SCC_EPCI_BAM1 0x134 -#define SCC_EPCI_BAM2 0x13c -#define SCC_EPCI_IADR 0x164 -#define SCC_EPCI_CLKRST 0x800 -#define SCC_EPCI_INTSET 0x804 -#define SCC_EPCI_STATUS 0x808 -#define SCC_EPCI_ABTSET 0x80c -#define SCC_EPCI_WATRP 0x810 -#define SCC_EPCI_DUMMYRADR 0x814 -#define SCC_EPCI_SWRESP 0x818 -#define SCC_EPCI_CNTOPT 0x81c -#define SCC_EPCI_ECMODE 0xf00 -#define SCC_EPCI_IOM_AC_NUM 5 -#define SCC_EPCI_IOM_ACTE(n) (0xf10 + (n) * 4) -#define SCC_EPCI_IOT_AC_NUM 4 -#define SCC_EPCI_IOT_ACTE(n) (0xf30 + (n) * 4) -#define SCC_EPCI_MAEA 0xf50 -#define SCC_EPCI_MAEC 0xf54 -#define SCC_EPCI_CKCTRL 0xff0 - -/* bits for SCC_EPCI_VCSR */ -#define SCC_EPCI_VCSR_FRE 0x00020000 -#define SCC_EPCI_VCSR_FWE 0x00010000 -#define SCC_EPCI_VCSR_DR 0x00000400 -#define SCC_EPCI_VCSR_SR 0x00000008 -#define SCC_EPCI_VCSR_AT 0x00000004 - -/* bits for SCC_EPCI_VIENAB/SCC_EPCI_VISTAT */ -#define SCC_EPCI_VISTAT_PMPE 0x00000008 -#define SCC_EPCI_VISTAT_PMFE 0x00000004 -#define SCC_EPCI_VISTAT_PRA 0x00000002 -#define SCC_EPCI_VISTAT_PRD 0x00000001 -#define SCC_EPCI_VISTAT_ALL 0x0000000f - -#define SCC_EPCI_VIENAB_PMPEE 0x00000008 -#define SCC_EPCI_VIENAB_PMFEE 0x00000004 -#define SCC_EPCI_VIENAB_PRA 0x00000002 -#define SCC_EPCI_VIENAB_PRD 0x00000001 -#define SCC_EPCI_VIENAB_ALL 0x0000000f - -/* bits for SCC_EPCI_CLKRST */ -#define SCC_EPCI_CLKRST_CKS_MASK 0x00030000 -#define SCC_EPCI_CLKRST_CKS_2 0x00000000 -#define SCC_EPCI_CLKRST_CKS_4 0x00010000 -#define SCC_EPCI_CLKRST_CKS_8 0x00020000 -#define SCC_EPCI_CLKRST_PCICRST 0x00000400 -#define SCC_EPCI_CLKRST_BC 0x00000200 -#define SCC_EPCI_CLKRST_PCIRST 0x00000100 -#define SCC_EPCI_CLKRST_PCKEN 0x00000001 - -/* bits for SCC_EPCI_INTSET/SCC_EPCI_STATUS */ -#define SCC_EPCI_INT_2M 0x01000000 -#define SCC_EPCI_INT_RERR 0x00200000 -#define SCC_EPCI_INT_SERR 0x00100000 -#define SCC_EPCI_INT_PRTER 0x00080000 -#define SCC_EPCI_INT_SER 0x00040000 -#define SCC_EPCI_INT_PER 0x00020000 -#define SCC_EPCI_INT_PAI 0x00010000 -#define SCC_EPCI_INT_1M 0x00000100 -#define SCC_EPCI_INT_PME 0x00000010 -#define SCC_EPCI_INT_INTD 0x00000008 -#define SCC_EPCI_INT_INTC 0x00000004 -#define SCC_EPCI_INT_INTB 0x00000002 -#define SCC_EPCI_INT_INTA 0x00000001 -#define SCC_EPCI_INT_DEVINT 0x0000000f -#define SCC_EPCI_INT_ALL 0x003f001f -#define SCC_EPCI_INT_ALLERR 0x003f0000 - -/* bits for SCC_EPCI_CKCTRL */ -#define SCC_EPCI_CKCTRL_CRST0 0x00010000 -#define SCC_EPCI_CKCTRL_CRST1 0x00020000 -#define SCC_EPCI_CKCTRL_OCLKEN 0x00000100 -#define SCC_EPCI_CKCTRL_LCLKEN 0x00000001 - -#define SCC_EPCI_IDSEL_AD_TO_SLOT(ad) ((ad) - 10) -#define SCC_EPCI_MAX_DEVNU SCC_EPCI_IDSEL_AD_TO_SLOT(32) - -/* bits for SCC_EPCI_CNTOPT */ -#define SCC_EPCI_CNTOPT_O2PMB 0x00000002 - -/* UHC registers */ -#define SCC_UHC_CKRCTRL 0xff0 -#define SCC_UHC_ECMODE 0xf00 - -/* bits for SCC_UHC_CKRCTRL */ -#define SCC_UHC_F48MCKLEN 0x00000001 -#define SCC_UHC_P_SUSPEND 0x00000002 -#define SCC_UHC_PHY_SUSPEND_SEL 0x00000004 -#define SCC_UHC_HCLKEN 0x00000100 -#define SCC_UHC_USBEN 0x00010000 -#define SCC_UHC_USBCEN 0x00020000 -#define SCC_UHC_PHYEN 0x00040000 - -/* bits for SCC_UHC_ECMODE */ -#define SCC_UHC_ECMODE_BY_BYTE 0x00000555 -#define SCC_UHC_ECMODE_BY_WORD 0x00000aaa - -#endif /* _CELLEB_SCC_H */ diff --git a/trunk/arch/powerpc/platforms/celleb/scc_epci.c b/trunk/arch/powerpc/platforms/celleb/scc_epci.c deleted file mode 100644 index 0edbc0c4f338..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/scc_epci.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Support for SCC external PCI - * - * (C) Copyright 2004-2007 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "scc.h" -#include "pci.h" -#include "interrupt.h" - -#define MAX_PCI_DEVICES 32 -#define MAX_PCI_FUNCTIONS 8 - -#define iob() __asm__ __volatile__("eieio; sync":::"memory") - - -#if 0 /* test code for epci dummy read */ -static void celleb_epci_dummy_read(struct pci_dev *dev) -{ - void *epci_base; - struct device_node *node; - struct pci_controller *hose; - u32 val; - - node = (struct device_node *)dev->bus->sysdata; - hose = pci_find_hose_for_OF_device(node); - - if (!hose) - return; - - epci_base = (void *)hose->cfg_addr; - - val = in_be32(epci_base + SCC_EPCI_WATRP); - iosync(); - - return; -} -#endif - -static inline void clear_and_disable_master_abort_interrupt( - struct pci_controller *hose) -{ - void __iomem *addr; - addr = (void *)hose->cfg_addr + PCI_COMMAND; - out_be32(addr, in_be32(addr) | (PCI_STATUS_REC_MASTER_ABORT << 16)); -} - -static int celleb_epci_check_abort(struct pci_controller *hose, - unsigned long addr) -{ - void __iomem *reg, *epci_base; - u32 val; - - iob(); - epci_base = (void *)hose->cfg_addr; - - reg = epci_base + PCI_COMMAND; - val = in_be32(reg); - - if (val & (PCI_STATUS_REC_MASTER_ABORT << 16)) { - out_be32(reg, - (val & 0xffff) | (PCI_STATUS_REC_MASTER_ABORT << 16)); - - /* clear PCI Controller error, FRE, PMFE */ - reg = epci_base + SCC_EPCI_STATUS; - out_be32(reg, SCC_EPCI_INT_PAI); - - reg = epci_base + SCC_EPCI_VCSR; - val = in_be32(reg) & 0xffff; - val |= SCC_EPCI_VCSR_FRE; - out_be32(reg, val); - - reg = epci_base + SCC_EPCI_VISTAT; - out_be32(reg, SCC_EPCI_VISTAT_PMFE); - return PCIBIOS_DEVICE_NOT_FOUND; - } - - return PCIBIOS_SUCCESSFUL; -} - -static unsigned long celleb_epci_make_config_addr(struct pci_controller *hose, - unsigned int devfn, int where) -{ - unsigned long addr; - struct pci_bus *bus = hose->bus; - - if (bus->self) - addr = (unsigned long)hose->cfg_data + - (((bus->number & 0xff) << 16) - | ((devfn & 0xff) << 8) - | (where & 0xff) - | 0x01000000); - else - addr = (unsigned long)hose->cfg_data + - (((devfn & 0xff) << 8) | (where & 0xff)); - - pr_debug("EPCI: config_addr = 0x%016lx\n", addr); - - return addr; -} - -static int celleb_epci_read_config(struct pci_bus *bus, - unsigned int devfn, int where, int size, u32 * val) -{ - unsigned long addr; - struct device_node *node; - struct pci_controller *hose; - - /* allignment check */ - BUG_ON(where % size); - - node = (struct device_node *)bus->sysdata; - hose = pci_find_hose_for_OF_device(node); - - if (!hose->cfg_data) - return PCIBIOS_DEVICE_NOT_FOUND; - - if (bus->number == hose->first_busno && devfn == 0) { - /* EPCI controller self */ - - addr = (unsigned long)hose->cfg_addr + where; - - switch (size) { - case 1: - *val = in_8((u8 *)addr); - break; - case 2: - *val = in_be16((u16 *)addr); - break; - case 4: - *val = in_be32((u32 *)addr); - break; - default: - return PCIBIOS_DEVICE_NOT_FOUND; - } - - } else { - - clear_and_disable_master_abort_interrupt(hose); - addr = celleb_epci_make_config_addr(hose, devfn, where); - - switch (size) { - case 1: - *val = in_8((u8 *)addr); - break; - case 2: - *val = in_le16((u16 *)addr); - break; - case 4: - *val = in_le32((u32 *)addr); - break; - default: - return PCIBIOS_DEVICE_NOT_FOUND; - } - } - - pr_debug("EPCI: " - "addr=0x%lx, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n", - addr, devfn, where, size, *val); - - return celleb_epci_check_abort(hose, 0); -} - -static int celleb_epci_write_config(struct pci_bus *bus, - unsigned int devfn, int where, int size, u32 val) -{ - unsigned long addr; - struct device_node *node; - struct pci_controller *hose; - - /* allignment check */ - BUG_ON(where % size); - - node = (struct device_node *)bus->sysdata; - hose = pci_find_hose_for_OF_device(node); - - if (!hose->cfg_data) - return PCIBIOS_DEVICE_NOT_FOUND; - - if (bus->number == hose->first_busno && devfn == 0) { - /* EPCI controller self */ - - addr = (unsigned long)hose->cfg_addr + where; - - switch (size) { - case 1: - out_8((u8 *)addr, val); - break; - case 2: - out_be16((u16 *)addr, val); - break; - case 4: - out_be32((u32 *)addr, val); - break; - default: - return PCIBIOS_DEVICE_NOT_FOUND; - } - - } else { - - clear_and_disable_master_abort_interrupt(hose); - addr = celleb_epci_make_config_addr(hose, devfn, where); - - switch (size) { - case 1: - out_8((u8 *)addr, val); - break; - case 2: - out_le16((u16 *)addr, val); - break; - case 4: - out_le32((u32 *)addr, val); - break; - default: - return PCIBIOS_DEVICE_NOT_FOUND; - } - } - - return celleb_epci_check_abort(hose, addr); -} - -struct pci_ops celleb_epci_ops = { - celleb_epci_read_config, - celleb_epci_write_config, -}; - -/* to be moved in FW */ -static int __devinit celleb_epci_init(struct pci_controller *hose) -{ - u32 val; - void __iomem *reg, *epci_base; - int hwres = 0; - - epci_base = (void *)hose->cfg_addr; - - /* PCI core reset(Internal bus and PCI clock) */ - reg = epci_base + SCC_EPCI_CKCTRL; - val = in_be32(reg); - if (val == 0x00030101) - hwres = 1; - else { - val &= ~(SCC_EPCI_CKCTRL_CRST0 | SCC_EPCI_CKCTRL_CRST1); - out_be32(reg, val); - - /* set PCI core clock */ - val = in_be32(reg); - val |= (SCC_EPCI_CKCTRL_OCLKEN | SCC_EPCI_CKCTRL_LCLKEN); - out_be32(reg, val); - - /* release PCI core reset (internal bus) */ - val = in_be32(reg); - val |= SCC_EPCI_CKCTRL_CRST0; - out_be32(reg, val); - - /* set PCI clock select */ - reg = epci_base + SCC_EPCI_CLKRST; - val = in_be32(reg); - val &= ~SCC_EPCI_CLKRST_CKS_MASK; - val |= SCC_EPCI_CLKRST_CKS_2; - out_be32(reg, val); - - /* set arbiter */ - reg = epci_base + SCC_EPCI_ABTSET; - out_be32(reg, 0x0f1f001f); /* temporary value */ - - /* buffer on */ - reg = epci_base + SCC_EPCI_CLKRST; - val = in_be32(reg); - val |= SCC_EPCI_CLKRST_BC; - out_be32(reg, val); - - /* PCI clock enable */ - val = in_be32(reg); - val |= SCC_EPCI_CLKRST_PCKEN; - out_be32(reg, val); - - /* release PCI core reset (all) */ - reg = epci_base + SCC_EPCI_CKCTRL; - val = in_be32(reg); - val |= (SCC_EPCI_CKCTRL_CRST0 | SCC_EPCI_CKCTRL_CRST1); - out_be32(reg, val); - - /* set base translation registers. (already set by Beat) */ - - /* set base address masks. (already set by Beat) */ - } - - /* release interrupt masks and clear all interrupts */ - reg = epci_base + SCC_EPCI_INTSET; - out_be32(reg, 0x013f011f); /* all interrupts enable */ - reg = epci_base + SCC_EPCI_VIENAB; - val = SCC_EPCI_VIENAB_PMPEE | SCC_EPCI_VIENAB_PMFEE; - out_be32(reg, val); - reg = epci_base + SCC_EPCI_STATUS; - out_be32(reg, 0xffffffff); - reg = epci_base + SCC_EPCI_VISTAT; - out_be32(reg, 0xffffffff); - - /* disable PCI->IB address translation */ - reg = epci_base + SCC_EPCI_VCSR; - val = in_be32(reg); - val &= ~(SCC_EPCI_VCSR_DR | SCC_EPCI_VCSR_AT); - out_be32(reg, val); - - /* set base addresses. (no need to set?) */ - - /* memory space, bus master enable */ - reg = epci_base + PCI_COMMAND; - val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - out_be32(reg, val); - - /* endian mode setup */ - reg = epci_base + SCC_EPCI_ECMODE; - val = 0x00550155; - out_be32(reg, val); - - /* set control option */ - reg = epci_base + SCC_EPCI_CNTOPT; - val = in_be32(reg); - val |= SCC_EPCI_CNTOPT_O2PMB; - out_be32(reg, val); - - /* XXX: temporay: set registers for address conversion setup */ - reg = epci_base + SCC_EPCI_CNF10_REG; - out_be32(reg, 0x80000008); - reg = epci_base + SCC_EPCI_CNF14_REG; - out_be32(reg, 0x40000008); - - reg = epci_base + SCC_EPCI_BAM0; - out_be32(reg, 0x80000000); - reg = epci_base + SCC_EPCI_BAM1; - out_be32(reg, 0xe0000000); - - reg = epci_base + SCC_EPCI_PVBAT; - out_be32(reg, 0x80000000); - - if (!hwres) { - /* release external PCI reset */ - reg = epci_base + SCC_EPCI_CLKRST; - val = in_be32(reg); - val |= SCC_EPCI_CLKRST_PCIRST; - out_be32(reg, val); - } - - return 0; -} - -int __devinit celleb_setup_epci(struct device_node *node, - struct pci_controller *hose) -{ - struct resource r; - - pr_debug("PCI: celleb_setup_epci()\n"); - - if (of_address_to_resource(node, 0, &r)) - goto error; - hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1)); - if (!hose->cfg_addr) - goto error; - pr_debug("EPCI: cfg_addr map 0x%016lx->0x%016lx + 0x%016lx\n", - r.start, (unsigned long)hose->cfg_addr, - (r.end - r.start + 1)); - - if (of_address_to_resource(node, 2, &r)) - goto error; - hose->cfg_data = ioremap(r.start, (r.end - r.start + 1)); - if (!hose->cfg_data) - goto error; - pr_debug("EPCI: cfg_data map 0x%016lx->0x%016lx + 0x%016lx\n", - r.start, (unsigned long)hose->cfg_data, - (r.end - r.start + 1)); - - celleb_epci_init(hose); - - return 0; - -error: - return 1; -} diff --git a/trunk/arch/powerpc/platforms/celleb/scc_sio.c b/trunk/arch/powerpc/platforms/celleb/scc_sio.c deleted file mode 100644 index bcd25f54d986..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/scc_sio.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * setup serial port in SCC - * - * (C) Copyright 2006 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include - -#include -#include - -/* sio irq0=0xb00010022 irq0=0xb00010023 irq2=0xb00010024 - mmio=0xfff000-0x1000,0xff2000-0x1000 */ -static int txx9_serial_bitmap = 0; - -static struct { - uint32_t offset; - uint32_t index; -} txx9_scc_tab[3] = { - { 0x300, 0 }, /* 0xFFF300 */ - { 0x400, 0 }, /* 0xFFF400 */ - { 0x800, 1 } /* 0xFF2800 */ -}; - -static int txx9_serial_init(void) -{ - extern int early_serial_txx9_setup(struct uart_port *port); - struct device_node *node; - int i; - struct uart_port req; - struct of_irq irq; - struct resource res; - - node = of_find_node_by_path("/ioif1/sio"); - if (!node) - return 0; - - for(i = 0; i < sizeof(txx9_scc_tab)/sizeof(txx9_scc_tab[0]); i++) { - if (!(txx9_serial_bitmap & (1< UHC_RESET_WAIT_MAX) { - printk(KERN_ERR "Failed to disable UHC reset %x\n", - in_be32(uhc_clkctrl)); - break; - } - } - - /* Endian Conversion Mode for Master ALL area */ - out_be32(uhc_ecmode, SCC_UHC_ECMODE_BY_BYTE); - - iounmap(uhc_base); -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2, - PCI_DEVICE_ID_TOSHIBA_SCC_USB, enable_scc_uhc); diff --git a/trunk/arch/powerpc/platforms/celleb/setup.c b/trunk/arch/powerpc/platforms/celleb/setup.c deleted file mode 100644 index 1de63acfda87..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/setup.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Celleb setup code - * - * (C) Copyright 2006-2007 TOSHIBA CORPORATION - * - * This code is based on arch/powerpc/platforms/cell/setup.c: - * Copyright (C) 1995 Linus Torvalds - * Adapted from 'alpha' version by Gary Thomas - * Modified by Cort Dougan (cort@cs.nmt.edu) - * Modified by PPC64 Team, IBM Corp - * Modified by Cell Team, IBM Deutschland Entwicklung GmbH - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "interrupt.h" -#include "beat_wrapper.h" -#include "beat.h" -#include "pci.h" - -static char celleb_machine_type[128] = "Celleb"; - -static void celleb_show_cpuinfo(struct seq_file *m) -{ - struct device_node *root; - const char *model = ""; - - root = of_find_node_by_path("/"); - if (root) - model = get_property(root, "model", NULL); - /* using "CHRP" is to trick anaconda into installing FCx into Celleb */ - seq_printf(m, "machine\t\t: %s %s\n", celleb_machine_type, model); - of_node_put(root); -} - -static int celleb_machine_type_hack(char *ptr) -{ - strncpy(celleb_machine_type, ptr, sizeof(celleb_machine_type)); - celleb_machine_type[sizeof(celleb_machine_type)-1] = 0; - return 0; -} - -__setup("celleb_machine_type_hack", celleb_machine_type_hack); - -static void celleb_progress(char *s, unsigned short hex) -{ - printk("*** %04x : %s\n", hex, s ? s : ""); -} - -static void __init celleb_setup_arch(void) -{ -#ifdef CONFIG_SPU_BASE - spu_priv1_ops = &spu_priv1_beat_ops; - spu_management_ops = &spu_management_of_ops; -#endif - -#ifdef CONFIG_SMP - smp_init_celleb(); -#endif - - /* init to some ~sane value until calibrate_delay() runs */ - loops_per_jiffy = 50000000; - - if (ROOT_DEV == 0) { - printk("No ramdisk, default root is /dev/hda2\n"); - ROOT_DEV = Root_HDA2; - } - -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif -} - -static void beat_power_save(void) -{ - beat_pause(0); -} - -static int __init celleb_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (!of_flat_dt_is_compatible(root, "Beat")) - return 0; - - powerpc_firmware_features |= FW_FEATURE_CELLEB_POSSIBLE; - hpte_init_beat(); - return 1; -} - -/* - * Cell has no legacy IO; anything calling this function has to - * fail or bad things will happen - */ -static int celleb_check_legacy_ioport(unsigned int baseport) -{ - return -ENODEV; -} - -static void celleb_kexec_cpu_down(int crash, int secondary) -{ - beatic_deinit_IRQ(); -} - -static struct of_device_id celleb_bus_ids[] = { - { .type = "scc", }, - { .type = "ioif", }, /* old style */ - {}, -}; - -static int __init celleb_publish_devices(void) -{ - if (!machine_is(celleb)) - return 0; - - /* Publish OF platform devices for southbridge IOs */ - of_platform_bus_probe(NULL, celleb_bus_ids, NULL); - - return 0; -} -device_initcall(celleb_publish_devices); - -define_machine(celleb) { - .name = "Cell Reference Set", - .probe = celleb_probe, - .setup_arch = celleb_setup_arch, - .show_cpuinfo = celleb_show_cpuinfo, - .restart = beat_restart, - .power_off = beat_power_off, - .halt = beat_halt, - .get_rtc_time = beat_get_rtc_time, - .set_rtc_time = beat_set_rtc_time, - .calibrate_decr = generic_calibrate_decr, - .check_legacy_ioport = celleb_check_legacy_ioport, - .progress = celleb_progress, - .power_save = beat_power_save, - .nvram_size = beat_nvram_get_size, - .nvram_read = beat_nvram_read, - .nvram_write = beat_nvram_write, - .set_dabr = beat_set_xdabr, - .init_IRQ = beatic_init_IRQ, - .get_irq = beatic_get_irq, - .pci_probe_mode = celleb_pci_probe_mode, - .pci_setup_phb = celleb_setup_phb, -#ifdef CONFIG_KEXEC - .kexec_cpu_down = celleb_kexec_cpu_down, - .machine_kexec = default_machine_kexec, - .machine_kexec_prepare = default_machine_kexec_prepare, - .machine_crash_shutdown = default_machine_crash_shutdown, -#endif -}; diff --git a/trunk/arch/powerpc/platforms/celleb/smp.c b/trunk/arch/powerpc/platforms/celleb/smp.c deleted file mode 100644 index a7631250aeb4..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/smp.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * SMP support for Celleb platform. (Incomplete) - * - * (C) Copyright 2006 TOSHIBA CORPORATION - * - * This code is based on arch/powerpc/platforms/cell/smp.c: - * Dave Engebretsen, Peter Bergner, and - * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com - * Plus various changes from other IBM teams... - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "interrupt.h" - -#ifdef DEBUG -#define DBG(fmt...) udbg_printf(fmt) -#else -#define DBG(fmt...) -#endif - -/* - * The primary thread of each non-boot processor is recorded here before - * smp init. - */ -/* static cpumask_t of_spin_map; */ - -/** - * smp_startup_cpu() - start the given cpu - * - * At boot time, there is nothing to do for primary threads which were - * started from Open Firmware. For anything else, call RTAS with the - * appropriate start location. - * - * Returns: - * 0 - failure - * 1 - success - */ -static inline int __devinit smp_startup_cpu(unsigned int lcpu) -{ - return 0; -} - -static void smp_beatic_message_pass(int target, int msg) -{ - unsigned int i; - - if (target < NR_CPUS) { - beatic_cause_IPI(target, msg); - } else { - for_each_online_cpu(i) { - if (target == MSG_ALL_BUT_SELF - && i == smp_processor_id()) - continue; - beatic_cause_IPI(i, msg); - } - } -} - -static int __init smp_beatic_probe(void) -{ - return cpus_weight(cpu_possible_map); -} - -static void __devinit smp_beatic_setup_cpu(int cpu) -{ - beatic_setup_cpu(cpu); -} - -static void __devinit smp_celleb_kick_cpu(int nr) -{ - BUG_ON(nr < 0 || nr >= NR_CPUS); - - if (!smp_startup_cpu(nr)) - return; -} - -static int smp_celleb_cpu_bootable(unsigned int nr) -{ - return 1; -} -static struct smp_ops_t bpa_beatic_smp_ops = { - .message_pass = smp_beatic_message_pass, - .probe = smp_beatic_probe, - .kick_cpu = smp_celleb_kick_cpu, - .setup_cpu = smp_beatic_setup_cpu, - .cpu_bootable = smp_celleb_cpu_bootable, -}; - -/* This is called very early */ -void __init smp_init_celleb(void) -{ - DBG(" -> smp_init_celleb()\n"); - - smp_ops = &bpa_beatic_smp_ops; - - DBG(" <- smp_init_celleb()\n"); -} diff --git a/trunk/arch/powerpc/platforms/celleb/spu_priv1.c b/trunk/arch/powerpc/platforms/celleb/spu_priv1.c deleted file mode 100644 index 2bf6700f747a..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/spu_priv1.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * spu hypervisor abstraction for Beat - * - * (C) Copyright 2006-2007 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#include -#include -#include - -#include "beat_wrapper.h" - -static inline void _int_mask_set(struct spu *spu, int class, u64 mask) -{ - spu->shadow_int_mask_RW[class] = mask; - beat_set_irq_mask_for_spe(spu->spe_id, class, mask); -} - -static inline u64 _int_mask_get(struct spu *spu, int class) -{ - return spu->shadow_int_mask_RW[class]; -} - -static void int_mask_set(struct spu *spu, int class, u64 mask) -{ - _int_mask_set(spu, class, mask); -} - -static u64 int_mask_get(struct spu *spu, int class) -{ - return _int_mask_get(spu, class); -} - -static void int_mask_and(struct spu *spu, int class, u64 mask) -{ - u64 old_mask; - old_mask = _int_mask_get(spu, class); - _int_mask_set(spu, class, old_mask & mask); -} - -static void int_mask_or(struct spu *spu, int class, u64 mask) -{ - u64 old_mask; - old_mask = _int_mask_get(spu, class); - _int_mask_set(spu, class, old_mask | mask); -} - -static void int_stat_clear(struct spu *spu, int class, u64 stat) -{ - beat_clear_interrupt_status_of_spe(spu->spe_id, class, stat); -} - -static u64 int_stat_get(struct spu *spu, int class) -{ - u64 int_stat; - beat_get_interrupt_status_of_spe(spu->spe_id, class, &int_stat); - return int_stat; -} - -static void cpu_affinity_set(struct spu *spu, int cpu) -{ - return; -} - -static u64 mfc_dar_get(struct spu *spu) -{ - u64 dar; - beat_get_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, mfc_dar_RW), &dar); - return dar; -} - -static u64 mfc_dsisr_get(struct spu *spu) -{ - u64 dsisr; - beat_get_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, mfc_dsisr_RW), &dsisr); - return dsisr; -} - -static void mfc_dsisr_set(struct spu *spu, u64 dsisr) -{ - beat_set_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, mfc_dsisr_RW), dsisr); -} - -static void mfc_sdr_setup(struct spu *spu) -{ - return; -} - -static void mfc_sr1_set(struct spu *spu, u64 sr1) -{ - beat_set_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, mfc_sr1_RW), sr1); -} - -static u64 mfc_sr1_get(struct spu *spu) -{ - u64 sr1; - beat_get_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, mfc_sr1_RW), &sr1); - return sr1; -} - -static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id) -{ - beat_set_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, mfc_tclass_id_RW), tclass_id); -} - -static u64 mfc_tclass_id_get(struct spu *spu) -{ - u64 tclass_id; - beat_get_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, mfc_tclass_id_RW), &tclass_id); - return tclass_id; -} - -static void tlb_invalidate(struct spu *spu) -{ - beat_set_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, tlb_invalidate_entry_W), 0ul); -} - -static void resource_allocation_groupID_set(struct spu *spu, u64 id) -{ - beat_set_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, resource_allocation_groupID_RW), - id); -} - -static u64 resource_allocation_groupID_get(struct spu *spu) -{ - u64 id; - beat_get_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, resource_allocation_groupID_RW), - &id); - return id; -} - -static void resource_allocation_enable_set(struct spu *spu, u64 enable) -{ - beat_set_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, resource_allocation_enable_RW), - enable); -} - -static u64 resource_allocation_enable_get(struct spu *spu) -{ - u64 enable; - beat_get_spe_privileged_state_1_registers( - spu->spe_id, - offsetof(struct spu_priv1, resource_allocation_enable_RW), - &enable); - return enable; -} - -const struct spu_priv1_ops spu_priv1_beat_ops = -{ - .int_mask_and = int_mask_and, - .int_mask_or = int_mask_or, - .int_mask_set = int_mask_set, - .int_mask_get = int_mask_get, - .int_stat_clear = int_stat_clear, - .int_stat_get = int_stat_get, - .cpu_affinity_set = cpu_affinity_set, - .mfc_dar_get = mfc_dar_get, - .mfc_dsisr_get = mfc_dsisr_get, - .mfc_dsisr_set = mfc_dsisr_set, - .mfc_sdr_setup = mfc_sdr_setup, - .mfc_sr1_set = mfc_sr1_set, - .mfc_sr1_get = mfc_sr1_get, - .mfc_tclass_id_set = mfc_tclass_id_set, - .mfc_tclass_id_get = mfc_tclass_id_get, - .tlb_invalidate = tlb_invalidate, - .resource_allocation_groupID_set = resource_allocation_groupID_set, - .resource_allocation_groupID_get = resource_allocation_groupID_get, - .resource_allocation_enable_set = resource_allocation_enable_set, - .resource_allocation_enable_get = resource_allocation_enable_get, -}; diff --git a/trunk/arch/powerpc/platforms/celleb/udbg_beat.c b/trunk/arch/powerpc/platforms/celleb/udbg_beat.c deleted file mode 100644 index d888c4674c62..000000000000 --- a/trunk/arch/powerpc/platforms/celleb/udbg_beat.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * udbg function for Beat - * - * (C) Copyright 2006 TOSHIBA CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include - -#include -#include -#include - -#include "beat.h" - -#define celleb_vtermno 0 - -static void udbg_putc_beat(char c) -{ - unsigned long rc; - - if (c == '\n') - udbg_putc_beat('\r'); - - rc = beat_put_term_char(celleb_vtermno, 1, (uint64_t)c << 56, 0); -} - -/* Buffered chars getc */ -static long inbuflen; -static long inbuf[2]; /* must be 2 longs */ - -static int udbg_getc_poll_beat(void) -{ - /* The interface is tricky because it may return up to 16 chars. - * We save them statically for future calls to udbg_getc(). - */ - char ch, *buf = (char *)inbuf; - int i; - long rc; - if (inbuflen == 0) { - /* get some more chars. */ - inbuflen = 0; - rc = beat_get_term_char(celleb_vtermno, &inbuflen, inbuf+0, inbuf+1); - if (rc != 0) - inbuflen = 0; /* otherwise inbuflen is garbage */ - } - if (inbuflen <= 0 || inbuflen > 16) { - /* Catch error case as well as other oddities (corruption) */ - inbuflen = 0; - return -1; - } - ch = buf[0]; - for (i = 1; i < inbuflen; i++) /* shuffle them down. */ - buf[i-1] = buf[i]; - inbuflen--; - return ch; -} - -static int udbg_getc_beat(void) -{ - int ch; - for (;;) { - ch = udbg_getc_poll_beat(); - if (ch == -1) { - /* This shouldn't be needed...but... */ - volatile unsigned long delay; - for (delay=0; delay < 2000000; delay++) - ; - } else { - return ch; - } - } -} - -/* call this from early_init() for a working debug console on - * vterm capable LPAR machines - */ -void __init udbg_init_debug_beat(void) -{ - udbg_putc = udbg_putc_beat; - udbg_getc = udbg_getc_beat; - udbg_getc_poll = udbg_getc_poll_beat; -} diff --git a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig index 886c522d78e9..b3c2ce4cb7a8 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig @@ -104,6 +104,15 @@ config RADSTONE_PPC7D config PAL4 bool "SBS-Palomar4" +config GEMINI + bool "Synergy-Gemini" + select PPC_INDIRECT_PCI + depends on BROKEN + help + Select Gemini if configuring for a Synergy Microsystems' Gemini + series Single Board Computer. More information is available at: + . + config EST8260 bool "EST8260" ---help--- diff --git a/trunk/arch/powerpc/platforms/maple/pci.c b/trunk/arch/powerpc/platforms/maple/pci.c index 73c59904697f..3f6a69f67195 100644 --- a/trunk/arch/powerpc/platforms/maple/pci.c +++ b/trunk/arch/powerpc/platforms/maple/pci.c @@ -425,6 +425,14 @@ static void __init setup_u4_pcie(struct pci_controller* hose) hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); + /* The bus contains a bridge from root -> device, we need to + * make it visible on bus 0 so that we pick the right type + * of config cycles. If we didn't, we would have to force all + * config cycles to be type 1. So we override the "bus-range" + * property here + */ + hose->first_busno = 0x00; + hose->last_busno = 0xff; u4_pcie = hose; } @@ -552,16 +560,13 @@ void __init maple_pci_init(void) return; } for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { - if (!np->type) - continue; - if (strcmp(np->type, "pci") && strcmp(np->type, "ht")) + if (np->name == NULL) continue; - if ((device_is_compatible(np, "u4-pcie") || - device_is_compatible(np, "u3-agp")) && - add_bridge(np) == 0) - of_node_get(np); - - if (device_is_compatible(np, "u3-ht")) { + if (!strcmp(np->name, "pci") || !strcmp(np->name, "pcie")) { + if (add_bridge(np) == 0) + of_node_get(np); + } + if (strcmp(np->name, "ht") == 0) { of_node_get(np); ht = np; } diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c index 82d3f9e28d7c..50855d4fd5a0 100644 --- a/trunk/arch/powerpc/platforms/maple/setup.c +++ b/trunk/arch/powerpc/platforms/maple/setup.c @@ -62,7 +62,6 @@ #include #include #include -#include #include "maple.h" @@ -196,8 +195,6 @@ void __init maple_setup_arch(void) maple_use_rtas_reboot_and_halt_if_present(); printk(KERN_DEBUG "Using native/NAP idle loop\n"); - - mmio_nvram_init(); } /* diff --git a/trunk/arch/powerpc/platforms/pasemi/Kconfig b/trunk/arch/powerpc/platforms/pasemi/Kconfig deleted file mode 100644 index 68dc529dfd2f..000000000000 --- a/trunk/arch/powerpc/platforms/pasemi/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -menu "PA Semi PWRficient options" - depends on PPC_PASEMI - -config PPC_PASEMI_IOMMU - bool "PA Semi IOMMU support" - depends on PPC_PASEMI - help - IOMMU support for PA6T-1682M - -endmenu diff --git a/trunk/arch/powerpc/platforms/pasemi/Makefile b/trunk/arch/powerpc/platforms/pasemi/Makefile index e657ccae90a9..1be1a993c5f5 100644 --- a/trunk/arch/powerpc/platforms/pasemi/Makefile +++ b/trunk/arch/powerpc/platforms/pasemi/Makefile @@ -1,2 +1 @@ -obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o - +obj-y += setup.o pci.o time.o diff --git a/trunk/arch/powerpc/platforms/pasemi/idle.c b/trunk/arch/powerpc/platforms/pasemi/idle.c deleted file mode 100644 index 1ca3ff381591..000000000000 --- a/trunk/arch/powerpc/platforms/pasemi/idle.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2006-2007 PA Semi, Inc - * - * Maintained by: Olof Johansson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#undef DEBUG - -#include -#include - -#include -#include - -#include "pasemi.h" - -struct sleep_mode { - char *name; - void (*entry)(void); -}; - -static struct sleep_mode modes[] = { - { .name = "spin", .entry = &idle_spin }, - { .name = "doze", .entry = &idle_doze }, -}; - -static int current_mode = 0; - -static int pasemi_system_reset_exception(struct pt_regs *regs) -{ - /* If we were woken up from power savings, we need to return - * to the calling function, since nip is not saved across - * all modes. - */ - - if (regs->msr & SRR1_WAKEMASK) - regs->nip = regs->link; - - switch (regs->msr & SRR1_WAKEMASK) { - case SRR1_WAKEEE: - do_IRQ(regs); - break; - case SRR1_WAKEDEC: - timer_interrupt(regs); - break; - default: - /* do system reset */ - return 0; - } - /* everything handled */ - regs->msr |= MSR_RI; - return 1; -} - -void __init pasemi_idle_init(void) -{ - ppc_md.system_reset_exception = pasemi_system_reset_exception; - ppc_md.power_save = modes[current_mode].entry; - printk(KERN_INFO "Using PA6T idle loop (%s)\n", modes[current_mode].name); -} - -static int __init idle_param(char *p) -{ - int i; - for (i = 0; i < sizeof(modes)/sizeof(struct sleep_mode); i++) { - if (!strcmp(modes[i].name, p)) { - current_mode = i; - break; - } - } - return 0; -} - -early_param("idle", idle_param); diff --git a/trunk/arch/powerpc/platforms/pasemi/iommu.c b/trunk/arch/powerpc/platforms/pasemi/iommu.c deleted file mode 100644 index 459a53b7d24d..000000000000 --- a/trunk/arch/powerpc/platforms/pasemi/iommu.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) 2005-2007, PA Semi, Inc - * - * Maintained by: Olof Johansson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include - - -#define IOBMAP_PAGE_SHIFT 12 -#define IOBMAP_PAGE_SIZE (1 << IOBMAP_PAGE_SHIFT) -#define IOBMAP_PAGE_MASK (IOBMAP_PAGE_SIZE - 1) - -#define IOBMAP_PAGE_FACTOR (PAGE_SHIFT - IOBMAP_PAGE_SHIFT) - -#define IOB_BASE 0xe0000000 -#define IOB_SIZE 0x3000 -/* Configuration registers */ -#define IOBCAP_REG 0x10 -#define IOBCOM_REG 0x40 -/* Enable IOB address translation */ -#define IOBCOM_ATEN 0x00000100 - -/* Address decode configuration register */ -#define IOB_AD_REG 0x53 -/* IOBCOM_AD_REG fields */ -#define IOB_AD_VGPRT 0x00000e00 -#define IOB_AD_VGAEN 0x00000100 -/* Direct mapping settings */ -#define IOB_AD_MPSEL_MASK 0x00000030 -#define IOB_AD_MPSEL_B38 0x00000000 -#define IOB_AD_MPSEL_B40 0x00000010 -#define IOB_AD_MPSEL_B42 0x00000020 -/* Translation window size / enable */ -#define IOB_AD_TRNG_MASK 0x00000003 -#define IOB_AD_TRNG_256M 0x00000000 -#define IOB_AD_TRNG_2G 0x00000001 -#define IOB_AD_TRNG_128G 0x00000003 - -#define IOB_TABLEBASE_REG 0x55 - -/* Base of the 64 4-byte L1 registers */ -#define IOB_XLT_L1_REGBASE 0xac0 - -/* Register to invalidate TLB entries */ -#define IOB_AT_INVAL_TLB_REG 0xb40 - -/* The top two bits of the level 1 entry contains valid and type flags */ -#define IOBMAP_L1E_V 0x40000000 -#define IOBMAP_L1E_V_B 0x80000000 - -/* For big page entries, the bottom two bits contains flags */ -#define IOBMAP_L1E_BIG_CACHED 0x00000002 -#define IOBMAP_L1E_BIG_PRIORITY 0x00000001 - -/* For regular level 2 entries, top 2 bits contain valid and cache flags */ -#define IOBMAP_L2E_V 0x80000000 -#define IOBMAP_L2E_V_CACHED 0xc0000000 - -static u32 *iob; -static u32 iob_l1_emptyval; -static u32 iob_l2_emptyval; -static u32 *iob_l2_base; - -static struct iommu_table iommu_table_iobmap; -static int iommu_table_iobmap_inited; - -static void iobmap_build(struct iommu_table *tbl, long index, - long npages, unsigned long uaddr, - enum dma_data_direction direction) -{ - u32 *ip; - u32 rpn; - unsigned long bus_addr; - - pr_debug("iobmap: build at: %lx, %lx, addr: %lx\n", index, npages, uaddr); - - bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; - - npages <<= IOBMAP_PAGE_FACTOR; - index <<= IOBMAP_PAGE_FACTOR; - - ip = ((u32 *)tbl->it_base) + index; - - while (npages--) { - rpn = virt_to_abs(uaddr) >> IOBMAP_PAGE_SHIFT; - - *(ip++) = IOBMAP_L2E_V | rpn; - /* invalidate tlb, can be optimized more */ - out_le32(iob+IOB_AT_INVAL_TLB_REG, bus_addr >> 14); - - uaddr += IOBMAP_PAGE_SIZE; - bus_addr += IOBMAP_PAGE_SIZE; - } -} - - -static void iobmap_free(struct iommu_table *tbl, long index, - long npages) -{ - u32 *ip; - unsigned long bus_addr; - - pr_debug("iobmap: free at: %lx, %lx\n", index, npages); - - bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; - - npages <<= IOBMAP_PAGE_FACTOR; - index <<= IOBMAP_PAGE_FACTOR; - - ip = ((u32 *)tbl->it_base) + index; - - while (npages--) { - *(ip++) = iob_l2_emptyval; - /* invalidate tlb, can be optimized more */ - out_le32(iob+IOB_AT_INVAL_TLB_REG, bus_addr >> 14); - bus_addr += IOBMAP_PAGE_SIZE; - } -} - - -static void iommu_table_iobmap_setup(void) -{ - pr_debug(" -> %s\n", __func__); - iommu_table_iobmap.it_busno = 0; - iommu_table_iobmap.it_offset = 0; - /* it_size is in number of entries */ - iommu_table_iobmap.it_size = 0x80000000 >> PAGE_SHIFT; - - /* Initialize the common IOMMU code */ - iommu_table_iobmap.it_base = (unsigned long)iob_l2_base; - iommu_table_iobmap.it_index = 0; - /* XXXOJN tune this to avoid IOB cache invals. - * Should probably be 8 (64 bytes) - */ - iommu_table_iobmap.it_blocksize = 4; - iommu_init_table(&iommu_table_iobmap, 0); - pr_debug(" <- %s\n", __func__); -} - - - -static void pci_dma_bus_setup_pasemi(struct pci_bus *bus) -{ - struct device_node *dn; - - pr_debug("pci_dma_bus_setup, bus %p, bus->self %p\n", bus, bus->self); - - if (!iommu_table_iobmap_inited) { - iommu_table_iobmap_inited = 1; - iommu_table_iobmap_setup(); - } - - dn = pci_bus_to_OF_node(bus); - - if (dn) - PCI_DN(dn)->iommu_table = &iommu_table_iobmap; - -} - - -static void pci_dma_dev_setup_pasemi(struct pci_dev *dev) -{ - pr_debug("pci_dma_dev_setup, dev %p (%s)\n", dev, pci_name(dev)); - - /* DMA device is untranslated, but all other PCI-e goes through - * the IOMMU - */ - if (dev->vendor == 0x1959 && dev->device == 0xa007) - dev->dev.archdata.dma_ops = &dma_direct_ops; - else - dev->dev.archdata.dma_data = &iommu_table_iobmap; -} - -static void pci_dma_bus_setup_null(struct pci_bus *b) { } -static void pci_dma_dev_setup_null(struct pci_dev *d) { } - -int iob_init(struct device_node *dn) -{ - unsigned long tmp; - u32 regword; - int i; - - pr_debug(" -> %s\n", __func__); - - /* Allocate a spare page to map all invalid IOTLB pages. */ - tmp = lmb_alloc(IOBMAP_PAGE_SIZE, IOBMAP_PAGE_SIZE); - if (!tmp) - panic("IOBMAP: Cannot allocate spare page!"); - /* Empty l1 is marked invalid */ - iob_l1_emptyval = 0; - /* Empty l2 is mapped to dummy page */ - iob_l2_emptyval = IOBMAP_L2E_V | (tmp >> IOBMAP_PAGE_SHIFT); - - iob = ioremap(IOB_BASE, IOB_SIZE); - if (!iob) - panic("IOBMAP: Cannot map registers!"); - - /* setup direct mapping of the L1 entries */ - for (i = 0; i < 64; i++) { - /* Each L1 covers 32MB, i.e. 8K entries = 32K of ram */ - regword = IOBMAP_L1E_V | (__pa(iob_l2_base + i*0x2000) >> 12); - out_le32(iob+IOB_XLT_L1_REGBASE+i, regword); - } - - /* set 2GB translation window, based at 0 */ - regword = in_le32(iob+IOB_AD_REG); - regword &= ~IOB_AD_TRNG_MASK; - regword |= IOB_AD_TRNG_2G; - out_le32(iob+IOB_AD_REG, regword); - - /* Enable translation */ - regword = in_le32(iob+IOBCOM_REG); - regword |= IOBCOM_ATEN; - out_le32(iob+IOBCOM_REG, regword); - - pr_debug(" <- %s\n", __func__); - - return 0; -} - - -/* These are called very early. */ -void iommu_init_early_pasemi(void) -{ - int iommu_off; - -#ifndef CONFIG_PPC_PASEMI_IOMMU - iommu_off = 1; -#else - iommu_off = of_chosen && - get_property(of_chosen, "linux,iommu-off", NULL); -#endif - if (iommu_off) { - /* Direct I/O, IOMMU off */ - ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_null; - ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_null; - pci_dma_ops = &dma_direct_ops; - - return; - } - - iob_init(NULL); - - ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pasemi; - ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pasemi; - ppc_md.tce_build = iobmap_build; - ppc_md.tce_free = iobmap_free; - pci_dma_ops = &dma_iommu_ops; -} - -void __init alloc_iobmap_l2(void) -{ -#ifndef CONFIG_PPC_PASEMI_IOMMU - return; -#endif - /* For 2G space, 8x64 pages (2^21 bytes) is max total l2 size */ - iob_l2_base = (u32 *)abs_to_virt(lmb_alloc_base(1UL<<21, 1UL<<21, 0x80000000)); - - printk(KERN_INFO "IOBMAP L2 allocated at: %p\n", iob_l2_base); -} diff --git a/trunk/arch/powerpc/platforms/pasemi/pasemi.h b/trunk/arch/powerpc/platforms/pasemi/pasemi.h index 2d3927e6edb0..51c2a2397ecf 100644 --- a/trunk/arch/powerpc/platforms/pasemi/pasemi.h +++ b/trunk/arch/powerpc/platforms/pasemi/pasemi.h @@ -3,17 +3,5 @@ extern unsigned long pas_get_boot_time(void); extern void pas_pci_init(void); -extern void __devinit pas_pci_irq_fixup(struct pci_dev *dev); -extern void __devinit pas_pci_dma_dev_setup(struct pci_dev *dev); - -extern void __init alloc_iobmap_l2(void); - -extern void __init pasemi_idle_init(void); - -/* Power savings modes, implemented in asm */ -extern void idle_spin(void); -extern void idle_doze(void); - - #endif /* _PASEMI_PASEMI_H */ diff --git a/trunk/arch/powerpc/platforms/pasemi/pci.c b/trunk/arch/powerpc/platforms/pasemi/pci.c index 7ecb2ba24db9..faa618e04047 100644 --- a/trunk/arch/powerpc/platforms/pasemi/pci.c +++ b/trunk/arch/powerpc/platforms/pasemi/pci.c @@ -163,19 +163,6 @@ static void __init pas_fixup_phb_resources(void) } -void __devinit pas_pci_irq_fixup(struct pci_dev *dev) -{ - /* DMA is special, 84 interrupts (128 -> 211), all but 128 - * need to be mapped by hand here. - */ - if (dev->vendor == 0x1959 && dev->device == 0xa007) { - int i; - for (i = 129; i < 212; i++) - irq_create_mapping(NULL, i); - } -} - - void __init pas_pci_init(void) { struct device_node *np, *root; diff --git a/trunk/arch/powerpc/platforms/pasemi/powersave.S b/trunk/arch/powerpc/platforms/pasemi/powersave.S deleted file mode 100644 index 6d0fba6aab17..000000000000 --- a/trunk/arch/powerpc/platforms/pasemi/powersave.S +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2006-2007 PA Semi, Inc - * - * Maintained by: Olof Johansson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include - -/* Power savings opcodes since not all binutils have them at this time */ -#define DOZE .long 0x4c000324 -#define NAP .long 0x4c000364 -#define SLEEP .long 0x4c0003a4 -#define RVW .long 0x4c0003e4 - -/* Common sequence to do before going to any of the - * powersavings modes. - */ - -#define PRE_SLEEP_SEQUENCE \ - std r3,8(r1); \ - ptesync ; \ - ld r3,8(r1); \ -1: cmpd r3,r3; \ - bne 1b - -_doze: - PRE_SLEEP_SEQUENCE - DOZE - b . - - -_GLOBAL(idle_spin) - blr - -_GLOBAL(idle_doze) - LOAD_REG_ADDR(r3, _doze) - b sleep_common - -/* Add more modes here later */ - -sleep_common: - mflr r0 - std r0, 16(r1) - stdu r1,-64(r1) - - LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE) - mfmsr r4 - andc r5,r4,r6 - mtmsrd r5,0 - - mtctr r3 - bctrl - - mtmsrd r4,0 - - addi r1,r1,64 - ld r0,16(r1) - mtlr r0 - blr - diff --git a/trunk/arch/powerpc/platforms/pasemi/setup.c b/trunk/arch/powerpc/platforms/pasemi/setup.c index 449cf1a08291..bea7d1bb1a3b 100644 --- a/trunk/arch/powerpc/platforms/pasemi/setup.c +++ b/trunk/arch/powerpc/platforms/pasemi/setup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2007 PA Semi, Inc + * Copyright (C) 2006 PA Semi, Inc * * Authors: Kip Walker, PA Semi * Olof Johansson, PA Semi @@ -38,46 +38,31 @@ #include "pasemi.h" -static void __iomem *reset_reg; - static void pas_restart(char *cmd) { - printk("Restarting...\n"); - while (1) - out_le32(reset_reg, 0x6000000); + printk("restart unimplemented, looping...\n"); + for (;;) ; } -#ifdef CONFIG_SMP -static DEFINE_SPINLOCK(timebase_lock); - -static void __devinit pas_give_timebase(void) +static void pas_power_off(void) { - unsigned long tb; - - spin_lock(&timebase_lock); - mtspr(SPRN_TBCTL, TBCTL_FREEZE); - tb = mftb(); - mtspr(SPRN_TBCTL, TBCTL_UPDATE_LOWER | (tb & 0xffffffff)); - mtspr(SPRN_TBCTL, TBCTL_UPDATE_UPPER | (tb >> 32)); - mtspr(SPRN_TBCTL, TBCTL_RESTART); - spin_unlock(&timebase_lock); - pr_debug("pas_give_timebase: cpu %d gave tb %lx\n", - smp_processor_id(), tb); + printk("power off unimplemented, looping...\n"); + for (;;) ; } -static void __devinit pas_take_timebase(void) +static void pas_halt(void) { - pr_debug("pas_take_timebase: cpu %d has tb %lx\n", - smp_processor_id(), mftb()); + pas_power_off(); } +#ifdef CONFIG_SMP struct smp_ops_t pas_smp_ops = { .probe = smp_mpic_probe, .message_pass = smp_mpic_message_pass, .kick_cpu = smp_generic_kick_cpu, .setup_cpu = smp_mpic_setup_cpu, - .give_timebase = pas_give_timebase, - .take_timebase = pas_take_timebase, + .give_timebase = smp_generic_give_timebase, + .take_timebase = smp_generic_take_timebase, }; #endif /* CONFIG_SMP */ @@ -87,6 +72,9 @@ void __init pas_setup_arch(void) /* Setup SMP callback */ smp_ops = &pas_smp_ops; #endif + /* no iommu yet */ + pci_dma_ops = &dma_direct_ops; + /* Lookup PCI hosts */ pas_pci_init(); @@ -94,11 +82,7 @@ void __init pas_setup_arch(void) conswitchp = &dummy_con; #endif - /* Remap SDC register for doing reset */ - /* XXXOJN This should maybe come out of the device tree */ - reset_reg = ioremap(0xfc101100, 4); - - pasemi_idle_init(); + printk(KERN_DEBUG "Using default idle loop\n"); } /* No legacy IO on our parts */ @@ -146,9 +130,8 @@ static __init void pas_init_IRQ(void) openpic_addr = of_read_number(opprop, naddr); printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); - mpic = mpic_alloc(mpic_node, openpic_addr, - MPIC_PRIMARY|MPIC_LARGE_VECTORS, - 0, 0, " PAS-OPIC "); + mpic = mpic_alloc(mpic_node, openpic_addr, MPIC_PRIMARY, 0, 0, + " PAS-OPIC "); BUG_ON(!mpic); mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); @@ -163,53 +146,6 @@ static void __init pas_progress(char *s, unsigned short hex) } -static int pas_machine_check_handler(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - unsigned long srr0, srr1, dsisr; - - srr0 = regs->nip; - srr1 = regs->msr; - dsisr = mfspr(SPRN_DSISR); - printk(KERN_ERR "Machine Check on CPU %d\n", cpu); - printk(KERN_ERR "SRR0 0x%016lx SRR1 0x%016lx\n", srr0, srr1); - printk(KERN_ERR "DSISR 0x%016lx DAR 0x%016lx\n", dsisr, regs->dar); - printk(KERN_ERR "Cause:\n"); - - if (srr1 & 0x200000) - printk(KERN_ERR "Signalled by SDC\n"); - if (srr1 & 0x100000) { - printk(KERN_ERR "Load/Store detected error:\n"); - if (dsisr & 0x8000) - printk(KERN_ERR "D-cache ECC double-bit error or bus error\n"); - if (dsisr & 0x4000) - printk(KERN_ERR "LSU snoop response error\n"); - if (dsisr & 0x2000) - printk(KERN_ERR "MMU SLB multi-hit or invalid B field\n"); - if (dsisr & 0x1000) - printk(KERN_ERR "Recoverable Duptags\n"); - if (dsisr & 0x800) - printk(KERN_ERR "Recoverable D-cache parity error count overflow\n"); - if (dsisr & 0x400) - printk(KERN_ERR "TLB parity error count overflow\n"); - } - if (srr1 & 0x80000) - printk(KERN_ERR "Bus Error\n"); - if (srr1 & 0x40000) - printk(KERN_ERR "I-side SLB multiple hit\n"); - if (srr1 & 0x20000) - printk(KERN_ERR "I-cache parity error hit\n"); - - /* SRR1[62] is from MSR[62] if recoverable, so pass that back */ - return !!(srr1 & 0x2); -} - -static void __init pas_init_early(void) -{ - iommu_init_early_pasemi(); -} - - /* * Called very early, MMU is off, device-tree isn't unflattened */ @@ -222,8 +158,6 @@ static int __init pas_probe(void) hpte_init_native(); - alloc_iobmap_l2(); - return 1; } @@ -231,14 +165,13 @@ define_machine(pas) { .name = "PA Semi PA6T-1682M", .probe = pas_probe, .setup_arch = pas_setup_arch, - .init_early = pas_init_early, .init_IRQ = pas_init_IRQ, .get_irq = mpic_get_irq, .restart = pas_restart, + .power_off = pas_power_off, + .halt = pas_halt, .get_boot_time = pas_get_boot_time, .calibrate_decr = generic_calibrate_decr, .check_legacy_ioport = pas_check_legacy_ioport, .progress = pas_progress, - .machine_check_exception = pas_machine_check_handler, - .pci_irq_fixup = pas_pci_irq_fixup, }; diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index d73fb73802bb..eeb2ae5ffc58 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -795,6 +795,7 @@ static void __devinit smp_core99_kick_cpu(int nr) ppc_md.progress("smp_core99_kick_cpu", 0x346); local_irq_save(flags); + local_irq_disable(); /* Save reset vector */ save_vector = *vector; diff --git a/trunk/arch/powerpc/platforms/ps3/Makefile b/trunk/arch/powerpc/platforms/ps3/Makefile index a0048fcf0866..1994904f580f 100644 --- a/trunk/arch/powerpc/platforms/ps3/Makefile +++ b/trunk/arch/powerpc/platforms/ps3/Makefile @@ -1,6 +1,5 @@ obj-y += setup.o mm.o time.o hvcall.o htab.o repository.o obj-y += interrupt.o exports.o os-area.o -obj-y += system-bus.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SPU_BASE) += spu.o diff --git a/trunk/arch/powerpc/platforms/ps3/htab.c b/trunk/arch/powerpc/platforms/ps3/htab.c index a4b5a1bc60f4..8fe1769655a3 100644 --- a/trunk/arch/powerpc/platforms/ps3/htab.c +++ b/trunk/arch/powerpc/platforms/ps3/htab.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "platform.h" diff --git a/trunk/arch/powerpc/platforms/ps3/interrupt.c b/trunk/arch/powerpc/platforms/ps3/interrupt.c index bb17283275aa..6f5de438b980 100644 --- a/trunk/arch/powerpc/platforms/ps3/interrupt.c +++ b/trunk/arch/powerpc/platforms/ps3/interrupt.c @@ -24,6 +24,7 @@ #include #include +#include #include #include "platform.h" @@ -34,149 +35,16 @@ #define DBG(fmt...) do{if(0)printk(fmt);}while(0) #endif -/** - * struct ps3_bmp - a per cpu irq status and mask bitmap structure - * @status: 256 bit status bitmap indexed by plug - * @unused_1: - * @mask: 256 bit mask bitmap indexed by plug - * @unused_2: - * @lock: - * @ipi_debug_brk_mask: - * - * The HV mantains per SMT thread mappings of HV outlet to HV plug on - * behalf of the guest. These mappings are implemented as 256 bit guest - * supplied bitmaps indexed by plug number. The addresses of the bitmaps - * are registered with the HV through lv1_configure_irq_state_bitmap(). - * The HV requires that the 512 bits of status + mask not cross a page - * boundary. PS3_BMP_MINALIGN is used to define this minimal 64 byte - * alignment. - * - * The HV supports 256 plugs per thread, assigned as {0..255}, for a total - * of 512 plugs supported on a processor. To simplify the logic this - * implementation equates HV plug value to Linux virq value, constrains each - * interrupt to have a system wide unique plug number, and limits the range - * of the plug values to map into the first dword of the bitmaps. This - * gives a usable range of plug values of {NUM_ISA_INTERRUPTS..63}. Note - * that there is no constraint on how many in this set an individual thread - * can acquire. - */ - -#define PS3_BMP_MINALIGN 64 - -struct ps3_bmp { - struct { - u64 status; - u64 unused_1[3]; - u64 mask; - u64 unused_2[3]; - }; - u64 ipi_debug_brk_mask; - spinlock_t lock; -}; - -/** - * struct ps3_private - a per cpu data structure - * @bmp: ps3_bmp structure - * @node: HV logical_ppe_id - * @cpu: HV thread_id - */ - -struct ps3_private { - struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); - u64 node; - unsigned int cpu; -}; - -static DEFINE_PER_CPU(struct ps3_private, ps3_private); - -int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet, - unsigned int *virq) -{ - int result; - struct ps3_private *pd; - - /* This defines the default interrupt distribution policy. */ - - if (cpu == PS3_BINDING_CPU_ANY) - cpu = 0; - - pd = &per_cpu(ps3_private, cpu); - - *virq = irq_create_mapping(NULL, outlet); - - if (*virq == NO_IRQ) { - pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n", - __func__, __LINE__, outlet); - result = -ENOMEM; - goto fail_create; - } - - /* Binds outlet to cpu + virq. */ - - result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); - - if (result) { - pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", - __func__, __LINE__, ps3_result(result)); - result = -EPERM; - goto fail_connect; - } - - pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, - outlet, cpu, *virq); - - result = set_irq_chip_data(*virq, pd); - - if (result) { - pr_debug("%s:%d: set_irq_chip_data failed\n", - __func__, __LINE__); - goto fail_set; - } - - return result; - -fail_set: - lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq); -fail_connect: - irq_dispose_mapping(*virq); -fail_create: - return result; -} -EXPORT_SYMBOL_GPL(ps3_alloc_irq); - -int ps3_free_irq(unsigned int virq) -{ - int result; - const struct ps3_private *pd = get_irq_chip_data(virq); - - pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, - pd->node, pd->cpu, virq); - - result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); - - if (result) - pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", - __func__, __LINE__, ps3_result(result)); - - set_irq_chip_data(virq, NULL); - irq_dispose_mapping(virq); - return result; -} -EXPORT_SYMBOL_GPL(ps3_free_irq); - /** * ps3_alloc_io_irq - Assign a virq to a system bus device. - * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be - * serviced on. - * @interrupt_id: The device interrupt id read from the system repository. + * interrupt_id: The device interrupt id read from the system repository. * @virq: The assigned Linux virq. * * An io irq represents a non-virtualized device interrupt. interrupt_id * coresponds to the interrupt number of the interrupt controller. */ -int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, - unsigned int *virq) +int ps3_alloc_io_irq(unsigned int interrupt_id, unsigned int *virq) { int result; unsigned long outlet; @@ -189,10 +57,12 @@ int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, return result; } - result = ps3_alloc_irq(cpu, outlet, virq); - BUG_ON(result); + *virq = irq_create_mapping(NULL, outlet); - return result; + pr_debug("%s:%d: interrupt_id %u => outlet %lu, virq %u\n", + __func__, __LINE__, interrupt_id, outlet, *virq); + + return 0; } int ps3_free_io_irq(unsigned int virq) @@ -205,15 +75,13 @@ int ps3_free_io_irq(unsigned int virq) pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", __func__, __LINE__, ps3_result(result)); - ps3_free_irq(virq); + irq_dispose_mapping(virq); return result; } /** * ps3_alloc_event_irq - Allocate a virq for use with a system event. - * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be - * serviced on. * @virq: The assigned Linux virq. * * The virq can be used with lv1_connect_interrupt_event_receive_port() to @@ -221,7 +89,7 @@ int ps3_free_io_irq(unsigned int virq) * events. */ -int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq) +int ps3_alloc_event_irq(unsigned int *virq) { int result; unsigned long outlet; @@ -235,10 +103,12 @@ int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq) return result; } - result = ps3_alloc_irq(cpu, outlet, virq); - BUG_ON(result); + *virq = irq_create_mapping(NULL, outlet); - return result; + pr_debug("%s:%d: outlet %lu, virq %u\n", __func__, __LINE__, outlet, + *virq); + + return 0; } int ps3_free_event_irq(unsigned int virq) @@ -253,7 +123,7 @@ int ps3_free_event_irq(unsigned int virq) pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", __func__, __LINE__, ps3_result(result)); - ps3_free_irq(virq); + irq_dispose_mapping(virq); pr_debug(" <- %s:%d\n", __func__, __LINE__); return result; @@ -266,8 +136,6 @@ int ps3_send_event_locally(unsigned int virq) /** * ps3_connect_event_irq - Assign a virq to a system bus device. - * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be - * serviced on. * @did: The HV device identifier read from the system repository. * @interrupt_id: The device interrupt id read from the system repository. * @virq: The assigned Linux virq. @@ -276,13 +144,12 @@ int ps3_send_event_locally(unsigned int virq) * coresponds to the software interrupt number. */ -int ps3_connect_event_irq(enum ps3_cpu_binding cpu, - const struct ps3_device_id *did, unsigned int interrupt_id, - unsigned int *virq) +int ps3_connect_event_irq(const struct ps3_device_id *did, + unsigned int interrupt_id, unsigned int *virq) { int result; - result = ps3_alloc_event_irq(cpu, virq); + result = ps3_alloc_event_irq(virq); if (result) return result; @@ -329,8 +196,6 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did, /** * ps3_alloc_vuart_irq - Configure the system virtual uart virq. - * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be - * serviced on. * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap. * @virq: The assigned Linux virq. * @@ -338,14 +203,13 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did, * freeing the interrupt will return a wrong state error. */ -int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp, - unsigned int *virq) +int ps3_alloc_vuart_irq(void* virt_addr_bmp, unsigned int *virq) { int result; unsigned long outlet; - u64 lpar_addr; + unsigned long lpar_addr; - BUG_ON(!is_kernel_addr((u64)virt_addr_bmp)); + BUG_ON(!is_kernel_addr((unsigned long)virt_addr_bmp)); lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp)); @@ -357,10 +221,12 @@ int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp, return result; } - result = ps3_alloc_irq(cpu, outlet, virq); - BUG_ON(result); + *virq = irq_create_mapping(NULL, outlet); - return result; + pr_debug("%s:%d: outlet %lu, virq %u\n", __func__, __LINE__, + outlet, *virq); + + return 0; } int ps3_free_vuart_irq(unsigned int virq) @@ -375,23 +241,21 @@ int ps3_free_vuart_irq(unsigned int virq) return result; } - ps3_free_irq(virq); + irq_dispose_mapping(virq); return result; } /** * ps3_alloc_spe_irq - Configure an spe virq. - * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be - * serviced on. * @spe_id: The spe_id returned from lv1_construct_logical_spe(). * @class: The spe interrupt class {0,1,2}. * @virq: The assigned Linux virq. * */ -int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id, - unsigned int class, unsigned int *virq) +int ps3_alloc_spe_irq(unsigned long spe_id, unsigned int class, + unsigned int *virq) { int result; unsigned long outlet; @@ -406,24 +270,73 @@ int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id, return result; } - result = ps3_alloc_irq(cpu, outlet, virq); - BUG_ON(result); + *virq = irq_create_mapping(NULL, outlet); - return result; + pr_debug("%s:%d: spe_id %lu, class %u, outlet %lu, virq %u\n", + __func__, __LINE__, spe_id, class, outlet, *virq); + + return 0; } int ps3_free_spe_irq(unsigned int virq) { - ps3_free_irq(virq); + irq_dispose_mapping(virq); return 0; } - #define PS3_INVALID_OUTLET ((irq_hw_number_t)-1) #define PS3_PLUG_MAX 63 +/** + * struct bmp - a per cpu irq status and mask bitmap structure + * @status: 256 bit status bitmap indexed by plug + * @unused_1: + * @mask: 256 bit mask bitmap indexed by plug + * @unused_2: + * @lock: + * @ipi_debug_brk_mask: + * + * The HV mantains per SMT thread mappings of HV outlet to HV plug on + * behalf of the guest. These mappings are implemented as 256 bit guest + * supplied bitmaps indexed by plug number. The address of the bitmaps are + * registered with the HV through lv1_configure_irq_state_bitmap(). + * + * The HV supports 256 plugs per thread, assigned as {0..255}, for a total + * of 512 plugs supported on a processor. To simplify the logic this + * implementation equates HV plug value to linux virq value, constrains each + * interrupt to have a system wide unique plug number, and limits the range + * of the plug values to map into the first dword of the bitmaps. This + * gives a usable range of plug values of {NUM_ISA_INTERRUPTS..63}. Note + * that there is no constraint on how many in this set an individual thread + * can aquire. + */ + +struct bmp { + struct { + unsigned long status; + unsigned long unused_1[3]; + unsigned long mask; + unsigned long unused_2[3]; + } __attribute__ ((packed)); + spinlock_t lock; + unsigned long ipi_debug_brk_mask; +}; + +/** + * struct private - a per cpu data structure + * @node: HV node id + * @cpu: HV thread id + * @bmp: an HV bmp structure + */ + +struct private { + unsigned long node; + unsigned int cpu; + struct bmp bmp; +}; + #if defined(DEBUG) -static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, +static void _dump_64_bmp(const char *header, const unsigned long *p, unsigned cpu, const char* func, int line) { pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n", @@ -433,14 +346,14 @@ static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, } static void __attribute__ ((unused)) _dump_256_bmp(const char *header, - const u64 *p, unsigned cpu, const char* func, int line) + const unsigned long *p, unsigned cpu, const char* func, int line) { pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", func, line, header, cpu, p[0], p[1], p[2], p[3]); } #define dump_bmp(_x) _dump_bmp(_x, __func__, __LINE__) -static void _dump_bmp(struct ps3_private* pd, const char* func, int line) +static void _dump_bmp(struct private* pd, const char* func, int line) { unsigned long flags; @@ -451,7 +364,7 @@ static void _dump_bmp(struct ps3_private* pd, const char* func, int line) } #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) -static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd, +static void __attribute__ ((unused)) _dump_mask(struct private* pd, const char* func, int line) { unsigned long flags; @@ -461,94 +374,109 @@ static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd, spin_unlock_irqrestore(&pd->bmp.lock, flags); } #else -static void dump_bmp(struct ps3_private* pd) {}; +static void dump_bmp(struct private* pd) {}; #endif /* defined(DEBUG) */ -static void ps3_chip_mask(unsigned int virq) +static void chip_mask(unsigned int virq) { - struct ps3_private *pd = get_irq_chip_data(virq); - u64 bit = 0x8000000000000000UL >> virq; - u64 *p = &pd->bmp.mask; - u64 old; unsigned long flags; + struct private *pd = get_irq_chip_data(virq); pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); - local_irq_save(flags); - asm volatile( - "1: ldarx %0,0,%3\n" - "andc %0,%0,%2\n" - "stdcx. %0,0,%3\n" - "bne- 1b" - : "=&r" (old), "+m" (*p) - : "r" (bit), "r" (p) - : "cc" ); + BUG_ON(virq < NUM_ISA_INTERRUPTS); + BUG_ON(virq > PS3_PLUG_MAX); + + spin_lock_irqsave(&pd->bmp.lock, flags); + pd->bmp.mask &= ~(0x8000000000000000UL >> virq); + spin_unlock_irqrestore(&pd->bmp.lock, flags); lv1_did_update_interrupt_mask(pd->node, pd->cpu); - local_irq_restore(flags); } -static void ps3_chip_unmask(unsigned int virq) +static void chip_unmask(unsigned int virq) { - struct ps3_private *pd = get_irq_chip_data(virq); - u64 bit = 0x8000000000000000UL >> virq; - u64 *p = &pd->bmp.mask; - u64 old; unsigned long flags; + struct private *pd = get_irq_chip_data(virq); pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); - local_irq_save(flags); - asm volatile( - "1: ldarx %0,0,%3\n" - "or %0,%0,%2\n" - "stdcx. %0,0,%3\n" - "bne- 1b" - : "=&r" (old), "+m" (*p) - : "r" (bit), "r" (p) - : "cc" ); + BUG_ON(virq < NUM_ISA_INTERRUPTS); + BUG_ON(virq > PS3_PLUG_MAX); + + spin_lock_irqsave(&pd->bmp.lock, flags); + pd->bmp.mask |= (0x8000000000000000UL >> virq); + spin_unlock_irqrestore(&pd->bmp.lock, flags); lv1_did_update_interrupt_mask(pd->node, pd->cpu); - local_irq_restore(flags); } -static void ps3_chip_eoi(unsigned int virq) +static void chip_eoi(unsigned int virq) { - const struct ps3_private *pd = get_irq_chip_data(virq); - lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq); + lv1_end_of_interrupt(virq); } static struct irq_chip irq_chip = { .typename = "ps3", - .mask = ps3_chip_mask, - .unmask = ps3_chip_unmask, - .eoi = ps3_chip_eoi, + .mask = chip_mask, + .unmask = chip_unmask, + .eoi = chip_eoi, }; -static void ps3_host_unmap(struct irq_host *h, unsigned int virq) +static void host_unmap(struct irq_host *h, unsigned int virq) { - set_irq_chip_data(virq, NULL); + int result; + + pr_debug("%s:%d: virq %d\n", __func__, __LINE__, virq); + + lv1_disconnect_irq_plug(virq); + + result = set_irq_chip_data(virq, NULL); + BUG_ON(result); } -static int ps3_host_map(struct irq_host *h, unsigned int virq, +static DEFINE_PER_CPU(struct private, private); + +static int host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hwirq) { - pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, + int result; + unsigned int cpu; + + pr_debug(" -> %s:%d\n", __func__, __LINE__); + pr_debug("%s:%d: hwirq %lu => virq %u\n", __func__, __LINE__, hwirq, virq); + /* bind this virq to a cpu */ + + preempt_disable(); + cpu = smp_processor_id(); + result = lv1_connect_irq_plug(virq, hwirq); + preempt_enable(); + + if (result) { + pr_info("%s:%d: lv1_connect_irq_plug failed:" + " %s\n", __func__, __LINE__, ps3_result(result)); + return -EPERM; + } + + result = set_irq_chip_data(virq, &per_cpu(private, cpu)); + BUG_ON(result); + set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq); - return 0; + pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; } -static struct irq_host_ops ps3_host_ops = { - .map = ps3_host_map, - .unmap = ps3_host_unmap, +static struct irq_host_ops host_ops = { + .map = host_map, + .unmap = host_unmap, }; void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) { - struct ps3_private *pd = &per_cpu(ps3_private, cpu); + struct private *pd = &per_cpu(private, cpu); pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq; @@ -556,32 +484,57 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) cpu, virq, pd->bmp.ipi_debug_brk_mask); } -unsigned int ps3_get_irq(void) +static int bmp_get_and_clear_status_bit(struct bmp *m) { - struct ps3_private *pd = &__get_cpu_var(ps3_private); - u64 x = (pd->bmp.status & pd->bmp.mask); - unsigned int plug; + unsigned long flags; + unsigned int bit; + unsigned long x; + + spin_lock_irqsave(&m->lock, flags); /* check for ipi break first to stop this cpu ASAP */ - if (x & pd->bmp.ipi_debug_brk_mask) - x &= pd->bmp.ipi_debug_brk_mask; + if (m->status & m->ipi_debug_brk_mask) { + m->status &= ~m->ipi_debug_brk_mask; + spin_unlock_irqrestore(&m->lock, flags); + return __ilog2(m->ipi_debug_brk_mask); + } + + x = (m->status & m->mask); - asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x)); - plug &= 0x3f; + for (bit = NUM_ISA_INTERRUPTS, x <<= bit; x; bit++, x <<= 1) + if (x & 0x8000000000000000UL) { + m->status &= ~(0x8000000000000000UL >> bit); + spin_unlock_irqrestore(&m->lock, flags); + return bit; + } - if (unlikely(plug) == NO_IRQ) { + spin_unlock_irqrestore(&m->lock, flags); + + pr_debug("%s:%d: not found\n", __func__, __LINE__); + return -1; +} + +unsigned int ps3_get_irq(void) +{ + int plug; + + struct private *pd = &__get_cpu_var(private); + + plug = bmp_get_and_clear_status_bit(&pd->bmp); + + if (plug < 1) { pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__, pd->cpu); - dump_bmp(&per_cpu(ps3_private, 0)); - dump_bmp(&per_cpu(ps3_private, 1)); + dump_bmp(&per_cpu(private, 0)); + dump_bmp(&per_cpu(private, 1)); return NO_IRQ; } #if defined(DEBUG) - if (unlikely(plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX)) { - dump_bmp(&per_cpu(ps3_private, 0)); - dump_bmp(&per_cpu(ps3_private, 1)); + if (plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX) { + dump_bmp(&per_cpu(private, 0)); + dump_bmp(&per_cpu(private, 1)); BUG(); } #endif @@ -591,27 +544,26 @@ unsigned int ps3_get_irq(void) void __init ps3_init_IRQ(void) { int result; + unsigned long node; unsigned cpu; struct irq_host *host; - host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops, + lv1_get_logical_ppe_id(&node); + + host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &host_ops, PS3_INVALID_OUTLET); irq_set_default_host(host); irq_set_virq_count(PS3_PLUG_MAX + 1); for_each_possible_cpu(cpu) { - struct ps3_private *pd = &per_cpu(ps3_private, cpu); + struct private *pd = &per_cpu(private, cpu); - lv1_get_logical_ppe_id(&pd->node); - pd->cpu = get_hard_smp_processor_id(cpu); + pd->node = node; + pd->cpu = cpu; spin_lock_init(&pd->bmp.lock); - pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__, - __LINE__, pd->node, pd->cpu, - ps3_mm_phys_to_lpar(__pa(&pd->bmp))); - - result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu, - ps3_mm_phys_to_lpar(__pa(&pd->bmp))); + result = lv1_configure_irq_state_bitmap(node, cpu, + ps3_mm_phys_to_lpar(__pa(&pd->bmp.status))); if (result) pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" diff --git a/trunk/arch/powerpc/platforms/ps3/mm.c b/trunk/arch/powerpc/platforms/ps3/mm.c index 42354de3f557..49c0d010d491 100644 --- a/trunk/arch/powerpc/platforms/ps3/mm.c +++ b/trunk/arch/powerpc/platforms/ps3/mm.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "platform.h" diff --git a/trunk/arch/powerpc/platforms/ps3/os-area.c b/trunk/arch/powerpc/platforms/ps3/os-area.c index 5c3da08bc0c4..58358305dc10 100644 --- a/trunk/arch/powerpc/platforms/ps3/os-area.c +++ b/trunk/arch/powerpc/platforms/ps3/os-area.c @@ -22,6 +22,7 @@ #include #include +#include #include "platform.h" @@ -58,13 +59,20 @@ struct os_area_header { u32 ldr_format; u32 ldr_size; u32 _reserved_2[6]; -}; +} __attribute__ ((packed)); enum { PARAM_BOOT_FLAG_GAME_OS = 0, PARAM_BOOT_FLAG_OTHER_OS = 1, }; +enum { + PARAM_AV_MULTI_OUT_NTSC = 0, + PARAM_AV_MULTI_OUT_PAL_RGB = 1, + PARAM_AV_MULTI_OUT_PAL_YCBCR = 2, + PARAM_AV_MULTI_OUT_SECAM = 3, +}; + enum { PARAM_CTRL_BUTTON_O_IS_YES = 0, PARAM_CTRL_BUTTON_X_IS_YES = 1, @@ -106,7 +114,7 @@ struct os_area_params { u8 dns_primary[4]; u8 dns_secondary[4]; u8 _reserved_5[8]; -}; +} __attribute__ ((packed)); /** * struct saved_params - Static working copies of data from the 'Other OS' area. @@ -249,13 +257,3 @@ u64 ps3_os_area_rtc_diff(void) { return saved_params.rtc_diff ? saved_params.rtc_diff : 946684800UL; } - -/** - * ps3_os_area_get_av_multi_out - Returns the default video mode. - */ - -enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void) -{ - return saved_params.av_multi_out; -} -EXPORT_SYMBOL_GPL(ps3_os_area_get_av_multi_out); diff --git a/trunk/arch/powerpc/platforms/ps3/platform.h b/trunk/arch/powerpc/platforms/ps3/platform.h index ca04f03305c7..23b111bea9d0 100644 --- a/trunk/arch/powerpc/platforms/ps3/platform.h +++ b/trunk/arch/powerpc/platforms/ps3/platform.h @@ -22,9 +22,6 @@ #define _PS3_PLATFORM_H #include -#include - -#include /* htab */ @@ -68,152 +65,4 @@ void ps3_spu_set_platform (void); static inline void ps3_spu_set_platform (void) {} #endif -/* repository bus info */ - -enum ps3_bus_type { - PS3_BUS_TYPE_SB = 4, - PS3_BUS_TYPE_STORAGE = 5, -}; - -enum ps3_dev_type { - PS3_DEV_TYPE_STOR_DISK = TYPE_DISK, /* 0 */ - PS3_DEV_TYPE_SB_GELIC = 3, - PS3_DEV_TYPE_SB_USB = 4, - PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ - PS3_DEV_TYPE_SB_GPIO = 6, - PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ -}; - -int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, - u64 *value); -int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id); -int ps3_repository_read_bus_type(unsigned int bus_index, - enum ps3_bus_type *bus_type); -int ps3_repository_read_bus_num_dev(unsigned int bus_index, - unsigned int *num_dev); - -/* repository bus device info */ - -enum ps3_interrupt_type { - PS3_INTERRUPT_TYPE_EVENT_PORT = 2, - PS3_INTERRUPT_TYPE_SB_OHCI = 3, - PS3_INTERRUPT_TYPE_SB_EHCI = 4, - PS3_INTERRUPT_TYPE_OTHER = 5, -}; - -enum ps3_reg_type { - PS3_REG_TYPE_SB_OHCI = 3, - PS3_REG_TYPE_SB_EHCI = 4, - PS3_REG_TYPE_SB_GPIO = 5, -}; - -int ps3_repository_read_dev_str(unsigned int bus_index, - unsigned int dev_index, const char *dev_str, u64 *value); -int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, - unsigned int *dev_id); -int ps3_repository_read_dev_type(unsigned int bus_index, - unsigned int dev_index, enum ps3_dev_type *dev_type); -int ps3_repository_read_dev_intr(unsigned int bus_index, - unsigned int dev_index, unsigned int intr_index, - enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id); -int ps3_repository_read_dev_reg_type(unsigned int bus_index, - unsigned int dev_index, unsigned int reg_index, - enum ps3_reg_type *reg_type); -int ps3_repository_read_dev_reg_addr(unsigned int bus_index, - unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, - u64 *len); -int ps3_repository_read_dev_reg(unsigned int bus_index, - unsigned int dev_index, unsigned int reg_index, - enum ps3_reg_type *reg_type, u64 *bus_addr, u64 *len); - -/* repository bus enumerators */ - -struct ps3_repository_device { - unsigned int bus_index; - unsigned int dev_index; - struct ps3_device_id did; -}; - -int ps3_repository_find_device(enum ps3_bus_type bus_type, - enum ps3_dev_type dev_type, - const struct ps3_repository_device *start_dev, - struct ps3_repository_device *dev); -static inline int ps3_repository_find_first_device( - enum ps3_bus_type bus_type, enum ps3_dev_type dev_type, - struct ps3_repository_device *dev) -{ - return ps3_repository_find_device(bus_type, dev_type, NULL, dev); -} -int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, - enum ps3_interrupt_type intr_type, unsigned int *interrupt_id); -int ps3_repository_find_reg(const struct ps3_repository_device *dev, - enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len); - -/* repository block device info */ - -int ps3_repository_read_stor_dev_port(unsigned int bus_index, - unsigned int dev_index, u64 *port); -int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index, - unsigned int dev_index, u64 *blk_size); -int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index, - unsigned int dev_index, u64 *num_blocks); -int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, - unsigned int dev_index, unsigned int *num_regions); -int ps3_repository_read_stor_dev_region_id(unsigned int bus_index, - unsigned int dev_index, unsigned int region_index, - unsigned int *region_id); -int ps3_repository_read_stor_dev_region_size(unsigned int bus_index, - unsigned int dev_index, unsigned int region_index, u64 *region_size); -int ps3_repository_read_stor_dev_region_start(unsigned int bus_index, - unsigned int dev_index, unsigned int region_index, u64 *region_start); -int ps3_repository_read_stor_dev_info(unsigned int bus_index, - unsigned int dev_index, u64 *port, u64 *blk_size, - u64 *num_blocks, unsigned int *num_regions); -int ps3_repository_read_stor_dev_region(unsigned int bus_index, - unsigned int dev_index, unsigned int region_index, - unsigned int *region_id, u64 *region_start, u64 *region_size); - -/* repository pu and memory info */ - -int ps3_repository_read_num_pu(unsigned int *num_pu); -int ps3_repository_read_ppe_id(unsigned int *pu_index, unsigned int *ppe_id); -int ps3_repository_read_rm_base(unsigned int ppe_id, u64 *rm_base); -int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size); -int ps3_repository_read_region_total(u64 *region_total); -int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, - u64 *region_total); - -/* repository pme info */ - -int ps3_repository_read_num_be(unsigned int *num_be); -int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id); -int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq); -int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq); - -/* repository 'Other OS' area */ - -int ps3_repository_read_boot_dat_addr(u64 *lpar_addr); -int ps3_repository_read_boot_dat_size(unsigned int *size); -int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size); - -/* repository spu info */ - -/** - * enum spu_resource_type - Type of spu resource. - * @spu_resource_type_shared: Logical spu is shared with other partions. - * @spu_resource_type_exclusive: Logical spu is not shared with other partions. - * - * Returned by ps3_repository_read_spu_resource_id(). - */ - -enum ps3_spu_resource_type { - PS3_SPU_RESOURCE_TYPE_SHARED = 0, - PS3_SPU_RESOURCE_TYPE_EXCLUSIVE = 0x8000000000000000UL, -}; - -int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved); -int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id); -int ps3_repository_read_spu_resource_id(unsigned int res_index, - enum ps3_spu_resource_type* resource_type, unsigned int *resource_id); - #endif diff --git a/trunk/arch/powerpc/platforms/ps3/repository.c b/trunk/arch/powerpc/platforms/ps3/repository.c index ae586a0e5d3f..273a0d621bdd 100644 --- a/trunk/arch/powerpc/platforms/ps3/repository.c +++ b/trunk/arch/powerpc/platforms/ps3/repository.c @@ -18,10 +18,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include -#include "platform.h" - enum ps3_vendor_id { PS3_VENDOR_ID_NONE = 0, PS3_VENDOR_ID_SONY = 0x8000000000000000UL, @@ -258,7 +257,7 @@ int ps3_repository_read_dev_type(unsigned int bus_index, int ps3_repository_read_dev_intr(unsigned int bus_index, unsigned int dev_index, unsigned int intr_index, - enum ps3_interrupt_type *intr_type, unsigned int* interrupt_id) + unsigned int *intr_type, unsigned int* interrupt_id) { int result; u64 v1; @@ -276,8 +275,7 @@ int ps3_repository_read_dev_intr(unsigned int bus_index, } int ps3_repository_read_dev_reg_type(unsigned int bus_index, - unsigned int dev_index, unsigned int reg_index, - enum ps3_reg_type *reg_type) + unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type) { int result; u64 v1; @@ -304,8 +302,8 @@ int ps3_repository_read_dev_reg_addr(unsigned int bus_index, } int ps3_repository_read_dev_reg(unsigned int bus_index, - unsigned int dev_index, unsigned int reg_index, - enum ps3_reg_type *reg_type, u64 *bus_addr, u64 *len) + unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type, + u64 *bus_addr, u64 *len) { int result = ps3_repository_read_dev_reg_type(bus_index, dev_index, reg_index, reg_type); @@ -345,7 +343,7 @@ int ps3_repository_dump_resource_info(unsigned int bus_index, } for (res_index = 0; res_index < 10; res_index++) { - enum ps3_reg_type reg_type; + enum ps3_region_type reg_type; u64 bus_addr; u64 len; @@ -369,55 +367,7 @@ int ps3_repository_dump_resource_info(unsigned int bus_index, return result; } -static int dump_stor_dev_info(unsigned int bus_index, unsigned int dev_index) -{ - int result = 0; - unsigned int num_regions, region_index; - u64 port, blk_size, num_blocks; - - pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, - bus_index, dev_index); - - result = ps3_repository_read_stor_dev_info(bus_index, dev_index, &port, - &blk_size, &num_blocks, &num_regions); - if (result) { - pr_debug("%s:%d ps3_repository_read_stor_dev_info" - " (%u:%u) failed\n", __func__, __LINE__, - bus_index, dev_index); - goto out; - } - - pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " - "%lu, num_regions %u\n", - __func__, __LINE__, bus_index, dev_index, port, - blk_size, num_blocks, num_regions); - - for (region_index = 0; region_index < num_regions; region_index++) { - unsigned int region_id; - u64 region_start, region_size; - - result = ps3_repository_read_stor_dev_region(bus_index, - dev_index, region_index, ®ion_id, ®ion_start, - ®ion_size); - if (result) { - pr_debug("%s:%d ps3_repository_read_stor_dev_region" - " (%u:%u) failed\n", __func__, __LINE__, - bus_index, dev_index); - break; - } - - pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", - __func__, __LINE__, bus_index, dev_index, region_id, - region_start, region_size); - } - -out: - pr_debug(" <- %s:%d\n", __func__, __LINE__); - return result; -} - -static int dump_device_info(unsigned int bus_index, enum ps3_bus_type bus_type, - unsigned int num_dev) +static int dump_device_info(unsigned int bus_index, unsigned int num_dev) { int result = 0; unsigned int dev_index; @@ -452,9 +402,6 @@ static int dump_device_info(unsigned int bus_index, enum ps3_bus_type bus_type, __LINE__, bus_index, dev_index, dev_type, dev_id); ps3_repository_dump_resource_info(bus_index, dev_index); - - if (bus_type == PS3_BUS_TYPE_STORAGE) - dump_stor_dev_info(bus_index, dev_index); } pr_debug(" <- %s:%d\n", __func__, __LINE__); @@ -505,7 +452,7 @@ int ps3_repository_dump_bus_info(void) __func__, __LINE__, bus_index, bus_type, bus_id, num_dev); - dump_device_info(bus_index, bus_type, num_dev); + dump_device_info(bus_index, num_dev); } pr_debug(" <- %s:%d\n", __func__, __LINE__); @@ -540,8 +487,7 @@ static int find_device(unsigned int bus_index, unsigned int num_dev, break; } - if (dev_index == num_dev) - return -1; + BUG_ON(dev_index == num_dev); pr_debug("%s:%d: found dev_type %u at dev_index %u\n", __func__, __LINE__, dev_type, dev_index); @@ -575,7 +521,7 @@ int ps3_repository_find_device (enum ps3_bus_type bus_type, pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__, bus_type, dev_type); - BUG_ON(start_dev && start_dev->bus_index > 10); + dev->bus_index = UINT_MAX; for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10; bus_index++) { @@ -586,15 +532,13 @@ int ps3_repository_find_device (enum ps3_bus_type bus_type, if (result) { pr_debug("%s:%d read_bus_type failed\n", __func__, __LINE__); - dev->bus_index = UINT_MAX; return result; } if (x == bus_type) break; } - if (bus_index >= 10) - return -ENODEV; + BUG_ON(bus_index == 10); pr_debug("%s:%d: found bus_type %u at bus_index %u\n", __func__, __LINE__, bus_type, bus_index); @@ -660,8 +604,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, } } - if (res_index == 10) - return -ENODEV; + BUG_ON(res_index == 10); pr_debug("%s:%d: found intr_type %u at res_index %u\n", __func__, __LINE__, intr_type, res_index); @@ -669,8 +612,8 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, return result; } -int ps3_repository_find_reg(const struct ps3_repository_device *dev, - enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len) +int ps3_repository_find_region(const struct ps3_repository_device *dev, + enum ps3_region_type reg_type, u64 *bus_addr, u64 *len) { int result = 0; unsigned int res_index; @@ -680,7 +623,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *dev, *bus_addr = *len = 0; for (res_index = 0; res_index < 10; res_index++) { - enum ps3_reg_type t; + enum ps3_region_type t; u64 a; u64 l; @@ -700,8 +643,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *dev, } } - if (res_index == 10) - return -ENODEV; + BUG_ON(res_index == 10); pr_debug("%s:%d: found reg_type %u at res_index %u\n", __func__, __LINE__, reg_type, res_index); @@ -709,136 +651,6 @@ int ps3_repository_find_reg(const struct ps3_repository_device *dev, return result; } -int ps3_repository_read_stor_dev_port(unsigned int bus_index, - unsigned int dev_index, u64 *port) -{ - return read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("port", 0), - 0, port, 0); -} - -int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index, - unsigned int dev_index, u64 *blk_size) -{ - return read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("blk_size", 0), - 0, blk_size, 0); -} - -int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index, - unsigned int dev_index, u64 *num_blocks) -{ - return read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("n_blocks", 0), - 0, num_blocks, 0); -} - -int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, - unsigned int dev_index, unsigned int *num_regions) -{ - int result; - u64 v1; - - result = read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("n_regs", 0), - 0, &v1, 0); - *num_regions = v1; - return result; -} - -int ps3_repository_read_stor_dev_region_id(unsigned int bus_index, - unsigned int dev_index, unsigned int region_index, - unsigned int *region_id) -{ - int result; - u64 v1; - - result = read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("region", region_index), - make_field("id", 0), - &v1, 0); - *region_id = v1; - return result; -} - -int ps3_repository_read_stor_dev_region_size(unsigned int bus_index, - unsigned int dev_index, unsigned int region_index, u64 *region_size) -{ - return read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("region", region_index), - make_field("size", 0), - region_size, 0); -} - -int ps3_repository_read_stor_dev_region_start(unsigned int bus_index, - unsigned int dev_index, unsigned int region_index, u64 *region_start) -{ - return read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("region", region_index), - make_field("start", 0), - region_start, 0); -} - -int ps3_repository_read_stor_dev_info(unsigned int bus_index, - unsigned int dev_index, u64 *port, u64 *blk_size, - u64 *num_blocks, unsigned int *num_regions) -{ - int result; - - result = ps3_repository_read_stor_dev_port(bus_index, dev_index, port); - if (result) - return result; - - result = ps3_repository_read_stor_dev_blk_size(bus_index, dev_index, - blk_size); - if (result) - return result; - - result = ps3_repository_read_stor_dev_num_blocks(bus_index, dev_index, - num_blocks); - if (result) - return result; - - result = ps3_repository_read_stor_dev_num_regions(bus_index, dev_index, - num_regions); - return result; -} - -int ps3_repository_read_stor_dev_region(unsigned int bus_index, - unsigned int dev_index, unsigned int region_index, - unsigned int *region_id, u64 *region_start, u64 *region_size) -{ - int result; - - result = ps3_repository_read_stor_dev_region_id(bus_index, dev_index, - region_index, region_id); - if (result) - return result; - - result = ps3_repository_read_stor_dev_region_start(bus_index, dev_index, - region_index, region_start); - if (result) - return result; - - result = ps3_repository_read_stor_dev_region_size(bus_index, dev_index, - region_index, region_size); - return result; -} - int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size) { return read_node(PS3_LPAR_ID_CURRENT, diff --git a/trunk/arch/powerpc/platforms/ps3/setup.c b/trunk/arch/powerpc/platforms/ps3/setup.c index e62505e18813..d8b5cadbe80e 100644 --- a/trunk/arch/powerpc/platforms/ps3/setup.c +++ b/trunk/arch/powerpc/platforms/ps3/setup.c @@ -41,18 +41,10 @@ #define DBG(fmt...) do{if(0)printk(fmt);}while(0) #endif -int ps3_get_firmware_version(union ps3_firmware_version *v) +static void ps3_show_cpuinfo(struct seq_file *m) { - int result = lv1_get_version_info(&v->raw); - - if (result) { - v->raw = 0; - return -1; - } - - return result; + seq_printf(m, "machine\t\t: %s\n", ppc_md.name); } -EXPORT_SYMBOL_GPL(ps3_get_firmware_version); static void ps3_power_save(void) { @@ -82,14 +74,8 @@ static void ps3_panic(char *str) static void __init ps3_setup_arch(void) { - union ps3_firmware_version v; - DBG(" -> %s:%d\n", __func__, __LINE__); - ps3_get_firmware_version(&v); - printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", v.major, v.minor, - v.rev); - ps3_spu_set_platform(); ps3_map_htab(); @@ -170,6 +156,7 @@ define_machine(ps3) { .name = "PS3", .probe = ps3_probe, .setup_arch = ps3_setup_arch, + .show_cpuinfo = ps3_show_cpuinfo, .init_IRQ = ps3_init_IRQ, .panic = ps3_panic, .get_boot_time = ps3_get_boot_time, diff --git a/trunk/arch/powerpc/platforms/ps3/smp.c b/trunk/arch/powerpc/platforms/ps3/smp.c index 6fb887961a6d..11d2080607ed 100644 --- a/trunk/arch/powerpc/platforms/ps3/smp.c +++ b/trunk/arch/powerpc/platforms/ps3/smp.c @@ -23,6 +23,7 @@ #include #include +#include #include "platform.h" @@ -110,7 +111,7 @@ static void __init ps3_smp_setup_cpu(int cpu) BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); for (i = 0; i < MSG_COUNT; i++) { - result = ps3_alloc_event_irq(cpu, &virqs[i]); + result = ps3_alloc_event_irq(&virqs[i]); if (result) continue; diff --git a/trunk/arch/powerpc/platforms/ps3/spu.c b/trunk/arch/powerpc/platforms/ps3/spu.c index d1929721b0e4..644532c3b7c4 100644 --- a/trunk/arch/powerpc/platforms/ps3/spu.c +++ b/trunk/arch/powerpc/platforms/ps3/spu.c @@ -26,10 +26,9 @@ #include #include +#include #include -#include "platform.h" - /* spu_management_ops */ /** @@ -51,7 +50,7 @@ enum spe_type { */ struct spe_shadow { - u8 padding_0140[0x0140]; + u8 padding_0000[0x0140]; u64 int_status_class0_RW; /* 0x0140 */ u64 int_status_class1_RW; /* 0x0148 */ u64 int_status_class2_RW; /* 0x0150 */ @@ -68,7 +67,8 @@ struct spe_shadow { u8 padding_0c08[0x0f00-0x0c08]; u64 spe_execution_status; /* 0x0f00 */ u8 padding_0f08[0x1000-0x0f08]; -}; +} __attribute__ ((packed)); + /** * enum spe_ex_state - Logical spe execution state. @@ -268,20 +268,20 @@ static int __init setup_interrupts(struct spu *spu) { int result; - result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, - 0, &spu->irqs[0]); + result = ps3_alloc_spe_irq(spu_pdata(spu)->spe_id, 0, + &spu->irqs[0]); if (result) goto fail_alloc_0; - result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, - 1, &spu->irqs[1]); + result = ps3_alloc_spe_irq(spu_pdata(spu)->spe_id, 1, + &spu->irqs[1]); if (result) goto fail_alloc_1; - result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, - 2, &spu->irqs[2]); + result = ps3_alloc_spe_irq(spu_pdata(spu)->spe_id, 2, + &spu->irqs[2]); if (result) goto fail_alloc_2; diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c index 9437f48cc9e7..da6e5362e7cd 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh.c @@ -747,7 +747,6 @@ struct eeh_early_enable_info { /* Enable eeh for the given device node. */ static void *early_enable_eeh(struct device_node *dn, void *data) { - unsigned int rets[3]; struct eeh_early_enable_info *info = data; int ret; const char *status = get_property(dn, "status", NULL); @@ -804,14 +803,16 @@ static void *early_enable_eeh(struct device_node *dn, void *data) regs[0], info->buid_hi, info->buid_lo, EEH_ENABLE); - enable = 0; if (ret == 0) { + eeh_subsystem_enabled = 1; + pdn->eeh_mode |= EEH_MODE_SUPPORTED; pdn->eeh_config_addr = regs[0]; /* If the newer, better, ibm,get-config-addr-info is supported, * then use that instead. */ pdn->eeh_pe_config_addr = 0; if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) { + unsigned int rets[2]; ret = rtas_call (ibm_get_config_addr_info, 4, 2, rets, pdn->eeh_config_addr, info->buid_hi, info->buid_lo, @@ -819,20 +820,6 @@ static void *early_enable_eeh(struct device_node *dn, void *data) if (ret == 0) pdn->eeh_pe_config_addr = rets[0]; } - - /* Some older systems (Power4) allow the - * ibm,set-eeh-option call to succeed even on nodes - * where EEH is not supported. Verify support - * explicitly. */ - ret = read_slot_reset_state(pdn, rets); - if ((ret == 0) && (rets[1] == 1)) - enable = 1; - } - - if (enable) { - eeh_subsystem_enabled = 1; - pdn->eeh_mode |= EEH_MODE_SUPPORTED; - #ifdef DEBUG printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n", dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr); diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c index a4c0bf84ef2e..cbd6b0711ab4 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c @@ -446,8 +446,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) */ printk(KERN_ERR "EEH: PCI device at location=%s driver=%s pci addr=%s \n" - "has failed %d times in the last hour " - "and has been permanently disabled. \n" + "has failed %d times and has been permanently disabled. \n" "Please try reseating this device or replacing it.\n", location, drv_str, pci_str, frozen_pdn->eeh_freeze_count); goto perm_error; diff --git a/trunk/arch/powerpc/platforms/pseries/firmware.c b/trunk/arch/powerpc/platforms/pseries/firmware.c index 90522e3c9d46..1c7b2baa5f73 100644 --- a/trunk/arch/powerpc/platforms/pseries/firmware.c +++ b/trunk/arch/powerpc/platforms/pseries/firmware.c @@ -59,7 +59,6 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = { {FW_FEATURE_XDABR, "hcall-xdabr"}, {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, {FW_FEATURE_SPLPAR, "hcall-splpar"}, - {FW_FEATURE_BULK_REMOVE, "hcall-bulk"}, }; /* Build up the firmware features bitmask using the contents of diff --git a/trunk/arch/powerpc/platforms/pseries/lpar.c b/trunk/arch/powerpc/platforms/pseries/lpar.c index 7496005566ef..721436db3ef0 100644 --- a/trunk/arch/powerpc/platforms/pseries/lpar.c +++ b/trunk/arch/powerpc/platforms/pseries/lpar.c @@ -502,70 +502,23 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va, BUG_ON(lpar_rc != H_SUCCESS); } -/* Flag bits for H_BULK_REMOVE */ -#define HBR_REQUEST 0x4000000000000000UL -#define HBR_RESPONSE 0x8000000000000000UL -#define HBR_END 0xc000000000000000UL -#define HBR_AVPN 0x0200000000000000UL -#define HBR_ANDCOND 0x0100000000000000UL - /* * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie * lock. */ static void pSeries_lpar_flush_hash_range(unsigned long number, int local) { - unsigned long i, pix, rc; + int i; unsigned long flags = 0; struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); - unsigned long param[9]; - unsigned long va; - unsigned long hash, index, shift, hidx, slot; - real_pte_t pte; - int psize; if (lock_tlbie) spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags); - psize = batch->psize; - pix = 0; - for (i = 0; i < number; i++) { - va = batch->vaddr[i]; - pte = batch->pte[i]; - pte_iterate_hashed_subpages(pte, psize, va, index, shift) { - hash = hpt_hash(va, shift); - hidx = __rpte_to_hidx(pte, index); - if (hidx & _PTEIDX_SECONDARY) - hash = ~hash; - slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; - slot += hidx & _PTEIDX_GROUP_IX; - if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) { - pSeries_lpar_hpte_invalidate(slot, va, psize, - local); - } else { - param[pix] = HBR_REQUEST | HBR_AVPN | slot; - param[pix+1] = hpte_encode_v(va, psize) & - HPTE_V_AVPN; - pix += 2; - if (pix == 8) { - rc = plpar_hcall9(H_BULK_REMOVE, param, - param[0], param[1], param[2], - param[3], param[4], param[5], - param[6], param[7]); - BUG_ON(rc != H_SUCCESS); - pix = 0; - } - } - } pte_iterate_hashed_end(); - } - if (pix) { - param[pix] = HBR_END; - rc = plpar_hcall9(H_BULK_REMOVE, param, param[0], param[1], - param[2], param[3], param[4], param[5], - param[6], param[7]); - BUG_ON(rc != H_SUCCESS); - } + for (i = 0; i < number; i++) + flush_hash_page(batch->vaddr[i], batch->pte[i], + batch->psize, local); if (lock_tlbie) spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); diff --git a/trunk/arch/powerpc/platforms/pseries/pci.c b/trunk/arch/powerpc/platforms/pseries/pci.c index c69bd15ced9c..715db5c89908 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci.c +++ b/trunk/arch/powerpc/platforms/pseries/pci.c @@ -77,7 +77,7 @@ void __init pSeries_final_fixup(void) /* * Assume the winbond 82c105 is the IDE controller on a - * p610/p615/p630. We should probably be more careful in case + * p610. We should probably be more careful in case * someone tries to plug in a similar adapter. */ static void fixup_winbond_82c105(struct pci_dev* dev) diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index 85dcdf178415..2621a7e72d2d 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -22,6 +22,4 @@ endif ifeq ($(ARCH),powerpc) obj-$(CONFIG_MTD) += rom.o obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o -obj-$(CONFIG_8xx) += mpc8xx_pic.o commproc.o -obj-$(CONFIG_UCODE_PATCH) += micropatch.o endif diff --git a/trunk/arch/powerpc/sysdev/commproc.c b/trunk/arch/powerpc/sysdev/commproc.c deleted file mode 100644 index 9b4fafd9a840..000000000000 --- a/trunk/arch/powerpc/sysdev/commproc.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * General Purpose functions for the global management of the - * Communication Processor Module. - * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) - * - * In addition to the individual control of the communication - * channels, there are a few functions that globally affect the - * communication processor. - * - * Buffer descriptors must be allocated from the dual ported memory - * space. The allocator for that is here. When the communication - * process is reset, we reclaim the memory available. There is - * currently no deallocator for this memory. - * The amount of space available is platform dependent. On the - * MBX, the EPPC software loads additional microcode into the - * communication processor, and uses some of the DP ram for this - * purpose. Current, the first 512 bytes and the last 256 bytes of - * memory are used. Right now I am conservative and only use the - * memory that can never be used for microcode. If there are - * applications that require more DP ram, we can expand the boundaries - * but then we have to be careful of any downloaded microcode. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define CPM_MAP_SIZE (0x4000) - -static void m8xx_cpm_dpinit(void); -static uint host_buffer; /* One page of host buffer */ -static uint host_end; /* end + 1 */ -cpm8xx_t *cpmp; /* Pointer to comm processor space */ -cpic8xx_t *cpic_reg; - -static struct device_node *cpm_pic_node; -static struct irq_host *cpm_pic_host; - -static void cpm_mask_irq(unsigned int irq) -{ - unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq; - - clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec)); -} - -static void cpm_unmask_irq(unsigned int irq) -{ - unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq; - - setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec)); -} - -static void cpm_end_irq(unsigned int irq) -{ - unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq; - - out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec)); -} - -static struct irq_chip cpm_pic = { - .typename = " CPM PIC ", - .mask = cpm_mask_irq, - .unmask = cpm_unmask_irq, - .eoi = cpm_end_irq, -}; - -int cpm_get_irq(void) -{ - int cpm_vec; - - /* Get the vector by setting the ACK bit and then reading - * the register. - */ - out_be16(&cpic_reg->cpic_civr, 1); - cpm_vec = in_be16(&cpic_reg->cpic_civr); - cpm_vec >>= 11; - - return irq_linear_revmap(cpm_pic_host, cpm_vec); -} - -static int cpm_pic_host_match(struct irq_host *h, struct device_node *node) -{ - return cpm_pic_node == node; -} - -static int cpm_pic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) -{ - pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw); - - get_irq_desc(virq)->status |= IRQ_LEVEL; - set_irq_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq); - return 0; -} - -/* The CPM can generate the error interrupt when there is a race condition - * between generating and masking interrupts. All we have to do is ACK it - * and return. This is a no-op function so we don't need any special - * tests in the interrupt handler. - */ -static irqreturn_t cpm_error_interrupt(int irq, void *dev) -{ - return IRQ_HANDLED; -} - -static struct irqaction cpm_error_irqaction = { - .handler = cpm_error_interrupt, - .mask = CPU_MASK_NONE, - .name = "error", -}; - -static struct irq_host_ops cpm_pic_host_ops = { - .match = cpm_pic_host_match, - .map = cpm_pic_host_map, -}; - -unsigned int cpm_pic_init(void) -{ - struct device_node *np = NULL; - struct resource res; - unsigned int sirq = NO_IRQ, hwirq, eirq; - int ret; - - pr_debug("cpm_pic_init\n"); - - np = of_find_compatible_node(NULL, "cpm-pic", "CPM"); - if (np == NULL) { - printk(KERN_ERR "CPM PIC init: can not find cpm-pic node\n"); - return sirq; - } - ret = of_address_to_resource(np, 0, &res); - if (ret) - goto end; - - cpic_reg = (void *)ioremap(res.start, res.end - res.start + 1); - if (cpic_reg == NULL) - goto end; - - sirq = irq_of_parse_and_map(np, 0); - if (sirq == NO_IRQ) - goto end; - - /* Initialize the CPM interrupt controller. */ - hwirq = (unsigned int)irq_map[sirq].hwirq; - out_be32(&cpic_reg->cpic_cicr, - (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) | - ((hwirq/2) << 13) | CICR_HP_MASK); - - out_be32(&cpic_reg->cpic_cimr, 0); - - cpm_pic_node = of_node_get(np); - - cpm_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm_pic_host_ops, 64); - if (cpm_pic_host == NULL) { - printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); - sirq = NO_IRQ; - goto end; - } - of_node_put(np); - - /* Install our own error handler. */ - np = of_find_node_by_type(NULL, "cpm"); - if (np == NULL) { - printk(KERN_ERR "CPM PIC init: can not find cpm node\n"); - goto end; - } - eirq= irq_of_parse_and_map(np, 0); - if (eirq == NO_IRQ) - goto end; - - if (setup_irq(eirq, &cpm_error_irqaction)) - printk(KERN_ERR "Could not allocate CPM error IRQ!"); - - setbits32(&cpic_reg->cpic_cicr, CICR_IEN); - -end: - of_node_put(np); - return sirq; -} - -void cpm_reset(void) -{ - cpm8xx_t *commproc; - sysconf8xx_t *siu_conf; - - commproc = (cpm8xx_t *)ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE); - -#ifdef CONFIG_UCODE_PATCH - /* Perform a reset. - */ - out_be16(&commproc->cp_cpcr, CPM_CR_RST | CPM_CR_FLG); - - /* Wait for it. - */ - while (in_be16(&commproc->cp_cpcr) & CPM_CR_FLG); - - cpm_load_patch(commproc); -#endif - - /* Set SDMA Bus Request priority 5. - * On 860T, this also enables FEC priority 6. I am not sure - * this is what we realy want for some applications, but the - * manual recommends it. - * Bit 25, FAM can also be set to use FEC aggressive mode (860T). - */ - siu_conf = (sysconf8xx_t*)immr_map(im_siu_conf); - out_be32(&siu_conf->sc_sdcr, 1); - immr_unmap(siu_conf); - - /* Reclaim the DP memory for our use. */ - m8xx_cpm_dpinit(); - - /* Tell everyone where the comm processor resides. - */ - cpmp = commproc; -} - -/* We used to do this earlier, but have to postpone as long as possible - * to ensure the kernel VM is now running. - */ -static void -alloc_host_memory(void) -{ - dma_addr_t physaddr; - - /* Set the host page for allocation. - */ - host_buffer = (uint)dma_alloc_coherent(NULL, PAGE_SIZE, &physaddr, - GFP_KERNEL); - host_end = host_buffer + PAGE_SIZE; -} - -/* We also own one page of host buffer space for the allocation of - * UART "fifos" and the like. - */ -uint -m8xx_cpm_hostalloc(uint size) -{ - uint retloc; - - if (host_buffer == 0) - alloc_host_memory(); - - if ((host_buffer + size) >= host_end) - return(0); - - retloc = host_buffer; - host_buffer += size; - - return(retloc); -} - -/* Set a baud rate generator. This needs lots of work. There are - * four BRGs, any of which can be wired to any channel. - * The internal baud rate clock is the system clock divided by 16. - * This assumes the baudrate is 16x oversampled by the uart. - */ -#define BRG_INT_CLK (get_brgfreq()) -#define BRG_UART_CLK (BRG_INT_CLK/16) -#define BRG_UART_CLK_DIV16 (BRG_UART_CLK/16) - -void -cpm_setbrg(uint brg, uint rate) -{ - volatile uint *bp; - - /* This is good enough to get SMCs running..... - */ - bp = (uint *)&cpmp->cp_brgc1; - bp += brg; - /* The BRG has a 12-bit counter. For really slow baud rates (or - * really fast processors), we may have to further divide by 16. - */ - if (((BRG_UART_CLK / rate) - 1) < 4096) - *bp = (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN; - else - *bp = (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) | - CPM_BRG_EN | CPM_BRG_DIV16; -} - -/* - * dpalloc / dpfree bits. - */ -static spinlock_t cpm_dpmem_lock; -/* - * 16 blocks should be enough to satisfy all requests - * until the memory subsystem goes up... - */ -static rh_block_t cpm_boot_dpmem_rh_block[16]; -static rh_info_t cpm_dpmem_info; - -#define CPM_DPMEM_ALIGNMENT 8 -static u8* dpram_vbase; -static uint dpram_pbase; - -void m8xx_cpm_dpinit(void) -{ - spin_lock_init(&cpm_dpmem_lock); - - dpram_vbase = immr_map_size(im_cpm.cp_dpmem, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE); - dpram_pbase = (uint)&((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem; - - /* Initialize the info header */ - rh_init(&cpm_dpmem_info, CPM_DPMEM_ALIGNMENT, - sizeof(cpm_boot_dpmem_rh_block) / - sizeof(cpm_boot_dpmem_rh_block[0]), - cpm_boot_dpmem_rh_block); - - /* - * Attach the usable dpmem area. - * XXX: This is actually crap. CPM_DATAONLY_BASE and - * CPM_DATAONLY_SIZE are a subset of the available dparm. It varies - * with the processor and the microcode patches applied / activated. - * But the following should be at least safe. - */ - rh_attach_region(&cpm_dpmem_info, (void *)CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE); -} - -/* - * Allocate the requested size worth of DP memory. - * This function returns an offset into the DPRAM area. - * Use cpm_dpram_addr() to get the virtual address of the area. - */ -uint cpm_dpalloc(uint size, uint align) -{ - void *start; - unsigned long flags; - - spin_lock_irqsave(&cpm_dpmem_lock, flags); - cpm_dpmem_info.alignment = align; - start = rh_alloc(&cpm_dpmem_info, size, "commproc"); - spin_unlock_irqrestore(&cpm_dpmem_lock, flags); - - return (uint)start; -} -EXPORT_SYMBOL(cpm_dpalloc); - -int cpm_dpfree(uint offset) -{ - int ret; - unsigned long flags; - - spin_lock_irqsave(&cpm_dpmem_lock, flags); - ret = rh_free(&cpm_dpmem_info, (void *)offset); - spin_unlock_irqrestore(&cpm_dpmem_lock, flags); - - return ret; -} -EXPORT_SYMBOL(cpm_dpfree); - -uint cpm_dpalloc_fixed(uint offset, uint size, uint align) -{ - void *start; - unsigned long flags; - - spin_lock_irqsave(&cpm_dpmem_lock, flags); - cpm_dpmem_info.alignment = align; - start = rh_alloc_fixed(&cpm_dpmem_info, (void *)offset, size, "commproc"); - spin_unlock_irqrestore(&cpm_dpmem_lock, flags); - - return (uint)start; -} -EXPORT_SYMBOL(cpm_dpalloc_fixed); - -void cpm_dpdump(void) -{ - rh_dump(&cpm_dpmem_info); -} -EXPORT_SYMBOL(cpm_dpdump); - -void *cpm_dpram_addr(uint offset) -{ - return (void *)(dpram_vbase + offset); -} -EXPORT_SYMBOL(cpm_dpram_addr); - -uint cpm_dpram_phys(u8* addr) -{ - return (dpram_pbase + (uint)(addr - dpram_vbase)); -} -EXPORT_SYMBOL(cpm_dpram_addr); diff --git a/trunk/arch/powerpc/sysdev/cpm2_pic.c b/trunk/arch/powerpc/sysdev/cpm2_pic.c index eabfe06fe05c..767ee6651adc 100644 --- a/trunk/arch/powerpc/sysdev/cpm2_pic.c +++ b/trunk/arch/powerpc/sysdev/cpm2_pic.c @@ -36,20 +36,9 @@ #include #include #include -#include #include "cpm2_pic.h" -/* External IRQS */ -#define CPM2_IRQ_EXT1 19 -#define CPM2_IRQ_EXT7 25 - -/* Port C IRQS */ -#define CPM2_IRQ_PORTC15 48 -#define CPM2_IRQ_PORTC0 63 - -static intctl_cpm2_t *cpm2_intctl; - static struct device_node *cpm2_pic_node; static struct irq_host *cpm2_pic_host; #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) @@ -79,55 +68,68 @@ static const u_char irq_to_siubit[] = { 24, 25, 26, 27, 28, 29, 30, 31, }; -static void cpm2_mask_irq(unsigned int virq) +static void cpm2_mask_irq(unsigned int irq_nr) { int bit, word; - unsigned int irq_nr = virq_to_hw(virq); + volatile uint *simr; + + irq_nr -= CPM_IRQ_OFFSET; bit = irq_to_siubit[irq_nr]; word = irq_to_siureg[irq_nr]; + simr = &(cpm2_intctl->ic_simrh); ppc_cached_irq_mask[word] &= ~(1 << bit); - out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]); + simr[word] = ppc_cached_irq_mask[word]; } -static void cpm2_unmask_irq(unsigned int virq) +static void cpm2_unmask_irq(unsigned int irq_nr) { int bit, word; - unsigned int irq_nr = virq_to_hw(virq); + volatile uint *simr; + + irq_nr -= CPM_IRQ_OFFSET; bit = irq_to_siubit[irq_nr]; word = irq_to_siureg[irq_nr]; + simr = &(cpm2_intctl->ic_simrh); ppc_cached_irq_mask[word] |= 1 << bit; - out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]); + simr[word] = ppc_cached_irq_mask[word]; } -static void cpm2_ack(unsigned int virq) +static void cpm2_mask_and_ack(unsigned int irq_nr) { int bit, word; - unsigned int irq_nr = virq_to_hw(virq); + volatile uint *simr, *sipnr; + + irq_nr -= CPM_IRQ_OFFSET; bit = irq_to_siubit[irq_nr]; word = irq_to_siureg[irq_nr]; - out_be32(&cpm2_intctl->ic_sipnrh + word, 1 << bit); + simr = &(cpm2_intctl->ic_simrh); + sipnr = &(cpm2_intctl->ic_sipnrh); + ppc_cached_irq_mask[word] &= ~(1 << bit); + simr[word] = ppc_cached_irq_mask[word]; + sipnr[word] = 1 << bit; } -static void cpm2_end_irq(unsigned int virq) +static void cpm2_end_irq(unsigned int irq_nr) { int bit, word; - unsigned int irq_nr = virq_to_hw(virq); + volatile uint *simr; if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && irq_desc[irq_nr].action) { + irq_nr -= CPM_IRQ_OFFSET; bit = irq_to_siubit[irq_nr]; word = irq_to_siureg[irq_nr]; + simr = &(cpm2_intctl->ic_simrh); ppc_cached_irq_mask[word] |= 1 << bit; - out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]); - + simr[word] = ppc_cached_irq_mask[word]; /* * Work around large numbers of spurious IRQs on PowerPC 82xx * systems. @@ -136,59 +138,13 @@ static void cpm2_end_irq(unsigned int virq) } } -static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) -{ - unsigned int src = virq_to_hw(virq); - struct irq_desc *desc = get_irq_desc(virq); - unsigned int vold, vnew, edibit; - - if (flow_type == IRQ_TYPE_NONE) - flow_type = IRQ_TYPE_LEVEL_LOW; - - if (flow_type & IRQ_TYPE_EDGE_RISING) { - printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n", - flow_type); - return -EINVAL; - } - - desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); - desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; - if (flow_type & IRQ_TYPE_LEVEL_LOW) { - desc->status |= IRQ_LEVEL; - desc->handle_irq = handle_level_irq; - } else - desc->handle_irq = handle_edge_irq; - - /* internal IRQ senses are LEVEL_LOW - * EXT IRQ and Port C IRQ senses are programmable - */ - if (src >= CPM2_IRQ_EXT1 && src <= CPM2_IRQ_EXT7) - edibit = (14 - (src - CPM2_IRQ_EXT1)); - else - if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) - edibit = (31 - (src - CPM2_IRQ_PORTC15)); - else - return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; - - vold = in_be32(&cpm2_intctl->ic_siexr); - - if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) - vnew = vold | (1 << edibit); - else - vnew = vold & ~(1 << edibit); - - if (vold != vnew) - out_be32(&cpm2_intctl->ic_siexr, vnew); - return 0; -} - static struct irq_chip cpm2_pic = { .typename = " CPM2 SIU ", - .mask = cpm2_mask_irq, + .enable = cpm2_unmask_irq, + .disable = cpm2_mask_irq, .unmask = cpm2_unmask_irq, - .ack = cpm2_ack, - .eoi = cpm2_end_irq, - .set_type = cpm2_set_irq_type, + .mask_ack = cpm2_mask_and_ack, + .end = cpm2_end_irq, }; unsigned int cpm2_get_irq(void) @@ -198,17 +154,17 @@ unsigned int cpm2_get_irq(void) /* For CPM2, read the SIVEC register and shift the bits down * to get the irq number. */ - bits = in_be32(&cpm2_intctl->ic_sivec); + bits = cpm2_intctl->ic_sivec; irq = bits >> 26; if (irq == 0) return(-1); - return irq_linear_revmap(cpm2_pic_host, irq); + return irq+CPM_IRQ_OFFSET; } static int cpm2_pic_host_match(struct irq_host *h, struct device_node *node) { - return cpm2_pic_node == node; + return cpm2_pic_node == NULL || cpm2_pic_node == node; } static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq, @@ -221,21 +177,39 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq, return 0; } +static void cpm2_host_unmap(struct irq_host *h, unsigned int virq) +{ + /* Make sure irq is masked in hardware */ + cpm2_mask_irq(virq); + + /* remove chip and handler */ + set_irq_chip_and_handler(virq, NULL, NULL); +} + static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct, u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) { + static const unsigned char map_cpm2_senses[4] = { + IRQ_TYPE_LEVEL_LOW, + IRQ_TYPE_LEVEL_HIGH, + IRQ_TYPE_EDGE_FALLING, + IRQ_TYPE_EDGE_RISING, + }; + *out_hwirq = intspec[0]; - if (intsize > 1) - *out_flags = intspec[1]; + if (intsize > 1 && intspec[1] < 4) + *out_flags = map_cpm2_senses[intspec[1]]; else *out_flags = IRQ_TYPE_NONE; + return 0; } static struct irq_host_ops cpm2_pic_host_ops = { .match = cpm2_pic_host_match, .map = cpm2_pic_host_map, + .unmap = cpm2_host_unmap, .xlate = cpm2_pic_host_xlate, }; @@ -243,37 +217,37 @@ void cpm2_pic_init(struct device_node *node) { int i; - cpm2_intctl = cpm2_map(im_intctl); - /* Clear the CPM IRQ controller, in case it has any bits set * from the bootloader */ /* Mask out everything */ - out_be32(&cpm2_intctl->ic_simrh, 0x00000000); - out_be32(&cpm2_intctl->ic_simrl, 0x00000000); + cpm2_intctl->ic_simrh = 0x00000000; + cpm2_intctl->ic_simrl = 0x00000000; wmb(); /* Ack everything */ - out_be32(&cpm2_intctl->ic_sipnrh, 0xffffffff); - out_be32(&cpm2_intctl->ic_sipnrl, 0xffffffff); + cpm2_intctl->ic_sipnrh = 0xffffffff; + cpm2_intctl->ic_sipnrl = 0xffffffff; wmb(); /* Dummy read of the vector */ - i = in_be32(&cpm2_intctl->ic_sivec); + i = cpm2_intctl->ic_sivec; rmb(); /* Initialize the default interrupt mapping priorities, * in case the boot rom changed something on us. */ - out_be16(&cpm2_intctl->ic_sicr, 0); - out_be32(&cpm2_intctl->ic_scprrh, 0x05309770); - out_be32(&cpm2_intctl->ic_scprrl, 0x05309770); + cpm2_intctl->ic_sicr = 0; + cpm2_intctl->ic_scprrh = 0x05309770; + cpm2_intctl->ic_scprrl = 0x05309770; /* create a legacy host */ - cpm2_pic_node = of_node_get(node); + if (node) + cpm2_pic_node = of_node_get(node); + cpm2_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm2_pic_host_ops, 64); if (cpm2_pic_host == NULL) { printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); diff --git a/trunk/arch/powerpc/sysdev/cpm2_pic.h b/trunk/arch/powerpc/sysdev/cpm2_pic.h index 30e5828a2781..2840616529e4 100644 --- a/trunk/arch/powerpc/sysdev/cpm2_pic.h +++ b/trunk/arch/powerpc/sysdev/cpm2_pic.h @@ -1,6 +1,8 @@ #ifndef _PPC_KERNEL_CPM2_H #define _PPC_KERNEL_CPM2_H +extern intctl_cpm2_t *cpm2_intctl; + extern unsigned int cpm2_get_irq(void); extern void cpm2_pic_init(struct device_node*); diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index 9f2a9a444bfb..ad31e56e892b 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -38,8 +38,7 @@ #include extern void init_fcc_ioports(struct fs_platform_info*); -extern void init_fec_ioports(struct fs_platform_info*); -extern void init_smc_ioports(struct fs_uart_platform_info*); +extern void init_scc_ioports(struct fs_uart_platform_info*); static phys_addr_t immrbase = -1; phys_addr_t get_immrbase(void) @@ -64,7 +63,7 @@ phys_addr_t get_immrbase(void) EXPORT_SYMBOL(get_immrbase); -#if defined(CONFIG_CPM2) || defined(CONFIG_8xx) +#ifdef CONFIG_CPM2 static u32 brgfreq = -1; @@ -545,8 +544,6 @@ arch_initcall(fsl_usb_of_init); #ifdef CONFIG_CPM2 -extern void init_scc_ioports(struct fs_uart_platform_info*); - static const char fcc_regs[] = "fcc_regs"; static const char fcc_regs_c[] = "fcc_regs_c"; static const char fcc_pram[] = "fcc_pram"; @@ -795,270 +792,3 @@ static int __init cpm_uart_of_init(void) arch_initcall(cpm_uart_of_init); #endif /* CONFIG_CPM2 */ - -#ifdef CONFIG_8xx - -extern void init_scc_ioports(struct fs_platform_info*); -extern int platform_device_skip(char *model, int id); - -static int __init fs_enet_mdio_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *mdio_dev; - struct resource res; - int ret; - - for (np = NULL, i = 0; - (np = of_find_compatible_node(np, "mdio", "fs_enet")) != NULL; - i++) { - struct fs_mii_fec_platform_info mdio_data; - - memset(&res, 0, sizeof(res)); - memset(&mdio_data, 0, sizeof(mdio_data)); - - ret = of_address_to_resource(np, 0, &res); - if (ret) - goto err; - - mdio_dev = - platform_device_register_simple("fsl-cpm-fec-mdio", - res.start, &res, 1); - if (IS_ERR(mdio_dev)) { - ret = PTR_ERR(mdio_dev); - goto err; - } - - mdio_data.mii_speed = ((((ppc_proc_freq + 4999999) / 2500000) / 2) & 0x3F) << 1; - - ret = - platform_device_add_data(mdio_dev, &mdio_data, - sizeof(struct fs_mii_fec_platform_info)); - if (ret) - goto unreg; - } - return 0; - -unreg: - platform_device_unregister(mdio_dev); -err: - return ret; -} - -arch_initcall(fs_enet_mdio_of_init); - -static const char *enet_regs = "regs"; -static const char *enet_pram = "pram"; -static const char *enet_irq = "interrupt"; -static char bus_id[9][BUS_ID_SIZE]; - -static int __init fs_enet_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *fs_enet_dev = NULL; - struct resource res; - int ret; - - for (np = NULL, i = 0; - (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL; - i++) { - struct resource r[4]; - struct device_node *phy = NULL, *mdio = NULL; - struct fs_platform_info fs_enet_data; - unsigned int *id, *phy_addr; - void *mac_addr; - phandle *ph; - char *model; - - memset(r, 0, sizeof(r)); - memset(&fs_enet_data, 0, sizeof(fs_enet_data)); - - model = (char *)get_property(np, "model", NULL); - if (model == NULL) { - ret = -ENODEV; - goto unreg; - } - - id = (u32 *) get_property(np, "device-id", NULL); - fs_enet_data.fs_no = *id; - - if (platform_device_skip(model, *id)) - continue; - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto err; - r[0].name = enet_regs; - - mac_addr = (void *)get_property(np, "mac-address", NULL); - memcpy(fs_enet_data.macaddr, mac_addr, 6); - - ph = (phandle *) get_property(np, "phy-handle", NULL); - if (ph != NULL) - phy = of_find_node_by_phandle(*ph); - - if (phy != NULL) { - phy_addr = (u32 *) get_property(phy, "reg", NULL); - fs_enet_data.phy_addr = *phy_addr; - fs_enet_data.has_phy = 1; - - mdio = of_get_parent(phy); - ret = of_address_to_resource(mdio, 0, &res); - if (ret) { - of_node_put(phy); - of_node_put(mdio); - goto unreg; - } - } - - model = (char*)get_property(np, "model", NULL); - strcpy(fs_enet_data.fs_type, model); - - if (strstr(model, "FEC")) { - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); - r[1].flags = IORESOURCE_IRQ; - r[1].name = enet_irq; - - fs_enet_dev = - platform_device_register_simple("fsl-cpm-fec", i, &r[0], 2); - - if (IS_ERR(fs_enet_dev)) { - ret = PTR_ERR(fs_enet_dev); - goto err; - } - - fs_enet_data.rx_ring = 128; - fs_enet_data.tx_ring = 16; - fs_enet_data.rx_copybreak = 240; - fs_enet_data.use_napi = 1; - fs_enet_data.napi_weight = 17; - - snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%x:%02x", - (u32)res.start, fs_enet_data.phy_addr); - fs_enet_data.bus_id = (char*)&bus_id[i]; - fs_enet_data.init_ioports = init_fec_ioports; - } - if (strstr(model, "SCC")) { - ret = of_address_to_resource(np, 1, &r[1]); - if (ret) - goto err; - r[1].name = enet_pram; - - r[2].start = r[2].end = irq_of_parse_and_map(np, 0); - r[2].flags = IORESOURCE_IRQ; - r[2].name = enet_irq; - - fs_enet_dev = - platform_device_register_simple("fsl-cpm-scc", i, &r[0], 3); - - if (IS_ERR(fs_enet_dev)) { - ret = PTR_ERR(fs_enet_dev); - goto err; - } - - fs_enet_data.rx_ring = 64; - fs_enet_data.tx_ring = 8; - fs_enet_data.rx_copybreak = 240; - fs_enet_data.use_napi = 1; - fs_enet_data.napi_weight = 17; - - snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%s", "fixed@10:1"); - fs_enet_data.bus_id = (char*)&bus_id[i]; - fs_enet_data.init_ioports = init_scc_ioports; - } - - of_node_put(phy); - of_node_put(mdio); - - ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, - sizeof(struct - fs_platform_info)); - if (ret) - goto unreg; - } - return 0; - -unreg: - platform_device_unregister(fs_enet_dev); -err: - return ret; -} - -arch_initcall(fs_enet_of_init); - - -static const char *smc_regs = "regs"; -static const char *smc_pram = "pram"; - -static int __init cpm_smc_uart_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *cpm_uart_dev; - int ret; - - for (np = NULL, i = 0; - (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL; - i++) { - struct resource r[3]; - struct fs_uart_platform_info cpm_uart_data; - int *id; - char *model; - - memset(r, 0, sizeof(r)); - memset(&cpm_uart_data, 0, sizeof(cpm_uart_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto err; - - r[0].name = smc_regs; - - ret = of_address_to_resource(np, 1, &r[1]); - if (ret) - goto err; - r[1].name = smc_pram; - - r[2].start = r[2].end = irq_of_parse_and_map(np, 0); - r[2].flags = IORESOURCE_IRQ; - - cpm_uart_dev = - platform_device_register_simple("fsl-cpm-smc:uart", i, &r[0], 3); - - if (IS_ERR(cpm_uart_dev)) { - ret = PTR_ERR(cpm_uart_dev); - goto err; - } - - model = (char*)get_property(np, "model", NULL); - strcpy(cpm_uart_data.fs_type, model); - - id = (int*)get_property(np, "device-id", NULL); - cpm_uart_data.fs_no = *id; - cpm_uart_data.uart_clk = ppc_proc_freq; - - cpm_uart_data.tx_num_fifo = 4; - cpm_uart_data.tx_buf_size = 32; - cpm_uart_data.rx_num_fifo = 4; - cpm_uart_data.rx_buf_size = 32; - - ret = - platform_device_add_data(cpm_uart_dev, &cpm_uart_data, - sizeof(struct - fs_uart_platform_info)); - if (ret) - goto unreg; - } - - return 0; - -unreg: - platform_device_unregister(cpm_uart_dev); -err: - return ret; -} - -arch_initcall(cpm_smc_uart_of_init); - -#endif /* CONFIG_8xx */ diff --git a/trunk/arch/powerpc/sysdev/grackle.c b/trunk/arch/powerpc/sysdev/grackle.c index 42053625f498..b6ec793a23be 100644 --- a/trunk/arch/powerpc/sysdev/grackle.c +++ b/trunk/arch/powerpc/sysdev/grackle.c @@ -56,8 +56,6 @@ static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) void __init setup_grackle(struct pci_controller *hose) { setup_indirect_pci(hose, 0xfec00000, 0xfee00000); - if (machine_is_compatible("PowerMac1,1")) - pci_assign_all_buses = 1; if (machine_is_compatible("AAPL,PowerBook1998")) grackle_set_loop_snoop(hose, 1); #if 0 /* Disabled for now, HW problems ??? */ diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/powerpc/sysdev/ipic.c index 473c415e9e25..746f78c15375 100644 --- a/trunk/arch/powerpc/sysdev/ipic.c +++ b/trunk/arch/powerpc/sysdev/ipic.c @@ -557,7 +557,8 @@ static struct irq_host_ops ipic_host_ops = { .xlate = ipic_host_xlate, }; -struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) +void __init ipic_init(struct device_node *node, + unsigned int flags) { struct ipic *ipic; struct resource res; @@ -565,24 +566,22 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) ipic = alloc_bootmem(sizeof(struct ipic)); if (ipic == NULL) - return NULL; + return; memset(ipic, 0, sizeof(struct ipic)); - ipic->of_node = of_node_get(node); + ipic->of_node = node ? of_node_get(node) : NULL; ipic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, NR_IPIC_INTS, &ipic_host_ops, 0); if (ipic->irqhost == NULL) { of_node_put(node); - return NULL; + return; } ret = of_address_to_resource(node, 0, &res); - if (ret) { - of_node_put(node); - return NULL; - } + if (ret) + return; ipic->regs = ioremap(res.start, res.end - res.start + 1); @@ -626,8 +625,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS, primary_ipic->regs); - - return ipic; } int ipic_set_priority(unsigned int virq, unsigned int priority) diff --git a/trunk/arch/powerpc/sysdev/micropatch.c b/trunk/arch/powerpc/sysdev/micropatch.c deleted file mode 100644 index 712b10a55f87..000000000000 --- a/trunk/arch/powerpc/sysdev/micropatch.c +++ /dev/null @@ -1,743 +0,0 @@ - -/* Microcode patches for the CPM as supplied by Motorola. - * This is the one for IIC/SPI. There is a newer one that - * also relocates SMC2, but this would require additional changes - * to uart.c, so I am holding off on that for a moment. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * I2C/SPI relocation patch arrays. - */ - -#ifdef CONFIG_I2C_SPI_UCODE_PATCH - -uint patch_2000[] = { - 0x7FFFEFD9, - 0x3FFD0000, - 0x7FFB49F7, - 0x7FF90000, - 0x5FEFADF7, - 0x5F89ADF7, - 0x5FEFAFF7, - 0x5F89AFF7, - 0x3A9CFBC8, - 0xE7C0EDF0, - 0x77C1E1BB, - 0xF4DC7F1D, - 0xABAD932F, - 0x4E08FDCF, - 0x6E0FAFF8, - 0x7CCF76CF, - 0xFD1FF9CF, - 0xABF88DC6, - 0xAB5679F7, - 0xB0937383, - 0xDFCE79F7, - 0xB091E6BB, - 0xE5BBE74F, - 0xB3FA6F0F, - 0x6FFB76CE, - 0xEE0DF9CF, - 0x2BFBEFEF, - 0xCFEEF9CF, - 0x76CEAD24, - 0x90B2DF9A, - 0x7FDDD0BF, - 0x4BF847FD, - 0x7CCF76CE, - 0xCFEF7E1F, - 0x7F1D7DFD, - 0xF0B6EF71, - 0x7FC177C1, - 0xFBC86079, - 0xE722FBC8, - 0x5FFFDFFF, - 0x5FB2FFFB, - 0xFBC8F3C8, - 0x94A67F01, - 0x7F1D5F39, - 0xAFE85F5E, - 0xFFDFDF96, - 0xCB9FAF7D, - 0x5FC1AFED, - 0x8C1C5FC1, - 0xAFDD5FC3, - 0xDF9A7EFD, - 0xB0B25FB2, - 0xFFFEABAD, - 0x5FB2FFFE, - 0x5FCE600B, - 0xE6BB600B, - 0x5FCEDFC6, - 0x27FBEFDF, - 0x5FC8CFDE, - 0x3A9CE7C0, - 0xEDF0F3C8, - 0x7F0154CD, - 0x7F1D2D3D, - 0x363A7570, - 0x7E0AF1CE, - 0x37EF2E68, - 0x7FEE10EC, - 0xADF8EFDE, - 0xCFEAE52F, - 0x7D0FE12B, - 0xF1CE5F65, - 0x7E0A4DF8, - 0xCFEA5F72, - 0x7D0BEFEE, - 0xCFEA5F74, - 0xE522EFDE, - 0x5F74CFDA, - 0x0B627385, - 0xDF627E0A, - 0x30D8145B, - 0xBFFFF3C8, - 0x5FFFDFFF, - 0xA7F85F5E, - 0xBFFE7F7D, - 0x10D31450, - 0x5F36BFFF, - 0xAF785F5E, - 0xBFFDA7F8, - 0x5F36BFFE, - 0x77FD30C0, - 0x4E08FDCF, - 0xE5FF6E0F, - 0xAFF87E1F, - 0x7E0FFD1F, - 0xF1CF5F1B, - 0xABF80D5E, - 0x5F5EFFEF, - 0x79F730A2, - 0xAFDD5F34, - 0x47F85F34, - 0xAFED7FDD, - 0x50B24978, - 0x47FD7F1D, - 0x7DFD70AD, - 0xEF717EC1, - 0x6BA47F01, - 0x2D267EFD, - 0x30DE5F5E, - 0xFFFD5F5E, - 0xFFEF5F5E, - 0xFFDF0CA0, - 0xAFED0A9E, - 0xAFDD0C3A, - 0x5F3AAFBD, - 0x7FBDB082, - 0x5F8247F8 -}; - -uint patch_2f00[] = { - 0x3E303430, - 0x34343737, - 0xABF7BF9B, - 0x994B4FBD, - 0xBD599493, - 0x349FFF37, - 0xFB9B177D, - 0xD9936956, - 0xBBFDD697, - 0xBDD2FD11, - 0x31DB9BB3, - 0x63139637, - 0x93733693, - 0x193137F7, - 0x331737AF, - 0x7BB9B999, - 0xBB197957, - 0x7FDFD3D5, - 0x73B773F7, - 0x37933B99, - 0x1D115316, - 0x99315315, - 0x31694BF4, - 0xFBDBD359, - 0x31497353, - 0x76956D69, - 0x7B9D9693, - 0x13131979, - 0x79376935 -}; -#endif - -/* - * I2C/SPI/SMC1 relocation patch arrays. - */ - -#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH - -uint patch_2000[] = { - 0x3fff0000, - 0x3ffd0000, - 0x3ffb0000, - 0x3ff90000, - 0x5f13eff8, - 0x5eb5eff8, - 0x5f88adf7, - 0x5fefadf7, - 0x3a9cfbc8, - 0x77cae1bb, - 0xf4de7fad, - 0xabae9330, - 0x4e08fdcf, - 0x6e0faff8, - 0x7ccf76cf, - 0xfdaff9cf, - 0xabf88dc8, - 0xab5879f7, - 0xb0925d8d, - 0xdfd079f7, - 0xb090e6bb, - 0xe5bbe74f, - 0x9e046f0f, - 0x6ffb76ce, - 0xee0cf9cf, - 0x2bfbefef, - 0xcfeef9cf, - 0x76cead23, - 0x90b3df99, - 0x7fddd0c1, - 0x4bf847fd, - 0x7ccf76ce, - 0xcfef77ca, - 0x7eaf7fad, - 0x7dfdf0b7, - 0xef7a7fca, - 0x77cafbc8, - 0x6079e722, - 0xfbc85fff, - 0xdfff5fb3, - 0xfffbfbc8, - 0xf3c894a5, - 0xe7c9edf9, - 0x7f9a7fad, - 0x5f36afe8, - 0x5f5bffdf, - 0xdf95cb9e, - 0xaf7d5fc3, - 0xafed8c1b, - 0x5fc3afdd, - 0x5fc5df99, - 0x7efdb0b3, - 0x5fb3fffe, - 0xabae5fb3, - 0xfffe5fd0, - 0x600be6bb, - 0x600b5fd0, - 0xdfc827fb, - 0xefdf5fca, - 0xcfde3a9c, - 0xe7c9edf9, - 0xf3c87f9e, - 0x54ca7fed, - 0x2d3a3637, - 0x756f7e9a, - 0xf1ce37ef, - 0x2e677fee, - 0x10ebadf8, - 0xefdecfea, - 0xe52f7d9f, - 0xe12bf1ce, - 0x5f647e9a, - 0x4df8cfea, - 0x5f717d9b, - 0xefeecfea, - 0x5f73e522, - 0xefde5f73, - 0xcfda0b61, - 0x5d8fdf61, - 0xe7c9edf9, - 0x7e9a30d5, - 0x1458bfff, - 0xf3c85fff, - 0xdfffa7f8, - 0x5f5bbffe, - 0x7f7d10d0, - 0x144d5f33, - 0xbfffaf78, - 0x5f5bbffd, - 0xa7f85f33, - 0xbffe77fd, - 0x30bd4e08, - 0xfdcfe5ff, - 0x6e0faff8, - 0x7eef7e9f, - 0xfdeff1cf, - 0x5f17abf8, - 0x0d5b5f5b, - 0xffef79f7, - 0x309eafdd, - 0x5f3147f8, - 0x5f31afed, - 0x7fdd50af, - 0x497847fd, - 0x7f9e7fed, - 0x7dfd70a9, - 0xef7e7ece, - 0x6ba07f9e, - 0x2d227efd, - 0x30db5f5b, - 0xfffd5f5b, - 0xffef5f5b, - 0xffdf0c9c, - 0xafed0a9a, - 0xafdd0c37, - 0x5f37afbd, - 0x7fbdb081, - 0x5f8147f8, - 0x3a11e710, - 0xedf0ccdd, - 0xf3186d0a, - 0x7f0e5f06, - 0x7fedbb38, - 0x3afe7468, - 0x7fedf4fc, - 0x8ffbb951, - 0xb85f77fd, - 0xb0df5ddd, - 0xdefe7fed, - 0x90e1e74d, - 0x6f0dcbf7, - 0xe7decfed, - 0xcb74cfed, - 0xcfeddf6d, - 0x91714f74, - 0x5dd2deef, - 0x9e04e7df, - 0xefbb6ffb, - 0xe7ef7f0e, - 0x9e097fed, - 0xebdbeffa, - 0xeb54affb, - 0x7fea90d7, - 0x7e0cf0c3, - 0xbffff318, - 0x5fffdfff, - 0xac59efea, - 0x7fce1ee5, - 0xe2ff5ee1, - 0xaffbe2ff, - 0x5ee3affb, - 0xf9cc7d0f, - 0xaef8770f, - 0x7d0fb0c6, - 0xeffbbfff, - 0xcfef5ede, - 0x7d0fbfff, - 0x5ede4cf8, - 0x7fddd0bf, - 0x49f847fd, - 0x7efdf0bb, - 0x7fedfffd, - 0x7dfdf0b7, - 0xef7e7e1e, - 0x5ede7f0e, - 0x3a11e710, - 0xedf0ccab, - 0xfb18ad2e, - 0x1ea9bbb8, - 0x74283b7e, - 0x73c2e4bb, - 0x2ada4fb8, - 0xdc21e4bb, - 0xb2a1ffbf, - 0x5e2c43f8, - 0xfc87e1bb, - 0xe74ffd91, - 0x6f0f4fe8, - 0xc7ba32e2, - 0xf396efeb, - 0x600b4f78, - 0xe5bb760b, - 0x53acaef8, - 0x4ef88b0e, - 0xcfef9e09, - 0xabf8751f, - 0xefef5bac, - 0x741f4fe8, - 0x751e760d, - 0x7fdbf081, - 0x741cafce, - 0xefcc7fce, - 0x751e70ac, - 0x741ce7bb, - 0x3372cfed, - 0xafdbefeb, - 0xe5bb760b, - 0x53f2aef8, - 0xafe8e7eb, - 0x4bf8771e, - 0x7e247fed, - 0x4fcbe2cc, - 0x7fbc30a9, - 0x7b0f7a0f, - 0x34d577fd, - 0x308b5db7, - 0xde553e5f, - 0xaf78741f, - 0x741f30f0, - 0xcfef5e2c, - 0x741f3eac, - 0xafb8771e, - 0x5e677fed, - 0x0bd3e2cc, - 0x741ccfec, - 0xe5ca53cd, - 0x6fcb4f74, - 0x5dadde4b, - 0x2ab63d38, - 0x4bb3de30, - 0x751f741c, - 0x6c42effa, - 0xefea7fce, - 0x6ffc30be, - 0xefec3fca, - 0x30b3de2e, - 0xadf85d9e, - 0xaf7daefd, - 0x5d9ede2e, - 0x5d9eafdd, - 0x761f10ac, - 0x1da07efd, - 0x30adfffe, - 0x4908fb18, - 0x5fffdfff, - 0xafbb709b, - 0x4ef85e67, - 0xadf814ad, - 0x7a0f70ad, - 0xcfef50ad, - 0x7a0fde30, - 0x5da0afed, - 0x3c12780f, - 0xefef780f, - 0xefef790f, - 0xa7f85e0f, - 0xffef790f, - 0xefef790f, - 0x14adde2e, - 0x5d9eadfd, - 0x5e2dfffb, - 0xe79addfd, - 0xeff96079, - 0x607ae79a, - 0xddfceff9, - 0x60795dff, - 0x607acfef, - 0xefefefdf, - 0xefbfef7f, - 0xeeffedff, - 0xebffe7ff, - 0xafefafdf, - 0xafbfaf7f, - 0xaeffadff, - 0xabffa7ff, - 0x6fef6fdf, - 0x6fbf6f7f, - 0x6eff6dff, - 0x6bff67ff, - 0x2fef2fdf, - 0x2fbf2f7f, - 0x2eff2dff, - 0x2bff27ff, - 0x4e08fd1f, - 0xe5ff6e0f, - 0xaff87eef, - 0x7e0ffdef, - 0xf11f6079, - 0xabf8f542, - 0x7e0af11c, - 0x37cfae3a, - 0x7fec90be, - 0xadf8efdc, - 0xcfeae52f, - 0x7d0fe12b, - 0xf11c6079, - 0x7e0a4df8, - 0xcfea5dc4, - 0x7d0befec, - 0xcfea5dc6, - 0xe522efdc, - 0x5dc6cfda, - 0x4e08fd1f, - 0x6e0faff8, - 0x7c1f761f, - 0xfdeff91f, - 0x6079abf8, - 0x761cee24, - 0xf91f2bfb, - 0xefefcfec, - 0xf91f6079, - 0x761c27fb, - 0xefdf5da7, - 0xcfdc7fdd, - 0xd09c4bf8, - 0x47fd7c1f, - 0x761ccfcf, - 0x7eef7fed, - 0x7dfdf093, - 0xef7e7f1e, - 0x771efb18, - 0x6079e722, - 0xe6bbe5bb, - 0xae0ae5bb, - 0x600bae85, - 0xe2bbe2bb, - 0xe2bbe2bb, - 0xaf02e2bb, - 0xe2bb2ff9, - 0x6079e2bb -}; - -uint patch_2f00[] = { - 0x30303030, - 0x3e3e3434, - 0xabbf9b99, - 0x4b4fbdbd, - 0x59949334, - 0x9fff37fb, - 0x9b177dd9, - 0x936956bb, - 0xfbdd697b, - 0xdd2fd113, - 0x1db9f7bb, - 0x36313963, - 0x79373369, - 0x3193137f, - 0x7331737a, - 0xf7bb9b99, - 0x9bb19795, - 0x77fdfd3d, - 0x573b773f, - 0x737933f7, - 0xb991d115, - 0x31699315, - 0x31531694, - 0xbf4fbdbd, - 0x35931497, - 0x35376956, - 0xbd697b9d, - 0x96931313, - 0x19797937, - 0x6935af78, - 0xb9b3baa3, - 0xb8788683, - 0x368f78f7, - 0x87778733, - 0x3ffffb3b, - 0x8e8f78b8, - 0x1d118e13, - 0xf3ff3f8b, - 0x6bd8e173, - 0xd1366856, - 0x68d1687b, - 0x3daf78b8, - 0x3a3a3f87, - 0x8f81378f, - 0xf876f887, - 0x77fd8778, - 0x737de8d6, - 0xbbf8bfff, - 0xd8df87f7, - 0xfd876f7b, - 0x8bfff8bd, - 0x8683387d, - 0xb873d87b, - 0x3b8fd7f8, - 0xf7338883, - 0xbb8ee1f8, - 0xef837377, - 0x3337b836, - 0x817d11f8, - 0x7378b878, - 0xd3368b7d, - 0xed731b7d, - 0x833731f3, - 0xf22f3f23 -}; - -uint patch_2e00[] = { - 0x27eeeeee, - 0xeeeeeeee, - 0xeeeeeeee, - 0xeeeeeeee, - 0xee4bf4fb, - 0xdbd259bb, - 0x1979577f, - 0xdfd2d573, - 0xb773f737, - 0x4b4fbdbd, - 0x25b9b177, - 0xd2d17376, - 0x956bbfdd, - 0x697bdd2f, - 0xff9f79ff, - 0xff9ff22f -}; -#endif - -/* - * USB SOF patch arrays. - */ - -#ifdef CONFIG_USB_SOF_UCODE_PATCH - -uint patch_2000[] = { - 0x7fff0000, - 0x7ffd0000, - 0x7ffb0000, - 0x49f7ba5b, - 0xba383ffb, - 0xf9b8b46d, - 0xe5ab4e07, - 0xaf77bffe, - 0x3f7bbf79, - 0xba5bba38, - 0xe7676076, - 0x60750000 -}; - -uint patch_2f00[] = { - 0x3030304c, - 0xcab9e441, - 0xa1aaf220 -}; -#endif - -void -cpm_load_patch(cpm8xx_t *cp) -{ - volatile uint *dp; /* Dual-ported RAM. */ - volatile cpm8xx_t *commproc; - volatile iic_t *iip; - volatile spi_t *spp; - volatile smc_uart_t *smp; - int i; - - commproc = cp; - -#ifdef CONFIG_USB_SOF_UCODE_PATCH - commproc->cp_rccr = 0; - - dp = (uint *)(commproc->cp_dpmem); - for (i=0; i<(sizeof(patch_2000)/4); i++) - *dp++ = patch_2000[i]; - - dp = (uint *)&(commproc->cp_dpmem[0x0f00]); - for (i=0; i<(sizeof(patch_2f00)/4); i++) - *dp++ = patch_2f00[i]; - - commproc->cp_rccr = 0x0009; - - printk("USB SOF microcode patch installed\n"); -#endif /* CONFIG_USB_SOF_UCODE_PATCH */ - -#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ - defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - - commproc->cp_rccr = 0; - - dp = (uint *)(commproc->cp_dpmem); - for (i=0; i<(sizeof(patch_2000)/4); i++) - *dp++ = patch_2000[i]; - - dp = (uint *)&(commproc->cp_dpmem[0x0f00]); - for (i=0; i<(sizeof(patch_2f00)/4); i++) - *dp++ = patch_2f00[i]; - - iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC]; -# define RPBASE 0x0500 - iip->iic_rpbase = RPBASE; - - /* Put SPI above the IIC, also 32-byte aligned. - */ - i = (RPBASE + sizeof(iic_t) + 31) & ~31; - spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI]; - spp->spi_rpbase = i; - -# if defined(CONFIG_I2C_SPI_UCODE_PATCH) - commproc->cp_cpmcr1 = 0x802a; - commproc->cp_cpmcr2 = 0x8028; - commproc->cp_cpmcr3 = 0x802e; - commproc->cp_cpmcr4 = 0x802c; - commproc->cp_rccr = 1; - - printk("I2C/SPI microcode patch installed.\n"); -# endif /* CONFIG_I2C_SPI_UCODE_PATCH */ - -# if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - - dp = (uint *)&(commproc->cp_dpmem[0x0e00]); - for (i=0; i<(sizeof(patch_2e00)/4); i++) - *dp++ = patch_2e00[i]; - - commproc->cp_cpmcr1 = 0x8080; - commproc->cp_cpmcr2 = 0x808a; - commproc->cp_cpmcr3 = 0x8028; - commproc->cp_cpmcr4 = 0x802a; - commproc->cp_rccr = 3; - - smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1]; - smp->smc_rpbase = 0x1FC0; - - printk("I2C/SPI/SMC1 microcode patch installed.\n"); -# endif /* CONFIG_I2C_SPI_SMC1_UCODE_PATCH) */ - -#endif /* some variation of the I2C/SPI patch was selected */ -} - -/* - * Take this entire routine out, since no one calls it and its - * logic is suspect. - */ - -#if 0 -void -verify_patch(volatile immap_t *immr) -{ - volatile uint *dp; - volatile cpm8xx_t *commproc; - int i; - - commproc = (cpm8xx_t *)&immr->im_cpm; - - printk("cp_rccr %x\n", commproc->cp_rccr); - commproc->cp_rccr = 0; - - dp = (uint *)(commproc->cp_dpmem); - for (i=0; i<(sizeof(patch_2000)/4); i++) - if (*dp++ != patch_2000[i]) { - printk("patch_2000 bad at %d\n", i); - dp--; - printk("found 0x%X, wanted 0x%X\n", *dp, patch_2000[i]); - break; - } - - dp = (uint *)&(commproc->cp_dpmem[0x0f00]); - for (i=0; i<(sizeof(patch_2f00)/4); i++) - if (*dp++ != patch_2f00[i]) { - printk("patch_2f00 bad at %d\n", i); - dp--; - printk("found 0x%X, wanted 0x%X\n", *dp, patch_2f00[i]); - break; - } - - commproc->cp_rccr = 0x0009; -} -#endif diff --git a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c b/trunk/arch/powerpc/sysdev/mpc8xx_pic.c deleted file mode 100644 index 2fc2bcd79b5e..000000000000 --- a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c +++ /dev/null @@ -1,197 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mpc8xx_pic.h" - - -#define PIC_VEC_SPURRIOUS 15 - -extern int cpm_get_irq(struct pt_regs *regs); - -static struct device_node *mpc8xx_pic_node; -static struct irq_host *mpc8xx_pic_host; -#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; -static sysconf8xx_t *siu_reg; - -int cpm_get_irq(struct pt_regs *regs); - -static void mpc8xx_unmask_irq(unsigned int virq) -{ - int bit, word; - unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq; - - bit = irq_nr & 0x1f; - word = irq_nr >> 5; - - ppc_cached_irq_mask[word] |= (1 << (31-bit)); - out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); -} - -static void mpc8xx_mask_irq(unsigned int virq) -{ - int bit, word; - unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq; - - bit = irq_nr & 0x1f; - word = irq_nr >> 5; - - ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); - out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); -} - -static void mpc8xx_ack(unsigned int virq) -{ - int bit; - unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq; - - bit = irq_nr & 0x1f; - out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); -} - -static void mpc8xx_end_irq(unsigned int virq) -{ - int bit, word; - unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq; - - bit = irq_nr & 0x1f; - word = irq_nr >> 5; - - ppc_cached_irq_mask[word] |= (1 << (31-bit)); - out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); -} - -static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type) -{ - struct irq_desc *desc = get_irq_desc(virq); - - desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); - desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; - if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) - desc->status |= IRQ_LEVEL; - - if (flow_type & IRQ_TYPE_EDGE_FALLING) { - irq_hw_number_t hw = (unsigned int)irq_map[virq].hwirq; - unsigned int siel = in_be32(&siu_reg->sc_siel); - - /* only external IRQ senses are programmable */ - if ((hw & 1) == 0) { - siel |= (0x80000000 >> hw); - out_be32(&siu_reg->sc_siel, siel); - desc->handle_irq = handle_edge_irq; - } - } - return 0; -} - -static struct irq_chip mpc8xx_pic = { - .typename = " MPC8XX SIU ", - .unmask = mpc8xx_unmask_irq, - .mask = mpc8xx_mask_irq, - .ack = mpc8xx_ack, - .eoi = mpc8xx_end_irq, - .set_type = mpc8xx_set_irq_type, -}; - -unsigned int mpc8xx_get_irq(void) -{ - int irq; - - /* For MPC8xx, read the SIVEC register and shift the bits down - * to get the irq number. - */ - irq = in_be32(&siu_reg->sc_sivec) >> 26; - - if (irq == PIC_VEC_SPURRIOUS) - irq = NO_IRQ; - - return irq_linear_revmap(mpc8xx_pic_host, irq); - -} - -static int mpc8xx_pic_host_match(struct irq_host *h, struct device_node *node) -{ - return mpc8xx_pic_node == node; -} - -static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) -{ - pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw); - - /* Set default irq handle */ - set_irq_chip_and_handler(virq, &mpc8xx_pic, handle_level_irq); - return 0; -} - - -static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct, - u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_flags) -{ - static unsigned char map_pic_senses[4] = { - IRQ_TYPE_EDGE_RISING, - IRQ_TYPE_LEVEL_LOW, - IRQ_TYPE_LEVEL_HIGH, - IRQ_TYPE_EDGE_FALLING, - }; - - *out_hwirq = intspec[0]; - if (intsize > 1 && intspec[1] < 4) - *out_flags = map_pic_senses[intspec[1]]; - else - *out_flags = IRQ_TYPE_NONE; - - return 0; -} - - -static struct irq_host_ops mpc8xx_pic_host_ops = { - .match = mpc8xx_pic_host_match, - .map = mpc8xx_pic_host_map, - .xlate = mpc8xx_pic_host_xlate, -}; - -int mpc8xx_pic_init(void) -{ - struct resource res; - struct device_node *np = NULL; - int ret; - - np = of_find_node_by_type(np, "mpc8xx-pic"); - - if (np == NULL) { - printk(KERN_ERR "Could not find open-pic node\n"); - return -ENOMEM; - } - - mpc8xx_pic_node = of_node_get(np); - - ret = of_address_to_resource(np, 0, &res); - of_node_put(np); - if (ret) - return ret; - - siu_reg = (void *)ioremap(res.start, res.end - res.start + 1); - if (siu_reg == NULL) - return -EINVAL; - - mpc8xx_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &mpc8xx_pic_host_ops, 64); - if (mpc8xx_pic_host == NULL) { - printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n"); - ret = -ENOMEM; - } - - return ret; -} diff --git a/trunk/arch/powerpc/sysdev/mpc8xx_pic.h b/trunk/arch/powerpc/sysdev/mpc8xx_pic.h deleted file mode 100644 index afa2ee6717c1..000000000000 --- a/trunk/arch/powerpc/sysdev/mpc8xx_pic.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _PPC_KERNEL_MPC8xx_H -#define _PPC_KERNEL_MPC8xx_H - -#include -#include - -extern struct hw_interrupt_type mpc8xx_pic; - -int mpc8xx_pic_init(void); -unsigned int mpc8xx_get_irq(void); - -#endif /* _PPC_KERNEL_PPC8xx_H */ diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index aa701cc27ecc..d01ced11694d 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -496,18 +496,13 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi) { unsigned int src = mpic_irq_to_hw(irq); - struct mpic *mpic; if (irq < NUM_ISA_INTERRUPTS) return NULL; - - mpic = irq_desc[irq].chip_data; - if (is_ipi) - *is_ipi = (src >= mpic->ipi_vecs[0] && - src <= mpic->ipi_vecs[3]); + *is_ipi = (src >= MPIC_VEC_IPI_0 && src <= MPIC_VEC_IPI_3); - return mpic; + return irq_desc[irq].chip_data; } /* Convert a cpu mask from logical to physical cpu numbers. */ @@ -545,11 +540,7 @@ static inline void mpic_eoi(struct mpic *mpic) #ifdef CONFIG_SMP static irqreturn_t mpic_ipi_action(int irq, void *dev_id) { - struct mpic *mpic; - - mpic = mpic_find(irq, NULL); - smp_message_recv(mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]); - + smp_message_recv(mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0); return IRQ_HANDLED; } #endif /* CONFIG_SMP */ @@ -672,7 +663,7 @@ static void mpic_end_ht_irq(unsigned int irq) static void mpic_unmask_ipi(unsigned int irq) { struct mpic *mpic = mpic_from_ipi(irq); - unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]; + unsigned int src = mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0; DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src); mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK); @@ -816,11 +807,11 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, DBG("mpic: map virq %d, hwirq 0x%lx\n", virq, hw); - if (hw == mpic->spurious_vec) + if (hw == MPIC_VEC_SPURRIOUS) return -EINVAL; #ifdef CONFIG_SMP - else if (hw >= mpic->ipi_vecs[0]) { + else if (hw >= MPIC_VEC_IPI_0) { WARN_ON(!(mpic->flags & MPIC_PRIMARY)); DBG("mpic: mapping as IPI\n"); @@ -913,7 +904,6 @@ struct mpic * __init mpic_alloc(struct device_node *node, u32 reg; const char *vers; int i; - int intvec_top; u64 paddr = phys_addr; mpic = alloc_bootmem(sizeof(struct mpic)); @@ -922,11 +912,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, memset(mpic, 0, sizeof(struct mpic)); mpic->name = name; - mpic->of_node = of_node_get(node); + mpic->of_node = node ? of_node_get(node) : NULL; - mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, isu_size, + mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 256, &mpic_host_ops, - flags & MPIC_LARGE_VECTORS ? 2048 : 256); + MPIC_VEC_SPURRIOUS); if (mpic->irqhost == NULL) { of_node_put(node); return NULL; @@ -954,21 +944,6 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->irq_count = irq_count; mpic->num_sources = 0; /* so far */ - if (flags & MPIC_LARGE_VECTORS) - intvec_top = 2047; - else - intvec_top = 255; - - mpic->timer_vecs[0] = intvec_top - 8; - mpic->timer_vecs[1] = intvec_top - 7; - mpic->timer_vecs[2] = intvec_top - 6; - mpic->timer_vecs[3] = intvec_top - 5; - mpic->ipi_vecs[0] = intvec_top - 4; - mpic->ipi_vecs[1] = intvec_top - 3; - mpic->ipi_vecs[2] = intvec_top - 2; - mpic->ipi_vecs[3] = intvec_top - 1; - mpic->spurious_vec = intvec_top; - /* Check for "big-endian" in device-tree */ if (node && get_property(node, "big-endian", NULL) != NULL) mpic->flags |= MPIC_BIG_ENDIAN; @@ -1109,6 +1084,11 @@ void __init mpic_init(struct mpic *mpic) int i; BUG_ON(mpic->num_sources == 0); + WARN_ON(mpic->num_sources > MPIC_VEC_IPI_0); + + /* Sanitize source count */ + if (mpic->num_sources > MPIC_VEC_IPI_0) + mpic->num_sources = MPIC_VEC_IPI_0; printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources); @@ -1124,7 +1104,7 @@ void __init mpic_init(struct mpic *mpic) i * MPIC_INFO(TIMER_STRIDE) + MPIC_INFO(TIMER_VECTOR_PRI), MPIC_VECPRI_MASK | - (mpic->timer_vecs[0] + i)); + (MPIC_VEC_TIMER_0 + i)); } /* Initialize IPIs to our reserved vectors and mark them disabled for now */ @@ -1133,7 +1113,7 @@ void __init mpic_init(struct mpic *mpic) mpic_ipi_write(i, MPIC_VECPRI_MASK | (10 << MPIC_VECPRI_PRIORITY_SHIFT) | - (mpic->ipi_vecs[0] + i)); + (MPIC_VEC_IPI_0 + i)); } /* Initialize interrupt sources */ @@ -1156,8 +1136,8 @@ void __init mpic_init(struct mpic *mpic) 1 << hard_smp_processor_id()); } - /* Init spurious vector */ - mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), mpic->spurious_vec); + /* Init spurrious vector */ + mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS); /* Disable 8259 passthrough, if supported */ if (!(mpic->flags & MPIC_NO_PTHROU_DIS)) @@ -1204,9 +1184,9 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) spin_lock_irqsave(&mpic_lock, flags); if (is_ipi) { - reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) & + reg = mpic_ipi_read(src - MPIC_VEC_IPI_0) & ~MPIC_VECPRI_PRIORITY_MASK; - mpic_ipi_write(src - mpic->ipi_vecs[0], + mpic_ipi_write(src - MPIC_VEC_IPI_0, reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); } else { reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) @@ -1227,7 +1207,7 @@ unsigned int mpic_irq_get_priority(unsigned int irq) spin_lock_irqsave(&mpic_lock, flags); if (is_ipi) - reg = mpic_ipi_read(src = mpic->ipi_vecs[0]); + reg = mpic_ipi_read(src = MPIC_VEC_IPI_0); else reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); spin_unlock_irqrestore(&mpic_lock, flags); @@ -1333,7 +1313,7 @@ unsigned int mpic_get_one_irq(struct mpic *mpic) #ifdef DEBUG_LOW DBG("%s: get_one_irq(): %d\n", mpic->name, src); #endif - if (unlikely(src == mpic->spurious_vec)) + if (unlikely(src == MPIC_VEC_SPURRIOUS)) return NO_IRQ; return irq_linear_revmap(mpic->irqhost, src); } @@ -1365,7 +1345,7 @@ void mpic_request_ipis(void) for (i = 0; i < 4; i++) { unsigned int vipi = irq_create_mapping(mpic->irqhost, - mpic->ipi_vecs[0] + i); + MPIC_VEC_IPI_0 + i); if (vipi == NO_IRQ) { printk(KERN_ERR "Failed to map IPI %d\n", i); break; diff --git a/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c b/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c index 4d1dcb45963d..74e48d94f27c 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -323,7 +323,7 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) return irq_linear_revmap(qe_ic->irqhost, irq); } -void qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc) +void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc) { struct qe_ic *qe_ic = desc->handler_data; unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); @@ -332,7 +332,7 @@ void qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc) generic_handle_irq(cascade_irq); } -void qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc) +void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc) { struct qe_ic *qe_ic = desc->handler_data; unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); @@ -352,7 +352,7 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags) return; memset(qe_ic, 0, sizeof(struct qe_ic)); - qe_ic->of_node = of_node_get(node); + qe_ic->of_node = node ? of_node_get(node) : NULL; qe_ic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, NR_QE_IC_INTS, &qe_ic_host_ops, 0); diff --git a/trunk/arch/powerpc/xmon/ppc-opc.c b/trunk/arch/powerpc/xmon/ppc-opc.c index af3780e52e76..5d841f4b3530 100644 --- a/trunk/arch/powerpc/xmon/ppc-opc.c +++ b/trunk/arch/powerpc/xmon/ppc-opc.c @@ -21,7 +21,6 @@ 02110-1301, USA. */ #include -#include #include "nonstdio.h" #include "ppc.h" @@ -4933,7 +4932,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { }; -const int powerpc_num_opcodes = ARRAY_SIZE(powerpc_opcodes); +const int powerpc_num_opcodes = + sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]); /* The macro table. This is only used by the assembler. */ @@ -4989,4 +4989,5 @@ const struct powerpc_macro powerpc_macros[] = { { "clrlslwi.",4, PPCCOM, "rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" }, }; -const int powerpc_num_macros = ARRAY_SIZE(powerpc_macros); +const int powerpc_num_macros = + sizeof (powerpc_macros) / sizeof (powerpc_macros[0]); diff --git a/trunk/arch/powerpc/xmon/spu-opc.c b/trunk/arch/powerpc/xmon/spu-opc.c index 530df3d6d7b2..efffde9edc6e 100644 --- a/trunk/arch/powerpc/xmon/spu-opc.c +++ b/trunk/arch/powerpc/xmon/spu-opc.c @@ -18,7 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -#include #include "spu.h" /* This file holds the Spu opcode table */ @@ -41,4 +40,5 @@ const struct spu_opcode spu_opcodes[] = { #undef APUOPFB }; -const int spu_num_opcodes = ARRAY_SIZE(spu_opcodes); +const int spu_num_opcodes = + sizeof (spu_opcodes) / sizeof (spu_opcodes[0]); diff --git a/trunk/arch/ppc/8xx_io/cs4218_tdm.c b/trunk/arch/ppc/8xx_io/cs4218_tdm.c index 684ed04eb8b8..b7bb5f0b3c5f 100644 --- a/trunk/arch/ppc/8xx_io/cs4218_tdm.c +++ b/trunk/arch/ppc/8xx_io/cs4218_tdm.c @@ -1379,6 +1379,7 @@ static void cs_nosound(unsigned long xx) } static DEFINE_TIMER(beep_timer, cs_nosound, 0, 0); +}; static void cs_mksound(unsigned int hz, unsigned int ticks) { diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index c22e60619d9b..8eb82efe05a1 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -670,6 +670,15 @@ config RADSTONE_PPC7D config PAL4 bool "SBS-Palomar4" +config GEMINI + bool "Synergy-Gemini" + depends on BROKEN + select PPC_INDIRECT_PCI + help + Select Gemini if configuring for a Synergy Microsystems' Gemini + series Single Board Computer. More information is available at: + . + config EST8260 bool "EST8260" ---help--- diff --git a/trunk/arch/ppc/boot/simple/Makefile b/trunk/arch/ppc/boot/simple/Makefile index bcfb6cde70c4..28be01b99c44 100644 --- a/trunk/arch/ppc/boot/simple/Makefile +++ b/trunk/arch/ppc/boot/simple/Makefile @@ -116,6 +116,10 @@ zimageinitrd-$(CONFIG_WALNUT) := zImage.initrd-TREE extra.o-$(CONFIG_CHESTNUT) := misc-chestnut.o end-$(CONFIG_CHESTNUT) := chestnut + zimage-$(CONFIG_GEMINI) := zImage-STRIPELF +zimageinitrd-$(CONFIG_GEMINI) := zImage.initrd-STRIPELF + end-$(CONFIG_GEMINI) := gemini + extra.o-$(CONFIG_KATANA) := misc-katana.o end-$(CONFIG_KATANA) := katana cacheflag-$(CONFIG_KATANA) := -include $(clear_L2_L3) diff --git a/trunk/arch/ppc/boot/simple/misc.c b/trunk/arch/ppc/boot/simple/misc.c index c3d3305eb5ca..a5df08963695 100644 --- a/trunk/arch/ppc/boot/simple/misc.c +++ b/trunk/arch/ppc/boot/simple/misc.c @@ -42,11 +42,14 @@ #endif /* Will / Can the user give input? + * Val Henson has requested that Gemini doesn't wait for the + * user to edit the cmdline or not. */ #if (defined(CONFIG_SERIAL_8250_CONSOLE) \ || defined(CONFIG_VGA_CONSOLE) \ || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ - || defined(CONFIG_SERIAL_MPSC_CONSOLE)) + || defined(CONFIG_SERIAL_MPSC_CONSOLE)) \ + && !defined(CONFIG_GEMINI) #define INTERACTIVE_CONSOLE 1 #endif @@ -175,6 +178,16 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) if (keyb_present) CRT_tstc(); /* Forces keyboard to be initialized */ +#ifdef CONFIG_GEMINI + /* + * If cmd_line is empty and cmd_preset is not, copy cmd_preset + * to cmd_line. This way we can override cmd_preset with the + * command line from Smon. + */ + + if ( (cmd_line[0] == '\0') && (cmd_preset[0] != '\0')) + memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); +#endif /* Display standard Linux/PPC boot prompt for kernel args */ puts("\nLinux/PPC load: "); diff --git a/trunk/arch/ppc/configs/gemini_defconfig b/trunk/arch/ppc/configs/gemini_defconfig new file mode 100644 index 000000000000..ebcd17b097f1 --- /dev/null +++ b/trunk/arch/ppc/configs/gemini_defconfig @@ -0,0 +1,618 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set + +# +# IBM 4xx options +# +# CONFIG_8260 is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_PPC_STD_MMU=y +# CONFIG_PPC_MULTIPLATFORM is not set +# CONFIG_APUS is not set +# CONFIG_WILLOW_2 is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +CONFIG_GEMINI=y +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +CONFIG_ALTIVEC=y +CONFIG_TAU=y +# CONFIG_TAU_INT is not set +# CONFIG_TAU_AVERAGE is not set +# CONFIG_CPU_FREQ is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C7xx is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_OAKNET is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Userland interfaces +# + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_SOLARIS_X86_PARTITION=y +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_KALLSYMS is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set diff --git a/trunk/arch/ppc/kernel/Makefile b/trunk/arch/ppc/kernel/Makefile index 6b4f022111e7..466437f4bcbb 100644 --- a/trunk/arch/ppc/kernel/Makefile +++ b/trunk/arch/ppc/kernel/Makefile @@ -12,6 +12,7 @@ obj-y := entry.o traps.o time.o misc.o \ setup.o \ ppc_htab.o obj-$(CONFIG_MODULES) += ppc_ksyms.o +obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_RAPIDIO) += rio.o obj-$(CONFIG_KGDB) += ppc-stub.o diff --git a/trunk/arch/powerpc/lib/dma-noncoherent.c b/trunk/arch/ppc/kernel/dma-mapping.c similarity index 94% rename from trunk/arch/powerpc/lib/dma-noncoherent.c rename to trunk/arch/ppc/kernel/dma-mapping.c index 48f3d13a3de5..10fec7363962 100644 --- a/trunk/arch/powerpc/lib/dma-noncoherent.c +++ b/trunk/arch/ppc/kernel/dma-mapping.c @@ -22,13 +22,37 @@ * published by the Free Software Foundation. */ +#include +#include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int map_page(unsigned long va, phys_addr_t pa, int flags); #include diff --git a/trunk/arch/ppc/kernel/head.S b/trunk/arch/ppc/kernel/head.S index c7cb9d5f24a3..100052aaea9a 100644 --- a/trunk/arch/ppc/kernel/head.S +++ b/trunk/arch/ppc/kernel/head.S @@ -310,7 +310,12 @@ i##n: \ /* System reset */ /* core99 pmac starts the seconary here by changing the vector, and putting it back to what it was (unknown_exception) when done. */ +#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP) + . = 0x100 + b __secondary_start_gemini +#else EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) +#endif /* Machine check */ . = 0x200 @@ -892,6 +897,19 @@ fix_mem_constants: #endif /* CONFIG_APUS */ #ifdef CONFIG_SMP +#ifdef CONFIG_GEMINI + .globl __secondary_start_gemini +__secondary_start_gemini: + mfspr r4,SPRN_HID0 + ori r4,r4,HID0_ICFI + li r3,0 + ori r3,r3,HID0_ICE + andc r4,r4,r3 + mtspr SPRN_HID0,r4 + sync + b __secondary_start +#endif /* CONFIG_GEMINI */ + .globl __secondary_start_pmac_0 __secondary_start_pmac_0: /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */ diff --git a/trunk/arch/ppc/kernel/ppc_ksyms.c b/trunk/arch/ppc/kernel/ppc_ksyms.c index 1f49503317cb..c8b65ca8a350 100644 --- a/trunk/arch/ppc/kernel/ppc_ksyms.c +++ b/trunk/arch/ppc/kernel/ppc_ksyms.c @@ -43,7 +43,6 @@ #include #include #include -#include #ifdef CONFIG_8xx #include diff --git a/trunk/arch/ppc/lib/rheap.c b/trunk/arch/ppc/lib/rheap.c index d40700795a9c..31e511856dc5 100644 --- a/trunk/arch/ppc/lib/rheap.c +++ b/trunk/arch/ppc/lib/rheap.c @@ -14,7 +14,6 @@ */ #include #include -#include #include #include @@ -655,7 +654,7 @@ void rh_dump(rh_info_t * info) int maxnr; int i, nr; - maxnr = ARRAY_SIZE(st); + maxnr = sizeof(st) / sizeof(st[0]); printk(KERN_INFO "info @0x%p (%d slots empty / %d max)\n", diff --git a/trunk/arch/ppc/mm/pgtable.c b/trunk/arch/ppc/mm/pgtable.c index 82b06a1ef95d..354a9408f024 100644 --- a/trunk/arch/ppc/mm/pgtable.c +++ b/trunk/arch/ppc/mm/pgtable.c @@ -313,8 +313,11 @@ void __init mapin_ram(void) } } +/* is x a power of 2? */ +#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) + /* is x a power of 4? */ -#define is_power_of_4(x) is_power_of_2(x) && (ffs(x) & 1)) +#define is_power_of_4(x) ((x) != 0 && (((x) & (x-1)) == 0) && (ffs(x) & 1)) /* * Set up a mapping for a block of I/O. diff --git a/trunk/arch/ppc/platforms/Makefile b/trunk/arch/ppc/platforms/Makefile index e17fad470621..90c622294423 100644 --- a/trunk/arch/ppc/platforms/Makefile +++ b/trunk/arch/ppc/platforms/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_TQM8260) += tqm8260_setup.o obj-$(CONFIG_CPCI690) += cpci690.o obj-$(CONFIG_EV64260) += ev64260.o obj-$(CONFIG_CHESTNUT) += chestnut.o +obj-$(CONFIG_GEMINI) += gemini_pci.o gemini_setup.o gemini_prom.o obj-$(CONFIG_LOPEC) += lopec.o obj-$(CONFIG_KATANA) += katana.o obj-$(CONFIG_HDPU) += hdpu.o diff --git a/trunk/arch/ppc/platforms/gemini.h b/trunk/arch/ppc/platforms/gemini.h new file mode 100644 index 000000000000..5528fd0a1216 --- /dev/null +++ b/trunk/arch/ppc/platforms/gemini.h @@ -0,0 +1,165 @@ +/* + * Onboard registers and descriptions for Synergy Microsystems' + * "Gemini" boards. + * + */ +#ifdef __KERNEL__ +#ifndef __PPC_GEMINI_H +#define __PPC_GEMINI_H + +/* Registers */ + +#define GEMINI_SERIAL_B (0xffeffb00) +#define GEMINI_SERIAL_A (0xffeffb08) +#define GEMINI_USWITCH (0xffeffd00) +#define GEMINI_BREV (0xffeffe00) +#define GEMINI_BECO (0xffeffe08) +#define GEMINI_FEAT (0xffeffe10) +#define GEMINI_BSTAT (0xffeffe18) +#define GEMINI_CPUSTAT (0xffeffe20) +#define GEMINI_L2CFG (0xffeffe30) +#define GEMINI_MEMCFG (0xffeffe38) +#define GEMINI_FLROM (0xffeffe40) +#define GEMINI_P0PCI (0xffeffe48) +#define GEMINI_FLWIN (0xffeffe50) +#define GEMINI_P0INTMASK (0xffeffe60) +#define GEMINI_P0INTAP (0xffeffe68) +#define GEMINI_PCIERR (0xffeffe70) +#define GEMINI_LEDBASE (0xffeffe80) +#define GEMINI_RTC (0xffe9fff8) +#define GEMINI_LEDS 8 +#define GEMINI_SWITCHES 8 + + +/* Flash ROM bit definitions */ +#define GEMINI_FLS_WEN (1<<0) +#define GEMINI_FLS_JMP (1<<6) +#define GEMINI_FLS_BOOT (1<<7) + +/* Memory bit definitions */ +#define GEMINI_MEM_TYPE_MASK 0xc0 +#define GEMINI_MEM_SIZE_MASK 0x38 +#define GEMINI_MEM_BANK_MASK 0x07 + +/* L2 cache bit definitions */ +#define GEMINI_L2_SIZE_MASK 0xc0 +#define GEMINI_L2_RATIO_MASK 0x03 + +/* Timebase register bit definitons */ +#define GEMINI_TIMEB0_EN (1<<0) +#define GEMINI_TIMEB1_EN (1<<1) +#define GEMINI_TIMEB2_EN (1<<2) +#define GEMINI_TIMEB3_EN (1<<3) + +/* CPU status bit definitions */ +#define GEMINI_CPU_ID_MASK 0x03 +#define GEMINI_CPU_COUNT_MASK 0x0c +#define GEMINI_CPU0_HALTED (1<<4) +#define GEMINI_CPU1_HALTED (1<<5) +#define GEMINI_CPU2_HALTED (1<<6) +#define GEMINI_CPU3_HALTED (1<<7) + +/* Board status bit definitions */ +#define GEMINI_BRD_FAIL (1<<0) /* FAIL led is lit */ +#define GEMINI_BRD_BUS_MASK 0x0c /* PowerPC bus speed */ + +/* Board family/feature bit descriptions */ +#define GEMINI_FEAT_HAS_FLASH (1<<0) +#define GEMINI_FEAT_HAS_ETH (1<<1) +#define GEMINI_FEAT_HAS_SCSI (1<<2) +#define GEMINI_FEAT_HAS_P0 (1<<3) +#define GEMINI_FEAT_FAM_MASK 0xf0 + +/* Mod/ECO bit definitions */ +#define GEMINI_ECO_LEVEL_MASK 0x0f +#define GEMINI_MOD_MASK 0xf0 + +/* Type/revision bit definitions */ +#define GEMINI_REV_MASK 0x0f +#define GEMINI_TYPE_MASK 0xf0 + +/* User switch definitions */ +#define GEMINI_SWITCH_VERBOSE 1 /* adds "debug" to boot cmd line */ +#define GEMINI_SWITCH_SINGLE_USER 7 /* boots into "single-user" mode */ + +#define SGS_RTC_CONTROL 0 +#define SGS_RTC_SECONDS 1 +#define SGS_RTC_MINUTES 2 +#define SGS_RTC_HOURS 3 +#define SGS_RTC_DAY 4 +#define SGS_RTC_DAY_OF_MONTH 5 +#define SGS_RTC_MONTH 6 +#define SGS_RTC_YEAR 7 + +#define SGS_RTC_SET 0x80 +#define SGS_RTC_IS_STOPPED 0x80 + +#define GRACKLE_CONFIG_ADDR_ADDR (0xfec00000) +#define GRACKLE_CONFIG_DATA_ADDR (0xfee00000) + +#define GEMINI_BOOT_INIT (0xfff00100) + +#ifndef __ASSEMBLY__ + +static inline void grackle_write( unsigned long addr, unsigned long data ) +{ + __asm__ __volatile__( + " stwbrx %1, 0, %0\n \ + sync\n \ + stwbrx %3, 0, %2\n \ + sync " + : /* no output */ + : "r" (GRACKLE_CONFIG_ADDR_ADDR), "r" (addr), + "r" (GRACKLE_CONFIG_DATA_ADDR), "r" (data)); +} + +static inline unsigned long grackle_read( unsigned long addr ) +{ + unsigned long val; + + __asm__ __volatile__( + " stwbrx %1, 0, %2\n \ + sync\n \ + lwbrx %0, 0, %3\n \ + sync " + : "=r" (val) + : "r" (addr), "r" (GRACKLE_CONFIG_ADDR_ADDR), + "r" (GRACKLE_CONFIG_DATA_ADDR)); + + return val; +} + +static inline void gemini_led_on( int led ) +{ + if (led >= 0 && led < GEMINI_LEDS) + *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 1; +} + +static inline void gemini_led_off(int led) +{ + if (led >= 0 && led < GEMINI_LEDS) + *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 0; +} + +static inline int gemini_led_val(int led) +{ + int val = 0; + if (led >= 0 && led < GEMINI_LEDS) + val = *(unsigned char *)(GEMINI_LEDBASE + (led<<3)); + return (val & 0x1); +} + +/* returns processor id from the board */ +static inline int gemini_processor(void) +{ + unsigned char cpu = *(unsigned char *)(GEMINI_CPUSTAT); + return (int) ((cpu == 0) ? 4 : (cpu & GEMINI_CPU_ID_MASK)); +} + + +extern void _gemini_reboot(void); +extern void gemini_prom_init(void); +extern void gemini_init_l2(void); +#endif /* __ASSEMBLY__ */ +#endif +#endif /* __KERNEL__ */ diff --git a/trunk/arch/ppc/platforms/gemini_pci.c b/trunk/arch/ppc/platforms/gemini_pci.c new file mode 100644 index 000000000000..95656091ba2b --- /dev/null +++ b/trunk/arch/ppc/platforms/gemini_pci.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +void __init gemini_pcibios_fixup(void) +{ + int i; + struct pci_dev *dev = NULL; + + for_each_pci_dev(dev) { + for(i = 0; i < 6; i++) { + if (dev->resource[i].flags & IORESOURCE_IO) { + dev->resource[i].start |= (0xfe << 24); + dev->resource[i].end |= (0xfe << 24); + } + } + } +} + + +/* The "bootloader" for Synergy boards does none of this for us, so we need to + lay it all out ourselves... --Dan */ +void __init gemini_find_bridges(void) +{ + struct pci_controller* hose; + + ppc_md.pcibios_fixup = gemini_pcibios_fixup; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); +} diff --git a/trunk/arch/ppc/platforms/gemini_prom.S b/trunk/arch/ppc/platforms/gemini_prom.S new file mode 100644 index 000000000000..e8c84d24f01f --- /dev/null +++ b/trunk/arch/ppc/platforms/gemini_prom.S @@ -0,0 +1,90 @@ +/* + * Not really prom support code (yet), but sort of anti-prom code. The current + * bootloader does a number of things it shouldn't and doesn't do things that it + * should. The stuff in here is mainly a hodge-podge collection of setup code + * to get the board up and running. + * ---Dan + */ + +#include +#include +#include +#include + +/* + * On 750's the MMU is on when Linux is booted, so we need to clear out the + * bootloader's BAT settings, make sure we're in supervisor state (gotcha!), + * and turn off the MMU. + * + */ + +_GLOBAL(gemini_prom_init) +#ifdef CONFIG_SMP + /* Since the MMU's on, get stuff in rom space that we'll need */ + lis r4,GEMINI_CPUSTAT@h + ori r4,r4,GEMINI_CPUSTAT@l + lbz r5,0(r4) + andi. r5,r5,3 + mr r24,r5 /* cpu # used later on */ +#endif + mfmsr r4 + li r3,MSR_PR /* ensure supervisor! */ + ori r3,r3,MSR_IR|MSR_DR + andc r4,r4,r3 + mtmsr r4 + isync +#if 0 + /* zero out the bats now that the MMU is off */ +prom_no_mmu: + li r3,0 + mtspr SPRN_IBAT0U,r3 + mtspr SPRN_IBAT0L,r3 + mtspr SPRN_IBAT1U,r3 + mtspr SPRN_IBAT1L,r3 + mtspr SPRN_IBAT2U,r3 + mtspr SPRN_IBAT2L,r3 + mtspr SPRN_IBAT3U,r3 + mtspr SPRN_IBAT3L,r3 + + mtspr SPRN_DBAT0U,r3 + mtspr SPRN_DBAT0L,r3 + mtspr SPRN_DBAT1U,r3 + mtspr SPRN_DBAT1L,r3 + mtspr SPRN_DBAT2U,r3 + mtspr SPRN_DBAT2L,r3 + mtspr SPRN_DBAT3U,r3 + mtspr SPRN_DBAT3L,r3 +#endif + + /* the bootloader (as far as I'm currently aware) doesn't mess with page + tables, but since we're already here, might as well zap these, too */ + li r4,0 + mtspr SPRN_SDR1,r4 + + li r4,16 + mtctr r4 + li r3,0 + li r4,0 +3: mtsrin r3,r4 + addi r3,r3,1 + bdnz 3b + +#ifdef CONFIG_SMP + /* The 750 book (and Mot/IBM support) says that this will "assist" snooping + when in SMP. Not sure yet whether this should stay or leave... */ + mfspr r4,SPRN_HID0 + ori r4,r4,HID0_ABE + mtspr SPRN_HID0,r4 + sync +#endif /* CONFIG_SMP */ + blr + +/* apparently, SMon doesn't pay attention to HID0[SRST]. Disable the MMU and + branch to 0xfff00100 */ +_GLOBAL(_gemini_reboot) + lis r5,GEMINI_BOOT_INIT@h + ori r5,r5,GEMINI_BOOT_INIT@l + li r6,MSR_IP + mtspr SPRN_SRR0,r5 + mtspr SPRN_SRR1,r6 + rfi diff --git a/trunk/arch/ppc/platforms/gemini_serial.h b/trunk/arch/ppc/platforms/gemini_serial.h new file mode 100644 index 000000000000..b915eff79fdb --- /dev/null +++ b/trunk/arch/ppc/platforms/gemini_serial.h @@ -0,0 +1,40 @@ +#ifdef __KERNEL__ +#ifndef __ASMPPC_GEMINI_SERIAL_H +#define __ASMPPC_GEMINI_SERIAL_H + +#include + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 4 +#endif + +/* Rate for the 24.576 Mhz clock for the onboard serial chip */ +#define BASE_BAUD (24576000 / 16) + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) +#endif + +#define STD_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, GEMINI_SERIAL_A, 15, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, GEMINI_SERIAL_B, 14, STD_COM_FLAGS }, /* ttyS1 */ \ + +#ifdef CONFIG_GEMINI_PU32 +#define PU32_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, NULL, 0, STD_COM_FLAGS }, +#else +#define PU32_SERIAL_PORT_DEFNS +#endif + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DEFNS \ + PU32_SERIAL_PORT_DEFNS + +#endif +#endif /* __KERNEL__ */ diff --git a/trunk/arch/ppc/platforms/gemini_setup.c b/trunk/arch/ppc/platforms/gemini_setup.c new file mode 100644 index 000000000000..f48048f362a8 --- /dev/null +++ b/trunk/arch/ppc/platforms/gemini_setup.c @@ -0,0 +1,577 @@ +/* + * Copyright (C) 1995 Linus Torvalds + * Adapted from 'alpha' version by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu) + * Synergy Microsystems board support by Dan Cox (dan@synergymicro.com) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void gemini_find_bridges(void); +static int gemini_get_clock_speed(void); +extern void gemini_pcibios_fixup(void); + +static char *gemini_board_families[] = { + "VGM", "VSS", "KGM", "VGR", "VCM", "VCS", "KCM", "VCR" +}; +static int gemini_board_count = sizeof(gemini_board_families) / + sizeof(gemini_board_families[0]); + +static unsigned int cpu_7xx[16] = { + 0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 +}; +static unsigned int cpu_6xx[16] = { + 0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0 +}; + +/* + * prom_init is the Gemini version of prom.c:prom_init. We only need + * the BSS clearing code, so I copied that out of prom.c. This is a + * lot simpler than hacking prom.c so it will build with Gemini. -VAL + */ + +#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset)) + +unsigned long +prom_init(void) +{ + unsigned long offset = reloc_offset(); + unsigned long phys; + extern char __bss_start, _end; + + /* First zero the BSS -- use memset, some arches don't have + * caches on yet */ + memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start); + + /* Default */ + phys = offset + KERNELBASE; + + gemini_prom_init(); + + return phys; +} + +int +gemini_show_cpuinfo(struct seq_file *m) +{ + unsigned char reg, rev; + char *family; + unsigned int type; + + reg = readb(GEMINI_FEAT); + family = gemini_board_families[((reg>>4) & 0xf)]; + if (((reg>>4) & 0xf) > gemini_board_count) + printk(KERN_ERR "cpuinfo(): unable to determine board family\n"); + + reg = readb(GEMINI_BREV); + type = (reg>>4) & 0xf; + rev = reg & 0xf; + + reg = readb(GEMINI_BECO); + + seq_printf(m, "machine\t\t: Gemini %s%d, rev %c, eco %d\n", + family, type, (rev + 'A'), (reg & 0xf)); + + seq_printf(m, "board\t\t: Gemini %s", family); + if (type > 9) + seq_printf(m, "%c", (type - 10) + 'A'); + else + seq_printf(m, "%d", type); + + seq_printf(m, ", rev %c, eco %d\n", (rev + 'A'), (reg & 0xf)); + + seq_printf(m, "clock\t\t: %dMhz\n", gemini_get_clock_speed()); + + return 0; +} + +static u_char gemini_openpic_initsenses[] = { + 1, + 1, + 1, + 1, + 0, + 0, + 1, /* remainder are level-triggered */ +}; + +#define GEMINI_MPIC_ADDR (0xfcfc0000) +#define GEMINI_MPIC_PCI_CFG (0x80005800) + +void __init gemini_openpic_init(void) +{ + + OpenPIC_Addr = (volatile struct OpenPIC *) + grackle_read(GEMINI_MPIC_PCI_CFG + 0x10); + OpenPIC_InitSenses = gemini_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof( gemini_openpic_initsenses ); + + ioremap( GEMINI_MPIC_ADDR, OPENPIC_SIZE); +} + + +extern unsigned long loops_per_jiffy; +extern int root_mountflags; +extern char cmd_line[]; + +void +gemini_heartbeat(void) +{ + static unsigned long led = GEMINI_LEDBASE+(4*8); + static char direction = 8; + + + /* We only want to do this on 1 CPU */ + if (smp_processor_id()) + return; + *(char *)led = 0; + if ( (led + direction) > (GEMINI_LEDBASE+(7*8)) || + (led + direction) < (GEMINI_LEDBASE+(4*8)) ) + direction *= -1; + led += direction; + *(char *)led = 0xff; + ppc_md.heartbeat_count = ppc_md.heartbeat_reset; +} + +void __init gemini_setup_arch(void) +{ + extern char cmd_line[]; + + + loops_per_jiffy = 50000000/HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + /* bootable off CDROM */ + if (initrd_start) + ROOT_DEV = Root_SR0; + else +#endif + ROOT_DEV = Root_SDA1; + + /* nothing but serial consoles... */ + sprintf(cmd_line, "%s console=ttyS0", cmd_line); + + printk("Boot arguments: %s\n", cmd_line); + + ppc_md.heartbeat = gemini_heartbeat; + ppc_md.heartbeat_reset = HZ/8; + ppc_md.heartbeat_count = 1; + + /* Lookup PCI hosts */ + gemini_find_bridges(); + /* take special pains to map the MPIC, since it isn't mapped yet */ + gemini_openpic_init(); + /* start the L2 */ + gemini_init_l2(); +} + + +int +gemini_get_clock_speed(void) +{ + unsigned long hid1, pvr; + int clock; + + pvr = mfspr(SPRN_PVR); + hid1 = (mfspr(SPRN_HID1) >> 28) & 0xf; + if (PVR_VER(pvr) == 8 || + PVR_VER(pvr) == 12) + hid1 = cpu_7xx[hid1]; + else + hid1 = cpu_6xx[hid1]; + + switch((readb(GEMINI_BSTAT) & 0xc) >> 2) { + + case 0: + default: + clock = (hid1*100)/3; + break; + + case 1: + clock = (hid1*125)/3; + break; + + case 2: + clock = (hid1*50); + break; + } + + return clock; +} + +void __init gemini_init_l2(void) +{ + unsigned char reg, brev, fam, creg; + unsigned long cache; + unsigned long pvr; + + reg = readb(GEMINI_L2CFG); + brev = readb(GEMINI_BREV); + fam = readb(GEMINI_FEAT); + pvr = mfspr(SPRN_PVR); + + switch(PVR_VER(pvr)) { + + case 8: + if (reg & 0xc0) + cache = (((reg >> 6) & 0x3) << 28); + else + cache = 0x3 << 28; + +#ifdef CONFIG_SMP + /* Pre-3.0 processor revs had snooping errata. Leave + their L2's disabled with SMP. -- Dan */ + if (PVR_CFG(pvr) < 3) { + printk("Pre-3.0 750; L2 left disabled!\n"); + return; + } +#endif /* CONFIG_SMP */ + + /* Special case: VGM5-B's came before L2 ratios were set on + the board. Processor speed shouldn't be too high, so + set L2 ratio to 1:1.5. */ + if ((brev == 0x51) && ((fam & 0xa0) >> 4) == 0) + reg |= 1; + + /* determine best cache ratio based upon what the board + tells us (which sometimes _may_ not be true) and + the processor speed. */ + else { + if (gemini_get_clock_speed() > 250) + reg = 2; + } + break; + case 12: + { + static unsigned long l2_size_val = 0; + + if (!l2_size_val) + l2_size_val = _get_L2CR(); + cache = l2_size_val; + break; + } + case 4: + case 9: + creg = readb(GEMINI_CPUSTAT); + if (((creg & 0xc) >> 2) != 1) + printk("Dual-604 boards don't support the use of L2\n"); + else + writeb(1, GEMINI_L2CFG); + return; + default: + printk("Unknown processor; L2 left disabled\n"); + return; + } + + cache |= ((1<>2)&0x3) { + case 0: + default: + freq = 66667; + break; + case 1: + freq = 83000; + break; + case 2: + freq = 100000; + break; + } + + freq *= 1000; + divisor = 4; + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +unsigned long __init gemini_find_end_of_memory(void) +{ + unsigned long total; + unsigned char reg; + + reg = readb(GEMINI_MEMCFG); + total = ((1<<((reg & 0x7) - 1)) * + (8<<((reg >> 3) & 0x7))); + total *= (1024*1024); + return total; +} + +static void __init +gemini_map_io(void) +{ + io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO); + io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO); +} + +#ifdef CONFIG_SMP +static int +smp_gemini_probe(void) +{ + int i, nr; + + nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK) >> 2; + if (nr == 0) + nr = 4; + + if (nr > 1) { + openpic_request_IPIs(); + for (i = 1; i < nr; ++i) + smp_hw_index[i] = i; + } + + return nr; +} + +static void +smp_gemini_kick_cpu(int nr) +{ + openpic_reset_processor_phys(1 << nr); + openpic_reset_processor_phys(0); +} + +static void +smp_gemini_setup_cpu(int cpu_nr) +{ + if (OpenPIC_Addr) + do_openpic_setup_cpu(); + if (cpu_nr > 0) + gemini_init_l2(); +} + +static struct smp_ops_t gemini_smp_ops = { + smp_openpic_message_pass, + smp_gemini_probe, + smp_gemini_kick_cpu, + smp_gemini_setup_cpu, + .give_timebase = smp_generic_give_timebase, + .take_timebase = smp_generic_take_timebase, +}; +#endif /* CONFIG_SMP */ + +void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + int i; + + /* Restore BATs for now */ + mtspr(SPRN_DBAT3U, 0xf0001fff); + mtspr(SPRN_DBAT3L, 0xf000002a); + + parse_bootinfo(find_bootinfo()); + + for(i = 0; i < GEMINI_LEDS; i++) + gemini_led_off(i); + + ISA_DMA_THRESHOLD = 0; + DMA_MODE_READ = 0; + DMA_MODE_WRITE = 0; + +#ifdef CONFIG_BLK_DEV_INITRD + if ( r4 ) + { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif + + ppc_md.setup_arch = gemini_setup_arch; + ppc_md.show_cpuinfo = gemini_show_cpuinfo; + ppc_md.init_IRQ = gemini_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + ppc_md.init = NULL; + + ppc_md.restart = gemini_restart; + ppc_md.power_off = gemini_power_off; + ppc_md.halt = gemini_halt; + + ppc_md.time_init = gemini_time_init; + ppc_md.set_rtc_time = gemini_set_rtc_time; + ppc_md.get_rtc_time = gemini_get_rtc_time; + ppc_md.calibrate_decr = gemini_calibrate_decr; + + ppc_md.find_end_of_memory = gemini_find_end_of_memory; + ppc_md.setup_io_mappings = gemini_map_io; + + ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup; + +#ifdef CONFIG_SMP + smp_ops = &gemini_smp_ops; +#endif /* CONFIG_SMP */ +} diff --git a/trunk/arch/ppc/platforms/mpc866ads_setup.c b/trunk/arch/ppc/platforms/mpc866ads_setup.c index 5b05d4bd0df7..8a0c07eb4449 100644 --- a/trunk/arch/ppc/platforms/mpc866ads_setup.c +++ b/trunk/arch/ppc/platforms/mpc866ads_setup.c @@ -369,7 +369,7 @@ int __init mpc866ads_init(void) ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART); #endif -#ifdef CONFIG_SERIAL_CPM_SMC2 +#ifdef CONFIG_SERIAL_CPM_SMC ppc_sys_device_enable(MPC8xx_CPM_SMC2); ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART); #endif diff --git a/trunk/arch/ppc/syslib/Makefile b/trunk/arch/ppc/syslib/Makefile index d84f04666972..dca23f2ef851 100644 --- a/trunk/arch/ppc/syslib/Makefile +++ b/trunk/arch/ppc/syslib/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o obj-$(CONFIG_EV64360) += todc_time.o obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o +obj-$(CONFIG_GEMINI) += open_pic.o obj-$(CONFIG_GT64260) += gt64260_pic.o obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o obj-$(CONFIG_HDPU) += pci_auto.o diff --git a/trunk/arch/ppc/syslib/m8260_pci_erratum9.c b/trunk/arch/ppc/syslib/m8260_pci_erratum9.c index ebb8c8f8f30c..5475709ce07b 100644 --- a/trunk/arch/ppc/syslib/m8260_pci_erratum9.c +++ b/trunk/arch/ppc/syslib/m8260_pci_erratum9.c @@ -105,8 +105,7 @@ void idma_pci9_init(void) idma_reg[IDMA_CHAN].idmr = 0; /* mask all IDMA interrupts */ idma_reg[IDMA_CHAN].idsr = 0xff; /* clear all event flags */ - printk(KERN_WARNING - "Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n", + printk("<4>Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n", IDMA_CHAN + 1); return; diff --git a/trunk/arch/ppc/syslib/m8xx_setup.c b/trunk/arch/ppc/syslib/m8xx_setup.c index 01e48d88f22d..d8d299bd1a12 100644 --- a/trunk/arch/ppc/syslib/m8xx_setup.c +++ b/trunk/arch/ppc/syslib/m8xx_setup.c @@ -77,7 +77,7 @@ static struct mtd_partition mpc8xxads_partitions[] = { } }; -#define mpc8xxads_part_num ARRAY_SIZE(mpc8xxads_partitions) +#define mpc8xxads_part_num (sizeof (mpc8xxads_partitions) / sizeof (mpc8xxads_partitions[0])) #endif diff --git a/trunk/arch/ppc/syslib/ppc85xx_rio.c b/trunk/arch/ppc/syslib/ppc85xx_rio.c index 2b097800cdd9..05b0e9415085 100644 --- a/trunk/arch/ppc/syslib/ppc85xx_rio.c +++ b/trunk/arch/ppc/syslib/ppc85xx_rio.c @@ -59,6 +59,8 @@ #define DBELL_TID(x) (*(u8 *)(x + DOORBELL_TID_OFFSET)) #define DBELL_INF(x) (*(u16 *)(x + DOORBELL_INFO_OFFSET)) +#define is_power_of_2(x) (((x) & ((x) - 1)) == 0) + struct rio_atmu_regs { u32 rowtar; u32 pad1; diff --git a/trunk/arch/ppc/xmon/ppc-opc.c b/trunk/arch/ppc/xmon/ppc-opc.c index 034313cef6e7..533a6c9973d4 100644 --- a/trunk/arch/ppc/xmon/ppc-opc.c +++ b/trunk/arch/ppc/xmon/ppc-opc.c @@ -19,7 +19,6 @@ along with this file; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include -#include #include "ansidecl.h" #include "ppc.h" @@ -2670,7 +2669,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { }; -const int powerpc_num_opcodes = ARRAY_SIZE(powerpc_opcodes); +const int powerpc_num_opcodes = + sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]); /* The macro table. This is only used by the assembler. */ @@ -2717,4 +2717,5 @@ const struct powerpc_macro powerpc_macros[] = { }; -const int powerpc_num_macros = ARRAY_SIZE(powerpc_macros); +const int powerpc_num_macros = + sizeof (powerpc_macros) / sizeof (powerpc_macros[0]); diff --git a/trunk/arch/ppc/xmon/start.c b/trunk/arch/ppc/xmon/start.c index 8f0b953179fa..d74a883e5bde 100644 --- a/trunk/arch/ppc/xmon/start.c +++ b/trunk/arch/ppc/xmon/start.c @@ -58,7 +58,10 @@ static struct sysrq_key_op sysrq_xmon_op = void xmon_map_scc(void) { -#if defined(CONFIG_405GP) +#if defined(CONFIG_GEMINI) + /* should already be mapped by the kernel boot */ + sccd = (volatile unsigned char *) 0xffeffb08; +#elif defined(CONFIG_405GP) sccd = (volatile unsigned char *)0xef600300; #elif defined(CONFIG_440EP) sccd = (volatile unsigned char *) ioremap(PPC440EP_UART0_ADDR, 8); diff --git a/trunk/arch/x86_64/kernel/early-quirks.c b/trunk/arch/x86_64/kernel/early-quirks.c index bd30d138113f..49802f1bee94 100644 --- a/trunk/arch/x86_64/kernel/early-quirks.c +++ b/trunk/arch/x86_64/kernel/early-quirks.c @@ -32,7 +32,7 @@ static void via_bugs(void) static int nvidia_hpet_detected __initdata; -static int __init nvidia_hpet_check(struct acpi_table_header *header) +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) { nvidia_hpet_detected = 1; return 0; @@ -53,7 +53,7 @@ static void nvidia_bugs(void) return; nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check); + acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { acpi_skip_timer_override = 1; printk(KERN_INFO "Nvidia board " diff --git a/trunk/arch/x86_64/kernel/genapic.c b/trunk/arch/x86_64/kernel/genapic.c index 0b3603adf56d..b007433f96bb 100644 --- a/trunk/arch/x86_64/kernel/genapic.c +++ b/trunk/arch/x86_64/kernel/genapic.c @@ -58,8 +58,8 @@ void __init clustered_apic_check(void) * Some x86_64 machines use physical APIC mode regardless of how many * procs/clusters are present (x86_64 ES7000 is an example). */ - if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID) - if (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) { + if (acpi_fadt.revision > FADT2_REVISION_ID) + if (acpi_fadt.force_apic_physical_destination_mode) { genapic = &apic_cluster; goto print; } diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c index 6be6730acb5c..d7bad90a5ad8 100644 --- a/trunk/arch/x86_64/kernel/io_apic.c +++ b/trunk/arch/x86_64/kernel/io_apic.c @@ -1956,31 +1956,24 @@ static struct irq_chip msi_chip = { .retrigger = ioapic_retrigger_irq, }; -int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) +int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) { struct msi_msg msg; - int irq, ret; - irq = create_irq(); - if (irq < 0) - return irq; - - set_irq_msi(irq, desc); + int ret; ret = msi_compose_msg(dev, irq, &msg); - if (ret < 0) { - destroy_irq(irq); + if (ret < 0) return ret; - } write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return irq; + return 0; } void arch_teardown_msi_irq(unsigned int irq) { - destroy_irq(irq); + return; } #endif /* CONFIG_PCI_MSI */ diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index 50dd8bef850e..08072568847d 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -798,7 +798,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) return gsi; /* Don't set up the ACPI SCI because it's already set up */ - if (acpi_gbl_FADT.sci_interrupt == gsi) + if (acpi_fadt.sci_int == gsi) return gsi; ioapic = mp_find_ioapic(gsi); diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index 335cc91c49b7..5cc76d0d331f 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -498,7 +498,7 @@ static unsigned long get_cmos_time(void) { unsigned int year, mon, day, hour, min, sec; unsigned long flags; - unsigned century = 0; + unsigned extyear = 0; spin_lock_irqsave(&rtc_lock, flags); @@ -510,9 +510,9 @@ static unsigned long get_cmos_time(void) mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); #ifdef CONFIG_ACPI - if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && - acpi_gbl_FADT.century) - century = CMOS_READ(acpi_gbl_FADT.century); + if (acpi_fadt.revision >= FADT2_REVISION_ID && + acpi_fadt.century) + extyear = CMOS_READ(acpi_fadt.century); #endif } while (sec != CMOS_READ(RTC_SECONDS)); @@ -530,10 +530,10 @@ static unsigned long get_cmos_time(void) BCD_TO_BIN(mon); BCD_TO_BIN(year); - if (century) { - BCD_TO_BIN(century); - year += century * 100; - printk(KERN_INFO "Extended CMOS year: %d\n", century * 100); + if (extyear) { + BCD_TO_BIN(extyear); + year += extyear; + printk(KERN_INFO "Extended CMOS year: %d\n", extyear); } else { /* * x86-64 systems only exists since 2002. @@ -954,7 +954,7 @@ __cpuinit int unsynchronized_tsc(void) if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { #ifdef CONFIG_ACPI /* But TSC doesn't tick in C3 so don't use it there */ - if (acpi_gbl_FADT.header.length > 0 && acpi_gbl_FADT.C3latency < 1000) + if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000) return 1; #endif return 0; diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index 2efe215fc76a..1087e150a218 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -101,7 +101,7 @@ static __init inline int srat_disabled(void) static __init int slit_valid(struct acpi_table_slit *slit) { int i, j; - int d = slit->locality_count; + int d = slit->localities; for (i = 0; i < d; i++) { for (j = 0; j < d; j++) { u8 val = slit->entry[d*i + j]; @@ -127,18 +127,18 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) /* Callback for Proximity Domain -> LAPIC mapping */ void __init -acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) +acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) { int pxm, node; if (srat_disabled()) return; - if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) { + if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) { bad_srat(); return; } - if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0) + if (pa->flags.enabled == 0) return; - pxm = pa->proximity_domain_lo; + pxm = pa->proximity_domain; node = setup_node(pxm); if (node < 0) { printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm); @@ -254,21 +254,21 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) /* Looks good */ if (nd->start == nd->end) { - nd->start = start; - nd->end = end; + nd->start = start; + nd->end = end; changed = 1; - } else { - if (nd->start == end) { - nd->start = start; + } else { + if (nd->start == end) { + nd->start = start; changed = 1; } - if (nd->end == start) { - nd->end = end; + if (nd->end == start) { + nd->end = end; changed = 1; } if (!changed) printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); - } + } ret = update_end_of_memory(nd->end); @@ -279,7 +279,7 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ void __init -acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) +acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) { struct bootnode *nd, oldnode; unsigned long start, end; @@ -288,17 +288,16 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) if (srat_disabled()) return; - if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) { + if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) { bad_srat(); return; } - if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0) + if (ma->flags.enabled == 0) return; - - if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info()) + if (ma->flags.hot_pluggable && !save_add_info()) return; - start = ma->base_address; - end = start + ma->length; + start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); + end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); pxm = ma->proximity_domain; node = setup_node(pxm); if (node < 0) { @@ -338,8 +337,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) push_node_boundaries(node, nd->start >> PAGE_SHIFT, nd->end >> PAGE_SHIFT); - if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && - (reserve_hotadd(node, start, end) < 0)) { + if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) { /* Ignore hotadd region. Undo damage */ printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); *nd = oldnode; @@ -396,7 +394,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) /* First clean up the node list */ for (i = 0; i < MAX_NUMNODES; i++) { - cutoff_node(i, start, end); + cutoff_node(i, start, end); if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) { unparse_node(i); node_set_offline(i); @@ -428,7 +426,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) if (!node_online(i)) setup_node_bootmem(i, nodes[i].start, nodes[i].end); - for (i = 0; i < NR_CPUS; i++) { + for (i = 0; i < NR_CPUS; i++) { if (cpu_to_node[i] == NUMA_NO_NODE) continue; if (!node_isset(cpu_to_node[i], nodes_parsed)) @@ -463,7 +461,7 @@ int __node_distance(int a, int b) if (!acpi_slit) return a == b ? 10 : 20; - index = acpi_slit->locality_count * node_to_pxm(a); + index = acpi_slit->localities * node_to_pxm(a); return acpi_slit->entry[index + node_to_pxm(b)]; } diff --git a/trunk/arch/x86_64/pci/mmconfig.c b/trunk/arch/x86_64/pci/mmconfig.c index faabb6e87f12..f8b6b2800a62 100644 --- a/trunk/arch/x86_64/pci/mmconfig.c +++ b/trunk/arch/x86_64/pci/mmconfig.c @@ -1,6 +1,6 @@ /* * mmconfig.c - Low-level direct PCI config space access via MMCONFIG - * + * * This is an 64bit optimized version that always keeps the full mmconfig * space mapped. This allows lockless config space operation. */ @@ -25,7 +25,7 @@ static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS); /* Static virtual mapping of the MMCONFIG aperture */ struct mmcfg_virt { - struct acpi_mcfg_allocation *cfg; + struct acpi_table_mcfg_config *cfg; char __iomem *virt; }; static struct mmcfg_virt *pci_mmcfg_virt; @@ -33,14 +33,14 @@ static struct mmcfg_virt *pci_mmcfg_virt; static char __iomem *get_virt(unsigned int seg, unsigned bus) { int cfg_num = -1; - struct acpi_mcfg_allocation *cfg; + struct acpi_table_mcfg_config *cfg; while (1) { ++cfg_num; if (cfg_num >= pci_mmcfg_config_num) break; cfg = pci_mmcfg_virt[cfg_num].cfg; - if (cfg->pci_segment != seg) + if (cfg->pci_segment_group_number != seg) continue; if ((cfg->start_bus_number <= bus) && (cfg->end_bus_number >= bus)) @@ -52,7 +52,7 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) this applies to all busses. */ cfg = &pci_mmcfg_config[0]; if (pci_mmcfg_config_num == 1 && - cfg->pci_segment == 0 && + cfg->pci_segment_group_number == 0 && (cfg->start_bus_number | cfg->end_bus_number) == 0) return pci_mmcfg_virt[0].virt; @@ -170,19 +170,19 @@ void __init pci_mmcfg_init(int type) if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; - acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); if ((pci_mmcfg_config_num == 0) || (pci_mmcfg_config == NULL) || - (pci_mmcfg_config[0].address == 0)) + (pci_mmcfg_config[0].base_address == 0)) return; /* Only do this check when type 1 works. If it doesn't work assume we run on a Mac and always use MCFG */ - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].address, - pci_mmcfg_config[0].address + MMCONFIG_APER_MIN, + if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { - printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %lx is not E820-reserved\n", - (unsigned long)pci_mmcfg_config[0].address); + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", + pci_mmcfg_config[0].base_address); printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); return; } @@ -194,16 +194,15 @@ void __init pci_mmcfg_init(int type) } for (i = 0; i < pci_mmcfg_config_num; ++i) { pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; - pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].address, + pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_MAX); if (!pci_mmcfg_virt[i].virt) { printk(KERN_ERR "PCI: Cannot map mmconfig aperture for " "segment %d\n", - pci_mmcfg_config[i].pci_segment); + pci_mmcfg_config[i].pci_segment_group_number); return; } - printk(KERN_INFO "PCI: Using MMCONFIG at %lx\n", - (unsigned long)pci_mmcfg_config[i].address); + printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address); } unreachable_devices(); diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 20eacc2c9e0e..f4f000abc4e9 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -3,7 +3,6 @@ # menu "ACPI (Advanced Configuration and Power Interface) Support" - depends on !X86_NUMAQ depends on !X86_VISWS depends on !IA64_HP_SIM depends on IA64 || X86 @@ -78,20 +77,6 @@ config ACPI_SLEEP_PROC_SLEEP Create /proc/acpi/sleep Deprecated by /sys/power/state -config ACPI_PROCFS - bool "Procfs interface (deprecated)" - depends on ACPI - default y - ---help--- - Procfs interface for ACPI is made optional for back-compatible. - As the same functions are duplicated in sysfs interface - and this proc interface will be removed some time later, - it's marked as deprecated. - ( /proc/acpi/debug_layer && debug_level are deprecated by - /sys/module/acpi/parameters/debug_layer && debug_level. - /proc/acpi/info is deprecated by - /sys/module/acpi/parameters/acpica_version ) - config ACPI_AC tristate "AC Adapter" depends on X86 @@ -122,7 +107,7 @@ config ACPI_BUTTON config ACPI_VIDEO tristate "Video" - depends on X86 && BACKLIGHT_CLASS_DEVICE + depends on X86 help This driver implement the ACPI Extensions For Display Adapters for integrated graphics devices on motherboard, as specified in @@ -154,13 +139,6 @@ config ACPI_DOCK help This driver adds support for ACPI controlled docking stations -config ACPI_BAY - tristate "Removable Drive Bay (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This driver adds support for ACPI controlled removable drive - bays such as the IBM ultrabay or the Dell Module Bay. - config ACPI_PROCESSOR tristate "Processor" default y @@ -208,22 +186,19 @@ config ACPI_ASUS Note: 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 parameters. - + More information and a userspace daemon for handling the extra buttons at . - + If you have an ACPI-compatible ASUS laptop, say Y or M here. This driver is still under development, so if your laptop is unsupported or something works not quite as expected, please use the mailing list - available on the above page (acpi4asus-user@lists.sourceforge.net). - - NOTE: This driver is deprecated and will probably be removed soon, - use asus-laptop instead. - + available on the above page (acpi4asus-user@lists.sourceforge.net) + config ACPI_IBM tristate "IBM ThinkPad Laptop Extras" depends on X86 diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index 856c32bccacb..bce7ca27b429 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -37,15 +37,13 @@ endif obj-y += sleep/ obj-y += bus.o glue.o -obj-y += scan.o obj-$(CONFIG_ACPI_AC) += ac.o obj-$(CONFIG_ACPI_BATTERY) += battery.o obj-$(CONFIG_ACPI_BUTTON) += button.o obj-$(CONFIG_ACPI_EC) += ec.o obj-$(CONFIG_ACPI_FAN) += fan.o obj-$(CONFIG_ACPI_DOCK) += dock.o -obj-$(CONFIG_ACPI_BAY) += bay.o -obj-$(CONFIG_ACPI_VIDEO) += video.o +obj-$(CONFIG_ACPI_VIDEO) += video.o obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o obj-$(CONFIG_ACPI_POWER) += power.o @@ -58,6 +56,7 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o +obj-y += scan.o motherboard.o obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o obj-y += cm_sbs.o obj-$(CONFIG_ACPI_SBS) += i2c_ec.o sbs.o diff --git a/trunk/drivers/acpi/asus_acpi.c b/trunk/drivers/acpi/asus_acpi.c index 31ad70a6e22e..396140bbbe57 100644 --- a/trunk/drivers/acpi/asus_acpi.c +++ b/trunk/drivers/acpi/asus_acpi.c @@ -26,7 +26,7 @@ * Pontus Fuchs - Helper functions, cleanup * Johann Wiesner - Small compile fixes * John Belmonte - ACPI code for Toshiba laptop was a good starting point. - * �ic Burghard - LED display support for W1N + * Éric Burghard - LED display support for W1N * */ @@ -1128,6 +1128,7 @@ static int asus_model_match(char *model) static int asus_hotk_get_info(void) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *model = NULL; int bsts_result; char *string = NULL; @@ -1141,9 +1142,11 @@ static int asus_hotk_get_info(void) * HID), this bit will be moved. A global variable asus_info contains * the DSDT header. */ - status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); + status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); if (ACPI_FAILURE(status)) printk(KERN_WARNING " Couldn't get the DSDT table header\n"); + else + asus_info = dsdt.pointer; /* We have to write 0 on init this far for all ASUS models */ if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { @@ -1355,6 +1358,8 @@ static void __exit asus_acpi_exit(void) acpi_bus_unregister_driver(&asus_hotk_driver); remove_proc_entry(PROC_ASUS, acpi_root_dir); + kfree(asus_info); + return; } diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 2f4521a48fe7..5f43e0d14899 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -64,7 +64,7 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); static int acpi_battery_add(struct acpi_device *device); static int acpi_battery_remove(struct acpi_device *device, int type); -static int acpi_battery_resume(struct acpi_device *device); +static int acpi_battery_resume(struct acpi_device *device, int status); static struct acpi_driver acpi_battery_driver = { .name = ACPI_BATTERY_DRIVER_NAME, @@ -753,7 +753,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) } /* this is needed to learn about changes made in suspended state */ -static int acpi_battery_resume(struct acpi_device *device) +static int acpi_battery_resume(struct acpi_device *device, int state) { struct acpi_battery *battery; diff --git a/trunk/drivers/acpi/bay.c b/trunk/drivers/acpi/bay.c deleted file mode 100644 index 667fa1dfa1a3..000000000000 --- a/trunk/drivers/acpi/bay.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - * bay.c - ACPI removable drive bay driver - * - * Copyright (C) 2006 Kristen Carlson Accardi - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ACPI_BAY_DRIVER_NAME "ACPI Removable Drive Bay Driver" - -ACPI_MODULE_NAME("bay") -MODULE_AUTHOR("Kristen Carlson Accardi"); -MODULE_DESCRIPTION(ACPI_BAY_DRIVER_NAME); -MODULE_LICENSE("GPL"); -#define ACPI_BAY_CLASS "bay" -#define ACPI_BAY_COMPONENT 0x10000000 -#define _COMPONENT ACPI_BAY_COMPONENT -#define bay_dprintk(h,s) {\ - char prefix[80] = {'\0'};\ - struct acpi_buffer buffer = {sizeof(prefix), prefix};\ - acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\ - printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); } -static void bay_notify(acpi_handle handle, u32 event, void *data); -static int acpi_bay_add(struct acpi_device *device); -static int acpi_bay_remove(struct acpi_device *device, int type); - -static struct acpi_driver acpi_bay_driver = { - .name = ACPI_BAY_DRIVER_NAME, - .class = ACPI_BAY_CLASS, - .ids = ACPI_BAY_HID, - .ops = { - .add = acpi_bay_add, - .remove = acpi_bay_remove, - }, -}; - -struct bay { - acpi_handle handle; - char *name; - struct list_head list; - struct platform_device *pdev; -}; - -static LIST_HEAD(drive_bays); - - -/***************************************************************************** - * Drive Bay functions * - *****************************************************************************/ -/** - * is_ejectable - see if a device is ejectable - * @handle: acpi handle of the device - * - * If an acpi object has a _EJ0 method, then it is ejectable - */ -static int is_ejectable(acpi_handle handle) -{ - acpi_status status; - acpi_handle tmp; - - status = acpi_get_handle(handle, "_EJ0", &tmp); - if (ACPI_FAILURE(status)) - return 0; - return 1; -} - -/** - * bay_present - see if the bay device is present - * @bay: the drive bay - * - * execute the _STA method. - */ -static int bay_present(struct bay *bay) -{ - unsigned long sta; - acpi_status status; - - if (bay) { - status = acpi_evaluate_integer(bay->handle, "_STA", NULL, &sta); - if (ACPI_SUCCESS(status) && sta) - return 1; - } - return 0; -} - -/** - * eject_device - respond to an eject request - * @handle - the device to eject - * - * Call this devices _EJ0 method. - */ -static void eject_device(acpi_handle handle) -{ - struct acpi_object_list arg_list; - union acpi_object arg; - - bay_dprintk(handle, "Ejecting device"); - - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 1; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0", - &arg_list, NULL))) - pr_debug("Failed to evaluate _EJ0!\n"); -} - -/* - * show_present - read method for "present" file in sysfs - */ -static ssize_t show_present(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct bay *bay = dev_get_drvdata(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", bay_present(bay)); - -} -DEVICE_ATTR(present, S_IRUGO, show_present, NULL); - -/* - * write_eject - write method for "eject" file in sysfs - */ -static ssize_t write_eject(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct bay *bay = dev_get_drvdata(dev); - - if (!count) - return -EINVAL; - - eject_device(bay->handle); - return count; -} -DEVICE_ATTR(eject, S_IWUSR, NULL, write_eject); - -/** - * is_ata - see if a device is an ata device - * @handle: acpi handle of the device - * - * If an acpi object has one of 4 ATA ACPI methods defined, - * then it is an ATA device - */ -static int is_ata(acpi_handle handle) -{ - acpi_handle tmp; - - if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) - return 1; - - return 0; -} - -/** - * parent_is_ata(acpi_handle handle) - * - */ -static int parent_is_ata(acpi_handle handle) -{ - acpi_handle phandle; - - if (acpi_get_parent(handle, &phandle)) - return 0; - - return is_ata(phandle); -} - -/** - * is_ejectable_bay - see if a device is an ejectable drive bay - * @handle: acpi handle of the device - * - * If an acpi object is ejectable and has one of the ACPI ATA - * methods defined, then we can safely call it an ejectable - * drive bay - */ -static int is_ejectable_bay(acpi_handle handle) -{ - if ((is_ata(handle) || parent_is_ata(handle)) && is_ejectable(handle)) - return 1; - return 0; -} - -/** - * eject_removable_drive - try to eject this drive - * @dev : the device structure of the drive - * - * If a device is a removable drive that requires an _EJ0 method - * to be executed in order to safely remove from the system, do - * it. ATM - always returns success - */ -int eject_removable_drive(struct device *dev) -{ - acpi_handle handle = DEVICE_ACPI_HANDLE(dev); - - if (handle) { - bay_dprintk(handle, "Got device handle"); - if (is_ejectable_bay(handle)) - eject_device(handle); - } else { - printk("No acpi handle for device\n"); - } - - /* should I return an error code? */ - return 0; -} -EXPORT_SYMBOL_GPL(eject_removable_drive); - -static int acpi_bay_add(struct acpi_device *device) -{ - bay_dprintk(device->handle, "adding bay device"); - strcpy(acpi_device_name(device), "Dockable Bay"); - strcpy(acpi_device_class(device), "bay"); - return 0; -} - -static int acpi_bay_add_fs(struct bay *bay) -{ - int ret; - struct device *dev = &bay->pdev->dev; - - ret = device_create_file(dev, &dev_attr_present); - if (ret) - goto add_fs_err; - ret = device_create_file(dev, &dev_attr_eject); - if (ret) { - device_remove_file(dev, &dev_attr_present); - goto add_fs_err; - } - return 0; - - add_fs_err: - bay_dprintk(bay->handle, "Error adding sysfs files\n"); - return ret; -} - -static void acpi_bay_remove_fs(struct bay *bay) -{ - struct device *dev = &bay->pdev->dev; - - /* cleanup sysfs */ - device_remove_file(dev, &dev_attr_present); - device_remove_file(dev, &dev_attr_eject); -} - -static int bay_is_dock_device(acpi_handle handle) -{ - acpi_handle parent; - - acpi_get_parent(handle, &parent); - - /* if the device or it's parent is dependent on the - * dock, then we are a dock device - */ - return (is_dock_device(handle) || is_dock_device(parent)); -} - -static int bay_add(acpi_handle handle, int id) -{ - acpi_status status; - struct bay *new_bay; - struct platform_device *pdev; - struct acpi_buffer nbuffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_get_name(handle, ACPI_FULL_PATHNAME, &nbuffer); - - bay_dprintk(handle, "Adding notify handler"); - - /* - * Initialize bay device structure - */ - new_bay = kzalloc(GFP_ATOMIC, sizeof(*new_bay)); - INIT_LIST_HEAD(&new_bay->list); - new_bay->handle = handle; - new_bay->name = (char *)nbuffer.pointer; - - /* initialize platform device stuff */ - pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0); - if (pdev == NULL) { - printk(KERN_ERR PREFIX "Error registering bay device\n"); - goto bay_add_err; - } - new_bay->pdev = pdev; - platform_set_drvdata(pdev, new_bay); - - if (acpi_bay_add_fs(new_bay)) { - platform_device_unregister(new_bay->pdev); - goto bay_add_err; - } - - /* register for events on this device */ - status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - bay_notify, new_bay); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Error installing bay notify handler\n"); - } - - /* if we are on a dock station, we should register for dock - * notifications. - */ - if (bay_is_dock_device(handle)) { - bay_dprintk(handle, "Is dependent on dock\n"); - register_hotplug_dock_device(handle, bay_notify, new_bay); - } - list_add(&new_bay->list, &drive_bays); - printk(KERN_INFO PREFIX "Bay [%s] Added\n", new_bay->name); - return 0; - -bay_add_err: - kfree(new_bay->name); - kfree(new_bay); - return -ENODEV; -} - -static int acpi_bay_remove(struct acpi_device *device, int type) -{ - /*** FIXME: do something here */ - return 0; -} - -/** - * bay_create_acpi_device - add new devices to acpi - * @handle - handle of the device to add - * - * This function will create a new acpi_device for the given - * handle if one does not exist already. This should cause - * acpi to scan for drivers for the given devices, and call - * matching driver's add routine. - * - * Returns a pointer to the acpi_device corresponding to the handle. - */ -static struct acpi_device * bay_create_acpi_device(acpi_handle handle) -{ - struct acpi_device *device = NULL; - struct acpi_device *parent_device; - acpi_handle parent; - int ret; - - bay_dprintk(handle, "Trying to get device"); - if (acpi_bus_get_device(handle, &device)) { - /* - * no device created for this object, - * so we should create one. - */ - bay_dprintk(handle, "No device for handle"); - acpi_get_parent(handle, &parent); - if (acpi_bus_get_device(parent, &parent_device)) - parent_device = NULL; - - ret = acpi_bus_add(&device, parent_device, handle, - ACPI_BUS_TYPE_DEVICE); - if (ret) { - pr_debug("error adding bus, %x\n", - -ret); - return NULL; - } - } - return device; -} - -/** - * bay_notify - act upon an acpi bay notification - * @handle: the bay handle - * @event: the acpi event - * @data: our driver data struct - * - */ -static void bay_notify(acpi_handle handle, u32 event, void *data) -{ - struct acpi_device *dev; - - bay_dprintk(handle, "Bay event"); - - switch(event) { - case ACPI_NOTIFY_BUS_CHECK: - printk("Bus Check\n"); - case ACPI_NOTIFY_DEVICE_CHECK: - printk("Device Check\n"); - dev = bay_create_acpi_device(handle); - if (dev) - acpi_bus_generate_event(dev, event, 0); - else - printk("No device for generating event\n"); - /* wouldn't it be a good idea to just rescan SATA - * right here? - */ - break; - case ACPI_NOTIFY_EJECT_REQUEST: - printk("Eject request\n"); - dev = bay_create_acpi_device(handle); - if (dev) - acpi_bus_generate_event(dev, event, 0); - else - printk("No device for generating eventn"); - - /* wouldn't it be a good idea to just call the - * eject_device here if we were a SATA device? - */ - break; - default: - printk("unknown event %d\n", event); - } -} - -static acpi_status -find_bay(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - int *count = (int *)context; - - /* - * there could be more than one ejectable bay. - * so, just return AE_OK always so that every object - * will be checked. - */ - if (is_ejectable_bay(handle)) { - bay_dprintk(handle, "found ejectable bay"); - if (!bay_add(handle, *count)) - (*count)++; - } - return AE_OK; -} - -static int __init bay_init(void) -{ - int bays = 0; - - INIT_LIST_HEAD(&drive_bays); - - /* look for dockable drive bays */ - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, find_bay, &bays, NULL); - - if (bays) - if ((acpi_bus_register_driver(&acpi_bay_driver) < 0)) - printk(KERN_ERR "Unable to register bay driver\n"); - - if (!bays) - return -ENODEV; - - return 0; -} - -static void __exit bay_exit(void) -{ - struct bay *bay, *tmp; - - list_for_each_entry_safe(bay, tmp, &drive_bays, list) { - if (is_dock_device(bay->handle)) - unregister_hotplug_dock_device(bay->handle); - acpi_bay_remove_fs(bay); - acpi_remove_notify_handler(bay->handle, ACPI_SYSTEM_NOTIFY, - bay_notify); - platform_device_unregister(bay->pdev); - kfree(bay->name); - kfree(bay); - } - - acpi_bus_unregister_driver(&acpi_bay_driver); -} - -postcore_initcall(bay_init); -module_exit(bay_exit); - diff --git a/trunk/drivers/acpi/blacklist.c b/trunk/drivers/acpi/blacklist.c index f289fd41e77d..f9c972b26f4f 100644 --- a/trunk/drivers/acpi/blacklist.c +++ b/trunk/drivers/acpi/blacklist.c @@ -44,7 +44,7 @@ struct acpi_blacklist_item { char oem_id[7]; char oem_table_id[9]; u32 oem_revision; - char *table; + acpi_table_type table; enum acpi_blacklist_predicates oem_revision_predicate; char *reason; u32 is_critical_error; @@ -56,18 +56,18 @@ struct acpi_blacklist_item { */ static struct acpi_blacklist_item acpi_blacklist[] __initdata = { /* Compaq Presario 1700 */ - {"PTLTD ", " DSDT ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal, + {"PTLTD ", " DSDT ", 0x06040000, ACPI_DSDT, less_than_or_equal, "Multiple problems", 1}, /* Sony FX120, FX140, FX150? */ - {"SONY ", "U0 ", 0x20010313, ACPI_SIG_DSDT, less_than_or_equal, + {"SONY ", "U0 ", 0x20010313, ACPI_DSDT, less_than_or_equal, "ACPI driver problem", 1}, /* Compaq Presario 800, Insyde BIOS */ - {"INT440", "SYSFexxx", 0x00001001, ACPI_SIG_DSDT, less_than_or_equal, + {"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT, less_than_or_equal, "Does not use _REG to protect EC OpRegions", 1}, /* IBM 600E - _ADR should return 7, but it returns 1 */ - {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, + {"IBM ", "TP600E ", 0x00000105, ACPI_DSDT, less_than_or_equal, "Incorrect _ADR", 1}, - {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions, + {"ASUS\0\0", "P2B-S ", 0, ACPI_DSDT, all_versions, "Bogus PCI routing", 1}, {""} @@ -79,7 +79,7 @@ static int __init blacklist_by_year(void) { int year = dmi_get_year(DMI_BIOS_DATE); /* Doesn't exist? Likely an old system */ - if (year == -1) + if (year == -1) return 1; /* 0? Likely a buggy new BIOS */ if (year == 0) @@ -103,21 +103,22 @@ int __init acpi_blacklisted(void) { int i = 0; int blacklisted = 0; - struct acpi_table_header table_header; + struct acpi_table_header *table_header; while (acpi_blacklist[i].oem_id[0] != '\0') { - if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) { + if (acpi_get_table_header_early + (acpi_blacklist[i].table, &table_header)) { i++; continue; } - if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) { + if (strncmp(acpi_blacklist[i].oem_id, table_header->oem_id, 6)) { i++; continue; } if (strncmp - (acpi_blacklist[i].oem_table_id, table_header.oem_table_id, + (acpi_blacklist[i].oem_table_id, table_header->oem_table_id, 8)) { i++; continue; @@ -126,14 +127,14 @@ int __init acpi_blacklisted(void) if ((acpi_blacklist[i].oem_revision_predicate == all_versions) || (acpi_blacklist[i].oem_revision_predicate == less_than_or_equal - && table_header.oem_revision <= + && table_header->oem_revision <= acpi_blacklist[i].oem_revision) || (acpi_blacklist[i].oem_revision_predicate == greater_than_or_equal - && table_header.oem_revision >= + && table_header->oem_revision >= acpi_blacklist[i].oem_revision) || (acpi_blacklist[i].oem_revision_predicate == equal - && table_header.oem_revision == + && table_header->oem_revision == acpi_blacklist[i].oem_revision)) { printk(KERN_ERR PREFIX diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index c26468da4295..766332e45592 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -44,6 +44,9 @@ ACPI_MODULE_NAME("acpi_bus") extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); #endif +struct fadt_descriptor acpi_fadt; +EXPORT_SYMBOL(acpi_fadt); + struct acpi_device *acpi_root; struct proc_dir_entry *acpi_root_dir; EXPORT_SYMBOL(acpi_root_dir); @@ -192,7 +195,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) if (!device->flags.power_manageable) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", - device->dev.kobj.name)); + device->kobj.name)); return -ENODEV; } /* @@ -579,12 +582,11 @@ static int __init acpi_bus_init_irq(void) return 0; } -acpi_native_uint acpi_gbl_permanent_mmap; - - void __init acpi_early_init(void) { acpi_status status = AE_OK; + struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt }; + if (acpi_disabled) return; @@ -595,15 +597,6 @@ void __init acpi_early_init(void) if (!acpi_strict) acpi_gbl_enable_interpreter_slack = TRUE; - acpi_gbl_permanent_mmap = 1; - - status = acpi_reallocate_root_table(); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX - "Unable to reallocate ACPI tables\n"); - goto error0; - } - status = acpi_initialize_subsystem(); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX @@ -618,25 +611,32 @@ void __init acpi_early_init(void) goto error0; } + /* + * Get a separate copy of the FADT for use by other drivers. + */ + status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to get the FADT\n"); + goto error0; + } #ifdef CONFIG_X86 if (!acpi_ioapic) { - extern u8 acpi_sci_flags; + extern acpi_interrupt_flags acpi_sci_flags; /* compatible (0) means level (3) */ - if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) { - acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK; - acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL; - } + if (acpi_sci_flags.trigger == 0) + acpi_sci_flags.trigger = 3; + /* Set PIC-mode SCI trigger type */ - acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt, - (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2); + acpi_pic_sci_set_trigger(acpi_fadt.sci_int, + acpi_sci_flags.trigger); } else { extern int acpi_sci_override_gsi; /* - * now that acpi_gbl_FADT is initialized, + * now that acpi_fadt is initialized, * update it with result from INT_SRC_OVR parsing */ - acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi; + acpi_fadt.sci_int = acpi_sci_override_gsi; } #endif diff --git a/trunk/drivers/acpi/button.c b/trunk/drivers/acpi/button.c index c726612fafb6..ac860583c203 100644 --- a/trunk/drivers/acpi/button.c +++ b/trunk/drivers/acpi/button.c @@ -75,7 +75,7 @@ static int acpi_button_state_open_fs(struct inode *inode, struct file *file); static struct acpi_driver acpi_button_driver = { .name = ACPI_BUTTON_DRIVER_NAME, .class = ACPI_BUTTON_CLASS, - .ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E", + .ids = "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E", .ops = { .add = acpi_button_add, .remove = acpi_button_remove, diff --git a/trunk/drivers/acpi/container.c b/trunk/drivers/acpi/container.c index 69a68fd394cf..0a1863ec91f3 100644 --- a/trunk/drivers/acpi/container.c +++ b/trunk/drivers/acpi/container.c @@ -167,7 +167,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) if (ACPI_FAILURE(status) || !device) { result = container_device_add(&device, handle); if (!result) - kobject_uevent(&device->dev.kobj, + kobject_uevent(&device->kobj, KOBJ_ONLINE); else printk("Failed to add container\n"); @@ -175,13 +175,13 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) } else { if (ACPI_SUCCESS(status)) { /* device exist and this is a remove request */ - kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); + kobject_uevent(&device->kobj, KOBJ_OFFLINE); } } break; case ACPI_NOTIFY_EJECT_REQUEST: if (!acpi_bus_get_device(handle, &device) && device) { - kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); + kobject_uevent(&device->kobj, KOBJ_OFFLINE); } break; default: diff --git a/trunk/drivers/acpi/debug.c b/trunk/drivers/acpi/debug.c index d48f65a8f658..35c6af8a83cd 100644 --- a/trunk/drivers/acpi/debug.c +++ b/trunk/drivers/acpi/debug.c @@ -13,11 +13,14 @@ #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("debug") - +#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" +#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" #ifdef MODULE_PARAM_PREFIX #undef MODULE_PARAM_PREFIX #endif -#define MODULE_PARAM_PREFIX "acpi." +#define MODULE_PARAM_PREFIX + module_param(acpi_dbg_layer, uint, 0400); +module_param(acpi_dbg_level, uint, 0400); struct acpi_dlayer { const char *name; @@ -83,60 +86,6 @@ static const struct acpi_dlevel acpi_debug_levels[] = { ACPI_DEBUG_INIT(ACPI_LV_EVENTS), }; -/* -------------------------------------------------------------------------- - FS Interface (/sys) - -------------------------------------------------------------------------- */ -static int param_get_debug_layer(char *buffer, struct kernel_param *kp) { - int result = 0; - int i; - - result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); - - for(i = 0; i common.next; - - /* Currently, only the following constants are supported */ - - switch (arg->common.aml_opcode) { - case AML_ZERO_OP: - info.bank_value = 0; - break; - - case AML_ONE_OP: - info.bank_value = 1; - break; - - case AML_BYTE_OP: - case AML_WORD_OP: - case AML_DWORD_OP: - case AML_QWORD_OP: - info.bank_value = (u32) arg->common.value.integer; - break; - - default: - info.bank_value = 0; - ACPI_ERROR((AE_INFO, - "Non-constant BankValue for BankField is not implemented")); - } + info.bank_value = (u32) arg->common.value.integer; /* Fourth arg is the field flags */ diff --git a/trunk/drivers/acpi/dispatcher/dsinit.c b/trunk/drivers/acpi/dispatcher/dsinit.c index af923c388520..1888c055d10f 100644 --- a/trunk/drivers/acpi/dispatcher/dsinit.c +++ b/trunk/drivers/acpi/dispatcher/dsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +44,6 @@ #include #include #include -#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsinit") @@ -91,7 +90,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, * We are only interested in NS nodes owned by the table that * was just loaded */ - if (node->owner_id != info->owner_id) { + if (node->owner_id != info->table_desc->owner_id) { return (AE_OK); } @@ -151,21 +150,14 @@ acpi_ds_init_one_object(acpi_handle obj_handle, ******************************************************************************/ acpi_status -acpi_ds_initialize_objects(acpi_native_uint table_index, +acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, struct acpi_namespace_node * start_node) { acpi_status status; struct acpi_init_walk_info info; - struct acpi_table_header *table; - acpi_owner_id owner_id; ACPI_FUNCTION_TRACE(ds_initialize_objects); - status = acpi_tb_get_owner_id(table_index, &owner_id); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "**** Starting initialization of namespace objects ****\n")); ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); @@ -174,8 +166,7 @@ acpi_ds_initialize_objects(acpi_native_uint table_index, info.op_region_count = 0; info.object_count = 0; info.device_count = 0; - info.table_index = table_index; - info.owner_id = owner_id; + info.table_desc = table_desc; /* Walk entire namespace from the supplied root */ @@ -185,14 +176,10 @@ acpi_ds_initialize_objects(acpi_native_uint table_index, ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); } - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", - table->signature, owner_id, info.object_count, + table_desc->pointer->signature, + table_desc->owner_id, info.object_count, info.device_count, info.method_count, info.op_region_count)); diff --git a/trunk/drivers/acpi/dispatcher/dsmethod.c b/trunk/drivers/acpi/dispatcher/dsmethod.c index 1cbe61905824..cf888add3191 100644 --- a/trunk/drivers/acpi/dispatcher/dsmethod.c +++ b/trunk/drivers/acpi/dispatcher/dsmethod.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -327,7 +327,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Calling method %p, currentstate=%p\n", + "Execute method %p, currentstate=%p\n", this_walk_state->prev_op, this_walk_state)); /* @@ -351,7 +351,49 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, return_ACPI_STATUS(status); } - /* Begin method parse/execution. Create a new walk state */ + /* + * 1) Parse the method. All "normal" methods are parsed for each execution. + * Internal methods (_OSI, etc.) do not require parsing. + */ + if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) { + + /* Create a new walk state for the parse */ + + next_walk_state = + acpi_ds_create_walk_state(obj_desc->method.owner_id, op, + obj_desc, NULL); + if (!next_walk_state) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Create and init a parse tree root */ + + op = acpi_ps_create_scope_op(); + if (!op) { + status = AE_NO_MEMORY; + goto cleanup; + } + + status = acpi_ds_init_aml_walk(next_walk_state, op, method_node, + obj_desc->method.aml_start, + obj_desc->method.aml_length, + NULL, 1); + if (ACPI_FAILURE(status)) { + acpi_ps_delete_parse_tree(op); + goto cleanup; + } + + /* Begin AML parse (deletes next_walk_state) */ + + status = acpi_ps_parse_aml(next_walk_state); + acpi_ps_delete_parse_tree(op); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + } + + /* 2) Begin method execution. Create a new walk state */ next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, obj_desc, thread); @@ -382,8 +424,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, obj_desc->method.aml_start, - obj_desc->method.aml_length, info, - ACPI_IMODE_EXECUTE); + obj_desc->method.aml_length, info, 3); ACPI_FREE(info); if (ACPI_FAILURE(status)) { @@ -404,8 +445,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, this_walk_state->num_operands = 0; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "**** Begin nested execution of [%4.4s] **** WalkState=%p\n", - method_node->name.ascii, next_walk_state)); + "Starting nested execution, newstate=%p\n", + next_walk_state)); /* Invoke an internal method if necessary */ diff --git a/trunk/drivers/acpi/dispatcher/dsmthdat.c b/trunk/drivers/acpi/dispatcher/dsmthdat.c index ba4626e06a5e..459160ff9058 100644 --- a/trunk/drivers/acpi/dispatcher/dsmthdat.c +++ b/trunk/drivers/acpi/dispatcher/dsmthdat.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/dispatcher/dsobject.c b/trunk/drivers/acpi/dispatcher/dsobject.c index a474ca2334d5..72190abb1d59 100644 --- a/trunk/drivers/acpi/dispatcher/dsobject.c +++ b/trunk/drivers/acpi/dispatcher/dsobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -260,7 +260,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, } obj_desc->buffer.flags |= AOPOBJ_DATA_VALID; - op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc); + op->common.node = (struct acpi_namespace_node *)obj_desc; return_ACPI_STATUS(AE_OK); } @@ -270,8 +270,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, * * PARAMETERS: walk_state - Current walk state * Op - Parser object to be translated - * element_count - Number of elements in the package - this is - * the num_elements argument to Package() + * package_length - Number of elements in the package * obj_desc_ptr - Where the ACPI internal object is returned * * RETURN: Status @@ -279,29 +278,18 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, * DESCRIPTION: Translate a parser Op package object to the equivalent * namespace object * - * NOTE: The number of elements in the package will be always be the num_elements - * count, regardless of the number of elements in the package list. If - * num_elements is smaller, only that many package list elements are used. - * if num_elements is larger, the Package object is padded out with - * objects of type Uninitialized (as per ACPI spec.) - * - * Even though the ASL compilers do not allow num_elements to be smaller - * than the Package list length (for the fixed length package opcode), some - * BIOS code modifies the AML on the fly to adjust the num_elements, and - * this code compensates for that. This also provides compatibility with - * other AML interpreters. - * ******************************************************************************/ acpi_status acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, union acpi_parse_object *op, - u32 element_count, + u32 package_length, union acpi_operand_object **obj_desc_ptr) { union acpi_parse_object *arg; union acpi_parse_object *parent; union acpi_operand_object *obj_desc = NULL; + u32 package_list_length; acpi_status status = AE_OK; acpi_native_uint i; @@ -330,13 +318,32 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, obj_desc->package.node = parent->common.node; } + obj_desc->package.count = package_length; + + /* Count the number of items in the package list */ + + arg = op->common.value.arg; + arg = arg->common.next; + for (package_list_length = 0; arg; package_list_length++) { + arg = arg->common.next; + } + + /* + * The package length (number of elements) will be the greater + * of the specified length and the length of the initializer list + */ + if (package_list_length > package_length) { + obj_desc->package.count = package_list_length; + } + /* - * Allocate the element array (array of pointers to the individual - * objects) based on the num_elements parameter. Add an extra pointer slot - * so that the list is always null terminated. + * Allocate the pointer array (array of pointers to the + * individual objects). Add an extra pointer slot so + * that the list is always null terminated. */ obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) - element_count + + obj_desc->package. + count + 1) * sizeof(void *)); if (!obj_desc->package.elements) { @@ -344,20 +351,15 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, return_ACPI_STATUS(AE_NO_MEMORY); } - obj_desc->package.count = element_count; - /* - * Initialize the elements of the package, up to the num_elements count. - * Package is automatically padded with uninitialized (NULL) elements - * if num_elements is greater than the package list length. Likewise, - * Package is truncated if num_elements is less than the list length. + * Initialize all elements of the package */ arg = op->common.value.arg; arg = arg->common.next; - for (i = 0; arg && (i < element_count); i++) { + for (i = 0; arg; i++) { if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { - /* This package element is already built, just get it */ + /* Object (package or buffer) is already built */ obj_desc->package.elements[i] = ACPI_CAST_PTR(union acpi_operand_object, @@ -371,14 +373,8 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, arg = arg->common.next; } - if (!arg) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Package List length larger than NumElements count (%X), truncated\n", - element_count)); - } - obj_desc->package.flags |= AOPOBJ_DATA_VALID; - op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc); + op->common.node = (struct acpi_namespace_node *)obj_desc; return_ACPI_STATUS(status); } @@ -492,9 +488,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, /* * Defer evaluation of Buffer term_arg operand */ - obj_desc->buffer.node = - ACPI_CAST_PTR(struct acpi_namespace_node, - walk_state->operands[0]); + obj_desc->buffer.node = (struct acpi_namespace_node *) + walk_state->operands[0]; obj_desc->buffer.aml_start = op->named.data; obj_desc->buffer.aml_length = op->named.length; break; @@ -504,9 +499,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, /* * Defer evaluation of Package term_arg operand */ - obj_desc->package.node = - ACPI_CAST_PTR(struct acpi_namespace_node, - walk_state->operands[0]); + obj_desc->package.node = (struct acpi_namespace_node *) + walk_state->operands[0]; obj_desc->package.aml_start = op->named.data; obj_desc->package.aml_length = op->named.length; break; diff --git a/trunk/drivers/acpi/dispatcher/dsopcode.c b/trunk/drivers/acpi/dispatcher/dsopcode.c index 6c6104a7a247..5b974a8fe614 100644 --- a/trunk/drivers/acpi/dispatcher/dsopcode.c +++ b/trunk/drivers/acpi/dispatcher/dsopcode.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -114,7 +114,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, } status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, - aml_length, NULL, ACPI_IMODE_LOAD_PASS1); + aml_length, NULL, 1); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); goto cleanup; @@ -157,7 +157,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, /* Execute the opcode and arguments */ status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, - aml_length, NULL, ACPI_IMODE_EXECUTE); + aml_length, NULL, 3); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); goto cleanup; diff --git a/trunk/drivers/acpi/dispatcher/dsutils.c b/trunk/drivers/acpi/dispatcher/dsutils.c index e4073e05a75c..05230baf5de8 100644 --- a/trunk/drivers/acpi/dispatcher/dsutils.c +++ b/trunk/drivers/acpi/dispatcher/dsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/dispatcher/dswexec.c b/trunk/drivers/acpi/dispatcher/dswexec.c index 69693fa07224..d7a616c3104e 100644 --- a/trunk/drivers/acpi/dispatcher/dswexec.c +++ b/trunk/drivers/acpi/dispatcher/dswexec.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -219,7 +219,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, if (!op) { status = acpi_ds_load2_begin_op(walk_state, out_op); if (ACPI_FAILURE(status)) { - goto error_exit; + return_ACPI_STATUS(status); } op = *out_op; @@ -238,7 +238,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, status = acpi_ds_scope_stack_pop(walk_state); if (ACPI_FAILURE(status)) { - goto error_exit; + return_ACPI_STATUS(status); } } } @@ -287,7 +287,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, status = acpi_ds_result_stack_push(walk_state); if (ACPI_FAILURE(status)) { - goto error_exit; + return_ACPI_STATUS(status); } status = acpi_ds_exec_begin_control_op(walk_state, op); @@ -328,10 +328,6 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, /* Nothing to do here during method execution */ return_ACPI_STATUS(status); - - error_exit: - status = acpi_ds_method_error(status, walk_state); - return_ACPI_STATUS(status); } /***************************************************************************** diff --git a/trunk/drivers/acpi/dispatcher/dswload.c b/trunk/drivers/acpi/dispatcher/dswload.c index 8ab9d1b29a4c..e3ca7f6539c1 100644 --- a/trunk/drivers/acpi/dispatcher/dswload.c +++ b/trunk/drivers/acpi/dispatcher/dswload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -196,7 +196,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, * one of the opcodes that actually opens a scope */ switch (node->type) { - case ACPI_TYPE_ANY: case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: @@ -547,7 +546,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, acpi_status status; acpi_object_type object_type; char *buffer_ptr; - u32 flags; ACPI_FUNCTION_TRACE(ds_load2_begin_op); @@ -671,7 +669,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, * one of the opcodes that actually opens a scope */ switch (node->type) { - case ACPI_TYPE_ANY: case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: @@ -753,20 +750,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, break; } - flags = ACPI_NS_NO_UPSEARCH; - if (walk_state->pass_number == ACPI_IMODE_EXECUTE) { - - /* Execution mode, node cannot already exist, node is temporary */ - - flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY); - } - - /* Add new entry or lookup existing entry */ + /* Add new entry into namespace */ status = acpi_ns_lookup(walk_state->scope_info, buffer_ptr, - object_type, ACPI_IMODE_LOAD_PASS2, flags, - walk_state, &node); + object_type, ACPI_IMODE_LOAD_PASS2, + ACPI_NS_NO_UPSEARCH, walk_state, &(node)); break; } diff --git a/trunk/drivers/acpi/dispatcher/dswscope.c b/trunk/drivers/acpi/dispatcher/dswscope.c index 3927c495e4bf..c9228972f5f6 100644 --- a/trunk/drivers/acpi/dispatcher/dswscope.c +++ b/trunk/drivers/acpi/dispatcher/dswscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/dispatcher/dswstate.c b/trunk/drivers/acpi/dispatcher/dswstate.c index 16c8e38b51ef..7817e5522679 100644 --- a/trunk/drivers/acpi/dispatcher/dswstate.c +++ b/trunk/drivers/acpi/dispatcher/dswstate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 688e83a16906..90990a4b6526 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -615,28 +615,20 @@ static acpi_status find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; - acpi_handle tmp, parent; + acpi_handle tmp; struct dock_station *ds = context; struct dock_dependent_device *dd; status = acpi_bus_get_ejd(handle, &tmp); - if (ACPI_FAILURE(status)) { - /* try the parent device as well */ - status = acpi_get_parent(handle, &parent); - if (ACPI_FAILURE(status)) - goto fdd_out; - /* see if parent is dependent on dock */ - status = acpi_bus_get_ejd(parent, &tmp); - if (ACPI_FAILURE(status)) - goto fdd_out; - } + if (ACPI_FAILURE(status)) + return AE_OK; if (tmp == ds->handle) { dd = alloc_dock_dependent_device(handle); if (dd) add_dock_dependent_device(ds, dd); } -fdd_out: + return AE_OK; } diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 743ce27fa0bb..cbdf031f3c09 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -872,8 +872,9 @@ static int __init acpi_ec_get_real_ecdt(void) acpi_status status; struct acpi_table_ecdt *ecdt_ptr; - status = acpi_get_table(ACPI_SIG_ECDT, 1, - (struct acpi_table_header **)&ecdt_ptr); + status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) + &ecdt_ptr); if (ACPI_FAILURE(status)) return -ENODEV; @@ -890,14 +891,14 @@ static int __init acpi_ec_get_real_ecdt(void) if (acpi_ec_mode == EC_INTR) { init_waitqueue_head(&ec_ecdt->wait); } - ec_ecdt->command_addr = ecdt_ptr->control.address; - ec_ecdt->data_addr = ecdt_ptr->data.address; - ec_ecdt->gpe = ecdt_ptr->gpe; + ec_ecdt->command_addr = ecdt_ptr->ec_control.address; + ec_ecdt->data_addr = ecdt_ptr->ec_data.address; + ec_ecdt->gpe = ecdt_ptr->gpe_bit; /* use the GL just to be safe */ ec_ecdt->global_lock = TRUE; ec_ecdt->uid = ecdt_ptr->uid; - status = acpi_get_handle(NULL, ecdt_ptr->id, &ec_ecdt->handle); + status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); if (ACPI_FAILURE(status)) { goto error; } diff --git a/trunk/drivers/acpi/events/evevent.c b/trunk/drivers/acpi/events/evevent.c index a1f87b5def2a..919037d6acff 100644 --- a/trunk/drivers/acpi/events/evevent.c +++ b/trunk/drivers/acpi/events/evevent.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -70,6 +70,13 @@ acpi_status acpi_ev_initialize_events(void) ACPI_FUNCTION_TRACE(ev_initialize_events); + /* Make sure we have ACPI tables */ + + if (!acpi_gbl_DSDT) { + ACPI_WARNING((AE_INFO, "No ACPI tables present!")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + /* * Initialize the Fixed and General Purpose Events. This is done prior to * enabling SCIs to prevent interrupts from occurring before the handlers are @@ -204,7 +211,8 @@ static acpi_status acpi_ev_fixed_event_initialize(void) if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { status = acpi_set_register(acpi_gbl_fixed_event_info[i]. - enable_register_id, 0); + enable_register_id, 0, + ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return (status); } @@ -290,7 +298,7 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) /* Clear the status bit */ (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. - status_register_id, 1); + status_register_id, 1, ACPI_MTX_DO_NOT_LOCK); /* * Make sure we've got a handler. If not, report an error. @@ -298,7 +306,8 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) */ if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, 0); + enable_register_id, 0, + ACPI_MTX_DO_NOT_LOCK); ACPI_ERROR((AE_INFO, "No installed handler for fixed event [%08X]", diff --git a/trunk/drivers/acpi/events/evgpe.c b/trunk/drivers/acpi/events/evgpe.c index dfac3ecc596e..c76c0583ca6a 100644 --- a/trunk/drivers/acpi/events/evgpe.c +++ b/trunk/drivers/acpi/events/evgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -121,9 +121,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, if (!gpe_register_info) { return_ACPI_STATUS(AE_NOT_EXIST); } - register_bit = (u8) - (1 << - (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); + register_bit = gpe_event_info->register_bit; /* 1) Disable case. Simply clear all enable bits */ @@ -460,7 +458,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) /* Examine one GPE bit */ - if (enabled_status_byte & (1 << j)) { + if (enabled_status_byte & + acpi_gbl_decode_to8bit[j]) { /* * Found an active GPE. Dispatch the event to a handler * or method. @@ -571,7 +570,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, - "while evaluating GPE method [%4.4s]", + "While evaluating GPE method [%4.4s]", acpi_ut_get_node_name (local_gpe_event_info.dispatch. method_node))); @@ -619,8 +618,6 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) ACPI_FUNCTION_TRACE(ev_gpe_dispatch); - acpi_gpe_count++; - /* * If edge-triggered, clear the GPE status bit now. Note that * level-triggered events are cleared after the GPE is serviced. @@ -636,23 +633,20 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) } } - if (!acpi_gbl_system_awake_and_running) { - /* - * We just woke up because of a wake GPE. Disable any further GPEs - * until we are fully up and running (Only wake GPEs should be enabled - * at this time, but we just brute-force disable them all.) - * 1) We must disable this particular wake GPE so it won't fire again - * 2) We want to disable all wake GPEs, since we are now awake - */ - (void)acpi_hw_disable_all_gpes(); + /* Save current system state */ + + if (acpi_gbl_system_awake_and_running) { + ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); + } else { + ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); } /* - * Dispatch the GPE to either an installed handler, or the control method - * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke - * it and do not attempt to run the method. If there is neither a handler - * nor a method, we disable this GPE to prevent further such pointless - * events from firing. + * Dispatch the GPE to either an installed handler, or the control + * method associated with this GPE (_Lxx or _Exx). + * If a handler exists, we invoke it and do not attempt to run the method. + * If there is neither a handler nor a method, we disable the level to + * prevent further events from coming in here. */ switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { case ACPI_GPE_DISPATCH_HANDLER: @@ -683,8 +677,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) case ACPI_GPE_DISPATCH_METHOD: /* - * Disable the GPE, so it doesn't keep firing before the method has a - * chance to run (it runs asynchronously with interrupts enabled). + * Disable GPE, so it doesn't keep firing before the method has a + * chance to run. */ status = acpi_ev_disable_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { @@ -717,7 +711,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) gpe_number)); /* - * Disable the GPE. The GPE will remain disabled until the ACPI + * Disable the GPE. The GPE will remain disabled until the ACPI * Core Subsystem is restarted, or a handler is installed. */ status = acpi_ev_disable_gpe(gpe_event_info); @@ -732,3 +726,50 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) return_UINT32(ACPI_INTERRUPT_HANDLED); } + +#ifdef ACPI_GPE_NOTIFY_CHECK +/******************************************************************************* + * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED + * + * FUNCTION: acpi_ev_check_for_wake_only_gpe + * + * PARAMETERS: gpe_event_info - info for this GPE + * + * RETURN: Status + * + * DESCRIPTION: Determine if a a GPE is "wake-only". + * + * Called from Notify() code in interpreter when a "DeviceWake" + * Notify comes in. + * + ******************************************************************************/ + +acpi_status +acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(ev_check_for_wake_only_gpe); + + if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */ + ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) { /* System state at GPE time */ + /* This must be a wake-only GPE, disable it */ + + status = acpi_ev_disable_gpe(gpe_event_info); + + /* Set GPE to wake-only. Do not change wake disabled/enabled status */ + + acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE); + + ACPI_INFO((AE_INFO, + "GPE %p was updated from wake/run to wake-only", + gpe_event_info)); + + /* This was a wake-only GPE */ + + return_ACPI_STATUS(AE_WAKE_ONLY_GPE); + } + + return_ACPI_STATUS(AE_OK); +} +#endif diff --git a/trunk/drivers/acpi/events/evgpeblk.c b/trunk/drivers/acpi/events/evgpeblk.c index ad5bc76edf46..95ddeb48bc0f 100644 --- a/trunk/drivers/acpi/events/evgpeblk.c +++ b/trunk/drivers/acpi/events/evgpeblk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -529,7 +529,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 /* Install new interrupt handler if not SCI_INT */ - if (interrupt_number != acpi_gbl_FADT.sci_interrupt) { + if (interrupt_number != acpi_gbl_FADT->sci_int) { status = acpi_os_install_interrupt_handler(interrupt_number, acpi_ev_gpe_xrupt_handler, gpe_xrupt); @@ -567,7 +567,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) /* We never want to remove the SCI interrupt handler */ - if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) { + if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) { gpe_xrupt->gpe_block_list_head = NULL; return_ACPI_STATUS(AE_OK); } @@ -796,31 +796,30 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) (u8) (gpe_block->block_base_number + (i * ACPI_GPE_REGISTER_WIDTH)); - this_register->status_address.address = - gpe_block->block_address.address + i; + ACPI_STORE_ADDRESS(this_register->status_address.address, + (gpe_block->block_address.address + i)); - this_register->enable_address.address = - gpe_block->block_address.address + i + - gpe_block->register_count; + ACPI_STORE_ADDRESS(this_register->enable_address.address, + (gpe_block->block_address.address + + i + gpe_block->register_count)); - this_register->status_address.space_id = - gpe_block->block_address.space_id; - this_register->enable_address.space_id = - gpe_block->block_address.space_id; - this_register->status_address.bit_width = + this_register->status_address.address_space_id = + gpe_block->block_address.address_space_id; + this_register->enable_address.address_space_id = + gpe_block->block_address.address_space_id; + this_register->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH; - this_register->enable_address.bit_width = + this_register->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH; - this_register->status_address.bit_offset = + this_register->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH; - this_register->enable_address.bit_offset = + this_register->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH; /* Init the event_info for each GPE within this register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { - this_event->gpe_number = - (u8) (this_register->base_gpe_number + j); + this_event->register_bit = acpi_gbl_decode_to8bit[j]; this_event->register_info = this_register; this_event++; } @@ -1110,12 +1109,11 @@ acpi_status acpi_ev_gpe_initialize(void) * If EITHER the register length OR the block address are zero, then that * particular block is not supported. */ - if (acpi_gbl_FADT.gpe0_block_length && - acpi_gbl_FADT.xgpe0_block.address) { + if (acpi_gbl_FADT->gpe0_blk_len && acpi_gbl_FADT->xgpe0_blk.address) { /* GPE block 0 exists (has both length and address > 0) */ - register_count0 = (u16) (acpi_gbl_FADT.gpe0_block_length / 2); + register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2); gpe_number_max = (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; @@ -1123,9 +1121,9 @@ acpi_status acpi_ev_gpe_initialize(void) /* Install GPE Block 0 */ status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, - &acpi_gbl_FADT.xgpe0_block, + &acpi_gbl_FADT->xgpe0_blk, register_count0, 0, - acpi_gbl_FADT.sci_interrupt, + acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]); if (ACPI_FAILURE(status)) { @@ -1134,21 +1132,20 @@ acpi_status acpi_ev_gpe_initialize(void) } } - if (acpi_gbl_FADT.gpe1_block_length && - acpi_gbl_FADT.xgpe1_block.address) { + if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) { /* GPE block 1 exists (has both length and address > 0) */ - register_count1 = (u16) (acpi_gbl_FADT.gpe1_block_length / 2); + register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2); /* Check for GPE0/GPE1 overlap (if both banks exist) */ if ((register_count0) && - (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) { + (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) { ACPI_ERROR((AE_INFO, "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", - gpe_number_max, acpi_gbl_FADT.gpe1_base, - acpi_gbl_FADT.gpe1_base + + gpe_number_max, acpi_gbl_FADT->gpe1_base, + acpi_gbl_FADT->gpe1_base + ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1))); @@ -1160,11 +1157,10 @@ acpi_status acpi_ev_gpe_initialize(void) status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, - &acpi_gbl_FADT.xgpe1_block, + &acpi_gbl_FADT->xgpe1_blk, register_count1, - acpi_gbl_FADT.gpe1_base, - acpi_gbl_FADT. - sci_interrupt, + acpi_gbl_FADT->gpe1_base, + acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks [1]); @@ -1177,7 +1173,7 @@ acpi_status acpi_ev_gpe_initialize(void) * GPE0 and GPE1 do not have to be contiguous in the GPE number * space. However, GPE0 always starts at GPE number zero. */ - gpe_number_max = acpi_gbl_FADT.gpe1_base + + gpe_number_max = acpi_gbl_FADT->gpe1_base + ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1); } } diff --git a/trunk/drivers/acpi/events/evmisc.c b/trunk/drivers/acpi/events/evmisc.c index 1b784ffe54c3..bf63edc6608d 100644 --- a/trunk/drivers/acpi/events/evmisc.c +++ b/trunk/drivers/acpi/events/evmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,17 +63,13 @@ static const char *acpi_notify_value_names[] = { }; #endif -/* Pointer to FACS needed for the Global Lock */ - -static struct acpi_table_facs *facs = NULL; - /* Local prototypes */ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); -static u32 acpi_ev_global_lock_handler(void *context); +static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context); -static acpi_status acpi_ev_remove_global_lock_handler(void); +static u32 acpi_ev_global_lock_handler(void *context); /******************************************************************************* * @@ -284,21 +280,51 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) acpi_ut_delete_generic_state(notify_info); } +/******************************************************************************* + * + * FUNCTION: acpi_ev_global_lock_thread + * + * PARAMETERS: Context - From thread interface, not used + * + * RETURN: None + * + * DESCRIPTION: Invoked by SCI interrupt handler upon acquisition of the + * Global Lock. Simply signal all threads that are waiting + * for the lock. + * + ******************************************************************************/ + +static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context) +{ + acpi_status status; + + /* Signal threads that are waiting for the lock */ + + if (acpi_gbl_global_lock_thread_count) { + + /* Send sufficient units to the semaphore */ + + status = + acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, + acpi_gbl_global_lock_thread_count); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not signal Global Lock semaphore")); + } + } +} + /******************************************************************************* * * FUNCTION: acpi_ev_global_lock_handler * * PARAMETERS: Context - From thread interface, not used * - * RETURN: ACPI_INTERRUPT_HANDLED + * RETURN: ACPI_INTERRUPT_HANDLED or ACPI_INTERRUPT_NOT_HANDLED * * DESCRIPTION: Invoked directly from the SCI handler when a global lock - * release interrupt occurs. Attempt to acquire the global lock, - * if successful, signal the thread waiting for the lock. - * - * NOTE: Assumes that the semaphore can be signaled from interrupt level. If - * this is not possible for some reason, a separate thread will have to be - * scheduled to do this. + * release interrupt occurs. Grab the global lock and queue + * the global lock thread for execution * ******************************************************************************/ @@ -307,24 +333,16 @@ static u32 acpi_ev_global_lock_handler(void *context) u8 acquired = FALSE; /* - * Attempt to get the lock. - * + * Attempt to get the lock * If we don't get it now, it will be marked pending and we will * take another interrupt when it becomes free. */ - ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); + ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); if (acquired) { /* Got the lock, now wake all threads waiting for it */ - acpi_gbl_global_lock_acquired = TRUE; - /* Send a unit to the semaphore */ - - if (ACPI_FAILURE(acpi_os_signal_semaphore( - acpi_gbl_global_lock_semaphore, 1))) { - ACPI_ERROR((AE_INFO, - "Could not signal Global Lock semaphore")); - } + acpi_ev_global_lock_thread(context); } return (ACPI_INTERRUPT_HANDLED); @@ -348,13 +366,6 @@ acpi_status acpi_ev_init_global_lock_handler(void) ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); - status = - acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - (struct acpi_table_header **)&facs); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - acpi_gbl_global_lock_present = TRUE; status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, acpi_ev_global_lock_handler, @@ -378,31 +389,6 @@ acpi_status acpi_ev_init_global_lock_handler(void) return_ACPI_STATUS(status); } -/******************************************************************************* - * - * FUNCTION: acpi_ev_remove_global_lock_handler - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Remove the handler for the Global Lock - * - ******************************************************************************/ - -static acpi_status acpi_ev_remove_global_lock_handler(void) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler); - - acpi_gbl_global_lock_present = FALSE; - status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL, - acpi_ev_global_lock_handler); - - return_ACPI_STATUS(status); -} - /****************************************************************************** * * FUNCTION: acpi_ev_acquire_global_lock @@ -413,16 +399,6 @@ static acpi_status acpi_ev_remove_global_lock_handler(void) * * DESCRIPTION: Attempt to gain ownership of the Global Lock. * - * MUTEX: Interpreter must be locked - * - * Note: The original implementation allowed multiple threads to "acquire" the - * Global Lock, and the OS would hold the lock until the last thread had - * released it. However, this could potentially starve the BIOS out of the - * lock, especially in the case where there is a tight handshake between the - * Embedded Controller driver and the BIOS. Therefore, this implementation - * allows only one thread to acquire the HW Global Lock at a time, and makes - * the global lock appear as a standard mutex on the OS side. - * *****************************************************************************/ acpi_status acpi_ev_acquire_global_lock(u16 timeout) @@ -432,51 +408,53 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) ACPI_FUNCTION_TRACE(ev_acquire_global_lock); - /* - * Only one thread can acquire the GL at a time, the global_lock_mutex - * enforces this. This interface releases the interpreter if we must wait. - */ - status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); +#ifndef ACPI_APPLICATION + /* Make sure that we actually have a global lock */ + + if (!acpi_gbl_global_lock_present) { + return_ACPI_STATUS(AE_NO_GLOBAL_LOCK); } +#endif + + /* One more thread wants the global lock */ + + acpi_gbl_global_lock_thread_count++; /* - * Make sure that a global lock actually exists. If not, just treat - * the lock as a standard mutex. + * If we (OS side vs. BIOS side) have the hardware lock already, + * we are done */ - if (!acpi_gbl_global_lock_present) { - acpi_gbl_global_lock_acquired = TRUE; + if (acpi_gbl_global_lock_acquired) { return_ACPI_STATUS(AE_OK); } - /* Attempt to acquire the actual hardware lock */ + /* We must acquire the actual hardware lock */ - ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); + ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); if (acquired) { /* We got the lock */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Acquired hardware Global Lock\n")); + "Acquired the HW Global Lock\n")); acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS(AE_OK); } /* - * Did not get the lock. The pending bit was set above, and we must now + * Did not get the lock. The pending bit was set above, and we must now * wait until we get the global lock released interrupt. */ - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n")); /* - * Wait for handshake with the global lock interrupt handler. - * This interface releases the interpreter if we must wait. + * Acquire the global lock semaphore first. + * Since this wait will block, we must release the interpreter */ - status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, - ACPI_WAIT_FOREVER); - + status = + acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, + timeout); return_ACPI_STATUS(status); } @@ -499,39 +477,38 @@ acpi_status acpi_ev_release_global_lock(void) ACPI_FUNCTION_TRACE(ev_release_global_lock); - /* Lock must be already acquired */ - - if (!acpi_gbl_global_lock_acquired) { + if (!acpi_gbl_global_lock_thread_count) { ACPI_WARNING((AE_INFO, - "Cannot release the ACPI Global Lock, it has not been acquired")); + "Cannot release HW Global Lock, it has not been acquired")); return_ACPI_STATUS(AE_NOT_ACQUIRED); } - if (acpi_gbl_global_lock_present) { + /* One fewer thread has the global lock */ - /* Allow any thread to release the lock */ + acpi_gbl_global_lock_thread_count--; + if (acpi_gbl_global_lock_thread_count) { - ACPI_RELEASE_GLOBAL_LOCK(facs, pending); + /* There are still some threads holding the lock, cannot release */ - /* - * If the pending bit was set, we must write GBL_RLS to the control - * register - */ - if (pending) { - status = - acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE, - 1); - } - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Released hardware Global Lock\n")); + return_ACPI_STATUS(AE_OK); } + /* + * No more threads holding lock, we can do the actual hardware + * release + */ + ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, pending); acpi_gbl_global_lock_acquired = FALSE; - /* Release the local GL mutex */ + /* + * If the pending bit was set, we must write GBL_RLS to the control + * register + */ + if (pending) { + status = acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE, + 1, ACPI_MTX_LOCK); + } - acpi_os_release_mutex(acpi_gbl_global_lock_mutex); return_ACPI_STATUS(status); } @@ -581,12 +558,6 @@ void acpi_ev_terminate(void) if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); } - - status = acpi_ev_remove_global_lock_handler(); - if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not remove Global Lock handler")); - } } /* Deallocate all handler objects installed within GPE info structs */ diff --git a/trunk/drivers/acpi/events/evregion.c b/trunk/drivers/acpi/events/evregion.c index e99f0c435a47..21caae04fe85 100644 --- a/trunk/drivers/acpi/events/evregion.c +++ b/trunk/drivers/acpi/events/evregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -291,6 +291,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 bit_width, acpi_integer * value) { acpi_status status; + acpi_status status2; acpi_adr_space_handler handler; acpi_adr_space_setup region_setup; union acpi_operand_object *handler_desc; @@ -344,7 +345,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * setup will potentially execute control methods * (e.g., _REG method for this region) */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = region_setup(region_obj, ACPI_REGION_ACTIVATE, handler_desc->address_space.context, @@ -352,7 +353,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, /* Re-enter the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } /* Check for failure of the Region Setup */ @@ -405,7 +409,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); } /* Call the handler */ @@ -426,7 +430,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * We just returned from a non-default handler, we must re-enter the * interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); diff --git a/trunk/drivers/acpi/events/evrgnini.c b/trunk/drivers/acpi/events/evrgnini.c index a4fa7e6822a3..203d1359190a 100644 --- a/trunk/drivers/acpi/events/evrgnini.c +++ b/trunk/drivers/acpi/events/evrgnini.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,11 +48,6 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evrgnini") -/* Local prototypes */ -static u8 acpi_ev_match_pci_root_bridge(char *id); - -static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); - /******************************************************************************* * * FUNCTION: acpi_ev_system_memory_region_setup @@ -67,7 +62,6 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); * DESCRIPTION: Setup a system_memory operation region * ******************************************************************************/ - acpi_status acpi_ev_system_memory_region_setup(acpi_handle handle, u32 function, @@ -174,9 +168,9 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, union acpi_operand_object *handler_obj; struct acpi_namespace_node *parent_node; struct acpi_namespace_node *pci_root_node; - struct acpi_namespace_node *pci_device_node; union acpi_operand_object *region_obj = (union acpi_operand_object *)handle; + struct acpi_device_id object_hID; ACPI_FUNCTION_TRACE(ev_pci_config_region_setup); @@ -221,30 +215,45 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, pci_root_node = parent_node; while (pci_root_node != acpi_gbl_root_node) { + status = + acpi_ut_execute_HID(pci_root_node, &object_hID); + if (ACPI_SUCCESS(status)) { + /* + * Got a valid _HID string, check if this is a PCI root. + * New for ACPI 3.0: check for a PCI Express root also. + */ + if (! + (ACPI_STRNCMP + (object_hID.value, PCI_ROOT_HID_STRING, + sizeof(PCI_ROOT_HID_STRING))) + || + !(ACPI_STRNCMP + (object_hID.value, + PCI_EXPRESS_ROOT_HID_STRING, + sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { + + /* Install a handler for this PCI root bridge */ - /* Get the _HID/_CID in order to detect a root_bridge */ - - if (acpi_ev_is_pci_root_bridge(pci_root_node)) { - - /* Install a handler for this PCI root bridge */ - - status = acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); - if (ACPI_FAILURE(status)) { - if (status == AE_SAME_HANDLER) { - /* - * It is OK if the handler is already installed on the root - * bridge. Still need to return a context object for the - * new PCI_Config operation region, however. - */ - status = AE_OK; - } else { - ACPI_EXCEPTION((AE_INFO, status, - "Could not install PciConfig handler for Root Bridge %4.4s", - acpi_ut_get_node_name - (pci_root_node))); + status = + acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); + if (ACPI_FAILURE(status)) { + if (status == AE_SAME_HANDLER) { + /* + * It is OK if the handler is already installed on the root + * bridge. Still need to return a context object for the + * new PCI_Config operation region, however. + */ + status = AE_OK; + } else { + ACPI_EXCEPTION((AE_INFO, + status, + "Could not install PciConfig handler for Root Bridge %4.4s", + acpi_ut_get_node_name + (pci_root_node))); + } } + break; } - break; } pci_root_node = acpi_ns_get_parent_node(pci_root_node); @@ -273,25 +282,14 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, /* * For PCI_Config space access, we need the segment, bus, * device and function numbers. Acquire them here. - * - * Find the parent device object. (This allows the operation region to be - * within a subscope under the device, such as a control method.) */ - pci_device_node = region_obj->region.node; - while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) { - pci_device_node = acpi_ns_get_parent_node(pci_device_node); - } - - if (!pci_device_node) { - return_ACPI_STATUS(AE_AML_OPERAND_TYPE); - } /* * Get the PCI device and function numbers from the _ADR object * contained in the parent's scope. */ status = - acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node, + acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node, &pci_value); /* @@ -329,91 +327,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, return_ACPI_STATUS(AE_OK); } -/******************************************************************************* - * - * FUNCTION: acpi_ev_match_pci_root_bridge - * - * PARAMETERS: Id - The HID/CID in string format - * - * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge - * - * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. - * - ******************************************************************************/ - -static u8 acpi_ev_match_pci_root_bridge(char *id) -{ - - /* - * Check if this is a PCI root. - * ACPI 3.0+: check for a PCI Express root also. - */ - if (!(ACPI_STRNCMP(id, - PCI_ROOT_HID_STRING, - sizeof(PCI_ROOT_HID_STRING))) || - !(ACPI_STRNCMP(id, - PCI_EXPRESS_ROOT_HID_STRING, - sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { - return (TRUE); - } - - return (FALSE); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ev_is_pci_root_bridge - * - * PARAMETERS: Node - Device node being examined - * - * RETURN: TRUE if device is a PCI/PCI-Express Root Bridge - * - * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by - * examining the _HID and _CID for the device. - * - ******************************************************************************/ - -static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) -{ - acpi_status status; - struct acpi_device_id hid; - struct acpi_compatible_id_list *cid; - acpi_native_uint i; - - /* - * Get the _HID and check for a PCI Root Bridge - */ - status = acpi_ut_execute_HID(node, &hid); - if (ACPI_FAILURE(status)) { - return (FALSE); - } - - if (acpi_ev_match_pci_root_bridge(hid.value)) { - return (TRUE); - } - - /* - * The _HID did not match. - * Get the _CID and check for a PCI Root Bridge - */ - status = acpi_ut_execute_CID(node, &cid); - if (ACPI_FAILURE(status)) { - return (FALSE); - } - - /* Check all _CIDs in the returned list */ - - for (i = 0; i < cid->count; i++) { - if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) { - ACPI_FREE(cid); - return (TRUE); - } - } - - ACPI_FREE(cid); - return (FALSE); -} - /******************************************************************************* * * FUNCTION: acpi_ev_pci_bar_region_setup @@ -519,9 +432,6 @@ acpi_ev_default_region_setup(acpi_handle handle, * a PCI address in the scope of the definition. This address is * required to perform an access to PCI config space. * - * MUTEX: Interpreter should be unlocked, because we may run the _REG - * method for this region. - * ******************************************************************************/ acpi_status diff --git a/trunk/drivers/acpi/events/evsci.c b/trunk/drivers/acpi/events/evsci.c index 7e5d15ce2395..8106215ad554 100644 --- a/trunk/drivers/acpi/events/evsci.c +++ b/trunk/drivers/acpi/events/evsci.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -142,10 +142,9 @@ u32 acpi_ev_install_sci_handler(void) ACPI_FUNCTION_TRACE(ev_install_sci_handler); - status = - acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, - acpi_ev_sci_xrupt_handler, - acpi_gbl_gpe_xrupt_list_head); + status = acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT->sci_int, + acpi_ev_sci_xrupt_handler, + acpi_gbl_gpe_xrupt_list_head); return_ACPI_STATUS(status); } @@ -176,9 +175,8 @@ acpi_status acpi_ev_remove_sci_handler(void) /* Just let the OS remove the handler and disable the level */ - status = - acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, - acpi_ev_sci_xrupt_handler); + status = acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT->sci_int, + acpi_ev_sci_xrupt_handler); return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/events/evxface.c b/trunk/drivers/acpi/events/evxface.c index 685a103a3587..923fd2b46955 100644 --- a/trunk/drivers/acpi/events/evxface.c +++ b/trunk/drivers/acpi/events/evxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -768,9 +768,11 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) return (AE_BAD_PARAMETER); } - /* Must lock interpreter to prevent race conditions */ + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return (status); + } - acpi_ex_enter_interpreter(); status = acpi_ev_acquire_global_lock(timeout); acpi_ex_exit_interpreter(); diff --git a/trunk/drivers/acpi/events/evxfevnt.c b/trunk/drivers/acpi/events/evxfevnt.c index 17065e98807c..7ebc2efac936 100644 --- a/trunk/drivers/acpi/events/evxfevnt.c +++ b/trunk/drivers/acpi/events/evxfevnt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +44,6 @@ #include #include #include -#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evxfevnt") @@ -66,14 +65,13 @@ acpi_status acpi_enable(void) ACPI_FUNCTION_TRACE(acpi_enable); - /* ACPI tables must be present */ + /* Make sure we have the FADT */ - if (!acpi_tb_tables_loaded()) { + if (!acpi_gbl_FADT) { + ACPI_WARNING((AE_INFO, "No FADT information present!")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } - /* Check current mode */ - if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { ACPI_DEBUG_PRINT((ACPI_DB_INIT, "System is already in ACPI mode\n")); @@ -113,6 +111,11 @@ acpi_status acpi_disable(void) ACPI_FUNCTION_TRACE(acpi_disable); + if (!acpi_gbl_FADT) { + ACPI_WARNING((AE_INFO, "No FADT information present!")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { ACPI_DEBUG_PRINT((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n")); @@ -166,7 +169,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, 1); + enable_register_id, 1, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -175,7 +178,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags) status = acpi_get_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, &value); + enable_register_id, &value, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -365,14 +368,14 @@ acpi_status acpi_disable_event(u32 event, u32 flags) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, 0); + enable_register_id, 0, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_get_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, &value); + enable_register_id, &value, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -418,7 +421,7 @@ acpi_status acpi_clear_event(u32 event) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. - status_register_id, 1); + status_register_id, 1, ACPI_MTX_LOCK); return_ACPI_STATUS(status); } @@ -507,7 +510,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) status = acpi_get_register(acpi_gbl_fixed_event_info[event]. - status_register_id, event_status); + status_register_id, event_status, ACPI_MTX_LOCK); return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/events/evxfregn.c b/trunk/drivers/acpi/events/evxfregn.c index 7bf09c5fb242..83b12a9afa32 100644 --- a/trunk/drivers/acpi/events/evxfregn.c +++ b/trunk/drivers/acpi/events/evxfregn.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exconfig.c b/trunk/drivers/acpi/executer/exconfig.c index 25802f302ffe..c8341fa5fe01 100644 --- a/trunk/drivers/acpi/executer/exconfig.c +++ b/trunk/drivers/acpi/executer/exconfig.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,7 +54,7 @@ ACPI_MODULE_NAME("exconfig") /* Local prototypes */ static acpi_status -acpi_ex_add_table(acpi_native_uint table_index, +acpi_ex_add_table(struct acpi_table_header *table, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle); @@ -74,11 +74,12 @@ acpi_ex_add_table(acpi_native_uint table_index, ******************************************************************************/ static acpi_status -acpi_ex_add_table(acpi_native_uint table_index, +acpi_ex_add_table(struct acpi_table_header *table, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle) { acpi_status status; + struct acpi_table_desc table_info; union acpi_operand_object *obj_desc; ACPI_FUNCTION_TRACE(ex_add_table); @@ -97,16 +98,42 @@ acpi_ex_add_table(acpi_native_uint table_index, /* Install the new table into the local data structures */ - obj_desc->reference.object = ACPI_CAST_PTR(void, table_index); + ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc)); + + table_info.type = ACPI_TABLE_ID_SSDT; + table_info.pointer = table; + table_info.length = (acpi_size) table->length; + table_info.allocation = ACPI_MEM_ALLOCATED; + + status = acpi_tb_install_table(&table_info); + obj_desc->reference.object = table_info.installed_desc; + + if (ACPI_FAILURE(status)) { + if (status == AE_ALREADY_EXISTS) { + + /* Table already exists, just return the handle */ + + return_ACPI_STATUS(AE_OK); + } + goto cleanup; + } /* Add the table to the namespace */ - status = acpi_ns_load_table(table_index, parent_node); + status = acpi_ns_load_table(table_info.installed_desc, parent_node); if (ACPI_FAILURE(status)) { - acpi_ut_remove_reference(obj_desc); - *ddb_handle = NULL; + + /* Uninstall table on error */ + + (void)acpi_tb_uninstall_table(table_info.installed_desc); + goto cleanup; } + return_ACPI_STATUS(AE_OK); + + cleanup: + acpi_ut_remove_reference(obj_desc); + *ddb_handle = NULL; return_ACPI_STATUS(status); } @@ -119,7 +146,7 @@ acpi_ex_add_table(acpi_native_uint table_index, * * RETURN: Status * - * DESCRIPTION: Load an ACPI table from the RSDT/XSDT + * DESCRIPTION: Load an ACPI table * ******************************************************************************/ @@ -129,20 +156,33 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, { acpi_status status; union acpi_operand_object **operand = &walk_state->operands[0]; - acpi_native_uint table_index; + struct acpi_table_header *table; struct acpi_namespace_node *parent_node; struct acpi_namespace_node *start_node; struct acpi_namespace_node *parameter_node = NULL; union acpi_operand_object *ddb_handle; - struct acpi_table_header *table; ACPI_FUNCTION_TRACE(ex_load_table_op); - /* Find the ACPI table in the RSDT/XSDT */ +#if 0 + /* + * Make sure that the signature does not match one of the tables that + * is already loaded. + */ + status = acpi_tb_match_signature(operand[0]->string.pointer, NULL); + if (status == AE_OK) { + + /* Signature matched -- don't allow override */ + + return_ACPI_STATUS(AE_ALREADY_EXISTS); + } +#endif + + /* Find the ACPI table */ status = acpi_tb_find_table(operand[0]->string.pointer, operand[1]->string.pointer, - operand[2]->string.pointer, &table_index); + operand[2]->string.pointer, &table); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) { return_ACPI_STATUS(status); @@ -205,7 +245,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, /* Load the table into the namespace */ - status = acpi_ex_add_table(table_index, parent_node, &ddb_handle); + status = acpi_ex_add_table(table, parent_node, &ddb_handle); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -226,13 +266,9 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, } } - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_SUCCESS(status)) { - ACPI_INFO((AE_INFO, - "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", - table->signature, table->oem_id, - table->oem_table_id)); - } + ACPI_INFO((AE_INFO, + "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", + table->signature, table->oem_id, table->oem_table_id)); *return_desc = ddb_handle; return_ACPI_STATUS(status); @@ -242,7 +278,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, * * FUNCTION: acpi_ex_load_op * - * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be + * PARAMETERS: obj_desc - Region or Field where the table will be * obtained * Target - Where a handle to the table will be stored * walk_state - Current state @@ -251,12 +287,6 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, * * DESCRIPTION: Load an ACPI table from a field or operation region * - * NOTE: Region Fields (Field, bank_field, index_fields) are resolved to buffer - * objects before this code is reached. - * - * If source is an operation region, it must refer to system_memory, as - * per the ACPI specification. - * ******************************************************************************/ acpi_status @@ -264,26 +294,22 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, union acpi_operand_object *target, struct acpi_walk_state *walk_state) { - union acpi_operand_object *ddb_handle; - struct acpi_table_desc table_desc; - acpi_native_uint table_index; acpi_status status; + union acpi_operand_object *ddb_handle; + union acpi_operand_object *buffer_desc = NULL; + struct acpi_table_header *table_ptr = NULL; + acpi_physical_address address; + struct acpi_table_header table_header; + acpi_integer temp; + u32 i; ACPI_FUNCTION_TRACE(ex_load_op); - ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); - - /* Source Object can be either an op_region or a Buffer/Field */ + /* Object can be either an op_region or a Field */ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_REGION: - /* Region must be system_memory (from ACPI spec) */ - - if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { - return_ACPI_STATUS(AE_AML_OPERAND_TYPE); - } - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", obj_desc, acpi_ut_get_object_type_name(obj_desc))); @@ -299,41 +325,113 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, } } - table_desc.address = obj_desc->region.address; - table_desc.length = obj_desc->region.length; - table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; - break; + /* Get the base physical address of the region */ - case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ + address = obj_desc->region.address; - /* Simply extract the buffer from the buffer object */ + /* Get part of the table header to get the table length */ - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Load from Buffer or Field %p %s\n", obj_desc, + table_header.length = 0; + for (i = 0; i < 8; i++) { + status = + acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, + (acpi_physical_address) + (i + address), 8, + &temp); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the one valid byte of the returned 64-bit value */ + + ACPI_CAST_PTR(u8, &table_header)[i] = (u8) temp; + } + + /* Sanity check the table length */ + + if (table_header.length < sizeof(struct acpi_table_header)) { + return_ACPI_STATUS(AE_BAD_HEADER); + } + + /* Allocate a buffer for the entire table */ + + table_ptr = ACPI_ALLOCATE(table_header.length); + if (!table_ptr) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Get the entire table from the op region */ + + for (i = 0; i < table_header.length; i++) { + status = + acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, + (acpi_physical_address) + (i + address), 8, + &temp); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + /* Get the one valid byte of the returned 64-bit value */ + + ACPI_CAST_PTR(u8, table_ptr)[i] = (u8) temp; + } + break; + + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Field %p %s\n", + obj_desc, acpi_ut_get_object_type_name(obj_desc))); - table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header, - obj_desc->buffer.pointer); - table_desc.length = table_desc.pointer->length; - table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; + /* + * The length of the field must be at least as large as the table. + * Read the entire field and thus the entire table. Buffer is + * allocated during the read. + */ + status = + acpi_ex_read_data_from_field(walk_state, obj_desc, + &buffer_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + table_ptr = ACPI_CAST_PTR(struct acpi_table_header, + buffer_desc->buffer.pointer); + + /* All done with the buffer_desc, delete it */ + + buffer_desc->buffer.pointer = NULL; + acpi_ut_remove_reference(buffer_desc); + + /* Sanity check the table length */ - obj_desc->buffer.pointer = NULL; + if (table_ptr->length < sizeof(struct acpi_table_header)) { + status = AE_BAD_HEADER; + goto cleanup; + } break; default: return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } - /* - * Install the new table into the local data structures - */ - status = acpi_tb_add_table(&table_desc, &table_index); - if (ACPI_FAILURE(status)) { + /* The table must be either an SSDT or a PSDT */ + + if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) && + (!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) { + ACPI_ERROR((AE_INFO, + "Table has invalid signature [%4.4s], must be SSDT or PSDT", + table_ptr->signature)); + status = AE_BAD_SIGNATURE; goto cleanup; } - status = - acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); + /* Install the new table into the local data structures */ + + status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle); if (ACPI_FAILURE(status)) { /* On error, table_ptr was deallocated above */ @@ -352,9 +450,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, return_ACPI_STATUS(status); } + ACPI_INFO((AE_INFO, + "Dynamic SSDT Load - OemId [%6.6s] OemTableId [%8.8s]", + table_ptr->oem_id, table_ptr->oem_table_id)); + cleanup: if (ACPI_FAILURE(status)) { - acpi_tb_delete_table(&table_desc); + ACPI_FREE(table_ptr); } return_ACPI_STATUS(status); } @@ -375,7 +477,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) { acpi_status status = AE_OK; union acpi_operand_object *table_desc = ddb_handle; - acpi_native_uint table_index; + struct acpi_table_desc *table_info; ACPI_FUNCTION_TRACE(ex_unload_table); @@ -391,18 +493,19 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Get the table index from the ddb_handle */ + /* Get the actual table descriptor from the ddb_handle */ - table_index = (acpi_native_uint) table_desc->reference.object; + table_info = (struct acpi_table_desc *)table_desc->reference.object; /* * Delete the entire namespace under this table Node * (Offset contains the table_id) */ - acpi_tb_delete_namespace_by_owner(table_index); - acpi_tb_release_owner_id(table_index); + acpi_ns_delete_namespace_by_owner(table_info->owner_id); + + /* Delete the table itself */ - acpi_tb_set_table_loaded_flag(table_index, FALSE); + (void)acpi_tb_uninstall_table(table_info->installed_desc); /* Delete the table descriptor (ddb_handle) */ diff --git a/trunk/drivers/acpi/executer/exconvrt.c b/trunk/drivers/acpi/executer/exconvrt.c index d470e8b1f4ea..544e81a6a438 100644 --- a/trunk/drivers/acpi/executer/exconvrt.c +++ b/trunk/drivers/acpi/executer/exconvrt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/excreate.c b/trunk/drivers/acpi/executer/excreate.c index 7c38528a7e83..34eec82c1b1e 100644 --- a/trunk/drivers/acpi/executer/excreate.c +++ b/trunk/drivers/acpi/executer/excreate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -359,9 +359,8 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *obj_desc; struct acpi_namespace_node *node; - union acpi_operand_object *region_obj2; - acpi_native_uint table_index; struct acpi_table_header *table; + union acpi_operand_object *region_obj2; ACPI_FUNCTION_TRACE(ex_create_table_region); @@ -381,7 +380,7 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) status = acpi_tb_find_table(operand[1]->string.pointer, operand[2]->string.pointer, - operand[3]->string.pointer, &table_index); + operand[3]->string.pointer, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -396,11 +395,6 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) region_obj2 = obj_desc->common.next_object; region_obj2->extra.region_context = NULL; - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Init the region from the operands */ obj_desc->region.space_id = REGION_DATA_TABLE; @@ -559,8 +553,7 @@ acpi_ex_create_method(u8 * aml_start, obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); if (!obj_desc) { - status = AE_NO_MEMORY; - goto exit; + return_ACPI_STATUS(AE_NO_MEMORY); } /* Save the method's AML pointer and length */ @@ -583,7 +576,10 @@ acpi_ex_create_method(u8 * aml_start, * Get the sync_level. If method is serialized, a mutex will be * created for this method when it is parsed. */ - if (method_flags & AML_METHOD_SERIALIZED) { + if (acpi_gbl_all_methods_serialized) { + obj_desc->method.sync_level = 0; + obj_desc->method.method_flags |= AML_METHOD_SERIALIZED; + } else if (method_flags & AML_METHOD_SERIALIZED) { /* * ACPI 1.0: sync_level = 0 * ACPI 2.0: sync_level = sync_level in method declaration @@ -601,7 +597,6 @@ acpi_ex_create_method(u8 * aml_start, acpi_ut_remove_reference(obj_desc); - exit: /* Remove a reference to the operand */ acpi_ut_remove_reference(operand[1]); diff --git a/trunk/drivers/acpi/executer/exdump.c b/trunk/drivers/acpi/executer/exdump.c index 68d283fd60e7..2450943add33 100644 --- a/trunk/drivers/acpi/executer/exdump.c +++ b/trunk/drivers/acpi/executer/exdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -59,6 +59,8 @@ static void acpi_ex_out_string(char *title, char *value); static void acpi_ex_out_pointer(char *title, void *value); +static void acpi_ex_out_address(char *title, acpi_physical_address value); + static void acpi_ex_dump_object(union acpi_operand_object *obj_desc, struct acpi_exdump_info *info); @@ -90,11 +92,10 @@ static struct acpi_exdump_info acpi_ex_dump_string[4] = { {ACPI_EXD_STRING, 0, NULL} }; -static struct acpi_exdump_info acpi_ex_dump_buffer[5] = { +static struct acpi_exdump_info acpi_ex_dump_buffer[4] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.node), "Parent Node"}, {ACPI_EXD_BUFFER, 0, NULL} }; @@ -164,8 +165,8 @@ static struct acpi_exdump_info acpi_ex_dump_power[5] = { static struct acpi_exdump_info acpi_ex_dump_processor[7] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL}, - {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"}, - {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.length), "Length"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.length), "Length"}, {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify), "System Notify"}, @@ -378,12 +379,18 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, break; case ACPI_EXD_POINTER: - case ACPI_EXD_ADDRESS: acpi_ex_out_pointer(name, *ACPI_CAST_PTR(void *, target)); break; + case ACPI_EXD_ADDRESS: + + acpi_ex_out_address(name, + *ACPI_CAST_PTR + (acpi_physical_address, target)); + break; + case ACPI_EXD_STRING: acpi_ut_print_string(obj_desc->string.pointer, @@ -827,6 +834,16 @@ static void acpi_ex_out_pointer(char *title, void *value) acpi_os_printf("%20s : %p\n", title, value); } +static void acpi_ex_out_address(char *title, acpi_physical_address value) +{ + +#if ACPI_MACHINE_WIDTH == 16 + acpi_os_printf("%20s : %p\n", title, value); +#else + acpi_os_printf("%20s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value)); +#endif +} + /******************************************************************************* * * FUNCTION: acpi_ex_dump_namespace_node diff --git a/trunk/drivers/acpi/executer/exfield.c b/trunk/drivers/acpi/executer/exfield.c index 2d88a3d8d1ad..9ea9c3a67ca9 100644 --- a/trunk/drivers/acpi/executer/exfield.c +++ b/trunk/drivers/acpi/executer/exfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exfldio.c b/trunk/drivers/acpi/executer/exfldio.c index 65a48b6170ee..40f0bee6faa5 100644 --- a/trunk/drivers/acpi/executer/exfldio.c +++ b/trunk/drivers/acpi/executer/exfldio.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -257,13 +257,14 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, } ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, - " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n", + " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n", acpi_ut_get_region_name(rgn_desc->region. space_id), rgn_desc->region.space_id, obj_desc->common_field.access_byte_width, obj_desc->common_field.base_byte_offset, - field_datum_byte_offset, (void *)address)); + field_datum_byte_offset, + ACPI_FORMAT_UINT64(address))); /* Invoke the appropriate address_space/op_region handler */ diff --git a/trunk/drivers/acpi/executer/exmisc.c b/trunk/drivers/acpi/executer/exmisc.c index f13d1cec2d6d..bd98aab017cf 100644 --- a/trunk/drivers/acpi/executer/exmisc.c +++ b/trunk/drivers/acpi/executer/exmisc.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exmutex.c b/trunk/drivers/acpi/executer/exmutex.c index 5101bad5baf8..bf90f04f2c60 100644 --- a/trunk/drivers/acpi/executer/exmutex.c +++ b/trunk/drivers/acpi/executer/exmutex.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +44,6 @@ #include #include -#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exmutex") @@ -151,7 +150,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Sanity check: we must have a valid thread ID */ + /* Sanity check -- we must have a valid thread ID */ if (!walk_state->thread) { ACPI_ERROR((AE_INFO, @@ -175,28 +174,24 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Support for multiple acquires by the owning thread */ if (obj_desc->mutex.owner_thread) { - if (obj_desc->mutex.owner_thread->thread_id == - walk_state->thread->thread_id) { + + /* Special case for Global Lock, allow all threads */ + + if ((obj_desc->mutex.owner_thread->thread_id == + walk_state->thread->thread_id) || + (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK)) { /* - * The mutex is already owned by this thread, just increment the - * acquisition depth + * The mutex is already owned by this thread, + * just increment the acquisition depth */ obj_desc->mutex.acquisition_depth++; return_ACPI_STATUS(AE_OK); } } - /* Acquire the mutex, wait if necessary. Special case for Global Lock */ - - if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { - status = - acpi_ev_acquire_global_lock((u16) time_desc->integer.value); - } else { - status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, - (u16) time_desc->integer. - value); - } + /* Acquire the mutex, wait if necessary */ + status = acpi_ex_system_acquire_mutex(time_desc, obj_desc); if (ACPI_FAILURE(status)) { /* Includes failure from a timeout on time_desc */ @@ -216,6 +211,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Link the mutex to the current thread for force-unlock at method exit */ acpi_ex_link_mutex(obj_desc, walk_state->thread); + return_ACPI_STATUS(AE_OK); } @@ -236,7 +232,7 @@ acpi_status acpi_ex_release_mutex(union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; + acpi_status status; ACPI_FUNCTION_TRACE(ex_release_mutex); @@ -253,7 +249,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); } - /* Sanity check: we must have a valid thread ID */ + /* Sanity check -- we must have a valid thread ID */ if (!walk_state->thread) { ACPI_ERROR((AE_INFO, @@ -268,7 +264,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, */ if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) - && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { + && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) { ACPI_ERROR((AE_INFO, "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", (unsigned long)walk_state->thread->thread_id, @@ -278,8 +274,8 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, } /* - * The sync level of the mutex must be less than or equal to the current - * sync level + * The sync level of the mutex must be less than or + * equal to the current sync level */ if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { ACPI_ERROR((AE_INFO, @@ -302,15 +298,11 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, acpi_ex_unlink_mutex(obj_desc); - /* Release the mutex, special case for Global Lock */ + /* Release the mutex */ - if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { - status = acpi_ev_release_global_lock(); - } else { - acpi_os_release_mutex(obj_desc->mutex.os_mutex); - } + status = acpi_ex_system_release_mutex(obj_desc); - /* Update the mutex and restore sync_level */ + /* Update the mutex and walk state, restore sync_level before acquire */ obj_desc->mutex.owner_thread = NULL; walk_state->thread->current_sync_level = @@ -329,49 +321,39 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, * * DESCRIPTION: Release all mutexes held by this thread * - * NOTE: This function is called as the thread is exiting the interpreter. - * Mutexes are not released when an individual control method is exited, but - * only when the parent thread actually exits the interpreter. This allows one - * method to acquire a mutex, and a different method to release it, as long as - * this is performed underneath a single parent control method. - * ******************************************************************************/ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) { union acpi_operand_object *next = thread->acquired_mutex_list; - union acpi_operand_object *obj_desc; + union acpi_operand_object *this; + acpi_status status; ACPI_FUNCTION_ENTRY(); /* Traverse the list of owned mutexes, releasing each one */ while (next) { - obj_desc = next; - next = obj_desc->mutex.next; - - obj_desc->mutex.prev = NULL; - obj_desc->mutex.next = NULL; - obj_desc->mutex.acquisition_depth = 0; - - /* Release the mutex, special case for Global Lock */ + this = next; + next = this->mutex.next; - if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { + this->mutex.acquisition_depth = 1; + this->mutex.prev = NULL; + this->mutex.next = NULL; - /* Ignore errors */ + /* Release the mutex */ - (void)acpi_ev_release_global_lock(); - } else { - acpi_os_release_mutex(obj_desc->mutex.os_mutex); + status = acpi_ex_system_release_mutex(this); + if (ACPI_FAILURE(status)) { + continue; } /* Mark mutex unowned */ - obj_desc->mutex.owner_thread = NULL; + this->mutex.owner_thread = NULL; /* Update Thread sync_level (Last mutex is the important one) */ - thread->current_sync_level = - obj_desc->mutex.original_sync_level; + thread->current_sync_level = this->mutex.original_sync_level; } } diff --git a/trunk/drivers/acpi/executer/exnames.c b/trunk/drivers/acpi/executer/exnames.c index 1ee4fb1175c6..d3d70364626c 100644 --- a/trunk/drivers/acpi/executer/exnames.c +++ b/trunk/drivers/acpi/executer/exnames.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exoparg1.c b/trunk/drivers/acpi/executer/exoparg1.c index 252f10acbbcc..6374d8be88e0 100644 --- a/trunk/drivers/acpi/executer/exoparg1.c +++ b/trunk/drivers/acpi/executer/exoparg1.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -104,7 +104,9 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) status = AE_NO_MEMORY; goto cleanup; } +#if ACPI_MACHINE_WIDTH != 16 return_desc->integer.value = acpi_os_get_timer(); +#endif break; default: /* Unknown opcode */ diff --git a/trunk/drivers/acpi/executer/exoparg2.c b/trunk/drivers/acpi/executer/exoparg2.c index 17e652e65379..7d2cbc113160 100644 --- a/trunk/drivers/acpi/executer/exoparg2.c +++ b/trunk/drivers/acpi/executer/exoparg2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exoparg3.c b/trunk/drivers/acpi/executer/exoparg3.c index 7fe67cf82cee..e2d945dfd509 100644 --- a/trunk/drivers/acpi/executer/exoparg3.c +++ b/trunk/drivers/acpi/executer/exoparg3.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exoparg6.c b/trunk/drivers/acpi/executer/exoparg6.c index bd80a9cb3d65..f0c0ba6eb408 100644 --- a/trunk/drivers/acpi/executer/exoparg6.c +++ b/trunk/drivers/acpi/executer/exoparg6.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exprep.c b/trunk/drivers/acpi/executer/exprep.c index a6696621ff1b..44d064f427b9 100644 --- a/trunk/drivers/acpi/executer/exprep.c +++ b/trunk/drivers/acpi/executer/exprep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exregion.c b/trunk/drivers/acpi/executer/exregion.c index 2e9ce94798c7..3cc97ba48b36 100644 --- a/trunk/drivers/acpi/executer/exregion.c +++ b/trunk/drivers/acpi/executer/exregion.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -155,15 +155,16 @@ acpi_ex_system_memory_space_handler(u32 function, /* Create a new mapping starting at the address given */ - mem_info->mapped_logical_address = - acpi_os_map_memory((acpi_native_uint) address, window_size); - if (!mem_info->mapped_logical_address) { + status = acpi_os_map_memory(address, window_size, + (void **)&mem_info-> + mapped_logical_address); + if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not map memory at %8.8X%8.8X, size %X", ACPI_FORMAT_UINT64(address), (u32) window_size)); mem_info->mapped_length = 0; - return_ACPI_STATUS(AE_NO_MEMORY); + return_ACPI_STATUS(status); } /* Save the physical address and mapping size */ @@ -209,10 +210,11 @@ acpi_ex_system_memory_space_handler(u32 function, *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); break; +#if ACPI_MACHINE_WIDTH != 16 case 64: *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); break; - +#endif default: /* bit_width was already validated */ break; @@ -234,9 +236,11 @@ acpi_ex_system_memory_space_handler(u32 function, ACPI_SET32(logical_addr_ptr) = (u32) * value; break; +#if ACPI_MACHINE_WIDTH != 16 case 64: ACPI_SET64(logical_addr_ptr) = (u64) * value; break; +#endif default: /* bit_width was already validated */ diff --git a/trunk/drivers/acpi/executer/exresnte.c b/trunk/drivers/acpi/executer/exresnte.c index 2b3a01cc4929..3089b05a1368 100644 --- a/trunk/drivers/acpi/executer/exresnte.c +++ b/trunk/drivers/acpi/executer/exresnte.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exresolv.c b/trunk/drivers/acpi/executer/exresolv.c index 6c64e55dab0e..6499de878017 100644 --- a/trunk/drivers/acpi/executer/exresolv.c +++ b/trunk/drivers/acpi/executer/exresolv.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -141,7 +141,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, acpi_status status = AE_OK; union acpi_operand_object *stack_desc; void *temp_node; - union acpi_operand_object *obj_desc = NULL; + union acpi_operand_object *obj_desc; u16 opcode; ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); @@ -299,6 +299,8 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, status = acpi_ds_get_package_arguments(stack_desc); break; + /* These cases may never happen here, but just in case.. */ + case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: @@ -312,10 +314,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, status = acpi_ex_read_data_from_field(walk_state, stack_desc, &obj_desc); - - /* Remove a reference to the original operand, then override */ - - acpi_ut_remove_reference(*stack_ptr); *stack_ptr = (void *)obj_desc; break; diff --git a/trunk/drivers/acpi/executer/exresop.c b/trunk/drivers/acpi/executer/exresop.c index ba761862a599..4c93d0972333 100644 --- a/trunk/drivers/acpi/executer/exresop.c +++ b/trunk/drivers/acpi/executer/exresop.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -611,20 +611,22 @@ acpi_ex_resolve_operands(u16 opcode, } goto next_operand; - case ARGI_REGION_OR_BUFFER: /* Used by Load() only */ + case ARGI_REGION_OR_FIELD: - /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */ + /* Need an operand of type REGION or a FIELD in a region */ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { - case ACPI_TYPE_BUFFER: case ACPI_TYPE_REGION: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: /* Valid operand */ break; default: ACPI_ERROR((AE_INFO, - "Needed [Region/Buffer], found [%s] %p", + "Needed [Region/RegionField], found [%s] %p", acpi_ut_get_object_type_name (obj_desc), obj_desc)); diff --git a/trunk/drivers/acpi/executer/exstore.c b/trunk/drivers/acpi/executer/exstore.c index f4b69a637820..0456405ba019 100644 --- a/trunk/drivers/acpi/executer/exstore.c +++ b/trunk/drivers/acpi/executer/exstore.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exstoren.c b/trunk/drivers/acpi/executer/exstoren.c index 1d622c625c64..591aaf0e18b3 100644 --- a/trunk/drivers/acpi/executer/exstoren.c +++ b/trunk/drivers/acpi/executer/exstoren.c @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exstorob.c b/trunk/drivers/acpi/executer/exstorob.c index 8233d40178ee..99ebe5adfcda 100644 --- a/trunk/drivers/acpi/executer/exstorob.c +++ b/trunk/drivers/acpi/executer/exstorob.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exsystem.c b/trunk/drivers/acpi/executer/exsystem.c index 9460baff3032..28aef3e69ecc 100644 --- a/trunk/drivers/acpi/executer/exsystem.c +++ b/trunk/drivers/acpi/executer/exsystem.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,6 +66,7 @@ ACPI_MODULE_NAME("exsystem") acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) { acpi_status status; + acpi_status status2; ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); @@ -78,7 +79,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) /* We must wait, so unlock the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = acpi_os_wait_semaphore(semaphore, 1, timeout); @@ -88,7 +89,13 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) /* Reacquire the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + + /* Report fatal error, could not acquire interpreter */ + + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); @@ -112,6 +119,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) { acpi_status status; + acpi_status status2; ACPI_FUNCTION_TRACE(ex_system_wait_mutex); @@ -124,7 +132,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) /* We must wait, so unlock the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = acpi_os_acquire_mutex(mutex, timeout); @@ -134,7 +142,13 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) /* Reacquire the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + + /* Report fatal error, could not acquire interpreter */ + + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); @@ -195,18 +209,96 @@ acpi_status acpi_ex_system_do_stall(u32 how_long) acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) { + acpi_status status; + ACPI_FUNCTION_ENTRY(); /* Since this thread will sleep, we must release the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); acpi_os_sleep(how_long); /* And now we must get the interpreter again */ - acpi_ex_reacquire_interpreter(); - return (AE_OK); + status = acpi_ex_enter_interpreter(); + return (status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ex_system_acquire_mutex + * + * PARAMETERS: time_desc - Maximum time to wait for the mutex + * obj_desc - The object descriptor for this op + * + * RETURN: Status + * + * DESCRIPTION: Provides an access point to perform synchronization operations + * within the AML. This function will cause a lock to be generated + * for the Mutex pointed to by obj_desc. + * + ******************************************************************************/ + +acpi_status +acpi_ex_system_acquire_mutex(union acpi_operand_object * time_desc, + union acpi_operand_object * obj_desc) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE_PTR(ex_system_acquire_mutex, obj_desc); + + if (!obj_desc) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Support for the _GL_ Mutex object -- go get the global lock */ + + if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) { + status = + acpi_ev_acquire_global_lock((u16) time_desc->integer.value); + return_ACPI_STATUS(status); + } + + status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, + (u16) time_desc->integer.value); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ex_system_release_mutex + * + * PARAMETERS: obj_desc - The object descriptor for this op + * + * RETURN: Status + * + * DESCRIPTION: Provides an access point to perform synchronization operations + * within the AML. This operation is a request to release a + * previously acquired Mutex. If the Mutex variable is set then + * it will be decremented. + * + ******************************************************************************/ + +acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE(ex_system_release_mutex); + + if (!obj_desc) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Support for the _GL_ Mutex object -- release the global lock */ + + if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) { + status = acpi_ev_release_global_lock(); + return_ACPI_STATUS(status); + } + + acpi_os_release_mutex(obj_desc->mutex.os_mutex); + return_ACPI_STATUS(AE_OK); } /******************************************************************************* @@ -222,7 +314,7 @@ acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) * ******************************************************************************/ -acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc) +acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc) { acpi_status status = AE_OK; diff --git a/trunk/drivers/acpi/executer/exutils.c b/trunk/drivers/acpi/executer/exutils.c index 6b0aeccbb69b..982c8b65876f 100644 --- a/trunk/drivers/acpi/executer/exutils.c +++ b/trunk/drivers/acpi/executer/exutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -76,15 +76,14 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base); * * PARAMETERS: None * - * RETURN: None + * RETURN: Status * - * DESCRIPTION: Enter the interpreter execution region. Failure to enter - * the interpreter region is a fatal system error. Used in - * conjunction with exit_interpreter. + * DESCRIPTION: Enter the interpreter execution region. Failure to enter + * the interpreter region is a fatal system error * ******************************************************************************/ -void acpi_ex_enter_interpreter(void) +acpi_status acpi_ex_enter_interpreter(void) { acpi_status status; @@ -92,42 +91,10 @@ void acpi_ex_enter_interpreter(void) status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not acquire AML Interpreter mutex")); + ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex")); } - return_VOID; -} - -/******************************************************************************* - * - * FUNCTION: acpi_ex_reacquire_interpreter - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Reacquire the interpreter execution region from within the - * interpreter code. Failure to enter the interpreter region is a - * fatal system error. Used in conjuction with - * relinquish_interpreter - * - ******************************************************************************/ - -void acpi_ex_reacquire_interpreter(void) -{ - ACPI_FUNCTION_TRACE(ex_reacquire_interpreter); - - /* - * If the global serialized flag is set, do not release the interpreter, - * since it was not actually released by acpi_ex_relinquish_interpreter. - * This forces the interpreter to be single threaded. - */ - if (!acpi_gbl_all_methods_serialized) { - acpi_ex_enter_interpreter(); - } - - return_VOID; + return_ACPI_STATUS(status); } /******************************************************************************* @@ -138,9 +105,17 @@ void acpi_ex_reacquire_interpreter(void) * * RETURN: None * - * DESCRIPTION: Exit the interpreter execution region. This is the top level - * routine used to exit the interpreter when all processing has - * been completed. + * DESCRIPTION: Exit the interpreter execution region + * + * Cases where the interpreter is unlocked: + * 1) Completion of the execution of a control method + * 2) Method blocked on a Sleep() AML opcode + * 3) Method blocked on an Acquire() AML opcode + * 4) Method blocked on a Wait() AML opcode + * 5) Method blocked to acquire the global lock + * 6) Method blocked to execute a serialized control method that is + * already executing + * 7) About to invoke a user-installed opregion handler * ******************************************************************************/ @@ -152,46 +127,7 @@ void acpi_ex_exit_interpreter(void) status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not release AML Interpreter mutex")); - } - - return_VOID; -} - -/******************************************************************************* - * - * FUNCTION: acpi_ex_relinquish_interpreter - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Exit the interpreter execution region, from within the - * interpreter - before attempting an operation that will possibly - * block the running thread. - * - * Cases where the interpreter is unlocked internally - * 1) Method to be blocked on a Sleep() AML opcode - * 2) Method to be blocked on an Acquire() AML opcode - * 3) Method to be blocked on a Wait() AML opcode - * 4) Method to be blocked to acquire the global lock - * 5) Method to be blocked waiting to execute a serialized control method - * that is currently executing - * 6) About to invoke a user-installed opregion handler - * - ******************************************************************************/ - -void acpi_ex_relinquish_interpreter(void) -{ - ACPI_FUNCTION_TRACE(ex_relinquish_interpreter); - - /* - * If the global serialized flag is set, do not release the interpreter. - * This forces the interpreter to be single threaded. - */ - if (!acpi_gbl_all_methods_serialized) { - acpi_ex_exit_interpreter(); + ACPI_ERROR((AE_INFO, "Could not release interpreter mutex")); } return_VOID; @@ -205,8 +141,8 @@ void acpi_ex_relinquish_interpreter(void) * * RETURN: none * - * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is - * 32-bit, as determined by the revision of the DSDT. + * DESCRIPTION: Truncate a number to 32-bits if the currently executing method + * belongs to a 32-bit ACPI table. * ******************************************************************************/ diff --git a/trunk/drivers/acpi/fan.c b/trunk/drivers/acpi/fan.c index af22fdf73413..f305a826ca2d 100644 --- a/trunk/drivers/acpi/fan.c +++ b/trunk/drivers/acpi/fan.c @@ -48,8 +48,8 @@ MODULE_LICENSE("GPL"); static int acpi_fan_add(struct acpi_device *device); static int acpi_fan_remove(struct acpi_device *device, int type); -static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state); -static int acpi_fan_resume(struct acpi_device *device); +static int acpi_fan_suspend(struct acpi_device *device, int state); +static int acpi_fan_resume(struct acpi_device *device, int state); static struct acpi_driver acpi_fan_driver = { .name = ACPI_FAN_DRIVER_NAME, @@ -237,7 +237,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type) return 0; } -static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state) +static int acpi_fan_suspend(struct acpi_device *device, int state) { if (!device) return -EINVAL; @@ -247,7 +247,7 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state) return AE_OK; } -static int acpi_fan_resume(struct acpi_device *device) +static int acpi_fan_resume(struct acpi_device *device, int state) { int result = 0; int power_state = 0; diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 7b6c9ff9bebe..8a0324b43e53 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -86,6 +86,129 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) return ret; } +/* Get PCI root bridge's handle from its segment and bus number */ +struct acpi_find_pci_root { + unsigned int seg; + unsigned int bus; + acpi_handle handle; +}; + +static acpi_status +do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) +{ + unsigned long *busnr = data; + struct acpi_resource_address64 address; + + if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && + resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 && + resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) + return AE_OK; + + acpi_resource_to_address64(resource, &address); + if ((address.address_length > 0) && + (address.resource_type == ACPI_BUS_NUMBER_RANGE)) + *busnr = address.minimum; + + return AE_OK; +} + +static int get_root_bridge_busnr(acpi_handle handle) +{ + acpi_status status; + unsigned long bus, bbn; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + + status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, + &bbn); + if (status == AE_NOT_FOUND) { + /* Assume bus = 0 */ + printk(KERN_INFO PREFIX + "Assume root bridge [%s] bus is 0\n", + (char *)buffer.pointer); + status = AE_OK; + bbn = 0; + } + if (ACPI_FAILURE(status)) { + bbn = -ENODEV; + goto exit; + } + if (bbn > 0) + goto exit; + + /* _BBN in some systems return 0 for all root bridges */ + bus = -1; + status = acpi_walk_resources(handle, METHOD_NAME__CRS, + do_root_bridge_busnr_callback, &bus); + /* If _CRS failed, we just use _BBN */ + if (ACPI_FAILURE(status) || (bus == -1)) + goto exit; + /* We select _CRS */ + if (bbn != bus) { + printk(KERN_INFO PREFIX + "_BBN and _CRS returns different value for %s. Select _CRS\n", + (char *)buffer.pointer); + bbn = bus; + } + exit: + kfree(buffer.pointer); + return (int)bbn; +} + +static acpi_status +find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context; + unsigned long seg, bus; + acpi_status status; + int tmp; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + + status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg); + if (status == AE_NOT_FOUND) { + /* Assume seg = 0 */ + status = AE_OK; + seg = 0; + } + if (ACPI_FAILURE(status)) { + status = AE_CTRL_DEPTH; + goto exit; + } + + tmp = get_root_bridge_busnr(handle); + if (tmp < 0) { + printk(KERN_ERR PREFIX + "Find root bridge failed for %s\n", + (char *)buffer.pointer); + status = AE_CTRL_DEPTH; + goto exit; + } + bus = tmp; + + if (seg == find->seg && bus == find->bus) + { + find->handle = handle; + status = AE_CTRL_TERMINATE; + } + else + status = AE_OK; + exit: + kfree(buffer.pointer); + return status; +} + +acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) +{ + struct acpi_find_pci_root find = { seg, bus, NULL }; + + acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL); + return find.handle; +} +EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); + /* Get device's handler per its address under its parent */ struct acpi_find_child { acpi_handle handle; diff --git a/trunk/drivers/acpi/hardware/hwacpi.c b/trunk/drivers/acpi/hardware/hwacpi.c index 6031ca13dd2f..de50fab2a910 100644 --- a/trunk/drivers/acpi/hardware/hwacpi.c +++ b/trunk/drivers/acpi/hardware/hwacpi.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,41 @@ #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwacpi") +/****************************************************************************** + * + * FUNCTION: acpi_hw_initialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize and validate the various ACPI registers defined in + * the FADT. + * + ******************************************************************************/ +acpi_status acpi_hw_initialize(void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(hw_initialize); + + /* We must have the ACPI tables by the time we get here */ + + if (!acpi_gbl_FADT) { + ACPI_ERROR((AE_INFO, "No FADT is present")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + /* Sanity check the FADT for valid values */ + + status = acpi_ut_validate_fadt(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + return_ACPI_STATUS(AE_OK); +} + /****************************************************************************** * * FUNCTION: acpi_hw_set_mode @@ -58,6 +93,7 @@ ACPI_MODULE_NAME("hwacpi") * DESCRIPTION: Transitions the system into the requested mode. * ******************************************************************************/ + acpi_status acpi_hw_set_mode(u32 mode) { @@ -70,7 +106,7 @@ acpi_status acpi_hw_set_mode(u32 mode) * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, * system does not support mode transition. */ - if (!acpi_gbl_FADT.smi_command) { + if (!acpi_gbl_FADT->smi_cmd) { ACPI_ERROR((AE_INFO, "No SMI_CMD in FADT, mode transition failed")); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); @@ -83,7 +119,7 @@ acpi_status acpi_hw_set_mode(u32 mode) * we make sure both the numbers are zero to determine these * transitions are not supported. */ - if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) { + if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) { ACPI_ERROR((AE_INFO, "No ACPI mode transition supported in this system (enable/disable both zero)")); return_ACPI_STATUS(AE_OK); @@ -94,8 +130,9 @@ acpi_status acpi_hw_set_mode(u32 mode) /* BIOS should have disabled ALL fixed and GP events */ - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, - (u32) acpi_gbl_FADT.acpi_enable, 8); + status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, + (u32) acpi_gbl_FADT->acpi_enable, + 8); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Attempting to enable ACPI mode\n")); break; @@ -106,8 +143,8 @@ acpi_status acpi_hw_set_mode(u32 mode) * BIOS should clear all fixed status bits and restore fixed event * enable bits to default */ - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, - (u32) acpi_gbl_FADT.acpi_disable, + status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, + (u32) acpi_gbl_FADT->acpi_disable, 8); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Attempting to enable Legacy (non-ACPI) mode\n")); @@ -167,11 +204,12 @@ u32 acpi_hw_get_mode(void) * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, * system does not support mode transition. */ - if (!acpi_gbl_FADT.smi_command) { + if (!acpi_gbl_FADT->smi_cmd) { return_UINT32(ACPI_SYS_MODE_ACPI); } - status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value); + status = + acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_UINT32(ACPI_SYS_MODE_LEGACY); } diff --git a/trunk/drivers/acpi/hardware/hwgpe.c b/trunk/drivers/acpi/hardware/hwgpe.c index 117a05cadaaa..608a3a60ee11 100644 --- a/trunk/drivers/acpi/hardware/hwgpe.c +++ b/trunk/drivers/acpi/hardware/hwgpe.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -105,20 +105,14 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info) acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) { acpi_status status; - u8 register_bit; ACPI_FUNCTION_ENTRY(); - register_bit = (u8) - (1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); - /* * Write a one to the appropriate bit in the status register to * clear this GPE. */ - status = acpi_hw_low_level_write(8, register_bit, + status = acpi_hw_low_level_write(8, gpe_event_info->register_bit, &gpe_event_info->register_info-> status_address); @@ -161,10 +155,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* Get the register bitmask for this GPE */ - register_bit = (u8) - (1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); + register_bit = gpe_event_info->register_bit; /* GPE currently enabled? (enabled for runtime?) */ diff --git a/trunk/drivers/acpi/hardware/hwregs.c b/trunk/drivers/acpi/hardware/hwregs.c index 1d371fa663f2..fa58c1edce1e 100644 --- a/trunk/drivers/acpi/hardware/hwregs.c +++ b/trunk/drivers/acpi/hardware/hwregs.c @@ -7,7 +7,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,15 +54,17 @@ ACPI_MODULE_NAME("hwregs") * * FUNCTION: acpi_hw_clear_acpi_status * - * PARAMETERS: None + * PARAMETERS: Flags - Lock the hardware or not * - * RETURN: None + * RETURN: none * * DESCRIPTION: Clears all fixed and general purpose status bits * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * + * NOTE: TBD: Flags parameter is obsolete, to be removed + * ******************************************************************************/ -acpi_status acpi_hw_clear_acpi_status(void) +acpi_status acpi_hw_clear_acpi_status(u32 flags) { acpi_status status; acpi_cpu_flags lock_flags = 0; @@ -71,7 +73,7 @@ acpi_status acpi_hw_clear_acpi_status(void) ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", ACPI_BITMASK_ALL_FIXED_STATUS, - (u16) acpi_gbl_FADT.xpm1a_event_block.address)); + (u16) acpi_gbl_FADT->xpm1a_evt_blk.address)); lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); @@ -84,10 +86,10 @@ acpi_status acpi_hw_clear_acpi_status(void) /* Clear the fixed events */ - if (acpi_gbl_FADT.xpm1b_event_block.address) { + if (acpi_gbl_FADT->xpm1b_evt_blk.address) { status = acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, - &acpi_gbl_FADT.xpm1b_event_block); + &acpi_gbl_FADT->xpm1b_evt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -251,15 +253,18 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) * * PARAMETERS: register_id - ID of ACPI bit_register to access * return_value - Value that was read from the register + * Flags - Lock the hardware or not * * RETURN: Status and the value read from specified Register. Value * returned is normalized to bit0 (is shifted all the way right) * * DESCRIPTION: ACPI bit_register read function. * + * NOTE: TBD: Flags parameter is obsolete, to be removed + * ******************************************************************************/ -acpi_status acpi_get_register(u32 register_id, u32 * return_value) +acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags) { u32 register_value = 0; struct acpi_bit_register_info *bit_reg_info; @@ -307,13 +312,16 @@ ACPI_EXPORT_SYMBOL(acpi_get_register) * PARAMETERS: register_id - ID of ACPI bit_register to access * Value - (only used on write) value to write to the * Register, NOT pre-normalized to the bit pos + * Flags - Lock the hardware or not * * RETURN: Status * * DESCRIPTION: ACPI Bit Register write function. * + * NOTE: TBD: Flags parameter is obsolete, to be removed + * ******************************************************************************/ -acpi_status acpi_set_register(u32 register_id, u32 value) +acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) { u32 register_value = 0; struct acpi_bit_register_info *bit_reg_info; @@ -414,9 +422,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", register_value, - ACPI_FORMAT_UINT64(acpi_gbl_FADT. - xpm2_control_block. - address))); + ACPI_FORMAT_UINT64(acpi_gbl_FADT-> + xpm2_cnt_blk.address))); ACPI_REGISTER_INSERT_VALUE(register_value, bit_reg_info->bit_position, @@ -426,9 +433,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n", register_value, - ACPI_FORMAT_UINT64(acpi_gbl_FADT. - xpm2_control_block. - address))); + ACPI_FORMAT_UINT64(acpi_gbl_FADT-> + xpm2_cnt_blk.address))); status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM2_CONTROL, @@ -489,7 +495,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) status = acpi_hw_low_level_read(16, &value1, - &acpi_gbl_FADT.xpm1a_event_block); + &acpi_gbl_FADT->xpm1a_evt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -498,7 +504,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) status = acpi_hw_low_level_read(16, &value2, - &acpi_gbl_FADT.xpm1b_event_block); + &acpi_gbl_FADT->xpm1b_evt_blk); value1 |= value2; break; @@ -521,14 +527,14 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) status = acpi_hw_low_level_read(16, &value1, - &acpi_gbl_FADT.xpm1a_control_block); + &acpi_gbl_FADT->xpm1a_cnt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } status = acpi_hw_low_level_read(16, &value2, - &acpi_gbl_FADT.xpm1b_control_block); + &acpi_gbl_FADT->xpm1b_cnt_blk); value1 |= value2; break; @@ -536,20 +542,19 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) status = acpi_hw_low_level_read(8, &value1, - &acpi_gbl_FADT.xpm2_control_block); + &acpi_gbl_FADT->xpm2_cnt_blk); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ status = acpi_hw_low_level_read(32, &value1, - &acpi_gbl_FADT.xpm_timer_block); + &acpi_gbl_FADT->xpm_tmr_blk); break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ - status = - acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); + status = acpi_os_read_port(acpi_gbl_FADT->smi_cmd, &value1, 8); break; default: @@ -630,7 +635,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1a_event_block); + &acpi_gbl_FADT->xpm1a_evt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -639,7 +644,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1b_event_block); + &acpi_gbl_FADT->xpm1b_evt_blk); break; case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ @@ -677,50 +682,49 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1a_control_block); + &acpi_gbl_FADT->xpm1a_cnt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1b_control_block); + &acpi_gbl_FADT->xpm1b_cnt_blk); break; case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1a_control_block); + &acpi_gbl_FADT->xpm1a_cnt_blk); break; case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1b_control_block); + &acpi_gbl_FADT->xpm1b_cnt_blk); break; case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ status = acpi_hw_low_level_write(8, value, - &acpi_gbl_FADT.xpm2_control_block); + &acpi_gbl_FADT->xpm2_cnt_blk); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ status = acpi_hw_low_level_write(32, value, - &acpi_gbl_FADT.xpm_timer_block); + &acpi_gbl_FADT->xpm_tmr_blk); break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ /* SMI_CMD is currently always in IO space */ - status = - acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); + status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, value, 8); break; default: @@ -779,7 +783,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) * Two address spaces supported: Memory or IO. * PCI_Config is not supported here because the GAS struct is insufficient */ - switch (reg->space_id) { + switch (reg->address_space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: status = acpi_os_read_memory((acpi_physical_address) address, @@ -788,20 +792,22 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) case ACPI_ADR_SPACE_SYSTEM_IO: - status = - acpi_os_read_port((acpi_io_address) address, value, width); + status = acpi_os_read_port((acpi_io_address) address, + value, width); break; default: ACPI_ERROR((AE_INFO, - "Unsupported address space: %X", reg->space_id)); + "Unsupported address space: %X", + reg->address_space_id)); return (AE_BAD_PARAMETER); } ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", - *value, width, ACPI_FORMAT_UINT64(address), - acpi_ut_get_region_name(reg->space_id))); + *value, width, + ACPI_FORMAT_UINT64(address), + acpi_ut_get_region_name(reg->address_space_id))); return (status); } @@ -848,7 +854,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) * Two address spaces supported: Memory or IO. * PCI_Config is not supported here because the GAS struct is insufficient */ - switch (reg->space_id) { + switch (reg->address_space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: status = acpi_os_write_memory((acpi_physical_address) address, @@ -857,20 +863,22 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) case ACPI_ADR_SPACE_SYSTEM_IO: - status = acpi_os_write_port((acpi_io_address) address, value, - width); + status = acpi_os_write_port((acpi_io_address) address, + value, width); break; default: ACPI_ERROR((AE_INFO, - "Unsupported address space: %X", reg->space_id)); + "Unsupported address space: %X", + reg->address_space_id)); return (AE_BAD_PARAMETER); } ACPI_DEBUG_PRINT((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", - value, width, ACPI_FORMAT_UINT64(address), - acpi_ut_get_region_name(reg->space_id))); + value, width, + ACPI_FORMAT_UINT64(address), + acpi_ut_get_region_name(reg->address_space_id))); return (status); } diff --git a/trunk/drivers/acpi/hardware/hwsleep.c b/trunk/drivers/acpi/hardware/hwsleep.c index 57901ca3ade9..8bb43cae60c2 100644 --- a/trunk/drivers/acpi/hardware/hwsleep.c +++ b/trunk/drivers/acpi/hardware/hwsleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -43,7 +43,6 @@ */ #include -#include #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwsleep") @@ -63,32 +62,17 @@ ACPI_MODULE_NAME("hwsleep") acpi_status acpi_set_firmware_waking_vector(acpi_physical_address physical_address) { - struct acpi_table_facs *facs; - acpi_status status; ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); - /* Get the FACS */ - - status = - acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - (struct acpi_table_header **)&facs); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Set the vector */ - if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { - /* - * ACPI 1.0 FACS or short table or optional X_ field is zero - */ - facs->firmware_waking_vector = (u32) physical_address; + if (acpi_gbl_common_fACS.vector_width == 32) { + *(ACPI_CAST_PTR + (u32, acpi_gbl_common_fACS.firmware_waking_vector)) + = (u32) physical_address; } else { - /* - * ACPI 2.0 FACS with valid X_ field - */ - facs->xfirmware_waking_vector = physical_address; + *acpi_gbl_common_fACS.firmware_waking_vector = physical_address; } return_ACPI_STATUS(AE_OK); @@ -113,8 +97,6 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) acpi_status acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) { - struct acpi_table_facs *facs; - acpi_status status; ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); @@ -122,29 +104,16 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Get the FACS */ - - status = - acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - (struct acpi_table_header **)&facs); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Get the vector */ - if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { - /* - * ACPI 1.0 FACS or short table or optional X_ field is zero - */ - *physical_address = - (acpi_physical_address) facs->firmware_waking_vector; + if (acpi_gbl_common_fACS.vector_width == 32) { + *physical_address = (acpi_physical_address) + * + (ACPI_CAST_PTR + (u32, acpi_gbl_common_fACS.firmware_waking_vector)); } else { - /* - * ACPI 2.0 FACS with valid X_ field - */ *physical_address = - (acpi_physical_address) facs->xfirmware_waking_vector; + *acpi_gbl_common_fACS.firmware_waking_vector; } return_ACPI_STATUS(AE_OK); @@ -277,14 +246,15 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) /* Clear wake status */ - status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); + status = + acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Clear all fixed and general purpose status bits */ - status = acpi_hw_clear_acpi_status(); + status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -397,7 +367,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) /* Wait until we enter sleep state */ do { - status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); + status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value, + ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -430,12 +401,13 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); - status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); + status = + acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - status = acpi_hw_clear_acpi_status(); + status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -457,12 +429,13 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) ACPI_FLUSH_CPU_CACHE(); - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, - (u32) acpi_gbl_FADT.S4bios_request, 8); + status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, + (u32) acpi_gbl_FADT->S4bios_req, 8); do { acpi_os_stall(1000); - status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); + status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value, + ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -595,11 +568,13 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) (void) acpi_set_register(acpi_gbl_fixed_event_info - [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1); + [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1, + ACPI_MTX_DO_NOT_LOCK); (void) acpi_set_register(acpi_gbl_fixed_event_info - [ACPI_EVENT_POWER_BUTTON].status_register_id, 1); + [ACPI_EVENT_POWER_BUTTON].status_register_id, 1, + ACPI_MTX_DO_NOT_LOCK); arg.integer.value = ACPI_SST_WORKING; status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); diff --git a/trunk/drivers/acpi/hardware/hwtimer.c b/trunk/drivers/acpi/hardware/hwtimer.c index c32eab696acd..c4ec47c939fd 100644 --- a/trunk/drivers/acpi/hardware/hwtimer.c +++ b/trunk/drivers/acpi/hardware/hwtimer.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,7 +66,7 @@ acpi_status acpi_get_timer_resolution(u32 * resolution) return_ACPI_STATUS(AE_BAD_PARAMETER); } - if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) { + if (acpi_gbl_FADT->tmr_val_ext == 0) { *resolution = 24; } else { *resolution = 32; @@ -98,8 +98,7 @@ acpi_status acpi_get_timer(u32 * ticks) return_ACPI_STATUS(AE_BAD_PARAMETER); } - status = - acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block); + status = acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT->xpm_tmr_blk); return_ACPI_STATUS(status); } @@ -154,7 +153,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) if (start_ticks < end_ticks) { delta_ticks = end_ticks - start_ticks; } else if (start_ticks > end_ticks) { - if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) { + if (acpi_gbl_FADT->tmr_val_ext == 0) { /* 24-bit Timer */ diff --git a/trunk/drivers/acpi/motherboard.c b/trunk/drivers/acpi/motherboard.c new file mode 100644 index 000000000000..2e17ec75af03 --- /dev/null +++ b/trunk/drivers/acpi/motherboard.c @@ -0,0 +1,191 @@ +/* + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* Purpose: Prevent PCMCIA cards from using motherboard resources. */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME("acpi_motherboard") + +/* Dell use PNP0C01 instead of PNP0C02 */ +#define ACPI_MB_HID1 "PNP0C01" +#define ACPI_MB_HID2 "PNP0C02" +/** + * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved + * Doesn't care about the failure of 'request_region', since other may reserve + * the io ports as well + */ +#define IS_RESERVED_ADDR(base, len) \ + (((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \ + && ((base) + (len) > PCIBIOS_MIN_IO)) +/* + * Clearing the flag (IORESOURCE_BUSY) allows drivers to use + * the io ports if they really know they can use it, while + * still preventing hotplug PCI devices from using it. + */ + +/* + * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01 + * and PNP0C02, redundant with acpi_reserve_io_ranges(). + * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP. + */ +static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) +{ + struct resource *requested_res = NULL; + + + if (res->type == ACPI_RESOURCE_TYPE_IO) { + struct acpi_resource_io *io_res = &res->data.io; + + if (io_res->minimum != io_res->maximum) + return AE_OK; + if (IS_RESERVED_ADDR + (io_res->minimum, io_res->address_length)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Motherboard resources 0x%08x - 0x%08x\n", + io_res->minimum, + io_res->minimum + + io_res->address_length)); + requested_res = + request_region(io_res->minimum, + io_res->address_length, "motherboard"); + } + } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_IO) { + struct acpi_resource_fixed_io *fixed_io_res = + &res->data.fixed_io; + + if (IS_RESERVED_ADDR + (fixed_io_res->address, fixed_io_res->address_length)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Motherboard resources 0x%08x - 0x%08x\n", + fixed_io_res->address, + fixed_io_res->address + + fixed_io_res->address_length)); + requested_res = + request_region(fixed_io_res->address, + fixed_io_res->address_length, + "motherboard"); + } + } else { + /* Memory mapped IO? */ + } + + if (requested_res) + requested_res->flags &= ~IORESOURCE_BUSY; + return AE_OK; +} + +static int acpi_motherboard_add(struct acpi_device *device) +{ + if (!device) + return -EINVAL; + acpi_walk_resources(device->handle, METHOD_NAME__CRS, + acpi_reserve_io_ranges, NULL); + + return 0; +} + +static struct acpi_driver acpi_motherboard_driver1 = { + .name = "motherboard", + .class = "", + .ids = ACPI_MB_HID1, + .ops = { + .add = acpi_motherboard_add, + }, +}; + +static struct acpi_driver acpi_motherboard_driver2 = { + .name = "motherboard", + .class = "", + .ids = ACPI_MB_HID2, + .ops = { + .add = acpi_motherboard_add, + }, +}; + +static void __init acpi_request_region (struct acpi_generic_address *addr, + unsigned int length, char *desc) +{ + if (!addr->address || !length) + return; + + if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) + request_region(addr->address, length, desc); + else if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + request_mem_region(addr->address, length, desc); +} + +static void __init acpi_reserve_resources(void) +{ + acpi_request_region(&acpi_gbl_FADT->xpm1a_evt_blk, + acpi_gbl_FADT->pm1_evt_len, "ACPI PM1a_EVT_BLK"); + + acpi_request_region(&acpi_gbl_FADT->xpm1b_evt_blk, + acpi_gbl_FADT->pm1_evt_len, "ACPI PM1b_EVT_BLK"); + + acpi_request_region(&acpi_gbl_FADT->xpm1a_cnt_blk, + acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1a_CNT_BLK"); + + acpi_request_region(&acpi_gbl_FADT->xpm1b_cnt_blk, + acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1b_CNT_BLK"); + + if (acpi_gbl_FADT->pm_tm_len == 4) + acpi_request_region(&acpi_gbl_FADT->xpm_tmr_blk, 4, "ACPI PM_TMR"); + + acpi_request_region(&acpi_gbl_FADT->xpm2_cnt_blk, + acpi_gbl_FADT->pm2_cnt_len, "ACPI PM2_CNT_BLK"); + + /* Length of GPE blocks must be a non-negative multiple of 2 */ + + if (!(acpi_gbl_FADT->gpe0_blk_len & 0x1)) + acpi_request_region(&acpi_gbl_FADT->xgpe0_blk, + acpi_gbl_FADT->gpe0_blk_len, "ACPI GPE0_BLK"); + + if (!(acpi_gbl_FADT->gpe1_blk_len & 0x1)) + acpi_request_region(&acpi_gbl_FADT->xgpe1_blk, + acpi_gbl_FADT->gpe1_blk_len, "ACPI GPE1_BLK"); +} + +static int __init acpi_motherboard_init(void) +{ + acpi_bus_register_driver(&acpi_motherboard_driver1); + acpi_bus_register_driver(&acpi_motherboard_driver2); + /* + * Guarantee motherboard IO reservation first + * This module must run after scan.c + */ + if (!acpi_disabled) + acpi_reserve_resources(); + return 0; +} + +/** + * Reserve motherboard resources after PCI claim BARs, + * but before PCI assign resources for uninitialized PCI devices + */ +fs_initcall(acpi_motherboard_init); diff --git a/trunk/drivers/acpi/namespace/nsaccess.c b/trunk/drivers/acpi/namespace/nsaccess.c index 57faf598bad8..c1c6c236df9a 100644 --- a/trunk/drivers/acpi/namespace/nsaccess.c +++ b/trunk/drivers/acpi/namespace/nsaccess.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -195,27 +195,31 @@ acpi_status acpi_ns_root_initialize(void) obj_desc->mutex.sync_level = (u8) (ACPI_TO_INTEGER(val) - 1); - /* Create a mutex */ + if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { - status = - acpi_os_create_mutex(&obj_desc->mutex. - os_mutex); - if (ACPI_FAILURE(status)) { - acpi_ut_remove_reference(obj_desc); - goto unlock_and_exit; - } + /* Create a counting semaphore for the global lock */ - /* Special case for ACPI Global Lock */ + status = + acpi_os_create_semaphore + (ACPI_NO_UNIT_LIMIT, 1, + &acpi_gbl_global_lock_semaphore); + if (ACPI_FAILURE(status)) { + acpi_ut_remove_reference + (obj_desc); + goto unlock_and_exit; + } - if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { - acpi_gbl_global_lock_mutex = - obj_desc->mutex.os_mutex; + /* Mark this mutex as very special */ - /* Create additional counting semaphore for global lock */ + obj_desc->mutex.os_mutex = + ACPI_GLOBAL_LOCK; + } else { + /* Create a mutex */ status = - acpi_os_create_semaphore(1, 0, - &acpi_gbl_global_lock_semaphore); + acpi_os_create_mutex(&obj_desc-> + mutex. + os_mutex); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference (obj_desc); diff --git a/trunk/drivers/acpi/namespace/nsalloc.c b/trunk/drivers/acpi/namespace/nsalloc.c index 1d693d8ad2d8..55b407aae266 100644 --- a/trunk/drivers/acpi/namespace/nsalloc.c +++ b/trunk/drivers/acpi/namespace/nsalloc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,9 +61,6 @@ ACPI_MODULE_NAME("nsalloc") struct acpi_namespace_node *acpi_ns_create_node(u32 name) { struct acpi_namespace_node *node; -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - u32 temp; -#endif ACPI_FUNCTION_TRACE(ns_create_node); @@ -74,15 +71,6 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name) ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - temp = - acpi_gbl_ns_node_list->total_allocated - - acpi_gbl_ns_node_list->total_freed; - if (temp > acpi_gbl_ns_node_list->max_occupied) { - acpi_gbl_ns_node_list->max_occupied = temp; - } -#endif - node->name.integer = name; ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED); return_PTR(node); diff --git a/trunk/drivers/acpi/namespace/nsdump.c b/trunk/drivers/acpi/namespace/nsdump.c index 1fc4f86676e1..d72df66aa965 100644 --- a/trunk/drivers/acpi/namespace/nsdump.c +++ b/trunk/drivers/acpi/namespace/nsdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -205,7 +205,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { this_node->name.integer = - acpi_ut_repair_name(this_node->name.ascii); + acpi_ut_repair_name(this_node->name.integer); ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", this_node->name.integer)); @@ -226,12 +226,6 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, obj_desc = acpi_ns_get_attached_object(this_node); acpi_dbg_level = dbg_level; - /* Temp nodes are those nodes created by a control method */ - - if (this_node->flags & ANOBJ_TEMPORARY) { - acpi_os_printf("(T) "); - } - switch (info->display_type & ACPI_DISPLAY_MASK) { case ACPI_DISPLAY_SUMMARY: @@ -629,8 +623,7 @@ acpi_ns_dump_objects(acpi_object_type type, info.display_type = display_type; (void)acpi_ns_walk_namespace(type, start_handle, max_depth, - ACPI_NS_WALK_NO_UNLOCK | - ACPI_NS_WALK_TEMP_NODES, + ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object, (void *)&info, NULL); } diff --git a/trunk/drivers/acpi/namespace/nsdumpdv.c b/trunk/drivers/acpi/namespace/nsdumpdv.c index 5097e167939e..c6bf5d30fca3 100644 --- a/trunk/drivers/acpi/namespace/nsdumpdv.c +++ b/trunk/drivers/acpi/namespace/nsdumpdv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/namespace/nseval.c b/trunk/drivers/acpi/namespace/nseval.c index aa6370c67ec1..4b0a4a8c9843 100644 --- a/trunk/drivers/acpi/namespace/nseval.c +++ b/trunk/drivers/acpi/namespace/nseval.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -154,7 +154,11 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) * Execute the method via the interpreter. The interpreter is locked * here before calling into the AML parser */ - acpi_ex_enter_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + status = acpi_ps_execute_method(info); acpi_ex_exit_interpreter(); } else { @@ -178,7 +182,10 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) * resolution, we must lock it because we could access an opregion. * The opregion access code assumes that the interpreter is locked. */ - acpi_ex_enter_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } /* Function has a strange interface */ diff --git a/trunk/drivers/acpi/namespace/nsinit.c b/trunk/drivers/acpi/namespace/nsinit.c index 326af8fc0ce7..aec8488c0019 100644 --- a/trunk/drivers/acpi/namespace/nsinit.c +++ b/trunk/drivers/acpi/namespace/nsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -213,7 +213,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle, u32 level, void *context, void **return_value) { acpi_object_type type; - acpi_status status = AE_OK; + acpi_status status; struct acpi_init_walk_info *info = (struct acpi_init_walk_info *)context; struct acpi_namespace_node *node = @@ -267,7 +267,10 @@ acpi_ns_init_one_object(acpi_handle obj_handle, /* * Must lock the interpreter before executing AML code */ - acpi_ex_enter_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return (status); + } /* * Each of these types can contain executable AML code within the diff --git a/trunk/drivers/acpi/namespace/nsload.c b/trunk/drivers/acpi/namespace/nsload.c index d4f9654fd20f..fe75d888e183 100644 --- a/trunk/drivers/acpi/namespace/nsload.c +++ b/trunk/drivers/acpi/namespace/nsload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,12 +44,13 @@ #include #include #include -#include #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsload") /* Local prototypes */ +static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type); + #ifdef ACPI_FUTURE_IMPLEMENTATION acpi_status acpi_ns_unload_namespace(acpi_handle handle); @@ -61,7 +62,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); * * FUNCTION: acpi_ns_load_table * - * PARAMETERS: table_index - Index for table to be loaded + * PARAMETERS: table_desc - Descriptor for table to be loaded * Node - Owning NS node * * RETURN: Status @@ -71,13 +72,42 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); ******************************************************************************/ acpi_status -acpi_ns_load_table(acpi_native_uint table_index, +acpi_ns_load_table(struct acpi_table_desc *table_desc, struct acpi_namespace_node *node) { acpi_status status; ACPI_FUNCTION_TRACE(ns_load_table); + /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */ + + if (! + (acpi_gbl_table_data[table_desc->type]. + flags & ACPI_TABLE_EXECUTABLE)) { + + /* Just ignore this table */ + + return_ACPI_STATUS(AE_OK); + } + + /* Check validity of the AML start and length */ + + if (!table_desc->aml_start) { + ACPI_ERROR((AE_INFO, "Null AML pointer")); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n", + table_desc->aml_start)); + + /* Ignore table if there is no AML contained within */ + + if (!table_desc->aml_length) { + ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]", + table_desc->pointer->signature)); + return_ACPI_STATUS(AE_OK); + } + /* * Parse the table and load the namespace with all named * objects found within. Control methods are NOT parsed @@ -87,34 +117,15 @@ acpi_ns_load_table(acpi_native_uint table_index, * to another control method, we can't continue parsing * because we don't know how many arguments to parse next! */ - status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* If table already loaded into namespace, just return */ - - if (acpi_tb_is_table_loaded(table_index)) { - status = AE_ALREADY_EXISTS; - goto unlock; - } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Loading table into namespace ****\n")); - status = acpi_tb_allocate_owner_id(table_index); + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { - goto unlock; - } - - status = acpi_ns_parse_table(table_index, node->child); - if (ACPI_SUCCESS(status)) { - acpi_tb_set_table_loaded_flag(table_index, TRUE); - } else { - acpi_tb_release_owner_id(table_index); + return_ACPI_STATUS(status); } - unlock: + status = acpi_ns_parse_table(table_desc, node->child); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { @@ -130,7 +141,7 @@ acpi_ns_load_table(acpi_native_uint table_index, ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Begin Table Method Parsing and Object Initialization ****\n")); - status = acpi_ds_initialize_objects(table_index, node); + status = acpi_ds_initialize_objects(table_desc, node); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Completed Table Method Parsing and Object Initialization ****\n")); @@ -138,7 +149,99 @@ acpi_ns_load_table(acpi_native_uint table_index, return_ACPI_STATUS(status); } -#ifdef ACPI_OBSOLETE_FUNCTIONS +/******************************************************************************* + * + * FUNCTION: acpi_ns_load_table_by_type + * + * PARAMETERS: table_type - Id of the table type to load + * + * RETURN: Status + * + * DESCRIPTION: Load an ACPI table or tables into the namespace. All tables + * of the given type are loaded. The mechanism allows this + * routine to be called repeatedly. + * + ******************************************************************************/ + +static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type) +{ + u32 i; + acpi_status status; + struct acpi_table_desc *table_desc; + + ACPI_FUNCTION_TRACE(ns_load_table_by_type); + + status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* + * Table types supported are: + * DSDT (one), SSDT/PSDT (multiple) + */ + switch (table_type) { + case ACPI_TABLE_ID_DSDT: + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n")); + + table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next; + + /* If table already loaded into namespace, just return */ + + if (table_desc->loaded_into_namespace) { + goto unlock_and_exit; + } + + /* Now load the single DSDT */ + + status = acpi_ns_load_table(table_desc, acpi_gbl_root_node); + if (ACPI_SUCCESS(status)) { + table_desc->loaded_into_namespace = TRUE; + } + break; + + case ACPI_TABLE_ID_SSDT: + case ACPI_TABLE_ID_PSDT: + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Namespace load: %d SSDT or PSDTs\n", + acpi_gbl_table_lists[table_type].count)); + + /* + * Traverse list of SSDT or PSDT tables + */ + table_desc = acpi_gbl_table_lists[table_type].next; + for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) { + /* + * Only attempt to load table into namespace if it is not + * already loaded! + */ + if (!table_desc->loaded_into_namespace) { + status = + acpi_ns_load_table(table_desc, + acpi_gbl_root_node); + if (ACPI_FAILURE(status)) { + break; + } + + table_desc->loaded_into_namespace = TRUE; + } + + table_desc = table_desc->next; + } + break; + + default: + status = AE_SUPPORT; + break; + } + + unlock_and_exit: + (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + return_ACPI_STATUS(status); +} + /******************************************************************************* * * FUNCTION: acpi_load_namespace @@ -185,7 +288,6 @@ acpi_status acpi_ns_load_namespace(void) return_ACPI_STATUS(status); } -#endif #ifdef ACPI_FUTURE_IMPLEMENTATION /******************************************************************************* diff --git a/trunk/drivers/acpi/namespace/nsnames.c b/trunk/drivers/acpi/namespace/nsnames.c index cbd94af08cc5..97b8332c9746 100644 --- a/trunk/drivers/acpi/namespace/nsnames.c +++ b/trunk/drivers/acpi/namespace/nsnames.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/namespace/nsobject.c b/trunk/drivers/acpi/namespace/nsobject.c index d9d7377bc6e6..aabe8794b908 100644 --- a/trunk/drivers/acpi/namespace/nsobject.c +++ b/trunk/drivers/acpi/namespace/nsobject.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/namespace/nsparse.c b/trunk/drivers/acpi/namespace/nsparse.c index e696aa847990..155505a4ef69 100644 --- a/trunk/drivers/acpi/namespace/nsparse.c +++ b/trunk/drivers/acpi/namespace/nsparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -45,7 +45,6 @@ #include #include #include -#include #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsparse") @@ -63,24 +62,14 @@ ACPI_MODULE_NAME("nsparse") * ******************************************************************************/ acpi_status -acpi_ns_one_complete_parse(acpi_native_uint pass_number, - acpi_native_uint table_index) +acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) { union acpi_parse_object *parse_root; acpi_status status; - acpi_native_uint aml_length; - u8 *aml_start; struct acpi_walk_state *walk_state; - struct acpi_table_header *table; - acpi_owner_id owner_id; ACPI_FUNCTION_TRACE(ns_one_complete_parse); - status = acpi_tb_get_owner_id(table_index, &owner_id); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Create and init a Root Node */ parse_root = acpi_ps_create_scope_op(); @@ -90,41 +79,26 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, /* Create and initialize a new walk state */ - walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state(table_desc->owner_id, + NULL, NULL, NULL); if (!walk_state) { acpi_ps_free_op(parse_root); return_ACPI_STATUS(AE_NO_MEMORY); } - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_FAILURE(status)) { - acpi_ds_delete_walk_state(walk_state); - acpi_ps_free_op(parse_root); - return_ACPI_STATUS(status); - } - - /* Table must consist of at least a complete header */ - - if (table->length < sizeof(struct acpi_table_header)) { - status = AE_BAD_HEADER; - } else { - aml_start = (u8 *) table + sizeof(struct acpi_table_header); - aml_length = table->length - sizeof(struct acpi_table_header); - status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, - aml_start, aml_length, NULL, - (u8) pass_number); - } - + status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, + table_desc->aml_start, + table_desc->aml_length, NULL, + pass_number); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); - acpi_ps_delete_parse_tree(parse_root); return_ACPI_STATUS(status); } /* Parse the AML */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", - (unsigned)pass_number)); + pass_number)); status = acpi_ps_parse_aml(walk_state); acpi_ps_delete_parse_tree(parse_root); @@ -145,7 +119,7 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, ******************************************************************************/ acpi_status -acpi_ns_parse_table(acpi_native_uint table_index, +acpi_ns_parse_table(struct acpi_table_desc *table_desc, struct acpi_namespace_node *start_node) { acpi_status status; @@ -160,10 +134,10 @@ acpi_ns_parse_table(acpi_native_uint table_index, * each Parser Op subtree is deleted when it is finished. This saves * a great deal of memory, and allows a small cache of parse objects * to service the entire parse. The second pass of the parse then - * performs another complete parse of the AML. + * performs another complete parse of the AML.. */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); - status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index); + status = acpi_ns_one_complete_parse(1, table_desc); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -178,7 +152,7 @@ acpi_ns_parse_table(acpi_native_uint table_index, * parse objects are all cached. */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); - status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index); + status = acpi_ns_one_complete_parse(2, table_desc); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/namespace/nssearch.c b/trunk/drivers/acpi/namespace/nssearch.c index e863be665ce8..500e2bbcfaf7 100644 --- a/trunk/drivers/acpi/namespace/nssearch.c +++ b/trunk/drivers/acpi/namespace/nssearch.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -321,8 +321,7 @@ acpi_ns_search_and_enter(u32 target_name, * even though there are a few bad names. */ if (!acpi_ut_valid_acpi_name(target_name)) { - target_name = - acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name)); + target_name = acpi_ut_repair_name(target_name); /* Report warning only if in strict mode or debug mode */ @@ -402,10 +401,6 @@ acpi_ns_search_and_enter(u32 target_name, } #endif - if (flags & ACPI_NS_TEMPORARY) { - new_node->flags |= ANOBJ_TEMPORARY; - } - /* Install the new object into the parent's list of children */ acpi_ns_install_node(walk_state, node, new_node, type); diff --git a/trunk/drivers/acpi/namespace/nsutils.c b/trunk/drivers/acpi/namespace/nsutils.c index 90fd059615ff..aa4e799d9a8c 100644 --- a/trunk/drivers/acpi/namespace/nsutils.c +++ b/trunk/drivers/acpi/namespace/nsutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -770,6 +770,13 @@ void acpi_ns_terminate(void) } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); + + /* + * 2) Now we can delete the ACPI tables + */ + acpi_tb_delete_all_tables(); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); + return_VOID; } diff --git a/trunk/drivers/acpi/namespace/nswalk.c b/trunk/drivers/acpi/namespace/nswalk.c index 94eb8f332d94..c8f6bef16ed0 100644 --- a/trunk/drivers/acpi/namespace/nswalk.c +++ b/trunk/drivers/acpi/namespace/nswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -126,7 +126,7 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, * PARAMETERS: Type - acpi_object_type to search for * start_node - Handle in namespace where search begins * max_depth - Depth to which search is to reach - * Flags - Whether to unlock the NS before invoking + * unlock_before_callback- Whether to unlock the NS before invoking * the callback routine * user_function - Called when an object of "Type" is found * Context - Passed to user function @@ -153,7 +153,7 @@ acpi_status acpi_ns_walk_namespace(acpi_object_type type, acpi_handle start_node, u32 max_depth, - u32 flags, + u8 unlock_before_callback, acpi_walk_callback user_function, void *context, void **return_value) { @@ -193,34 +193,20 @@ acpi_ns_walk_namespace(acpi_object_type type, acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, child_node); if (child_node) { - - /* Found next child, get the type if we are not searching for ANY */ - - if (type != ACPI_TYPE_ANY) { - child_type = child_node->type; - } - /* - * Ignore all temporary namespace nodes (created during control - * method execution) unless told otherwise. These temporary nodes - * can cause a race condition because they can be deleted during the - * execution of the user function (if the namespace is unlocked before - * invocation of the user function.) Only the debugger namespace dump - * will examine the temporary nodes. + * Found node, Get the type if we are not + * searching for ANY */ - if ((child_node->flags & ANOBJ_TEMPORARY) && - !(flags & ACPI_NS_WALK_TEMP_NODES)) { - status = AE_CTRL_DEPTH; + if (type != ACPI_TYPE_ANY) { + child_type = child_node->type; } - /* Type must match requested type */ - - else if (child_type == type) { + if (child_type == type) { /* - * Found a matching node, invoke the user callback function. - * Unlock the namespace if flag is set. + * Found a matching node, invoke the user + * callback function */ - if (flags & ACPI_NS_WALK_UNLOCK) { + if (unlock_before_callback) { mutex_status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); @@ -230,11 +216,10 @@ acpi_ns_walk_namespace(acpi_object_type type, } } - status = - user_function(child_node, level, context, - return_value); + status = user_function(child_node, level, + context, return_value); - if (flags & ACPI_NS_WALK_UNLOCK) { + if (unlock_before_callback) { mutex_status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); @@ -266,17 +251,20 @@ acpi_ns_walk_namespace(acpi_object_type type, } /* - * Depth first search: Attempt to go down another level in the - * namespace if we are allowed to. Don't go any further if we have - * reached the caller specified maximum depth or if the user - * function has specified that the maximum depth has been reached. + * Depth first search: + * Attempt to go down another level in the namespace + * if we are allowed to. Don't go any further if we + * have reached the caller specified maximum depth + * or if the user function has specified that the + * maximum depth has been reached. */ if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) { - - /* There is at least one child of this node, visit it */ - + /* + * There is at least one child of this + * node, visit the onde + */ level++; parent_node = child_node; child_node = NULL; @@ -284,8 +272,9 @@ acpi_ns_walk_namespace(acpi_object_type type, } } else { /* - * No more children of this node (acpi_ns_get_next_node failed), go - * back upwards in the namespace tree to the node's parent. + * No more children of this node (acpi_ns_get_next_node + * failed), go back upwards in the namespace tree to + * the node's parent. */ level--; child_node = parent_node; diff --git a/trunk/drivers/acpi/namespace/nsxfeval.c b/trunk/drivers/acpi/namespace/nsxfeval.c index 7ac6ace50059..dca6799ac678 100644 --- a/trunk/drivers/acpi/namespace/nsxfeval.c +++ b/trunk/drivers/acpi/namespace/nsxfeval.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -170,6 +170,7 @@ acpi_evaluate_object(acpi_handle handle, struct acpi_buffer *return_buffer) { acpi_status status; + acpi_status status2; struct acpi_evaluate_info *info; acpi_size buffer_space_needed; u32 i; @@ -328,12 +329,14 @@ acpi_evaluate_object(acpi_handle handle, * Delete the internal return object. NOTE: Interpreter must be * locked to avoid race condition. */ - acpi_ex_enter_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_SUCCESS(status2)) { - /* Remove one reference on the return object (should delete it) */ + /* Remove one reference on the return object (should delete it) */ - acpi_ut_remove_reference(info->return_object); - acpi_ex_exit_interpreter(); + acpi_ut_remove_reference(info->return_object); + acpi_ex_exit_interpreter(); + } } cleanup: diff --git a/trunk/drivers/acpi/namespace/nsxfname.c b/trunk/drivers/acpi/namespace/nsxfname.c index b489781b22a8..978213a6c19f 100644 --- a/trunk/drivers/acpi/namespace/nsxfname.c +++ b/trunk/drivers/acpi/namespace/nsxfname.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -84,41 +84,38 @@ acpi_get_handle(acpi_handle parent, /* Convert a parent handle to a prefix node */ if (parent) { + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); + } + prefix_node = acpi_ns_map_handle_to_node(parent); if (!prefix_node) { + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - } - - /* - * Valid cases are: - * 1) Fully qualified pathname - * 2) Parent + Relative pathname - * - * Error for - */ - if (acpi_ns_valid_root_prefix(pathname[0])) { - /* Pathname is fully qualified (starts with '\') */ - - /* Special case for root-only, since we can't search for it */ - - if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) { - *ret_handle = - acpi_ns_convert_entry_to_handle(acpi_gbl_root_node); - return (AE_OK); + status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); } - } else if (!prefix_node) { + } - /* Relative path with null prefix is disallowed */ + /* Special case for root, since we can't search for it */ - return (AE_BAD_PARAMETER); + if (ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH) == 0) { + *ret_handle = + acpi_ns_convert_entry_to_handle(acpi_gbl_root_node); + return (AE_OK); } - /* Find the Node and convert to a handle */ + /* + * Find the Node and convert to a handle + */ + status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, + &node); - status = - acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node); + *ret_handle = NULL; if (ACPI_SUCCESS(status)) { *ret_handle = acpi_ns_convert_entry_to_handle(node); } diff --git a/trunk/drivers/acpi/namespace/nsxfobj.c b/trunk/drivers/acpi/namespace/nsxfobj.c index faa375887201..a18b1c223129 100644 --- a/trunk/drivers/acpi/namespace/nsxfobj.c +++ b/trunk/drivers/acpi/namespace/nsxfobj.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/numa.c b/trunk/drivers/acpi/numa.c index 4a9faff4c01d..bd96a7045925 100644 --- a/trunk/drivers/acpi/numa.c +++ b/trunk/drivers/acpi/numa.c @@ -45,7 +45,7 @@ int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS] int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; -extern int __init acpi_table_parse_madt_family(char *id, +extern int __init acpi_table_parse_madt_family(enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler, @@ -89,7 +89,7 @@ void __cpuinit acpi_unmap_pxm_to_node(int node) node_clear(node, nodes_found_map); } -void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) +void __init acpi_table_print_srat_entry(acpi_table_entry_header * header) { ACPI_FUNCTION_NAME("acpi_table_print_srat_entry"); @@ -99,35 +99,36 @@ void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) switch (header->type) { - case ACPI_SRAT_TYPE_CPU_AFFINITY: + case ACPI_SRAT_PROCESSOR_AFFINITY: #ifdef ACPI_DEBUG_OUTPUT { - struct acpi_srat_cpu_affinity *p = - (struct acpi_srat_cpu_affinity *)header; + struct acpi_table_processor_affinity *p = + (struct acpi_table_processor_affinity *)header; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n", - p->apic_id, p->local_sapic_eid, - p->proximity_domain_lo, - (p->flags & ACPI_SRAT_CPU_ENABLED)? - "enabled" : "disabled")); + p->apic_id, p->lsapic_eid, + p->proximity_domain, + p->flags. + enabled ? "enabled" : "disabled")); } #endif /* ACPI_DEBUG_OUTPUT */ break; - case ACPI_SRAT_TYPE_MEMORY_AFFINITY: + case ACPI_SRAT_MEMORY_AFFINITY: #ifdef ACPI_DEBUG_OUTPUT { - struct acpi_srat_mem_affinity *p = - (struct acpi_srat_mem_affinity *)header; + struct acpi_table_memory_affinity *p = + (struct acpi_table_memory_affinity *)header; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "SRAT Memory (0x%lx length 0x%lx type 0x%x) in proximity domain %d %s%s\n", - (unsigned long)p->base_address, - (unsigned long)p->length, + "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n", + p->base_addr_hi, p->base_addr_lo, + p->length_hi, p->length_lo, p->memory_type, p->proximity_domain, - (p->flags & ACPI_SRAT_MEM_ENABLED)? - "enabled" : "disabled", - (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)? - " hot-pluggable" : "")); + p->flags. + enabled ? "enabled" : "disabled", + p->flags. + hot_pluggable ? " hot-pluggable" : + "")); } #endif /* ACPI_DEBUG_OUTPUT */ break; @@ -140,18 +141,18 @@ void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) } } -static int __init acpi_parse_slit(struct acpi_table_header *table) +static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size) { struct acpi_table_slit *slit; u32 localities; - if (!table) + if (!phys_addr || !size) return -EINVAL; - slit = (struct acpi_table_slit *)table; + slit = (struct acpi_table_slit *)__va(phys_addr); /* downcast just for %llu vs %lu for i386/ia64 */ - localities = (u32) slit->locality_count; + localities = (u32) slit->localities; acpi_numa_slit_init(slit); @@ -159,12 +160,12 @@ static int __init acpi_parse_slit(struct acpi_table_header *table) } static int __init -acpi_parse_processor_affinity(struct acpi_subtable_header * header, +acpi_parse_processor_affinity(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_srat_cpu_affinity *processor_affinity; + struct acpi_table_processor_affinity *processor_affinity; - processor_affinity = (struct acpi_srat_cpu_affinity *)header; + processor_affinity = (struct acpi_table_processor_affinity *)header; if (!processor_affinity) return -EINVAL; @@ -177,12 +178,12 @@ acpi_parse_processor_affinity(struct acpi_subtable_header * header, } static int __init -acpi_parse_memory_affinity(struct acpi_subtable_header * header, +acpi_parse_memory_affinity(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_srat_mem_affinity *memory_affinity; + struct acpi_table_memory_affinity *memory_affinity; - memory_affinity = (struct acpi_srat_mem_affinity *)header; + memory_affinity = (struct acpi_table_memory_affinity *)header; if (!memory_affinity) return -EINVAL; @@ -194,23 +195,23 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, return 0; } -static int __init acpi_parse_srat(struct acpi_table_header *table) +static int __init acpi_parse_srat(unsigned long phys_addr, unsigned long size) { struct acpi_table_srat *srat; - if (!table) + if (!phys_addr || !size) return -EINVAL; - srat = (struct acpi_table_srat *)table; + srat = (struct acpi_table_srat *)__va(phys_addr); return 0; } int __init -acpi_table_parse_srat(enum acpi_srat_type id, +acpi_table_parse_srat(enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries) { - return acpi_table_parse_madt_family(ACPI_SIG_SRAT, + return acpi_table_parse_madt_family(ACPI_SRAT, sizeof(struct acpi_table_srat), id, handler, max_entries); } @@ -220,17 +221,17 @@ int __init acpi_numa_init(void) int result; /* SRAT: Static Resource Affinity Table */ - result = acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat); + result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat); if (result > 0) { - result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, + result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY, acpi_parse_processor_affinity, NR_CPUS); - result = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific + result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific } /* SLIT: System Locality Information Table */ - result = acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); + result = acpi_table_parse(ACPI_SLIT, acpi_parse_slit); acpi_numa_arch_fixup(); return 0; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 0f6f3bcbc8eb..57ae1e5cde0a 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -76,54 +75,6 @@ static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; static struct workqueue_struct *kacpid_wq; -static void __init acpi_request_region (struct acpi_generic_address *addr, - unsigned int length, char *desc) -{ - struct resource *res; - - if (!addr->address || !length) - return; - - if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) - res = request_region(addr->address, length, desc); - else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) - res = request_mem_region(addr->address, length, desc); -} - -static int __init acpi_reserve_resources(void) -{ - acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length, - "ACPI PM1a_EVT_BLK"); - - acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length, - "ACPI PM1b_EVT_BLK"); - - acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length, - "ACPI PM1a_CNT_BLK"); - - acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length, - "ACPI PM1b_CNT_BLK"); - - if (acpi_gbl_FADT.pm_timer_length == 4) - acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR"); - - acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length, - "ACPI PM2_CNT_BLK"); - - /* Length of GPE blocks must be a non-negative multiple of 2 */ - - if (!(acpi_gbl_FADT.gpe0_block_length & 0x1)) - acpi_request_region(&acpi_gbl_FADT.xgpe0_block, - acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK"); - - if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) - acpi_request_region(&acpi_gbl_FADT.xgpe1_block, - acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); - - return 0; -} -device_initcall(acpi_reserve_resources); - acpi_status acpi_os_initialize(void) { return AE_OK; @@ -185,43 +136,53 @@ void acpi_os_vprintf(const char *fmt, va_list args) #endif } -acpi_physical_address __init acpi_os_get_root_pointer(void) +acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr) { if (efi_enabled) { + addr->pointer_type = ACPI_PHYSICAL_POINTER; if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) - return efi.acpi20; + addr->pointer.physical = efi.acpi20; else if (efi.acpi != EFI_INVALID_TABLE_ADDR) - return efi.acpi; + addr->pointer.physical = efi.acpi; else { printk(KERN_ERR PREFIX "System description tables not found\n"); - return 0; + return AE_NOT_FOUND; } - } else - return acpi_find_rsdp(); + } else { + if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) { + printk(KERN_ERR PREFIX + "System description tables not found\n"); + return AE_NOT_FOUND; + } + } + + return AE_OK; } -void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size) +acpi_status +acpi_os_map_memory(acpi_physical_address phys, acpi_size size, + void __iomem ** virt) { if (phys > ULONG_MAX) { printk(KERN_ERR PREFIX "Cannot map memory that high\n"); - return 0; + return AE_BAD_PARAMETER; } - if (acpi_gbl_permanent_mmap) - /* - * ioremap checks to ensure this is in reserved space - */ - return ioremap((unsigned long)phys, size); - else - return __acpi_map_table((unsigned long)phys, size); + /* + * ioremap checks to ensure this is in reserved space + */ + *virt = ioremap((unsigned long)phys, size); + + if (!*virt) + return AE_NO_MEMORY; + + return AE_OK; } EXPORT_SYMBOL_GPL(acpi_os_map_memory); void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) { - if (acpi_gbl_permanent_mmap) { - iounmap(virt); - } + iounmap(virt); } EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); @@ -293,7 +254,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, * FADT. It may not be the same if an interrupt source override exists * for the SCI. */ - gsi = acpi_gbl_FADT.sci_interrupt; + gsi = acpi_fadt.sci_int; if (acpi_gsi_to_irq(gsi, &irq) < 0) { printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", gsi); diff --git a/trunk/drivers/acpi/parser/psargs.c b/trunk/drivers/acpi/parser/psargs.c index c2b9835c890b..bf88e076c3e9 100644 --- a/trunk/drivers/acpi/parser/psargs.c +++ b/trunk/drivers/acpi/parser/psargs.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/psloop.c b/trunk/drivers/acpi/parser/psloop.c index 773aee82fbb8..e1541db3753a 100644 --- a/trunk/drivers/acpi/parser/psloop.c +++ b/trunk/drivers/acpi/parser/psloop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,11 +42,12 @@ */ /* - * Parse the AML and build an operation tree as most interpreters, (such as - * Perl) do. Parsing is done by hand rather than with a YACC generated parser - * to tightly constrain stack and dynamic memory usage. Parsing is kept - * flexible and the code fairly compact by parsing based on a list of AML - * opcode templates in aml_op_info[]. + * Parse the AML and build an operation tree as most interpreters, + * like Perl, do. Parsing is done by hand rather than with a YACC + * generated parser to tightly constrain stack and dynamic memory + * usage. At the same time, parsing is kept flexible and the code + * fairly compact by parsing based on a list of AML opcode + * templates in aml_op_info[] */ #include @@ -59,761 +60,6 @@ ACPI_MODULE_NAME("psloop") static u32 acpi_gbl_depth = 0; -/* Local prototypes */ - -static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state); - -static acpi_status -acpi_ps_build_named_op(struct acpi_walk_state *walk_state, - u8 * aml_op_start, - union acpi_parse_object *unnamed_op, - union acpi_parse_object **op); - -static acpi_status -acpi_ps_create_op(struct acpi_walk_state *walk_state, - u8 * aml_op_start, union acpi_parse_object **new_op); - -static acpi_status -acpi_ps_get_arguments(struct acpi_walk_state *walk_state, - u8 * aml_op_start, union acpi_parse_object *op); - -static acpi_status -acpi_ps_complete_op(struct acpi_walk_state *walk_state, - union acpi_parse_object **op, acpi_status status); - -static acpi_status -acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, - union acpi_parse_object *op, acpi_status status); - -/******************************************************************************* - * - * FUNCTION: acpi_ps_get_aml_opcode - * - * PARAMETERS: walk_state - Current state - * - * RETURN: Status - * - * DESCRIPTION: Extract the next AML opcode from the input stream. - * - ******************************************************************************/ - -static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) -{ - - ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state); - - walk_state->aml_offset = - (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml, - walk_state->parser_state.aml_start); - walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state)); - - /* - * First cut to determine what we have found: - * 1) A valid AML opcode - * 2) A name string - * 3) An unknown/invalid opcode - */ - walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode); - - switch (walk_state->op_info->class) { - case AML_CLASS_ASCII: - case AML_CLASS_PREFIX: - /* - * Starts with a valid prefix or ASCII char, this is a name - * string. Convert the bare name string to a namepath. - */ - walk_state->opcode = AML_INT_NAMEPATH_OP; - walk_state->arg_types = ARGP_NAMESTRING; - break; - - case AML_CLASS_UNKNOWN: - - /* The opcode is unrecognized. Just skip unknown opcodes */ - - ACPI_ERROR((AE_INFO, - "Found unknown opcode %X at AML address %p offset %X, ignoring", - walk_state->opcode, walk_state->parser_state.aml, - walk_state->aml_offset)); - - ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128); - - /* Assume one-byte bad opcode */ - - walk_state->parser_state.aml++; - return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); - - default: - - /* Found opcode info, this is a normal opcode */ - - walk_state->parser_state.aml += - acpi_ps_get_opcode_size(walk_state->opcode); - walk_state->arg_types = walk_state->op_info->parse_args; - break; - } - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_build_named_op - * - * PARAMETERS: walk_state - Current state - * aml_op_start - Begin of named Op in AML - * unnamed_op - Early Op (not a named Op) - * Op - Returned Op - * - * RETURN: Status - * - * DESCRIPTION: Parse a named Op - * - ******************************************************************************/ - -static acpi_status -acpi_ps_build_named_op(struct acpi_walk_state *walk_state, - u8 * aml_op_start, - union acpi_parse_object *unnamed_op, - union acpi_parse_object **op) -{ - acpi_status status = AE_OK; - union acpi_parse_object *arg = NULL; - - ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); - - unnamed_op->common.value.arg = NULL; - unnamed_op->common.aml_opcode = walk_state->opcode; - - /* - * Get and append arguments until we find the node that contains - * the name (the type ARGP_NAME). - */ - while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) && - (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) { - status = - acpi_ps_get_next_arg(walk_state, - &(walk_state->parser_state), - GET_CURRENT_ARG_TYPE(walk_state-> - arg_types), &arg); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - acpi_ps_append_arg(unnamed_op, arg); - INCREMENT_ARG_LIST(walk_state->arg_types); - } - - /* - * Make sure that we found a NAME and didn't run out of arguments - */ - if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) { - return_ACPI_STATUS(AE_AML_NO_OPERAND); - } - - /* We know that this arg is a name, move to next arg */ - - INCREMENT_ARG_LIST(walk_state->arg_types); - - /* - * Find the object. This will either insert the object into - * the namespace or simply look it up - */ - walk_state->op = NULL; - - status = walk_state->descending_callback(walk_state, op); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog")); - return_ACPI_STATUS(status); - } - - if (!*op) { - return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); - } - - status = acpi_ps_next_parse_state(walk_state, *op, status); - if (ACPI_FAILURE(status)) { - if (status == AE_CTRL_PENDING) { - return_ACPI_STATUS(AE_CTRL_PARSE_PENDING); - } - return_ACPI_STATUS(status); - } - - acpi_ps_append_arg(*op, unnamed_op->common.value.arg); - acpi_gbl_depth++; - - if ((*op)->common.aml_opcode == AML_REGION_OP) { - /* - * Defer final parsing of an operation_region body, because we don't - * have enough info in the first pass to parse it correctly (i.e., - * there may be method calls within the term_arg elements of the body.) - * - * However, we must continue parsing because the opregion is not a - * standalone package -- we don't know where the end is at this point. - * - * (Length is unknown until parse of the body complete) - */ - (*op)->named.data = aml_op_start; - (*op)->named.length = 0; - } - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_create_op - * - * PARAMETERS: walk_state - Current state - * aml_op_start - Op start in AML - * new_op - Returned Op - * - * RETURN: Status - * - * DESCRIPTION: Get Op from AML - * - ******************************************************************************/ - -static acpi_status -acpi_ps_create_op(struct acpi_walk_state *walk_state, - u8 * aml_op_start, union acpi_parse_object **new_op) -{ - acpi_status status = AE_OK; - union acpi_parse_object *op; - union acpi_parse_object *named_op = NULL; - - ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); - - status = acpi_ps_get_aml_opcode(walk_state); - if (status == AE_CTRL_PARSE_CONTINUE) { - return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); - } - - /* Create Op structure and append to parent's argument list */ - - walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode); - op = acpi_ps_alloc_op(walk_state->opcode); - if (!op) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - if (walk_state->op_info->flags & AML_NAMED) { - status = - acpi_ps_build_named_op(walk_state, aml_op_start, op, - &named_op); - acpi_ps_free_op(op); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - *new_op = named_op; - return_ACPI_STATUS(AE_OK); - } - - /* Not a named opcode, just allocate Op and append to parent */ - - if (walk_state->op_info->flags & AML_CREATE) { - /* - * Backup to beginning of create_xXXfield declaration - * body_length is unknown until we parse the body - */ - op->named.data = aml_op_start; - op->named.length = 0; - } - - acpi_ps_append_arg(acpi_ps_get_parent_scope - (&(walk_state->parser_state)), op); - - if (walk_state->descending_callback != NULL) { - /* - * Find the object. This will either insert the object into - * the namespace or simply look it up - */ - walk_state->op = *new_op = op; - - status = walk_state->descending_callback(walk_state, &op); - status = acpi_ps_next_parse_state(walk_state, op, status); - if (status == AE_CTRL_PENDING) { - status = AE_CTRL_PARSE_PENDING; - } - } - - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_get_arguments - * - * PARAMETERS: walk_state - Current state - * aml_op_start - Op start in AML - * Op - Current Op - * - * RETURN: Status - * - * DESCRIPTION: Get arguments for passed Op. - * - ******************************************************************************/ - -static acpi_status -acpi_ps_get_arguments(struct acpi_walk_state *walk_state, - u8 * aml_op_start, union acpi_parse_object *op) -{ - acpi_status status = AE_OK; - union acpi_parse_object *arg = NULL; - - ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state); - - switch (op->common.aml_opcode) { - case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ - case AML_WORD_OP: /* AML_WORDDATA_ARG */ - case AML_DWORD_OP: /* AML_DWORDATA_ARG */ - case AML_QWORD_OP: /* AML_QWORDATA_ARG */ - case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ - - /* Fill in constant or string argument directly */ - - acpi_ps_get_next_simple_arg(&(walk_state->parser_state), - GET_CURRENT_ARG_TYPE(walk_state-> - arg_types), - op); - break; - - case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ - - status = - acpi_ps_get_next_namepath(walk_state, - &(walk_state->parser_state), op, - 1); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - walk_state->arg_types = 0; - break; - - default: - /* - * 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) { - walk_state->aml_offset = - (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml, - walk_state->parser_state. - aml_start); - - status = - acpi_ps_get_next_arg(walk_state, - &(walk_state->parser_state), - GET_CURRENT_ARG_TYPE - (walk_state->arg_types), &arg); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - if (arg) { - arg->common.aml_offset = walk_state->aml_offset; - acpi_ps_append_arg(op, arg); - } - - INCREMENT_ARG_LIST(walk_state->arg_types); - } - - /* Special processing for certain opcodes */ - - /* TBD (remove): Temporary mechanism to disable this code if needed */ - -#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE - - if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) && - ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { - /* - * We want to skip If/Else/While constructs during Pass1 because we - * want to actually conditionally execute the code during Pass2. - * - * Except for disassembly, where we always want to walk the - * If/Else/While packages - */ - switch (op->common.aml_opcode) { - case AML_IF_OP: - case AML_ELSE_OP: - case AML_WHILE_OP: - - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "Pass1: Skipping an If/Else/While body\n")); - - /* Skip body of if/else/while in pass 1 */ - - walk_state->parser_state.aml = - walk_state->parser_state.pkg_end; - walk_state->arg_count = 0; - break; - - default: - break; - } - } -#endif - - switch (op->common.aml_opcode) { - case AML_METHOD_OP: - /* - * Skip parsing of control method because we don't have enough - * info in the first pass to parse it correctly. - * - * Save the length and address of the body - */ - op->named.data = walk_state->parser_state.aml; - op->named.length = (u32) - (walk_state->parser_state.pkg_end - - walk_state->parser_state.aml); - - /* Skip body of method */ - - walk_state->parser_state.aml = - walk_state->parser_state.pkg_end; - walk_state->arg_count = 0; - break; - - case AML_BUFFER_OP: - case AML_PACKAGE_OP: - case AML_VAR_PACKAGE_OP: - - if ((op->common.parent) && - (op->common.parent->common.aml_opcode == - AML_NAME_OP) - && (walk_state->pass_number <= - ACPI_IMODE_LOAD_PASS2)) { - /* - * 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) - (walk_state->parser_state.pkg_end - - aml_op_start); - - /* Skip body */ - - walk_state->parser_state.aml = - walk_state->parser_state.pkg_end; - walk_state->arg_count = 0; - } - break; - - case AML_WHILE_OP: - - if (walk_state->control_state) { - walk_state->control_state->control.package_end = - walk_state->parser_state.pkg_end; - } - break; - - default: - - /* No action for all other opcodes */ - break; - } - - break; - } - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_complete_op - * - * PARAMETERS: walk_state - Current state - * Op - Returned Op - * Status - Parse status before complete Op - * - * RETURN: Status - * - * DESCRIPTION: Complete Op - * - ******************************************************************************/ - -static acpi_status -acpi_ps_complete_op(struct acpi_walk_state *walk_state, - union acpi_parse_object **op, acpi_status status) -{ - acpi_status status2; - - ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state); - - /* - * Finished one argument of the containing scope - */ - walk_state->parser_state.scope->parse_scope.arg_count--; - - /* Close this Op (will result in parse subtree deletion) */ - - status2 = acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - - *op = NULL; - - switch (status) { - case AE_OK: - break; - - case AE_CTRL_TRANSFER: - - /* We are about to transfer to a called method */ - - walk_state->prev_op = NULL; - walk_state->prev_arg_types = walk_state->arg_types; - return_ACPI_STATUS(status); - - case AE_CTRL_END: - - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - - if (*op) { - walk_state->op = *op; - walk_state->op_info = - acpi_ps_get_opcode_info((*op)->common.aml_opcode); - walk_state->opcode = (*op)->common.aml_opcode; - - status = walk_state->ascending_callback(walk_state); - status = - acpi_ps_next_parse_state(walk_state, *op, status); - - status2 = acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - } - - status = AE_OK; - break; - - case AE_CTRL_BREAK: - case AE_CTRL_CONTINUE: - - /* Pop off scopes until we find the While */ - - while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) { - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - - if ((*op)->common.aml_opcode != AML_WHILE_OP) { - status2 = acpi_ds_result_stack_pop(walk_state); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - } - } - - /* Close this iteration of the While loop */ - - walk_state->op = *op; - walk_state->op_info = - acpi_ps_get_opcode_info((*op)->common.aml_opcode); - walk_state->opcode = (*op)->common.aml_opcode; - - status = walk_state->ascending_callback(walk_state); - status = acpi_ps_next_parse_state(walk_state, *op, status); - - status2 = acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - - status = AE_OK; - break; - - case AE_CTRL_TERMINATE: - - /* Clean up */ - do { - if (*op) { - status2 = - acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - status2 = acpi_ds_result_stack_pop(walk_state); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - - acpi_ut_delete_generic_state - (acpi_ut_pop_generic_state - (&walk_state->control_state)); - } - - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - - } while (*op); - - return_ACPI_STATUS(AE_OK); - - default: /* All other non-AE_OK status */ - - do { - if (*op) { - status2 = - acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - } - - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - - } while (*op); - -#if 0 - /* - * TBD: Cleanup parse ops on error - */ - if (*op == NULL) { - acpi_ps_pop_scope(parser_state, op, - &walk_state->arg_types, - &walk_state->arg_count); - } -#endif - walk_state->prev_op = NULL; - walk_state->prev_arg_types = walk_state->arg_types; - return_ACPI_STATUS(status); - } - - /* This scope complete? */ - - if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) { - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op)); - } else { - *op = NULL; - } - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_complete_final_op - * - * PARAMETERS: walk_state - Current state - * Op - Current Op - * Status - Current parse status before complete last - * Op - * - * RETURN: Status - * - * DESCRIPTION: Complete last Op. - * - ******************************************************************************/ - -static acpi_status -acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, - union acpi_parse_object *op, acpi_status status) -{ - acpi_status status2; - - ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state); - - /* - * Complete the last Op (if not completed), and clear the scope stack. - * It is easily possible to end an AML "package" with an unbounded number - * of open scopes (such as when several ASL blocks are closed with - * sequential closing braces). We want to terminate each one cleanly. - */ - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n", - op)); - do { - if (op) { - if (walk_state->ascending_callback != NULL) { - walk_state->op = op; - walk_state->op_info = - acpi_ps_get_opcode_info(op->common. - aml_opcode); - walk_state->opcode = op->common.aml_opcode; - - status = - walk_state->ascending_callback(walk_state); - status = - acpi_ps_next_parse_state(walk_state, op, - status); - if (status == AE_CTRL_PENDING) { - status = - acpi_ps_complete_op(walk_state, &op, - AE_OK); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } - - if (status == AE_CTRL_TERMINATE) { - status = AE_OK; - - /* Clean up */ - do { - if (op) { - status2 = - acpi_ps_complete_this_op - (walk_state, op); - if (ACPI_FAILURE - (status2)) { - return_ACPI_STATUS - (status2); - } - } - - acpi_ps_pop_scope(& - (walk_state-> - parser_state), - &op, - &walk_state-> - arg_types, - &walk_state-> - arg_count); - - } while (op); - - return_ACPI_STATUS(status); - } - - else if (ACPI_FAILURE(status)) { - - /* First error is most important */ - - (void) - acpi_ps_complete_this_op(walk_state, - op); - return_ACPI_STATUS(status); - } - } - - status2 = acpi_ps_complete_this_op(walk_state, op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - } - - acpi_ps_pop_scope(&(walk_state->parser_state), &op, - &walk_state->arg_types, - &walk_state->arg_count); - - } while (op); - - return_ACPI_STATUS(status); -} - /******************************************************************************* * * FUNCTION: acpi_ps_parse_loop @@ -830,7 +76,10 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) { acpi_status status = AE_OK; + acpi_status status2; union acpi_parse_object *op = NULL; /* current op */ + union acpi_parse_object *arg = NULL; + union acpi_parse_object *pre_op = NULL; struct acpi_parse_state *parser_state; u8 *aml_op_start = NULL; @@ -879,7 +128,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) "Invoked method did not return a value")); } - ACPI_EXCEPTION((AE_INFO, status, "GetPredicate Failed")); return_ACPI_STATUS(status); @@ -905,30 +153,222 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) } #endif - /* Iterative parsing loop, while there is more AML to process: */ + /* Iterative parsing loop, while there is more AML to process: */ + + while ((parser_state->aml < parser_state->aml_end) || (op)) { + aml_op_start = parser_state->aml; + if (!op) { + + /* Get the next opcode from the AML stream */ + + walk_state->aml_offset = + (u32) ACPI_PTR_DIFF(parser_state->aml, + parser_state->aml_start); + walk_state->opcode = acpi_ps_peek_opcode(parser_state); + + /* + * First cut to determine what we have found: + * 1) A valid AML opcode + * 2) A name string + * 3) An unknown/invalid opcode + */ + walk_state->op_info = + acpi_ps_get_opcode_info(walk_state->opcode); + switch (walk_state->op_info->class) { + case AML_CLASS_ASCII: + case AML_CLASS_PREFIX: + /* + * Starts with a valid prefix or ASCII char, this is a name + * string. Convert the bare name string to a namepath. + */ + walk_state->opcode = AML_INT_NAMEPATH_OP; + walk_state->arg_types = ARGP_NAMESTRING; + break; + + case AML_CLASS_UNKNOWN: + + /* The opcode is unrecognized. Just skip unknown opcodes */ + + ACPI_ERROR((AE_INFO, + "Found unknown opcode %X at AML address %p offset %X, ignoring", + walk_state->opcode, + parser_state->aml, + walk_state->aml_offset)); + + ACPI_DUMP_BUFFER(parser_state->aml, 128); + + /* Assume one-byte bad opcode */ + + parser_state->aml++; + continue; + + default: + + /* Found opcode info, this is a normal opcode */ + + parser_state->aml += + acpi_ps_get_opcode_size(walk_state->opcode); + walk_state->arg_types = + walk_state->op_info->parse_args; + break; + } + + /* Create Op structure and append to parent's argument list */ + + if (walk_state->op_info->flags & AML_NAMED) { + + /* Allocate a new pre_op if necessary */ + + if (!pre_op) { + pre_op = + acpi_ps_alloc_op(walk_state-> + opcode); + if (!pre_op) { + status = AE_NO_MEMORY; + goto close_this_op; + } + } + + pre_op->common.value.arg = NULL; + pre_op->common.aml_opcode = walk_state->opcode; + + /* + * Get and append arguments until we find the node that contains + * the name (the type ARGP_NAME). + */ + while (GET_CURRENT_ARG_TYPE + (walk_state->arg_types) + && + (GET_CURRENT_ARG_TYPE + (walk_state->arg_types) != ARGP_NAME)) { + status = + acpi_ps_get_next_arg(walk_state, + parser_state, + GET_CURRENT_ARG_TYPE + (walk_state-> + arg_types), + &arg); + if (ACPI_FAILURE(status)) { + goto close_this_op; + } + + acpi_ps_append_arg(pre_op, arg); + INCREMENT_ARG_LIST(walk_state-> + arg_types); + } + + /* + * Make sure that we found a NAME and didn't run out of + * arguments + */ + if (!GET_CURRENT_ARG_TYPE + (walk_state->arg_types)) { + status = AE_AML_NO_OPERAND; + goto close_this_op; + } + + /* We know that this arg is a name, move to next arg */ + + INCREMENT_ARG_LIST(walk_state->arg_types); - while ((parser_state->aml < parser_state->aml_end) || (op)) { - aml_op_start = parser_state->aml; - if (!op) { - status = - acpi_ps_create_op(walk_state, aml_op_start, &op); - if (ACPI_FAILURE(status)) { - if (status == AE_CTRL_PARSE_CONTINUE) { + /* + * Find the object. This will either insert the object into + * the namespace or simply look it up + */ + walk_state->op = NULL; + + status = + walk_state->descending_callback(walk_state, + &op); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "During name lookup/catalog")); + goto close_this_op; + } + + if (!op) { continue; } - if (status == AE_CTRL_PARSE_PENDING) { + status = + acpi_ps_next_parse_state(walk_state, op, + status); + if (status == AE_CTRL_PENDING) { status = AE_OK; + goto close_this_op; } - status = - acpi_ps_complete_op(walk_state, &op, - status); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto close_this_op; } - continue; + acpi_ps_append_arg(op, + pre_op->common.value.arg); + acpi_gbl_depth++; + + if (op->common.aml_opcode == AML_REGION_OP) { + /* + * Defer final parsing of an operation_region body, + * because we don't have enough info in the first pass + * to parse it correctly (i.e., there may be method + * calls within the term_arg elements of the body.) + * + * However, we must continue parsing because + * the opregion is not a standalone package -- + * we don't know where the end is at this point. + * + * (Length is unknown until parse of the body complete) + */ + op->named.data = aml_op_start; + op->named.length = 0; + } + } else { + /* Not a named opcode, just allocate Op and append to parent */ + + walk_state->op_info = + acpi_ps_get_opcode_info(walk_state->opcode); + op = acpi_ps_alloc_op(walk_state->opcode); + if (!op) { + status = AE_NO_MEMORY; + goto close_this_op; + } + + if (walk_state->op_info->flags & AML_CREATE) { + /* + * Backup to beginning of create_xXXfield declaration + * body_length is unknown until we parse the body + */ + op->named.data = aml_op_start; + op->named.length = 0; + } + + acpi_ps_append_arg(acpi_ps_get_parent_scope + (parser_state), op); + + if ((walk_state->descending_callback != NULL)) { + /* + * Find the object. This will either insert the object into + * the namespace or simply look it up + */ + walk_state->op = op; + + status = + walk_state-> + descending_callback(walk_state, + &op); + status = + acpi_ps_next_parse_state(walk_state, + op, + status); + if (status == AE_CTRL_PENDING) { + status = AE_OK; + goto close_this_op; + } + + if (ACPI_FAILURE(status)) { + goto close_this_op; + } + } } op->common.aml_offset = walk_state->aml_offset; @@ -955,17 +395,172 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) /* Get arguments */ - status = - acpi_ps_get_arguments(walk_state, aml_op_start, op); - if (ACPI_FAILURE(status)) { + switch (op->common.aml_opcode) { + case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ + case AML_WORD_OP: /* AML_WORDDATA_ARG */ + case AML_DWORD_OP: /* AML_DWORDATA_ARG */ + case AML_QWORD_OP: /* AML_QWORDATA_ARG */ + case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ + + /* Fill in constant or string argument directly */ + + acpi_ps_get_next_simple_arg(parser_state, + GET_CURRENT_ARG_TYPE + (walk_state-> + arg_types), op); + break; + + case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ + status = - acpi_ps_complete_op(walk_state, &op, - status); + acpi_ps_get_next_namepath(walk_state, + parser_state, op, + 1); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto close_this_op; } - continue; + walk_state->arg_types = 0; + break; + + default: + /* + * 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) { + walk_state->aml_offset = (u32) + ACPI_PTR_DIFF(parser_state->aml, + parser_state-> + aml_start); + + status = + acpi_ps_get_next_arg(walk_state, + parser_state, + GET_CURRENT_ARG_TYPE + (walk_state-> + arg_types), + &arg); + if (ACPI_FAILURE(status)) { + goto close_this_op; + } + + if (arg) { + arg->common.aml_offset = + walk_state->aml_offset; + acpi_ps_append_arg(op, arg); + } + INCREMENT_ARG_LIST(walk_state-> + arg_types); + } + + /* Special processing for certain opcodes */ + + /* TBD (remove): Temporary mechanism to disable this code if needed */ + +#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE + + if ((walk_state->pass_number <= + ACPI_IMODE_LOAD_PASS1) + && + ((walk_state-> + parse_flags & ACPI_PARSE_DISASSEMBLE) == + 0)) { + /* + * We want to skip If/Else/While constructs during Pass1 + * because we want to actually conditionally execute the + * code during Pass2. + * + * Except for disassembly, where we always want to + * walk the If/Else/While packages + */ + switch (op->common.aml_opcode) { + case AML_IF_OP: + case AML_ELSE_OP: + case AML_WHILE_OP: + + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Pass1: Skipping an If/Else/While body\n")); + + /* Skip body of if/else/while in pass 1 */ + + parser_state->aml = + parser_state->pkg_end; + walk_state->arg_count = 0; + break; + + default: + break; + } + } +#endif + switch (op->common.aml_opcode) { + case AML_METHOD_OP: + + /* + * Skip parsing of control method + * because we don't have enough info in the first pass + * 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 */ + + parser_state->aml = + parser_state->pkg_end; + walk_state->arg_count = 0; + break; + + case AML_BUFFER_OP: + case AML_PACKAGE_OP: + case AML_VAR_PACKAGE_OP: + + if ((op->common.parent) && + (op->common.parent->common. + aml_opcode == AML_NAME_OP) + && (walk_state->pass_number <= + ACPI_IMODE_LOAD_PASS2)) { + /* + * 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 */ + + parser_state->aml = + parser_state->pkg_end; + walk_state->arg_count = 0; + } + break; + + case AML_WHILE_OP: + + if (walk_state->control_state) { + walk_state->control_state-> + control.package_end = + parser_state->pkg_end; + } + break; + + default: + + /* No action for all other opcodes */ + break; + } + break; } } @@ -980,16 +575,8 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) walk_state->arg_types, walk_state->arg_count); if (ACPI_FAILURE(status)) { - status = - acpi_ps_complete_op(walk_state, &op, - status); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - continue; + goto close_this_op; } - op = NULL; continue; } @@ -1041,16 +628,269 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) acpi_ps_next_parse_state(walk_state, op, status); if (status == AE_CTRL_PENDING) { status = AE_OK; + goto close_this_op; } } - status = acpi_ps_complete_op(walk_state, &op, status); - if (ACPI_FAILURE(status)) { + close_this_op: + /* + * Finished one argument of the containing scope + */ + parser_state->scope->parse_scope.arg_count--; + + /* Finished with pre_op */ + + if (pre_op) { + acpi_ps_free_op(pre_op); + pre_op = NULL; + } + + /* Close this Op (will result in parse subtree deletion) */ + + status2 = acpi_ps_complete_this_op(walk_state, op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + op = NULL; + + switch (status) { + case AE_OK: + break; + + case AE_CTRL_TRANSFER: + + /* We are about to transfer to a called method. */ + + walk_state->prev_op = op; + walk_state->prev_arg_types = walk_state->arg_types; + return_ACPI_STATUS(status); + + case AE_CTRL_END: + + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + + if (op) { + walk_state->op = op; + walk_state->op_info = + acpi_ps_get_opcode_info(op->common. + aml_opcode); + walk_state->opcode = op->common.aml_opcode; + + status = + walk_state->ascending_callback(walk_state); + status = + acpi_ps_next_parse_state(walk_state, op, + status); + + status2 = + acpi_ps_complete_this_op(walk_state, op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + op = NULL; + } + status = AE_OK; + break; + + case AE_CTRL_BREAK: + case AE_CTRL_CONTINUE: + + /* Pop off scopes until we find the While */ + + while (!op || (op->common.aml_opcode != AML_WHILE_OP)) { + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + + if (op->common.aml_opcode != AML_WHILE_OP) { + status2 = + acpi_ds_result_stack_pop + (walk_state); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + } + } + + /* Close this iteration of the While loop */ + + walk_state->op = op; + walk_state->op_info = + acpi_ps_get_opcode_info(op->common.aml_opcode); + walk_state->opcode = op->common.aml_opcode; + + status = walk_state->ascending_callback(walk_state); + status = + acpi_ps_next_parse_state(walk_state, op, status); + + status2 = acpi_ps_complete_this_op(walk_state, op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + op = NULL; + + status = AE_OK; + break; + + case AE_CTRL_TERMINATE: + + status = AE_OK; + + /* Clean up */ + do { + if (op) { + status2 = + acpi_ps_complete_this_op(walk_state, + op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + + status2 = + acpi_ds_result_stack_pop + (walk_state); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + + acpi_ut_delete_generic_state + (acpi_ut_pop_generic_state + (&walk_state->control_state)); + } + + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + + } while (op); + + return_ACPI_STATUS(status); + + default: /* All other non-AE_OK status */ + + do { + if (op) { + status2 = + acpi_ps_complete_this_op(walk_state, + op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + } + + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + + } while (op); + + /* + * TBD: Cleanup parse ops on error + */ +#if 0 + if (op == NULL) { + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + } +#endif + walk_state->prev_op = op; + walk_state->prev_arg_types = walk_state->arg_types; return_ACPI_STATUS(status); } + /* This scope complete? */ + + if (acpi_ps_has_completed_scope(parser_state)) { + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Popped scope, Op=%p\n", op)); + } else { + op = NULL; + } + } /* while parser_state->Aml */ - status = acpi_ps_complete_final_op(walk_state, op, status); + /* + * Complete the last Op (if not completed), and clear the scope stack. + * It is easily possible to end an AML "package" with an unbounded number + * of open scopes (such as when several ASL blocks are closed with + * sequential closing braces). We want to terminate each one cleanly. + */ + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n", + op)); + do { + if (op) { + if (walk_state->ascending_callback != NULL) { + walk_state->op = op; + walk_state->op_info = + acpi_ps_get_opcode_info(op->common. + aml_opcode); + walk_state->opcode = op->common.aml_opcode; + + status = + walk_state->ascending_callback(walk_state); + status = + acpi_ps_next_parse_state(walk_state, op, + status); + if (status == AE_CTRL_PENDING) { + status = AE_OK; + goto close_this_op; + } + + if (status == AE_CTRL_TERMINATE) { + status = AE_OK; + + /* Clean up */ + do { + if (op) { + status2 = + acpi_ps_complete_this_op + (walk_state, op); + if (ACPI_FAILURE + (status2)) { + return_ACPI_STATUS + (status2); + } + } + + acpi_ps_pop_scope(parser_state, + &op, + &walk_state-> + arg_types, + &walk_state-> + arg_count); + + } while (op); + + return_ACPI_STATUS(status); + } + + else if (ACPI_FAILURE(status)) { + + /* First error is most important */ + + (void) + acpi_ps_complete_this_op(walk_state, + op); + return_ACPI_STATUS(status); + } + } + + status2 = acpi_ps_complete_this_op(walk_state, op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + } + + acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, + &walk_state->arg_count); + + } while (op); + return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/parser/psopcode.c b/trunk/drivers/acpi/parser/psopcode.c index 16d8b6cc3c22..4bd25e32769f 100644 --- a/trunk/drivers/acpi/parser/psopcode.c +++ b/trunk/drivers/acpi/parser/psopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/psparse.c b/trunk/drivers/acpi/parser/psparse.c index 5d63f48e56b5..a02aa62fe1e5 100644 --- a/trunk/drivers/acpi/parser/psparse.c +++ b/trunk/drivers/acpi/parser/psparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -540,11 +540,6 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) if ((status == AE_ALREADY_EXISTS) && (!walk_state->method_desc->method.mutex)) { - ACPI_INFO((AE_INFO, - "Marking method %4.4s as Serialized", - walk_state->method_node->name. - ascii)); - /* * Method tried to create an object twice. The probable cause is * that the method cannot handle reentrancy. diff --git a/trunk/drivers/acpi/parser/psscope.c b/trunk/drivers/acpi/parser/psscope.c index 77cfa4ed0cfe..a3e0314de24d 100644 --- a/trunk/drivers/acpi/parser/psscope.c +++ b/trunk/drivers/acpi/parser/psscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/pstree.c b/trunk/drivers/acpi/parser/pstree.c index 966e7ea2a0c4..0015717ef096 100644 --- a/trunk/drivers/acpi/parser/pstree.c +++ b/trunk/drivers/acpi/parser/pstree.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/psutils.c b/trunk/drivers/acpi/parser/psutils.c index 8ca52002db55..d405387b7414 100644 --- a/trunk/drivers/acpi/parser/psutils.c +++ b/trunk/drivers/acpi/parser/psutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/pswalk.c b/trunk/drivers/acpi/parser/pswalk.c index 49f9757434e4..a84a547a0f1b 100644 --- a/trunk/drivers/acpi/parser/pswalk.c +++ b/trunk/drivers/acpi/parser/pswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/psxface.c b/trunk/drivers/acpi/parser/psxface.c index 94103bced75e..5d996c1140af 100644 --- a/trunk/drivers/acpi/parser/psxface.c +++ b/trunk/drivers/acpi/parser/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,6 +54,8 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info); static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); +static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info); + static void acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); @@ -213,8 +215,6 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) { acpi_status status; - union acpi_parse_object *op; - struct acpi_walk_state *walk_state; ACPI_FUNCTION_TRACE(ps_execute_method); @@ -234,7 +234,8 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) } /* - * The caller "owns" the parameters, so give each one an extra reference + * The caller "owns" the parameters, so give each one an extra + * reference */ acpi_ps_update_parameter_list(info, REF_INCREMENT); @@ -243,50 +244,30 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) acpi_ps_start_trace(info); /* - * Execute the method. Performs parse simultaneously + * 1) Perform the first pass parse of the method to enter any + * named objects that it creates into the namespace */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n", - info->resolved_node->name.ascii, info->resolved_node, - info->obj_desc)); - - /* Create and init a Root Node */ - - op = acpi_ps_create_scope_op(); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* Create and initialize a new walk state */ - - info->pass_number = ACPI_IMODE_EXECUTE; - walk_state = - acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL, - NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup; - } + "**** Begin Method Parse **** Entry=%p obj=%p\n", + info->resolved_node, info->obj_desc)); - status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node, - info->obj_desc->method.aml_start, - info->obj_desc->method.aml_length, info, - info->pass_number); + info->pass_number = 1; + status = acpi_ps_execute_pass(info); if (ACPI_FAILURE(status)) { - acpi_ds_delete_walk_state(walk_state); goto cleanup; } - /* Parse the AML */ - - status = acpi_ps_parse_aml(walk_state); + /* + * 2) Execute the method. Performs second pass parse simultaneously + */ + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "**** Begin Method Execution **** Entry=%p obj=%p\n", + info->resolved_node, info->obj_desc)); - /* walk_state was deleted by parse_aml */ + info->pass_number = 3; + status = acpi_ps_execute_pass(info); cleanup: - acpi_ps_delete_parse_tree(op); - /* End optional tracing */ acpi_ps_stop_trace(info); @@ -349,3 +330,62 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) } } } + +/******************************************************************************* + * + * FUNCTION: acpi_ps_execute_pass + * + * PARAMETERS: Info - See struct acpi_evaluate_info + * (Used: pass_number, Node, and obj_desc) + * + * RETURN: Status + * + * DESCRIPTION: Single AML pass: Parse or Execute a control method + * + ******************************************************************************/ + +static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info) +{ + acpi_status status; + union acpi_parse_object *op; + struct acpi_walk_state *walk_state; + + ACPI_FUNCTION_TRACE(ps_execute_pass); + + /* Create and init a Root Node */ + + op = acpi_ps_create_scope_op(); + if (!op) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Create and initialize a new walk state */ + + walk_state = + acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL, + NULL, NULL); + if (!walk_state) { + status = AE_NO_MEMORY; + goto cleanup; + } + + status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node, + info->obj_desc->method.aml_start, + info->obj_desc->method.aml_length, + info->pass_number == 1 ? NULL : info, + info->pass_number); + if (ACPI_FAILURE(status)) { + acpi_ds_delete_walk_state(walk_state); + goto cleanup; + } + + /* Parse the AML */ + + status = acpi_ps_parse_aml(walk_state); + + /* Walk state was deleted by parse_aml */ + + cleanup: + acpi_ps_delete_parse_tree(op); + return_ACPI_STATUS(status); +} diff --git a/trunk/drivers/acpi/pci_link.c b/trunk/drivers/acpi/pci_link.c index 0f683c8c6fbc..481e633bbf41 100644 --- a/trunk/drivers/acpi/pci_link.c +++ b/trunk/drivers/acpi/pci_link.c @@ -513,7 +513,7 @@ int __init acpi_irq_penalty_init(void) } } /* Add a penalty for the SCI */ - acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING; + acpi_irq_penalty[acpi_fadt.sci_int] += PIRQ_PENALTY_PCI_USING; return 0; } @@ -785,7 +785,7 @@ static int irqrouter_resume(struct sys_device *dev) /* Make sure SCI is enabled again (Apple firmware bug?) */ - acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); + acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1, ACPI_MTX_DO_NOT_LOCK); list_for_each(node, &acpi_link.entries) { link = list_entry(node, struct acpi_pci_link, node); diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index 4ecf701687e8..a860efa2c562 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -117,19 +117,6 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) EXPORT_SYMBOL(acpi_pci_unregister_driver); -acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) -{ - struct acpi_pci_root *tmp; - - list_for_each_entry(tmp, &acpi_pci_roots, node) { - if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) - return tmp->device->handle; - } - return NULL; -} - -EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); - static acpi_status get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) { @@ -165,21 +152,6 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) return AE_OK; } -static void acpi_pci_bridge_scan(struct acpi_device *device) -{ - int status; - struct acpi_device *child = NULL; - - if (device->flags.bus_address) - if (device->parent && device->parent->ops.bind) { - status = device->parent->ops.bind(device); - if (!status) { - list_for_each_entry(child, &device->children, node) - acpi_pci_bridge_scan(child); - } - } -} - static int acpi_pci_root_add(struct acpi_device *device) { int result = 0; @@ -188,7 +160,6 @@ static int acpi_pci_root_add(struct acpi_device *device) acpi_status status = AE_OK; unsigned long value = 0; acpi_handle handle = NULL; - struct acpi_device *child; if (!device) @@ -204,6 +175,9 @@ static int acpi_pci_root_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); acpi_driver_data(device) = root; + /* + * TBD: Doesn't the bus driver automatically set this? + */ device->ops.bind = acpi_pci_bind; /* @@ -325,12 +299,6 @@ static int acpi_pci_root_add(struct acpi_device *device) result = acpi_pci_irq_add_prt(device->handle, root->id.segment, root->id.bus); - /* - * Scan and bind all _ADR-Based Devices - */ - list_for_each_entry(child, &device->children, node) - acpi_pci_bridge_scan(child); - end: if (result) { if (!list_empty(&root->node)) diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 0079bc51082c..5f9496d59ed6 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -375,126 +375,30 @@ static int acpi_processor_remove_fs(struct acpi_device *device) } /* Use the acpiid in MADT to map cpus in case of SMP */ - #ifndef CONFIG_SMP -static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;} +#define convert_acpiid_to_cpu(acpi_id) (-1) #else -static struct acpi_table_madt *madt; - -static int map_lapic_id(struct acpi_subtable_header *entry, - u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_apic *lapic = - (struct acpi_madt_local_apic *)entry; - if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && - lapic->processor_id == acpi_id) { - *apic_id = lapic->id; - return 1; - } - return 0; -} - -static int map_lsapic_id(struct acpi_subtable_header *entry, - u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_sapic *lsapic = - (struct acpi_madt_local_sapic *)entry; - /* Only check enabled APICs*/ - if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { - /* First check against id */ - if (lsapic->processor_id == acpi_id) { - *apic_id = lsapic->id; - return 1; - /* Check against optional uid */ - } else if (entry->length >= 16 && - lsapic->uid == acpi_id) { - *apic_id = lsapic->uid; - return 1; - } - } - return 0; -} - #ifdef CONFIG_IA64 +#define arch_acpiid_to_apicid ia64_acpiid_to_sapicid #define arch_cpu_to_apicid ia64_cpu_to_sapicid +#define ARCH_BAD_APICID (0xffff) #else +#define arch_acpiid_to_apicid x86_acpiid_to_apicid #define arch_cpu_to_apicid x86_cpu_to_apicid +#define ARCH_BAD_APICID (0xff) #endif -static int map_madt_entry(u32 acpi_id) -{ - unsigned long madt_end, entry; - int apic_id = -1; - - if (!madt) - return apic_id; - - entry = (unsigned long)madt; - madt_end = entry + madt->header.length; - - /* Parse all entries looking for a match. */ - - entry += sizeof(struct acpi_table_madt); - while (entry + sizeof(struct acpi_subtable_header) < madt_end) { - struct acpi_subtable_header *header = - (struct acpi_subtable_header *)entry; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - if (map_lapic_id(header, acpi_id, &apic_id)) - break; - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - if (map_lsapic_id(header, acpi_id, &apic_id)) - break; - } - entry += header->length; - } - return apic_id; -} - -static int map_mat_entry(acpi_handle handle, u32 acpi_id) -{ - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_subtable_header *header; - int apic_id = -1; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - goto exit; - - if (!buffer.length || !buffer.pointer) - goto exit; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER || - obj->buffer.length < sizeof(struct acpi_subtable_header)) { - goto exit; - } - - header = (struct acpi_subtable_header *)obj->buffer.pointer; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - map_lapic_id(header, acpi_id, &apic_id); - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - map_lsapic_id(header, acpi_id, &apic_id); - } - -exit: - if (buffer.pointer) - kfree(buffer.pointer); - return apic_id; -} - -static int get_cpu_id(acpi_handle handle, u32 acpi_id) +static int convert_acpiid_to_cpu(u8 acpi_id) { + u16 apic_id; int i; - int apic_id = -1; - apic_id = map_mat_entry(handle, acpi_id); - if (apic_id == -1) - apic_id = map_madt_entry(acpi_id); - if (apic_id == -1) - return apic_id; + apic_id = arch_acpiid_to_apicid[acpi_id]; + if (apic_id == ARCH_BAD_APICID) + return -1; - for (i = 0; i < NR_CPUS; ++i) { + for (i = 0; i < NR_CPUS; i++) { if (arch_cpu_to_apicid[i] == apic_id) return i; } @@ -506,7 +410,7 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id) Driver Interface -------------------------------------------------------------------------- */ -static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) +static int acpi_processor_get_info(struct acpi_processor *pr) { acpi_status status = 0; union acpi_object object = { 0 }; @@ -527,7 +431,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) * Check to see if we have bus mastering arbitration control. This * is required for proper C3 usage (to maintain cache coherency). */ - if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) { + if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) { pr->flags.bm_control = 1; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Bus mastering arbitration control present\n")); @@ -535,35 +439,24 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No bus mastering arbitration control\n")); - /* Check if it is a Device with HID and UID */ - if (has_uid) { - unsigned long value; - status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, - NULL, &value); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Evaluating processor _UID\n"); - return -ENODEV; - } - pr->acpi_id = value; - } else { - /* - * Evalute the processor object. Note that it is common on SMP to - * have the first (boot) processor with a valid PBLK address while - * all others have a NULL address. - */ - status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Evaluating processor object\n"); - return -ENODEV; - } - - /* - * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. - * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c - */ - pr->acpi_id = object.processor.proc_id; + /* + * Evalute the processor object. Note that it is common on SMP to + * have the first (boot) processor with a valid PBLK address while + * all others have a NULL address. + */ + status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Evaluating processor object\n"); + return -ENODEV; } - cpu_index = get_cpu_id(pr->handle, pr->acpi_id); + + /* + * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. + * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c + */ + pr->acpi_id = object.processor.proc_id; + + cpu_index = convert_acpiid_to_cpu(pr->acpi_id); /* Handle UP system running SMP kernel, with no LAPIC in MADT */ if (!cpu0_initialized && (cpu_index == -1) && @@ -580,7 +473,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) * less than the max # of CPUs. They should be ignored _iff * they are physically not present. */ - if (pr->id == -1) { + if (cpu_index == -1) { if (ACPI_FAILURE (acpi_processor_hotadd_init(pr->handle, &pr->id))) { return -ENODEV; @@ -597,8 +490,8 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) object.processor.pblk_length); else { pr->throttling.address = object.processor.pblk_address; - pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset; - pr->throttling.duty_width = acpi_gbl_FADT.duty_width; + pr->throttling.duty_offset = acpi_fadt.duty_offset; + pr->throttling.duty_width = acpi_fadt.duty_width; pr->pblk = object.processor.pblk_address; @@ -632,7 +525,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) pr = acpi_driver_data(device); - result = acpi_processor_get_info(pr, device->flags.unique_id); + result = acpi_processor_get_info(pr); if (result) { /* Processor is physically not present */ return 0; @@ -814,7 +707,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) return -ENODEV; if ((pr->id >= 0) && (pr->id < NR_CPUS)) { - kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); + kobject_uevent(&(*device)->kobj, KOBJ_ONLINE); } return 0; } @@ -852,13 +745,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) } if (pr->id >= 0 && (pr->id < NR_CPUS)) { - kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); + kobject_uevent(&device->kobj, KOBJ_OFFLINE); break; } result = acpi_processor_start(device); if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) { - kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); + kobject_uevent(&device->kobj, KOBJ_ONLINE); } else { printk(KERN_ERR PREFIX "Device [%s] failed to start\n", acpi_device_bid(device)); @@ -881,7 +774,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) } if ((pr->id < NR_CPUS) && (cpu_present(pr->id))) - kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); + kobject_uevent(&device->kobj, KOBJ_OFFLINE); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -1002,12 +895,6 @@ static int __init acpi_processor_init(void) memset(&processors, 0, sizeof(processors)); memset(&errata, 0, sizeof(errata)); -#ifdef CONFIG_SMP - if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, - (struct acpi_table_header **)&madt))) - madt = 0; -#endif - acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); if (!acpi_processor_dir) return -ENOMEM; diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 6c6751b1405b..3f30af21574e 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -160,7 +160,7 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2) { if (t2 >= t1) return (t2 - t1); - else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) + else if (!acpi_fadt.tmr_val_ext) return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); else return ((0xFFFFFFFF - t1) + t2); @@ -187,7 +187,8 @@ acpi_processor_power_activate(struct acpi_processor *pr, case ACPI_STATE_C3: /* Disable bus master reload */ if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, + ACPI_MTX_DO_NOT_LOCK); break; } } @@ -197,7 +198,8 @@ acpi_processor_power_activate(struct acpi_processor *pr, case ACPI_STATE_C3: /* Enable bus master reload */ if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, + ACPI_MTX_DO_NOT_LOCK); break; } @@ -234,7 +236,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) /* Dummy wait op - must do something useless after P_LVL2 read because chipsets cannot guarantee that STPCLK# signal gets asserted in time to freeze execution properly. */ - unused = inl(acpi_gbl_FADT.xpm_timer_block.address); + unused = inl(acpi_fadt.xpm_tmr_blk.address); } } @@ -289,10 +291,12 @@ static void acpi_processor_idle(void) pr->power.bm_activity <<= diff; - acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); + acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, + &bm_status, ACPI_MTX_DO_NOT_LOCK); if (bm_status) { pr->power.bm_activity |= 0x1; - acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); + acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, + 1, ACPI_MTX_DO_NOT_LOCK); } /* * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect @@ -334,7 +338,7 @@ static void acpi_processor_idle(void) * detection phase, to work cleanly with logical CPU hotplug. */ if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && - !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) + !pr->flags.has_cst && !acpi_fadt.plvl2_up) cx = &pr->power.states[ACPI_STATE_C1]; #endif @@ -380,11 +384,11 @@ static void acpi_processor_idle(void) case ACPI_STATE_C2: /* Get start time (ticks) */ - t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C2 */ acpi_cstate_enter(cx); /* Get end time (ticks) */ - t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); + t2 = inl(acpi_fadt.xpm_tmr_blk.address); #ifdef CONFIG_GENERIC_TIME /* TSC halts in C2, so notify users */ @@ -407,7 +411,8 @@ static void acpi_processor_idle(void) * All CPUs are trying to go to C3 * Disable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, + ACPI_MTX_DO_NOT_LOCK); } } else { /* SMP with no shared cache... Invalidate cache */ @@ -415,15 +420,16 @@ static void acpi_processor_idle(void) } /* Get start time (ticks) */ - t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C3 */ acpi_cstate_enter(cx); /* Get end time (ticks) */ - t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); + t2 = inl(acpi_fadt.xpm_tmr_blk.address); if (pr->flags.bm_check) { /* Enable bus master arbitration */ atomic_dec(&c3_cpu_count); - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, + ACPI_MTX_DO_NOT_LOCK); } #ifdef CONFIG_GENERIC_TIME @@ -451,7 +457,7 @@ static void acpi_processor_idle(void) #ifdef CONFIG_HOTPLUG_CPU /* Don't do promotion/demotion */ if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && - !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) { + !pr->flags.has_cst && !acpi_fadt.plvl2_up) { next_state = cx; goto end; } @@ -621,8 +627,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) * Check for P_LVL2_UP flag before entering C2 and above on * an SMP system. */ - if ((num_online_cpus() > 1) && - !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) + if ((num_online_cpus() > 1) && !acpi_fadt.plvl2_up) return -ENODEV; #endif @@ -631,8 +636,8 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5; /* determine latencies from FADT */ - pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency; - pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency; + pr->power.states[ACPI_STATE_C2].latency = acpi_fadt.plvl2_lat; + pr->power.states[ACPI_STATE_C3].latency = acpi_fadt.plvl3_lat; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "lvl2[0x%08x] lvl3[0x%08x]\n", @@ -878,13 +883,14 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, * WBINVD should be set in fadt, for C3 state to be * supported on when bm_check is not required. */ - if (!(acpi_gbl_FADT.flags & ACPI_FADT_WBINVD)) { + if (acpi_fadt.wb_invd != 1) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cache invalidation should work properly" " for C3 to be enabled on SMP systems\n")); return; } - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, + 0, ACPI_MTX_DO_NOT_LOCK); } /* @@ -1090,7 +1096,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", pr->power.states[i].latency, pr->power.states[i].usage, - (unsigned long long)pr->power.states[i].time); + pr->power.states[i].time); } end: @@ -1158,9 +1164,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, if (!pr) return -EINVAL; - if (acpi_gbl_FADT.cst_control && !nocst) { + if (acpi_fadt.cst_cnt && !nocst) { status = - acpi_os_write_port(acpi_gbl_FADT.smi_command, acpi_gbl_FADT.cst_control, 8); + acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Notifying BIOS of _CST ability failed")); diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index 058f13cf3b79..cbb6f0814ce2 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -352,24 +352,31 @@ int acpi_processor_notify_smm(struct module *calling_module) is_done = -EIO; - /* Can't write pstate_control to smi_command if either value is zero */ - if ((!acpi_gbl_FADT.smi_command) || (!acpi_gbl_FADT.pstate_control)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_control\n")); + /* Can't write pstate_cnt to smi_cmd if either value is zero */ + if ((!acpi_fadt.smi_cmd) || (!acpi_fadt.pstate_cnt)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_cnt\n")); module_put(calling_module); return 0; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Writing pstate_control [0x%x] to smi_command [0x%x]\n", - acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command)); + "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n", + acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd)); - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, - (u32) acpi_gbl_FADT.pstate_control, 8); + /* FADT v1 doesn't support pstate_cnt, many BIOS vendors use + * it anyway, so we need to support it... */ + if (acpi_fadt_is_v1) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Using v1.0 FADT reserved value for pstate_cnt\n")); + } + + status = acpi_os_write_port(acpi_fadt.smi_cmd, + (u32) acpi_fadt.pstate_cnt, 8); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, - "Failed to write pstate_control [0x%x] to " - "smi_command [0x%x]", acpi_gbl_FADT.pstate_control, - acpi_gbl_FADT.smi_command)); + "Failed to write pstate_cnt [0x%x] to " + "smi_cmd [0x%x]", acpi_fadt.pstate_cnt, + acpi_fadt.smi_cmd)); module_put(calling_module); return status; } diff --git a/trunk/drivers/acpi/processor_throttling.c b/trunk/drivers/acpi/processor_throttling.c index 89dff3639abe..0ec7dcde0063 100644 --- a/trunk/drivers/acpi/processor_throttling.c +++ b/trunk/drivers/acpi/processor_throttling.c @@ -125,7 +125,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) /* Used to clear all duty_value bits */ duty_mask = pr->throttling.state_count - 1; - duty_mask <<= acpi_gbl_FADT.duty_offset; + duty_mask <<= acpi_fadt.duty_offset; duty_mask = ~duty_mask; } @@ -208,7 +208,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) return 0; } - pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width; + pr->throttling.state_count = 1 << acpi_fadt.duty_width; /* * Compute state values. Note that throttling displays a linear power/ diff --git a/trunk/drivers/acpi/resources/rsaddr.c b/trunk/drivers/acpi/resources/rsaddr.c index 271e61509eeb..8fa3213ce000 100644 --- a/trunk/drivers/acpi/resources/rsaddr.c +++ b/trunk/drivers/acpi/resources/rsaddr.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rscalc.c b/trunk/drivers/acpi/resources/rscalc.c index 8c6d3fdec38a..cf87b0230026 100644 --- a/trunk/drivers/acpi/resources/rscalc.c +++ b/trunk/drivers/acpi/resources/rscalc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rscreate.c b/trunk/drivers/acpi/resources/rscreate.c index 1358c06a969c..008058acdd39 100644 --- a/trunk/drivers/acpi/resources/rscreate.c +++ b/trunk/drivers/acpi/resources/rscreate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsdump.c b/trunk/drivers/acpi/resources/rsdump.c index de20a5d6decf..9c99a723a860 100644 --- a/trunk/drivers/acpi/resources/rsdump.c +++ b/trunk/drivers/acpi/resources/rsdump.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsinfo.c b/trunk/drivers/acpi/resources/rsinfo.c index 7e3c335ab320..9e7ae2f8a1d3 100644 --- a/trunk/drivers/acpi/resources/rsinfo.c +++ b/trunk/drivers/acpi/resources/rsinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsio.c b/trunk/drivers/acpi/resources/rsio.c index b297bc3e4419..ea567167c4f2 100644 --- a/trunk/drivers/acpi/resources/rsio.c +++ b/trunk/drivers/acpi/resources/rsio.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsirq.c b/trunk/drivers/acpi/resources/rsirq.c index 5657f7b95039..1fa63bc2e36f 100644 --- a/trunk/drivers/acpi/resources/rsirq.c +++ b/trunk/drivers/acpi/resources/rsirq.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rslist.c b/trunk/drivers/acpi/resources/rslist.c index a92755c8877d..29423ce030ca 100644 --- a/trunk/drivers/acpi/resources/rslist.c +++ b/trunk/drivers/acpi/resources/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsmemory.c b/trunk/drivers/acpi/resources/rsmemory.c index 521eab7dd8df..a5131936d690 100644 --- a/trunk/drivers/acpi/resources/rsmemory.c +++ b/trunk/drivers/acpi/resources/rsmemory.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsmisc.c b/trunk/drivers/acpi/resources/rsmisc.c index 3b63b561b94e..faf6e106b785 100644 --- a/trunk/drivers/acpi/resources/rsmisc.c +++ b/trunk/drivers/acpi/resources/rsmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsutils.c b/trunk/drivers/acpi/resources/rsutils.c index 2442a8f8df57..a9cbee8e8b44 100644 --- a/trunk/drivers/acpi/resources/rsutils.c +++ b/trunk/drivers/acpi/resources/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsxface.c b/trunk/drivers/acpi/resources/rsxface.c index 991f8901498c..1999e2ab7daa 100644 --- a/trunk/drivers/acpi/resources/rsxface.c +++ b/trunk/drivers/acpi/resources/rsxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 64f26db10c8e..283d87522c5d 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -21,305 +21,101 @@ extern struct acpi_device *acpi_root; #define ACPI_BUS_DEVICE_NAME "System Bus" static LIST_HEAD(acpi_device_list); -static LIST_HEAD(acpi_bus_id_list); DEFINE_SPINLOCK(acpi_device_lock); LIST_HEAD(acpi_wakeup_device_list); -struct acpi_device_bus_id{ - char bus_id[15]; - unsigned int instance_no; - struct list_head node; -}; -static int acpi_eject_operation(acpi_handle handle, int lockable) -{ - struct acpi_object_list arg_list; - union acpi_object arg; - acpi_status status = AE_OK; - - /* - * TBD: evaluate _PS3? - */ - - if (lockable) { - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 0; - acpi_evaluate_object(handle, "_LCK", &arg_list, NULL); - } - - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 1; - - /* - * TBD: _EJD support. - */ - - status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); - if (ACPI_FAILURE(status)) { - return (-ENODEV); - } - - return (0); -} -static ssize_t -acpi_eject_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t count) +static void acpi_device_release(struct kobject *kobj) { - int result; - int ret = count; - int islockable; - acpi_status status; - acpi_handle handle; - acpi_object_type type = 0; - struct acpi_device *acpi_device = to_acpi_device(d); - - if ((!count) || (buf[0] != '1')) { - return -EINVAL; - } -#ifndef FORCE_EJECT - if (acpi_device->driver == NULL) { - ret = -ENODEV; - goto err; - } -#endif - status = acpi_get_type(acpi_device->handle, &type); - if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) { - ret = -ENODEV; - goto err; - } - - islockable = acpi_device->flags.lockable; - handle = acpi_device->handle; - - result = acpi_bus_trim(acpi_device, 1); - - if (!result) - result = acpi_eject_operation(handle, islockable); - - if (result) { - ret = -EBUSY; - } - err: - return ret; -} - -static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); - -static ssize_t -acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - - return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id); + struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj); + kfree(dev->pnp.cid_list); + kfree(dev); } -static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); -static ssize_t -acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; - int result; - - result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); - if(result) - goto end; +struct acpi_device_attribute { + struct attribute attr; + ssize_t(*show) (struct acpi_device *, char *); + ssize_t(*store) (struct acpi_device *, const char *, size_t); +}; - result = sprintf(buf, "%s\n", (char*)path.pointer); - kfree(path.pointer); - end: - return result; -} -static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); +typedef void acpi_device_sysfs_files(struct kobject *, + const struct attribute *); -static int acpi_device_setup_files(struct acpi_device *dev) -{ - acpi_status status; - acpi_handle temp; - int result = 0; +static void setup_sys_fs_device_files(struct acpi_device *dev, + acpi_device_sysfs_files * func); - /* - * Devices gotten from FADT don't have a "path" attribute - */ - if(dev->handle) { - result = device_create_file(&dev->dev, &dev_attr_path); - if(result) - goto end; - } +#define create_sysfs_device_files(dev) \ + setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file) +#define remove_sysfs_device_files(dev) \ + setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file) - if(dev->flags.hardware_id) { - result = device_create_file(&dev->dev, &dev_attr_hid); - if(result) - goto end; - } +#define to_acpi_device(n) container_of(n, struct acpi_device, kobj) +#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr); - /* - * If device has _EJ0, 'eject' file is created that is used to trigger - * hot-removal function from userland. - */ - status = acpi_get_handle(dev->handle, "_EJ0", &temp); - if (ACPI_SUCCESS(status)) - result = device_create_file(&dev->dev, &dev_attr_eject); - end: - return result; -} - -static void acpi_device_remove_files(struct acpi_device *dev) +static ssize_t acpi_device_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) { - acpi_status status; - acpi_handle temp; - - /* - * If device has _EJ0, 'eject' file is created that is used to trigger - * hot-removal function from userland. - */ - status = acpi_get_handle(dev->handle, "_EJ0", &temp); - if (ACPI_SUCCESS(status)) - device_remove_file(&dev->dev, &dev_attr_eject); - - if(dev->flags.hardware_id) - device_remove_file(&dev->dev, &dev_attr_hid); - if(dev->handle) - device_remove_file(&dev->dev, &dev_attr_path); + struct acpi_device *device = to_acpi_device(kobj); + struct acpi_device_attribute *attribute = to_handle_attr(attr); + return attribute->show ? attribute->show(device, buf) : -EIO; } -/* -------------------------------------------------------------------------- - ACPI Bus operations - -------------------------------------------------------------------------- */ -static void acpi_device_release(struct device *dev) +static ssize_t acpi_device_attr_store(struct kobject *kobj, + struct attribute *attr, const char *buf, + size_t len) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - - kfree(acpi_dev->pnp.cid_list); - kfree(acpi_dev); + struct acpi_device *device = to_acpi_device(kobj); + struct acpi_device_attribute *attribute = to_handle_attr(attr); + return attribute->store ? attribute->store(device, buf, len) : -EIO; } -static int acpi_device_suspend(struct device *dev, pm_message_t state) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = acpi_dev->driver; - - if (acpi_drv && acpi_drv->ops.suspend) - return acpi_drv->ops.suspend(acpi_dev, state); - return 0; -} - -static int acpi_device_resume(struct device *dev) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = acpi_dev->driver; +static struct sysfs_ops acpi_device_sysfs_ops = { + .show = acpi_device_attr_show, + .store = acpi_device_attr_store, +}; - if (acpi_drv && acpi_drv->ops.resume) - return acpi_drv->ops.resume(acpi_dev); - return 0; -} +static struct kobj_type ktype_acpi_ns = { + .sysfs_ops = &acpi_device_sysfs_ops, + .release = acpi_device_release, +}; -static int acpi_bus_match(struct device *dev, struct device_driver *drv) +static int namespace_uevent(struct kset *kset, struct kobject *kobj, + char **envp, int num_envp, char *buffer, + int buffer_size) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = to_acpi_driver(drv); + struct acpi_device *dev = to_acpi_device(kobj); + int i = 0; + int len = 0; - return !acpi_match_ids(acpi_dev, acpi_drv->ids); -} + if (!dev->driver) + return 0; -static int acpi_device_uevent(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - int i = 0, length = 0, ret = 0; - - if (acpi_dev->flags.hardware_id) - ret = add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "HWID=%s", acpi_dev->pnp.hardware_id); - if (ret) + if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, + "PHYSDEVDRIVER=%s", dev->driver->name)) return -ENOMEM; - if (acpi_dev->flags.compatible_ids) { - int j; - struct acpi_compatible_id_list *cid_list; - - cid_list = acpi_dev->pnp.cid_list; - - for (j = 0; j < cid_list->count; j++) { - ret = add_uevent_var(envp, num_envp, &i, buffer, - buffer_size, &length, "COMPTID=%s", - cid_list->id[j].value); - if (ret) - return -ENOMEM; - } - } envp[i] = NULL; - return 0; -} -static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *); -static int acpi_start_single_object(struct acpi_device *); -static int acpi_device_probe(struct device * dev) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); - int ret; - - ret = acpi_bus_driver_init(acpi_dev, acpi_drv); - if (!ret) { - if (acpi_dev->bus_ops.acpi_op_start) - acpi_start_single_object(acpi_dev); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Found driver [%s] for device [%s]\n", - acpi_drv->name, acpi_dev->pnp.bus_id)); - get_device(dev); - } - return ret; -} - -static int acpi_device_remove(struct device * dev) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = acpi_dev->driver; - - if (acpi_drv) { - if (acpi_drv->ops.stop) - acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type); - if (acpi_drv->ops.remove) - acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); - } - acpi_dev->driver = NULL; - acpi_driver_data(dev) = NULL; - - put_device(dev); return 0; } -static void acpi_device_shutdown(struct device *dev) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = acpi_dev->driver; - - if (acpi_drv && acpi_drv->ops.shutdown) - acpi_drv->ops.shutdown(acpi_dev); - - return ; -} +static struct kset_uevent_ops namespace_uevent_ops = { + .uevent = &namespace_uevent, +}; -static struct bus_type acpi_bus_type = { - .name = "acpi", - .suspend = acpi_device_suspend, - .resume = acpi_device_resume, - .shutdown = acpi_device_shutdown, - .match = acpi_bus_match, - .probe = acpi_device_probe, - .remove = acpi_device_remove, - .uevent = acpi_device_uevent, +static struct kset acpi_namespace_kset = { + .kobj = { + .name = "namespace", + }, + .subsys = &acpi_subsys, + .ktype = &ktype_acpi_ns, + .uevent_ops = &namespace_uevent_ops, }; -static int acpi_device_register(struct acpi_device *device, +static void acpi_device_register(struct acpi_device *device, struct acpi_device *parent) { - int result; - struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; - int found = 0; + int err; + /* * Linkage * ------- @@ -330,33 +126,7 @@ static int acpi_device_register(struct acpi_device *device, INIT_LIST_HEAD(&device->g_list); INIT_LIST_HEAD(&device->wakeup_list); - new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); - if (!new_bus_id) { - printk(KERN_ERR PREFIX "Memory allocation error\n"); - return -ENOMEM; - } - spin_lock(&acpi_device_lock); - /* - * Find suitable bus_id and instance number in acpi_bus_id_list - * If failed, create one and link it into acpi_bus_id_list - */ - list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { - if(!strcmp(acpi_device_bus_id->bus_id, device->flags.hardware_id? device->pnp.hardware_id : "device")) { - acpi_device_bus_id->instance_no ++; - found = 1; - kfree(new_bus_id); - break; - } - } - if(!found) { - acpi_device_bus_id = new_bus_id; - strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device"); - acpi_device_bus_id->instance_no = 0; - list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); - } - sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); - if (device->parent) { list_add_tail(&device->node, &device->parent->children); list_add_tail(&device->g_list, &device->parent->g_list); @@ -366,33 +136,16 @@ static int acpi_device_register(struct acpi_device *device, list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); spin_unlock(&acpi_device_lock); - if (device->parent) - device->dev.parent = &parent->dev; - device->dev.bus = &acpi_bus_type; - device_initialize(&device->dev); - device->dev.release = &acpi_device_release; - result = device_add(&device->dev); - if(result) { - printk("Error adding device %s", device->dev.bus_id); - goto end; - } - - result = acpi_device_setup_files(device); - if(result) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id)); - - device->removal_type = ACPI_BUS_REMOVAL_NORMAL; - return 0; - end: - spin_lock(&acpi_device_lock); - if (device->parent) { - list_del(&device->node); - list_del(&device->g_list); - } else - list_del(&device->g_list); - list_del(&device->wakeup_list); - spin_unlock(&acpi_device_lock); - return result; + strlcpy(device->kobj.name, device->pnp.bus_id, KOBJ_NAME_LEN); + if (parent) + device->kobj.parent = &parent->kobj; + device->kobj.ktype = &ktype_acpi_ns; + device->kobj.kset = &acpi_namespace_kset; + err = kobject_register(&device->kobj); + if (err < 0) + printk(KERN_WARNING "%s: kobject_register error: %d\n", + __FUNCTION__, err); + create_sysfs_device_files(device); } static void acpi_device_unregister(struct acpi_device *device, int type) @@ -405,143 +158,81 @@ static void acpi_device_unregister(struct acpi_device *device, int type) list_del(&device->g_list); list_del(&device->wakeup_list); + spin_unlock(&acpi_device_lock); acpi_detach_data(device->handle, acpi_bus_data_handler); - - acpi_device_remove_files(device); - device_unregister(&device->dev); -} - -/* -------------------------------------------------------------------------- - Driver Management - -------------------------------------------------------------------------- */ -/** - * acpi_bus_driver_init - add a device to a driver - * @device: the device to add and initialize - * @driver: driver for the device - * - * Used to initialize a device via its device driver. Called whenever a - * driver is bound to a device. Invokes the driver's add() ops. - */ -static int -acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) -{ - int result = 0; - - - if (!device || !driver) - return -EINVAL; - - if (!driver->ops.add) - return -ENOSYS; - - result = driver->ops.add(device); - if (result) { - device->driver = NULL; - acpi_driver_data(device) = NULL; - return result; - } - - device->driver = driver; - - /* - * TBD - Configuration Management: Assign resources to device based - * upon possible configuration and currently allocated resources. - */ - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Driver successfully bound to device\n")); - return 0; + remove_sysfs_device_files(device); + kobject_unregister(&device->kobj); } -static int acpi_start_single_object(struct acpi_device *device) +void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) { - int result = 0; - struct acpi_driver *driver; - - - if (!(driver = device->driver)) - return 0; - if (driver->ops.start) { - result = driver->ops.start(device); - if (result && driver->ops.remove) - driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); - } + /* TBD */ - return result; + return; } -/** - * acpi_bus_register_driver - register a driver with the ACPI bus - * @driver: driver being registered - * - * Registers a driver with the ACPI bus. Searches the namespace for all - * devices that match the driver's criteria and binds. Returns zero for - * success or a negative error status for failure. - */ -int acpi_bus_register_driver(struct acpi_driver *driver) +static int acpi_bus_get_power_flags(struct acpi_device *device) { - int ret; - - if (acpi_disabled) - return -ENODEV; - driver->drv.name = driver->name; - driver->drv.bus = &acpi_bus_type; - driver->drv.owner = driver->owner; + acpi_status status = 0; + acpi_handle handle = NULL; + u32 i = 0; - ret = driver_register(&driver->drv); - return ret; -} -EXPORT_SYMBOL(acpi_bus_register_driver); + /* + * Power Management Flags + */ + status = acpi_get_handle(device->handle, "_PSC", &handle); + if (ACPI_SUCCESS(status)) + device->power.flags.explicit_get = 1; + status = acpi_get_handle(device->handle, "_IRC", &handle); + if (ACPI_SUCCESS(status)) + device->power.flags.inrush_current = 1; -/** - * acpi_bus_unregister_driver - unregisters a driver with the APIC bus - * @driver: driver to unregister - * - * Unregisters a driver with the ACPI bus. Searches the namespace for all - * devices that match the driver's criteria and unbinds. - */ -void acpi_bus_unregister_driver(struct acpi_driver *driver) -{ - driver_unregister(&driver->drv); -} + /* + * Enumerate supported power management states + */ + for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { + struct acpi_device_power_state *ps = &device->power.states[i]; + char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; -EXPORT_SYMBOL(acpi_bus_unregister_driver); + /* Evaluate "_PRx" to se if power resources are referenced */ + acpi_evaluate_reference(device->handle, object_name, NULL, + &ps->resources); + if (ps->resources.count) { + device->power.flags.power_resources = 1; + ps->flags.valid = 1; + } -/* -------------------------------------------------------------------------- - Device Enumeration - -------------------------------------------------------------------------- */ -acpi_status -acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) -{ - acpi_status status; - acpi_handle tmp; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object *obj; + /* Evaluate "_PSx" to see if we can do explicit sets */ + object_name[2] = 'S'; + status = acpi_get_handle(device->handle, object_name, &handle); + if (ACPI_SUCCESS(status)) { + ps->flags.explicit_set = 1; + ps->flags.valid = 1; + } - status = acpi_get_handle(handle, "_EJD", &tmp); - if (ACPI_FAILURE(status)) - return status; + /* State is valid if we have some power control */ + if (ps->resources.count || ps->flags.explicit_set) + ps->flags.valid = 1; - status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); - if (ACPI_SUCCESS(status)) { - obj = buffer.pointer; - status = acpi_get_handle(NULL, obj->string.pointer, ejd); - kfree(buffer.pointer); + ps->power = -1; /* Unknown - driver assigned */ + ps->latency = -1; /* Unknown - driver assigned */ } - return status; -} -EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); -void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) -{ + /* Set defaults for D0 and D3 states (always valid) */ + device->power.states[ACPI_STATE_D0].flags.valid = 1; + device->power.states[ACPI_STATE_D0].power = 100; + device->power.states[ACPI_STATE_D3].flags.valid = 1; + device->power.states[ACPI_STATE_D3].power = 0; - /* TBD */ + /* TBD: System wake support and resource requirements. */ - return; + device->power.state = ACPI_STATE_UNKNOWN; + + return 0; } int acpi_match_ids(struct acpi_device *device, char *ids) @@ -563,12 +254,6 @@ int acpi_match_ids(struct acpi_device *device, char *ids) return -ENOENT; } -static int acpi_bus_get_perf_flags(struct acpi_device *device) -{ - device->performance.state = ACPI_STATE_UNKNOWN; - return 0; -} - static acpi_status acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, union acpi_object *package) @@ -647,72 +332,365 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E")) device->wakeup.flags.run_wake = 1; - end: - if (ACPI_FAILURE(status)) - device->flags.wake_capable = 0; + end: + if (ACPI_FAILURE(status)) + device->flags.wake_capable = 0; + return 0; +} + +/* -------------------------------------------------------------------------- + ACPI sysfs device file support + -------------------------------------------------------------------------- */ +static ssize_t acpi_eject_store(struct acpi_device *device, + const char *buf, size_t count); + +#define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \ +static struct acpi_device_attribute acpi_device_attr_##_name = \ + __ATTR(_name, _mode, _show, _store) + +ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); + +/** + * setup_sys_fs_device_files - sets up the device files under device namespace + * @dev: acpi_device object + * @func: function pointer to create or destroy the device file + */ +static void +setup_sys_fs_device_files(struct acpi_device *dev, + acpi_device_sysfs_files * func) +{ + acpi_status status; + acpi_handle temp = NULL; + + /* + * If device has _EJ0, 'eject' file is created that is used to trigger + * hot-removal function from userland. + */ + status = acpi_get_handle(dev->handle, "_EJ0", &temp); + if (ACPI_SUCCESS(status)) + (*(func)) (&dev->kobj, &acpi_device_attr_eject.attr); +} + +static int acpi_eject_operation(acpi_handle handle, int lockable) +{ + struct acpi_object_list arg_list; + union acpi_object arg; + acpi_status status = AE_OK; + + /* + * TBD: evaluate _PS3? + */ + + if (lockable) { + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = 0; + acpi_evaluate_object(handle, "_LCK", &arg_list, NULL); + } + + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = 1; + + /* + * TBD: _EJD support. + */ + + status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); + if (ACPI_FAILURE(status)) { + return (-ENODEV); + } + + return (0); +} + +static ssize_t +acpi_eject_store(struct acpi_device *device, const char *buf, size_t count) +{ + int result; + int ret = count; + int islockable; + acpi_status status; + acpi_handle handle; + acpi_object_type type = 0; + + if ((!count) || (buf[0] != '1')) { + return -EINVAL; + } +#ifndef FORCE_EJECT + if (device->driver == NULL) { + ret = -ENODEV; + goto err; + } +#endif + status = acpi_get_type(device->handle, &type); + if (ACPI_FAILURE(status) || (!device->flags.ejectable)) { + ret = -ENODEV; + goto err; + } + + islockable = device->flags.lockable; + handle = device->handle; + + result = acpi_bus_trim(device, 1); + + if (!result) + result = acpi_eject_operation(handle, islockable); + + if (result) { + ret = -EBUSY; + } + err: + return ret; +} + +/* -------------------------------------------------------------------------- + Performance Management + -------------------------------------------------------------------------- */ + +static int acpi_bus_get_perf_flags(struct acpi_device *device) +{ + device->performance.state = ACPI_STATE_UNKNOWN; + return 0; +} + +/* -------------------------------------------------------------------------- + Driver Management + -------------------------------------------------------------------------- */ + +static LIST_HEAD(acpi_bus_drivers); + +/** + * acpi_bus_match - match device IDs to driver's supported IDs + * @device: the device that we are trying to match to a driver + * @driver: driver whose device id table is being checked + * + * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it + * matches the specified driver's criteria. + */ +static int +acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver) +{ + if (driver && driver->ops.match) + return driver->ops.match(device, driver); + return acpi_match_ids(device, driver->ids); +} + +/** + * acpi_bus_driver_init - add a device to a driver + * @device: the device to add and initialize + * @driver: driver for the device + * + * Used to initialize a device via its device driver. Called whenever a + * driver is bound to a device. Invokes the driver's add() and start() ops. + */ +static int +acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) +{ + int result = 0; + + + if (!device || !driver) + return -EINVAL; + + if (!driver->ops.add) + return -ENOSYS; + + result = driver->ops.add(device); + if (result) { + device->driver = NULL; + acpi_driver_data(device) = NULL; + return result; + } + + device->driver = driver; + + /* + * TBD - Configuration Management: Assign resources to device based + * upon possible configuration and currently allocated resources. + */ + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Driver successfully bound to device\n")); + return 0; +} + +static int acpi_start_single_object(struct acpi_device *device) +{ + int result = 0; + struct acpi_driver *driver; + + + if (!(driver = device->driver)) + return 0; + + if (driver->ops.start) { + result = driver->ops.start(device); + if (result && driver->ops.remove) + driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); + } + + return result; +} + +static void acpi_driver_attach(struct acpi_driver *drv) +{ + struct list_head *node, *next; + + + spin_lock(&acpi_device_lock); + list_for_each_safe(node, next, &acpi_device_list) { + struct acpi_device *dev = + container_of(node, struct acpi_device, g_list); + + if (dev->driver || !dev->status.present) + continue; + spin_unlock(&acpi_device_lock); + + if (!acpi_bus_match(dev, drv)) { + if (!acpi_bus_driver_init(dev, drv)) { + acpi_start_single_object(dev); + atomic_inc(&drv->references); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Found driver [%s] for device [%s]\n", + drv->name, dev->pnp.bus_id)); + } + } + spin_lock(&acpi_device_lock); + } + spin_unlock(&acpi_device_lock); +} + +static void acpi_driver_detach(struct acpi_driver *drv) +{ + struct list_head *node, *next; + + + spin_lock(&acpi_device_lock); + list_for_each_safe(node, next, &acpi_device_list) { + struct acpi_device *dev = + container_of(node, struct acpi_device, g_list); + + if (dev->driver == drv) { + spin_unlock(&acpi_device_lock); + if (drv->ops.remove) + drv->ops.remove(dev, ACPI_BUS_REMOVAL_NORMAL); + spin_lock(&acpi_device_lock); + dev->driver = NULL; + dev->driver_data = NULL; + atomic_dec(&drv->references); + } + } + spin_unlock(&acpi_device_lock); +} + +/** + * acpi_bus_register_driver - register a driver with the ACPI bus + * @driver: driver being registered + * + * Registers a driver with the ACPI bus. Searches the namespace for all + * devices that match the driver's criteria and binds. Returns zero for + * success or a negative error status for failure. + */ +int acpi_bus_register_driver(struct acpi_driver *driver) +{ + + if (acpi_disabled) + return -ENODEV; + + spin_lock(&acpi_device_lock); + list_add_tail(&driver->node, &acpi_bus_drivers); + spin_unlock(&acpi_device_lock); + acpi_driver_attach(driver); + return 0; } -static int acpi_bus_get_power_flags(struct acpi_device *device) +EXPORT_SYMBOL(acpi_bus_register_driver); + +/** + * acpi_bus_unregister_driver - unregisters a driver with the APIC bus + * @driver: driver to unregister + * + * Unregisters a driver with the ACPI bus. Searches the namespace for all + * devices that match the driver's criteria and unbinds. + */ +void acpi_bus_unregister_driver(struct acpi_driver *driver) { - acpi_status status = 0; - acpi_handle handle = NULL; - u32 i = 0; + acpi_driver_detach(driver); + if (!atomic_read(&driver->references)) { + spin_lock(&acpi_device_lock); + list_del_init(&driver->node); + spin_unlock(&acpi_device_lock); + } + return; +} - /* - * Power Management Flags - */ - status = acpi_get_handle(device->handle, "_PSC", &handle); - if (ACPI_SUCCESS(status)) - device->power.flags.explicit_get = 1; - status = acpi_get_handle(device->handle, "_IRC", &handle); - if (ACPI_SUCCESS(status)) - device->power.flags.inrush_current = 1; +EXPORT_SYMBOL(acpi_bus_unregister_driver); - /* - * Enumerate supported power management states - */ - for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { - struct acpi_device_power_state *ps = &device->power.states[i]; - char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; +/** + * acpi_bus_find_driver - check if there is a driver installed for the device + * @device: device that we are trying to find a supporting driver for + * + * Parses the list of registered drivers looking for a driver applicable for + * the specified device. + */ +static int acpi_bus_find_driver(struct acpi_device *device) +{ + int result = 0; + struct list_head *node, *next; - /* Evaluate "_PRx" to se if power resources are referenced */ - acpi_evaluate_reference(device->handle, object_name, NULL, - &ps->resources); - if (ps->resources.count) { - device->power.flags.power_resources = 1; - ps->flags.valid = 1; - } - /* Evaluate "_PSx" to see if we can do explicit sets */ - object_name[2] = 'S'; - status = acpi_get_handle(device->handle, object_name, &handle); - if (ACPI_SUCCESS(status)) { - ps->flags.explicit_set = 1; - ps->flags.valid = 1; + spin_lock(&acpi_device_lock); + list_for_each_safe(node, next, &acpi_bus_drivers) { + struct acpi_driver *driver = + container_of(node, struct acpi_driver, node); + + atomic_inc(&driver->references); + spin_unlock(&acpi_device_lock); + if (!acpi_bus_match(device, driver)) { + result = acpi_bus_driver_init(device, driver); + if (!result) + goto Done; } - - /* State is valid if we have some power control */ - if (ps->resources.count || ps->flags.explicit_set) - ps->flags.valid = 1; - - ps->power = -1; /* Unknown - driver assigned */ - ps->latency = -1; /* Unknown - driver assigned */ + atomic_dec(&driver->references); + spin_lock(&acpi_device_lock); } + spin_unlock(&acpi_device_lock); - /* Set defaults for D0 and D3 states (always valid) */ - device->power.states[ACPI_STATE_D0].flags.valid = 1; - device->power.states[ACPI_STATE_D0].power = 100; - device->power.states[ACPI_STATE_D3].flags.valid = 1; - device->power.states[ACPI_STATE_D3].power = 0; + Done: + return result; +} - /* TBD: System wake support and resource requirements. */ +/* -------------------------------------------------------------------------- + Device Enumeration + -------------------------------------------------------------------------- */ - device->power.state = ACPI_STATE_UNKNOWN; +acpi_status +acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) +{ + acpi_status status; + acpi_handle tmp; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *obj; - return 0; + status = acpi_get_handle(handle, "_EJD", &tmp); + if (ACPI_FAILURE(status)) + return status; + + status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); + if (ACPI_SUCCESS(status)) { + obj = buffer.pointer; + status = acpi_get_handle(NULL, obj->string.pointer, ejd); + kfree(buffer.pointer); + } + return status; } +EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); + static int acpi_bus_get_flags(struct acpi_device *device) { @@ -804,75 +782,6 @@ static void acpi_device_get_busid(struct acpi_device *device, } } -static int -acpi_video_bus_match(struct acpi_device *device) -{ - acpi_handle h_dummy1; - acpi_handle h_dummy2; - acpi_handle h_dummy3; - - - if (!device) - return -EINVAL; - - /* Since there is no HID, CID for ACPI Video drivers, we have - * to check well known required nodes for each feature we support. - */ - - /* Does this device able to support video switching ? */ - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) && - ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2))) - return 0; - - /* Does this device able to retrieve a video ROM ? */ - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1))) - return 0; - - /* Does this device able to configure which video head to be POSTed ? */ - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) && - ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) && - ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3))) - return 0; - - return -ENODEV; -} - -/* - * acpi_bay_match - see if a device is an ejectable driver bay - * - * If an acpi object is ejectable and has one of the ACPI ATA methods defined, - * then we can safely call it an ejectable drive bay - */ -static int acpi_bay_match(struct acpi_device *device){ - acpi_status status; - acpi_handle handle; - acpi_handle tmp; - acpi_handle phandle; - - handle = device->handle; - - status = acpi_get_handle(handle, "_EJ0", &tmp); - if (ACPI_FAILURE(status)) - return -ENODEV; - - if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) - return 0; - - if (acpi_get_parent(handle, &phandle)) - return -ENODEV; - - if ((ACPI_SUCCESS(acpi_get_handle(phandle, "_GTF", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(phandle, "_GTM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(phandle, "_STM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(phandle, "_SDD", &tmp)))) - return 0; - - return -ENODEV; -} - static void acpi_device_set_id(struct acpi_device *device, struct acpi_device *parent, acpi_handle handle, int type) @@ -903,16 +812,6 @@ static void acpi_device_set_id(struct acpi_device *device, device->pnp.bus_address = info->address; device->flags.bus_address = 1; } - - if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){ - status = acpi_video_bus_match(device); - if(ACPI_SUCCESS(status)) - hid = ACPI_VIDEO_HID; - - status = acpi_bay_match(device); - if (ACPI_SUCCESS(status)) - hid = ACPI_BAY_HID; - } break; case ACPI_BUS_TYPE_POWER: hid = ACPI_POWER_HID; @@ -989,24 +888,86 @@ static int acpi_device_set_context(struct acpi_device *device, int type) return result; } +static void acpi_device_get_debug_info(struct acpi_device *device, + acpi_handle handle, int type) +{ +#ifdef CONFIG_ACPI_DEBUG_OUTPUT + char *type_string = NULL; + char name[80] = { '?', '\0' }; + struct acpi_buffer buffer = { sizeof(name), name }; + + switch (type) { + case ACPI_BUS_TYPE_DEVICE: + type_string = "Device"; + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + break; + case ACPI_BUS_TYPE_POWER: + type_string = "Power Resource"; + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + break; + case ACPI_BUS_TYPE_PROCESSOR: + type_string = "Processor"; + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + break; + case ACPI_BUS_TYPE_SYSTEM: + type_string = "System"; + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + break; + case ACPI_BUS_TYPE_THERMAL: + type_string = "Thermal Zone"; + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + break; + case ACPI_BUS_TYPE_POWER_BUTTON: + type_string = "Power Button"; + sprintf(name, "PWRB"); + break; + case ACPI_BUS_TYPE_SLEEP_BUTTON: + type_string = "Sleep Button"; + sprintf(name, "SLPB"); + break; + } + + printk(KERN_DEBUG "Found %s %s [%p]\n", type_string, name, handle); +#endif /*CONFIG_ACPI_DEBUG_OUTPUT */ +} + static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) { + int result = 0; + struct acpi_driver *driver; + + if (!dev) return -EINVAL; - dev->removal_type = ACPI_BUS_REMOVAL_EJECT; - device_release_driver(&dev->dev); + driver = dev->driver; + + if ((driver) && (driver->ops.remove)) { + + if (driver->ops.stop) { + result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT); + if (result) + return result; + } + + result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT); + if (result) { + return result; + } + + atomic_dec(&dev->driver->references); + dev->driver = NULL; + acpi_driver_data(dev) = NULL; + } if (!rmdevice) return 0; - /* - * unbind _ADR-Based Devices when hot removal - */ if (dev->flags.bus_address) { if ((dev->parent) && (dev->parent->ops.unbind)) dev->parent->ops.unbind(dev); } + acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); return 0; @@ -1014,8 +975,7 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) static int acpi_add_single_object(struct acpi_device **child, - struct acpi_device *parent, acpi_handle handle, int type, - struct acpi_bus_ops *ops) + struct acpi_device *parent, acpi_handle handle, int type) { int result = 0; struct acpi_device *device = NULL; @@ -1032,8 +992,6 @@ acpi_add_single_object(struct acpi_device **child, device->handle = handle; device->parent = parent; - device->bus_ops = *ops; /* workround for not call .start */ - acpi_device_get_busid(device, handle, type); @@ -1118,16 +1076,33 @@ acpi_add_single_object(struct acpi_device **child, if ((result = acpi_device_set_context(device, type))) goto end; - result = acpi_device_register(device, parent); + acpi_device_get_debug_info(device, handle, type); + + acpi_device_register(device, parent); /* - * Bind _ADR-Based Devices when hot add + * Bind _ADR-Based Devices + * ----------------------- + * If there's a a bus address (_ADR) then we utilize the parent's + * 'bind' function (if exists) to bind the ACPI- and natively- + * enumerated device representations. */ if (device->flags.bus_address) { if (device->parent && device->parent->ops.bind) device->parent->ops.bind(device); } + /* + * Locate & Attach Driver + * ---------------------- + * If there's a hardware id (_HID) or compatible ids (_CID) we check + * to see if there's a driver installed for this kind of device. Note + * that drivers can install before or after a device is enumerated. + * + * TBD: Assumes LDM provides driver hot-plug capability. + */ + acpi_bus_find_driver(device); + end: if (!result) *child = device; @@ -1213,14 +1188,14 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) if (ops->acpi_op_add) status = acpi_add_single_object(&child, parent, - chandle, type, ops); + chandle, type); else status = acpi_bus_get_device(chandle, &child); if (ACPI_FAILURE(status)) continue; - if (ops->acpi_op_start && !(ops->acpi_op_add)) { + if (ops->acpi_op_start) { status = acpi_start_single_object(child); if (ACPI_FAILURE(status)) continue; @@ -1258,13 +1233,13 @@ acpi_bus_add(struct acpi_device **child, int result; struct acpi_bus_ops ops; - memset(&ops, 0, sizeof(ops)); - ops.acpi_op_add = 1; - result = acpi_add_single_object(child, parent, handle, type, &ops); - if (!result) + result = acpi_add_single_object(child, parent, handle, type); + if (!result) { + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; result = acpi_bus_scan(*child, &ops); - + } return result; } @@ -1350,35 +1325,127 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) { int result = 0; struct acpi_device *device = NULL; - struct acpi_bus_ops ops; + if (!root) return -ENODEV; - memset(&ops, 0, sizeof(ops)); - ops.acpi_op_add = 1; - ops.acpi_op_start = 1; - /* * Enumerate all fixed-feature devices. */ - if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { + if (acpi_fadt.pwr_button == 0) { result = acpi_add_single_object(&device, acpi_root, NULL, - ACPI_BUS_TYPE_POWER_BUTTON, - &ops); + ACPI_BUS_TYPE_POWER_BUTTON); + if (!result) + result = acpi_start_single_object(device); } - if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { + if (acpi_fadt.sleep_button == 0) { result = acpi_add_single_object(&device, acpi_root, NULL, - ACPI_BUS_TYPE_SLEEP_BUTTON, - &ops); + ACPI_BUS_TYPE_SLEEP_BUTTON); + if (!result) + result = acpi_start_single_object(device); } return result; } + +static inline struct acpi_device * to_acpi_dev(struct device * dev) +{ + return container_of(dev, struct acpi_device, dev); +} + + +static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state) +{ + struct acpi_device * dev, * next; + int result; + + spin_lock(&acpi_device_lock); + list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) { + if (dev->driver && dev->driver->ops.suspend) { + spin_unlock(&acpi_device_lock); + result = dev->driver->ops.suspend(dev, 0); + if (result) { + printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n", + acpi_device_name(dev), + acpi_device_bid(dev), result); + } + spin_lock(&acpi_device_lock); + } + } + spin_unlock(&acpi_device_lock); + return 0; +} + + +static int acpi_device_suspend(struct device * dev, pm_message_t state) +{ + struct acpi_device * acpi_dev = to_acpi_dev(dev); + + /* + * For now, we should only register 1 generic device - + * the ACPI root device - and from there, we walk the + * tree of ACPI devices to suspend each one using the + * ACPI driver methods. + */ + if (acpi_dev->handle == ACPI_ROOT_OBJECT) + root_suspend(acpi_dev, state); + return 0; +} + + + +static int root_resume(struct acpi_device * acpi_dev) +{ + struct acpi_device * dev, * next; + int result; + + spin_lock(&acpi_device_lock); + list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) { + if (dev->driver && dev->driver->ops.resume) { + spin_unlock(&acpi_device_lock); + result = dev->driver->ops.resume(dev, 0); + if (result) { + printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n", + acpi_device_name(dev), + acpi_device_bid(dev), result); + } + spin_lock(&acpi_device_lock); + } + } + spin_unlock(&acpi_device_lock); + return 0; +} + + +static int acpi_device_resume(struct device * dev) +{ + struct acpi_device * acpi_dev = to_acpi_dev(dev); + + /* + * For now, we should only register 1 generic device - + * the ACPI root device - and from there, we walk the + * tree of ACPI devices to resume each one using the + * ACPI driver methods. + */ + if (acpi_dev->handle == ACPI_ROOT_OBJECT) + root_resume(acpi_dev); + return 0; +} + + +static struct bus_type acpi_bus_type = { + .name = "acpi", + .suspend = acpi_device_suspend, + .resume = acpi_device_resume, +}; + + + static int __init acpi_scan_init(void) { int result; @@ -1388,9 +1455,9 @@ static int __init acpi_scan_init(void) if (acpi_disabled) return 0; - memset(&ops, 0, sizeof(ops)); - ops.acpi_op_add = 1; - ops.acpi_op_start = 1; + result = kset_register(&acpi_namespace_kset); + if (result < 0) + printk(KERN_ERR PREFIX "kset_register error: %d\n", result); result = bus_register(&acpi_bus_type); if (result) { @@ -1402,16 +1469,32 @@ static int __init acpi_scan_init(void) * Create the root device in the bus's device tree */ result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, - ACPI_BUS_TYPE_SYSTEM, &ops); + ACPI_BUS_TYPE_SYSTEM); if (result) goto Done; + result = acpi_start_single_object(acpi_root); + if (result) + goto Done; + + acpi_root->dev.bus = &acpi_bus_type; + snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name); + result = device_register(&acpi_root->dev); + if (result) { + /* We don't want to quit even if we failed to add suspend/resume */ + printk(KERN_ERR PREFIX "Could not register device\n"); + } + /* * Enumerate devices in the ACPI namespace. */ result = acpi_bus_scan_fixed(acpi_root); - if (!result) + if (!result) { + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; + ops.acpi_op_start = 1; result = acpi_bus_scan(acpi_root, &ops); + } if (result) acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); diff --git a/trunk/drivers/acpi/sleep/proc.c b/trunk/drivers/acpi/sleep/proc.c index ccc11b33d89c..34962578039d 100644 --- a/trunk/drivers/acpi/sleep/proc.c +++ b/trunk/drivers/acpi/sleep/proc.c @@ -73,7 +73,7 @@ acpi_system_write_sleep(struct file *file, static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) { u32 sec, min, hr; - u32 day, mo, yr, cent = 0; + u32 day, mo, yr; unsigned char rtc_control = 0; unsigned long flags; @@ -87,19 +87,20 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) rtc_control = CMOS_READ(RTC_CONTROL); /* If we ever get an FACP with proper values... */ - if (acpi_gbl_FADT.day_alarm) + if (acpi_gbl_FADT->day_alrm) /* ACPI spec: only low 6 its should be cared */ - day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F; + day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F; else day = CMOS_READ(RTC_DAY_OF_MONTH); - if (acpi_gbl_FADT.month_alarm) - mo = CMOS_READ(acpi_gbl_FADT.month_alarm); + if (acpi_gbl_FADT->mon_alrm) + mo = CMOS_READ(acpi_gbl_FADT->mon_alrm); else mo = CMOS_READ(RTC_MONTH); - if (acpi_gbl_FADT.century) - cent = CMOS_READ(acpi_gbl_FADT.century); - - yr = CMOS_READ(RTC_YEAR); + if (acpi_gbl_FADT->century) + yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + + CMOS_READ(RTC_YEAR); + else + yr = CMOS_READ(RTC_YEAR); spin_unlock_irqrestore(&rtc_lock, flags); @@ -110,11 +111,10 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) BCD_TO_BIN(day); BCD_TO_BIN(mo); BCD_TO_BIN(yr); - BCD_TO_BIN(cent); } /* we're trusting the FADT (see above) */ - if (!acpi_gbl_FADT.century) + if (!acpi_gbl_FADT->century) /* If we're not trusting the FADT, we should at least make it * right for _this_ century... ehm, what is _this_ century? * @@ -134,8 +134,6 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) * */ yr += 2000; - else - yr += cent * 100; seq_printf(seq, "%4.4u-", yr); (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); @@ -319,12 +317,12 @@ acpi_system_write_alarm(struct file *file, * offsets into the CMOS RAM here -- which for some reason are pointing * to the RTC area of memory. */ - if (acpi_gbl_FADT.day_alarm) - CMOS_WRITE(day, acpi_gbl_FADT.day_alarm); - if (acpi_gbl_FADT.month_alarm) - CMOS_WRITE(mo, acpi_gbl_FADT.month_alarm); - if (acpi_gbl_FADT.century) - CMOS_WRITE(yr / 100, acpi_gbl_FADT.century); + if (acpi_gbl_FADT->day_alrm) + CMOS_WRITE(day, acpi_gbl_FADT->day_alrm); + if (acpi_gbl_FADT->mon_alrm) + CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm); + if (acpi_gbl_FADT->century) + CMOS_WRITE(yr / 100, acpi_gbl_FADT->century); /* enable the rtc alarm interrupt */ rtc_control |= RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); diff --git a/trunk/drivers/acpi/system.c b/trunk/drivers/acpi/system.c index 7147b0bdab0a..d86dcb3c2366 100644 --- a/trunk/drivers/acpi/system.c +++ b/trunk/drivers/acpi/system.c @@ -32,11 +32,6 @@ #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("acpi_system") -#ifdef MODULE_PARAM_PREFIX -#undef MODULE_PARAM_PREFIX -#endif -#define MODULE_PARAM_PREFIX "acpi." - #define ACPI_SYSTEM_CLASS "system" #define ACPI_SYSTEM_DRIVER_NAME "ACPI System Driver" #define ACPI_SYSTEM_DEVICE_NAME "System" @@ -44,24 +39,11 @@ ACPI_MODULE_NAME("acpi_system") #define ACPI_SYSTEM_FILE_EVENT "event" #define ACPI_SYSTEM_FILE_DSDT "dsdt" #define ACPI_SYSTEM_FILE_FADT "fadt" - -/* - * Make ACPICA version work as module param - */ -static int param_get_acpica_version(char *buffer, struct kernel_param *kp) { - int result; - - result = sprintf(buffer, "%x", ACPI_CA_VERSION); - - return result; -} - -module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); +extern struct fadt_descriptor acpi_fadt; /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_PROCFS static int acpi_system_read_info(struct seq_file *seq, void *offset) { @@ -81,7 +63,6 @@ static const struct file_operations acpi_system_info_ops = { .llseek = seq_lseek, .release = single_release, }; -#endif static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, loff_t *); @@ -95,16 +76,17 @@ acpi_system_read_dsdt(struct file *file, char __user * buffer, size_t count, loff_t * ppos) { acpi_status status = AE_OK; - struct acpi_table_header *dsdt = NULL; + struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; ssize_t res; - status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); + status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); if (ACPI_FAILURE(status)) return -ENODEV; res = simple_read_from_buffer(buffer, count, ppos, - dsdt, dsdt->length); + dsdt.pointer, dsdt.length); + kfree(dsdt.pointer); return res; } @@ -121,16 +103,17 @@ acpi_system_read_fadt(struct file *file, char __user * buffer, size_t count, loff_t * ppos) { acpi_status status = AE_OK; - struct acpi_table_header *fadt = NULL; + struct acpi_buffer fadt = { ACPI_ALLOCATE_BUFFER, NULL }; ssize_t res; - status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); + status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &fadt); if (ACPI_FAILURE(status)) return -ENODEV; res = simple_read_from_buffer(buffer, count, ppos, - fadt, fadt->length); + fadt.pointer, fadt.length); + kfree(fadt.pointer); return res; } @@ -145,7 +128,6 @@ static int __init acpi_system_init(void) if (acpi_disabled) return 0; -#ifdef CONFIG_ACPI_PROCFS /* 'info' [R] */ name = ACPI_SYSTEM_FILE_INFO; entry = create_proc_entry(name, S_IRUGO, acpi_root_dir); @@ -154,7 +136,6 @@ static int __init acpi_system_init(void) else { entry->proc_fops = &acpi_system_info_ops; } -#endif /* 'dsdt' [R] */ name = ACPI_SYSTEM_FILE_DSDT; @@ -178,9 +159,7 @@ static int __init acpi_system_init(void) Error: remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); -#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); -#endif error = -EFAULT; goto Done; diff --git a/trunk/drivers/acpi/tables.c b/trunk/drivers/acpi/tables.c index ba4cb200314a..ffa30c9fccbf 100644 --- a/trunk/drivers/acpi/tables.c +++ b/trunk/drivers/acpi/tables.c @@ -38,97 +38,154 @@ #define ACPI_MAX_TABLES 128 +static char *acpi_table_signatures[ACPI_TABLE_COUNT] = { + [ACPI_TABLE_UNKNOWN] = "????", + [ACPI_APIC] = "APIC", + [ACPI_BOOT] = "BOOT", + [ACPI_DBGP] = "DBGP", + [ACPI_DSDT] = "DSDT", + [ACPI_ECDT] = "ECDT", + [ACPI_ETDT] = "ETDT", + [ACPI_FADT] = "FACP", + [ACPI_FACS] = "FACS", + [ACPI_OEMX] = "OEM", + [ACPI_PSDT] = "PSDT", + [ACPI_SBST] = "SBST", + [ACPI_SLIT] = "SLIT", + [ACPI_SPCR] = "SPCR", + [ACPI_SRAT] = "SRAT", + [ACPI_SSDT] = "SSDT", + [ACPI_SPMI] = "SPMI", + [ACPI_HPET] = "HPET", + [ACPI_MCFG] = "MCFG", +}; + static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; -static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; +/* System Description Table (RSDT/XSDT) */ +struct acpi_table_sdt { + unsigned long pa; + enum acpi_table_id id; + unsigned long size; +} __attribute__ ((packed)); + +static unsigned long sdt_pa; /* Physical Address */ +static unsigned long sdt_count; /* Table count */ -void acpi_table_print_madt_entry(struct acpi_subtable_header * header) +static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata; + +void acpi_table_print(struct acpi_table_header *header, unsigned long phys_addr) +{ + char *name = NULL; + + if (!header) + return; + + /* Some table signatures aren't good table names */ + + if (!strncmp((char *)&header->signature, + acpi_table_signatures[ACPI_APIC], + sizeof(header->signature))) { + name = "MADT"; + } else if (!strncmp((char *)&header->signature, + acpi_table_signatures[ACPI_FADT], + sizeof(header->signature))) { + name = "FADT"; + } else + name = header->signature; + + printk(KERN_DEBUG PREFIX + "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", name, + header->revision, header->oem_id, header->oem_table_id, + header->oem_revision, header->asl_compiler_id, + header->asl_compiler_revision, (void *)phys_addr); +} + +void acpi_table_print_madt_entry(acpi_table_entry_header * header) { if (!header) return; switch (header->type) { - case ACPI_MADT_TYPE_LOCAL_APIC: + case ACPI_MADT_LAPIC: { - struct acpi_madt_local_apic *p = - (struct acpi_madt_local_apic *)header; + struct acpi_table_lapic *p = + (struct acpi_table_lapic *)header; printk(KERN_INFO PREFIX "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", - p->processor_id, p->id, - (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + p->acpi_id, p->id, + p->flags.enabled ? "enabled" : "disabled"); } break; - case ACPI_MADT_TYPE_IO_APIC: + case ACPI_MADT_IOAPIC: { - struct acpi_madt_io_apic *p = - (struct acpi_madt_io_apic *)header; + struct acpi_table_ioapic *p = + (struct acpi_table_ioapic *)header; printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", p->id, p->address, p->global_irq_base); } break; - case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: + case ACPI_MADT_INT_SRC_OVR: { - struct acpi_madt_interrupt_override *p = - (struct acpi_madt_interrupt_override *)header; + struct acpi_table_int_src_ovr *p = + (struct acpi_table_int_src_ovr *)header; printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", - p->bus, p->source_irq, p->global_irq, - mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], - mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]); - if (p->inti_flags & - ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK)) + p->bus, p->bus_irq, p->global_irq, + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger]); + if (p->flags.reserved) printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n", - p->inti_flags & - ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK)); + p->flags.reserved); } break; - case ACPI_MADT_TYPE_NMI_SOURCE: + case ACPI_MADT_NMI_SRC: { - struct acpi_madt_nmi_source *p = - (struct acpi_madt_nmi_source *)header; + struct acpi_table_nmi_src *p = + (struct acpi_table_nmi_src *)header; printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n", - mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], - mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger], p->global_irq); } break; - case ACPI_MADT_TYPE_LOCAL_APIC_NMI: + case ACPI_MADT_LAPIC_NMI: { - struct acpi_madt_local_apic_nmi *p = - (struct acpi_madt_local_apic_nmi *)header; + struct acpi_table_lapic_nmi *p = + (struct acpi_table_lapic_nmi *)header; printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", - p->processor_id, - mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK ], - mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], + p->acpi_id, + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger], p->lint); } break; - case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: + case ACPI_MADT_LAPIC_ADDR_OVR: { - struct acpi_madt_local_apic_override *p = - (struct acpi_madt_local_apic_override *)header; + struct acpi_table_lapic_addr_ovr *p = + (struct acpi_table_lapic_addr_ovr *)header; printk(KERN_INFO PREFIX "LAPIC_ADDR_OVR (address[%p])\n", (void *)(unsigned long)p->address); } break; - case ACPI_MADT_TYPE_IO_SAPIC: + case ACPI_MADT_IOSAPIC: { - struct acpi_madt_io_sapic *p = - (struct acpi_madt_io_sapic *)header; + struct acpi_table_iosapic *p = + (struct acpi_table_iosapic *)header; printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", p->id, (void *)(unsigned long)p->address, @@ -136,26 +193,26 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header * header) } break; - case ACPI_MADT_TYPE_LOCAL_SAPIC: + case ACPI_MADT_LSAPIC: { - struct acpi_madt_local_sapic *p = - (struct acpi_madt_local_sapic *)header; + struct acpi_table_lsapic *p = + (struct acpi_table_lsapic *)header; printk(KERN_INFO PREFIX "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", - p->processor_id, p->id, p->eid, - (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + p->acpi_id, p->id, p->eid, + p->flags.enabled ? "enabled" : "disabled"); } break; - case ACPI_MADT_TYPE_INTERRUPT_SOURCE: + case ACPI_MADT_PLAT_INT_SRC: { - struct acpi_madt_interrupt_source *p = - (struct acpi_madt_interrupt_source *)header; + struct acpi_table_plat_int_src *p = + (struct acpi_table_plat_int_src *)header; printk(KERN_INFO PREFIX "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", - mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], - mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], - p->type, p->id, p->eid, p->io_sapic_vector, + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger], + p->type, p->id, p->eid, p->iosapic_vector, p->global_irq); } break; @@ -168,76 +225,342 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header * header) } } +static int +acpi_table_compute_checksum(void *table_pointer, unsigned long length) +{ + u8 *p = table_pointer; + unsigned long remains = length; + unsigned long sum = 0; + + if (!p || !length) + return -EINVAL; + + while (remains--) + sum += *p++; + + return (sum & 0xFF); +} +/* + * acpi_get_table_header_early() + * for acpi_blacklisted(), acpi_table_get_sdt() + */ int __init -acpi_table_parse_madt_family(char *id, +acpi_get_table_header_early(enum acpi_table_id id, + struct acpi_table_header **header) +{ + unsigned int i; + enum acpi_table_id temp_id; + + /* DSDT is different from the rest */ + if (id == ACPI_DSDT) + temp_id = ACPI_FADT; + else + temp_id = id; + + /* Locate the table. */ + + for (i = 0; i < sdt_count; i++) { + if (sdt_entry[i].id != temp_id) + continue; + *header = (void *) + __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); + if (!*header) { + printk(KERN_WARNING PREFIX "Unable to map %s\n", + acpi_table_signatures[temp_id]); + return -ENODEV; + } + break; + } + + if (!*header) { + printk(KERN_WARNING PREFIX "%s not present\n", + acpi_table_signatures[id]); + return -ENODEV; + } + + /* Map the DSDT header via the pointer in the FADT */ + if (id == ACPI_DSDT) { + struct fadt_descriptor *fadt = + (struct fadt_descriptor *)*header; + + if (fadt->revision == 3 && fadt->Xdsdt) { + *header = (void *)__acpi_map_table(fadt->Xdsdt, + sizeof(struct + acpi_table_header)); + } else if (fadt->V1_dsdt) { + *header = (void *)__acpi_map_table(fadt->V1_dsdt, + sizeof(struct + acpi_table_header)); + } else + *header = NULL; + + if (!*header) { + printk(KERN_WARNING PREFIX "Unable to map DSDT\n"); + return -ENODEV; + } + } + + return 0; +} + +int __init +acpi_table_parse_madt_family(enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler, unsigned int max_entries) { - struct acpi_table_header *madt = NULL; - struct acpi_subtable_header *entry; + void *madt = NULL; + acpi_table_entry_header *entry; unsigned int count = 0; unsigned long madt_end; + unsigned int i; if (!handler) return -EINVAL; /* Locate the MADT (if exists). There should only be one. */ - acpi_get_table(id, 0, &madt); + + for (i = 0; i < sdt_count; i++) { + if (sdt_entry[i].id != id) + continue; + madt = (void *) + __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); + if (!madt) { + printk(KERN_WARNING PREFIX "Unable to map %s\n", + acpi_table_signatures[id]); + return -ENODEV; + } + break; + } if (!madt) { - printk(KERN_WARNING PREFIX "%4.4s not present\n", id); + printk(KERN_WARNING PREFIX "%s not present\n", + acpi_table_signatures[id]); return -ENODEV; } - madt_end = (unsigned long)madt + madt->length; + madt_end = (unsigned long)madt + sdt_entry[i].size; /* Parse all entries looking for a match. */ - entry = (struct acpi_subtable_header *) + entry = (acpi_table_entry_header *) ((unsigned long)madt + madt_size); - while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < + while (((unsigned long)entry) + sizeof(acpi_table_entry_header) < madt_end) { if (entry->type == entry_id && (!max_entries || count++ < max_entries)) if (handler(entry, madt_end)) return -EINVAL; - entry = (struct acpi_subtable_header *) + entry = (acpi_table_entry_header *) ((unsigned long)entry + entry->length); } if (max_entries && count > max_entries) { - printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of " - "%i found\n", id, entry_id, count - max_entries, count); + printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of " + "%i found\n", acpi_table_signatures[id], entry_id, + count - max_entries, count); } return count; } int __init -acpi_table_parse_madt(enum acpi_madt_type id, +acpi_table_parse_madt(enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries) { - return acpi_table_parse_madt_family(ACPI_SIG_MADT, + return acpi_table_parse_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt), id, handler, max_entries); } -int __init acpi_table_parse(char *id, acpi_table_handler handler) +int __init acpi_table_parse(enum acpi_table_id id, acpi_table_handler handler) { - struct acpi_table_header *table = NULL; + int count = 0; + unsigned int i = 0; + if (!handler) return -EINVAL; - acpi_get_table(id, 0, &table); - if (table) { - handler(table); - return 1; - } else - return 0; + for (i = 0; i < sdt_count; i++) { + if (sdt_entry[i].id != id) + continue; + count++; + if (count == 1) + handler(sdt_entry[i].pa, sdt_entry[i].size); + + else + printk(KERN_WARNING PREFIX + "%d duplicate %s table ignored.\n", count, + acpi_table_signatures[id]); + } + + return count; +} + +static int __init acpi_table_get_sdt(struct acpi_table_rsdp *rsdp) +{ + struct acpi_table_header *header = NULL; + unsigned int i, id = 0; + + if (!rsdp) + return -EINVAL; + + /* First check XSDT (but only on ACPI 2.0-compatible systems) */ + + if ((rsdp->revision >= 2) && + (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) { + + struct acpi_table_xsdt *mapped_xsdt = NULL; + + sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address; + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); + + if (!header) { + printk(KERN_WARNING PREFIX + "Unable to map XSDT header\n"); + return -ENODEV; + } + + /* remap in the entire table before processing */ + mapped_xsdt = (struct acpi_table_xsdt *) + __acpi_map_table(sdt_pa, header->length); + if (!mapped_xsdt) { + printk(KERN_WARNING PREFIX "Unable to map XSDT\n"); + return -ENODEV; + } + header = &mapped_xsdt->header; + + if (strncmp(header->signature, "XSDT", 4)) { + printk(KERN_WARNING PREFIX + "XSDT signature incorrect\n"); + return -ENODEV; + } + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n"); + return -ENODEV; + } + + sdt_count = + (header->length - sizeof(struct acpi_table_header)) >> 3; + if (sdt_count > ACPI_MAX_TABLES) { + printk(KERN_WARNING PREFIX + "Truncated %lu XSDT entries\n", + (sdt_count - ACPI_MAX_TABLES)); + sdt_count = ACPI_MAX_TABLES; + } + + for (i = 0; i < sdt_count; i++) + sdt_entry[i].pa = (unsigned long)mapped_xsdt->entry[i]; + } + + /* Then check RSDT */ + + else if (rsdp->rsdt_address) { + + struct acpi_table_rsdt *mapped_rsdt = NULL; + + sdt_pa = rsdp->rsdt_address; + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); + if (!header) { + printk(KERN_WARNING PREFIX + "Unable to map RSDT header\n"); + return -ENODEV; + } + + /* remap in the entire table before processing */ + mapped_rsdt = (struct acpi_table_rsdt *) + __acpi_map_table(sdt_pa, header->length); + if (!mapped_rsdt) { + printk(KERN_WARNING PREFIX "Unable to map RSDT\n"); + return -ENODEV; + } + header = &mapped_rsdt->header; + + if (strncmp(header->signature, "RSDT", 4)) { + printk(KERN_WARNING PREFIX + "RSDT signature incorrect\n"); + return -ENODEV; + } + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n"); + return -ENODEV; + } + + sdt_count = + (header->length - sizeof(struct acpi_table_header)) >> 2; + if (sdt_count > ACPI_MAX_TABLES) { + printk(KERN_WARNING PREFIX + "Truncated %lu RSDT entries\n", + (sdt_count - ACPI_MAX_TABLES)); + sdt_count = ACPI_MAX_TABLES; + } + + for (i = 0; i < sdt_count; i++) + sdt_entry[i].pa = (unsigned long)mapped_rsdt->entry[i]; + } + + else { + printk(KERN_WARNING PREFIX + "No System Description Table (RSDT/XSDT) specified in RSDP\n"); + return -ENODEV; + } + + acpi_table_print(header, sdt_pa); + + for (i = 0; i < sdt_count; i++) { + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_entry[i].pa, + sizeof(struct acpi_table_header)); + if (!header) + continue; + + /* remap in the entire table before processing */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_entry[i].pa, header->length); + if (!header) + continue; + + acpi_table_print(header, sdt_entry[i].pa); + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); + continue; + } + + sdt_entry[i].size = header->length; + + for (id = 0; id < ACPI_TABLE_COUNT; id++) { + if (!strncmp((char *)&header->signature, + acpi_table_signatures[id], + sizeof(header->signature))) { + sdt_entry[i].id = id; + } + } + } + + /* + * The DSDT is *not* in the RSDT (why not? no idea.) but we want + * to print its info, because this is what people usually blacklist + * against. Unfortunately, we don't know the phys_addr, so just + * print 0. Maybe no one will notice. + */ + if (!acpi_get_table_header_early(ACPI_DSDT, &header)) + acpi_table_print(header, 0); + + return 0; } /* @@ -245,13 +568,54 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) * * find RSDP, find and checksum SDT/XSDT. * checksum all tables, print SDT/XSDT - * + * * result: sdt_entry[] is initialized */ - int __init acpi_table_init(void) { - acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); + struct acpi_table_rsdp *rsdp = NULL; + unsigned long rsdp_phys = 0; + int result = 0; + + /* Locate and map the Root System Description Table (RSDP) */ + + rsdp_phys = acpi_find_rsdp(); + if (!rsdp_phys) { + printk(KERN_ERR PREFIX "Unable to locate RSDP\n"); + return -ENODEV; + } + + rsdp = (struct acpi_table_rsdp *)__acpi_map_table(rsdp_phys, + sizeof(struct acpi_table_rsdp)); + if (!rsdp) { + printk(KERN_WARNING PREFIX "Unable to map RSDP\n"); + return -ENODEV; + } + + printk(KERN_DEBUG PREFIX + "RSDP (v%3.3d %6.6s ) @ 0x%p\n", + rsdp->revision, rsdp->oem_id, (void *)rsdp_phys); + + if (rsdp->revision < 2) + result = + acpi_table_compute_checksum(rsdp, + sizeof(struct acpi_table_rsdp)); + else + result = + acpi_table_compute_checksum(rsdp, + ((struct acpi20_table_rsdp *) + rsdp)->length); + + if (result) { + printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); + return -ENODEV; + } + + /* Locate and map the System Description table (RSDT/XSDT) */ + + if (acpi_table_get_sdt(rsdp)) + return -ENODEV; + return 0; } diff --git a/trunk/drivers/acpi/tables/Makefile b/trunk/drivers/acpi/tables/Makefile index 0a7d7afac255..aa4c69594d97 100644 --- a/trunk/drivers/acpi/tables/Makefile +++ b/trunk/drivers/acpi/tables/Makefile @@ -2,6 +2,7 @@ # Makefile for all Linux ACPI interpreter subdirectories # -obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o +obj-y := tbconvrt.o tbget.o tbrsdt.o tbxface.o \ + tbgetall.o tbinstal.o tbutils.o tbxfroot.o EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/trunk/drivers/acpi/tables/tbconvrt.c b/trunk/drivers/acpi/tables/tbconvrt.c new file mode 100644 index 000000000000..d697fcb35d52 --- /dev/null +++ b/trunk/drivers/acpi/tables/tbconvrt.c @@ -0,0 +1,622 @@ +/****************************************************************************** + * + * Module Name: tbconvrt - ACPI Table conversion utilities + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbconvrt") + +/* Local prototypes */ +static void +acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, + u8 register_bit_width, + acpi_physical_address address); + +static void +acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, + struct fadt_descriptor_rev1 *original_fadt); + +static void +acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, + struct fadt_descriptor *original_fadt); + +u8 acpi_fadt_is_v1; +ACPI_EXPORT_SYMBOL(acpi_fadt_is_v1) + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_count + * + * PARAMETERS: RSDP - Pointer to the RSDP + * RSDT - Pointer to the RSDT/XSDT + * + * RETURN: The number of tables pointed to by the RSDT or XSDT. + * + * DESCRIPTION: Calculate the number of tables. Automatically handles either + * an RSDT or XSDT. + * + ******************************************************************************/ + +u32 +acpi_tb_get_table_count(struct rsdp_descriptor *RSDP, + struct acpi_table_header *RSDT) +{ + u32 pointer_size; + + ACPI_FUNCTION_ENTRY(); + + /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ + + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + pointer_size = sizeof(u32); + } else { + pointer_size = sizeof(u64); + } + + /* + * Determine the number of tables pointed to by the RSDT/XSDT. + * This is defined by the ACPI Specification to be the number of + * pointers contained within the RSDT/XSDT. The size of the pointers + * is architecture-dependent. + */ + return ((RSDT->length - + sizeof(struct acpi_table_header)) / pointer_size); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_to_xsdt + * + * PARAMETERS: table_info - Info about the RSDT + * + * RETURN: Status + * + * DESCRIPTION: Convert an RSDT to an XSDT (internal common format) + * + ******************************************************************************/ + +acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) +{ + acpi_size table_size; + u32 i; + struct xsdt_descriptor *new_table; + + ACPI_FUNCTION_ENTRY(); + + /* Compute size of the converted XSDT */ + + table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof(u64)) + + sizeof(struct acpi_table_header); + + /* Allocate an XSDT */ + + new_table = ACPI_ALLOCATE_ZEROED(table_size); + if (!new_table) { + return (AE_NO_MEMORY); + } + + /* Copy the header and set the length */ + + ACPI_MEMCPY(new_table, table_info->pointer, + sizeof(struct acpi_table_header)); + new_table->length = (u32) table_size; + + /* Copy the table pointers */ + + for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { + + /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ + + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + ACPI_STORE_ADDRESS(new_table->table_offset_entry[i], + (ACPI_CAST_PTR + (struct rsdt_descriptor, + table_info->pointer))-> + table_offset_entry[i]); + } else { + new_table->table_offset_entry[i] = + (ACPI_CAST_PTR(struct xsdt_descriptor, + table_info->pointer))-> + table_offset_entry[i]; + } + } + + /* Delete the original table (either mapped or in a buffer) */ + + acpi_tb_delete_single_table(table_info); + + /* Point the table descriptor to the new table */ + + table_info->pointer = + ACPI_CAST_PTR(struct acpi_table_header, new_table); + table_info->length = table_size; + table_info->allocation = ACPI_MEM_ALLOCATED; + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_init_generic_address + * + * PARAMETERS: new_gas_struct - GAS struct to be initialized + * register_bit_width - Width of this register + * Address - Address of the register + * + * RETURN: None + * + * DESCRIPTION: Initialize a GAS structure. + * + ******************************************************************************/ + +static void +acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, + u8 register_bit_width, + acpi_physical_address address) +{ + + ACPI_STORE_ADDRESS(new_gas_struct->address, address); + + new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; + new_gas_struct->register_bit_width = register_bit_width; + new_gas_struct->register_bit_offset = 0; + new_gas_struct->access_width = 0; +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_fadt1 + * + * PARAMETERS: local_fadt - Pointer to new FADT + * original_fadt - Pointer to old FADT + * + * RETURN: None, populates local_fadt + * + * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format + * + ******************************************************************************/ + +static void +acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, + struct fadt_descriptor_rev1 *original_fadt) +{ + + /* ACPI 1.0 FACS */ + /* The BIOS stored FADT should agree with Revision 1.0 */ + acpi_fadt_is_v1 = 1; + + /* + * Copy the table header and the common part of the tables. + * + * The 2.0 table is an extension of the 1.0 table, so the entire 1.0 + * table can be copied first, then expand some fields to 64 bits. + */ + ACPI_MEMCPY(local_fadt, original_fadt, + sizeof(struct fadt_descriptor_rev1)); + + /* Convert table pointers to 64-bit fields */ + + ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, + local_fadt->V1_firmware_ctrl); + ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); + + /* + * System Interrupt Model isn't used in ACPI 2.0 + * (local_fadt->Reserved1 = 0;) + */ + + /* + * This field is set by the OEM to convey the preferred power management + * profile to OSPM. It doesn't have any 1.0 equivalence. Since we don't + * know what kind of 32-bit system this is, we will use "unspecified". + */ + local_fadt->prefer_PM_profile = PM_UNSPECIFIED; + + /* + * Processor Performance State Control. This is the value OSPM writes to + * the SMI_CMD register to assume processor performance state control + * responsibility. There isn't any equivalence in 1.0, but as many 1.x + * ACPI tables contain _PCT and _PSS we also keep this value, unless + * acpi_strict is set. + */ + if (acpi_strict) + local_fadt->pstate_cnt = 0; + + /* + * Support for the _CST object and C States change notification. + * This data item hasn't any 1.0 equivalence so leave it zero. + */ + local_fadt->cst_cnt = 0; + + /* + * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0. + * It primarily adds the FADT reset mechanism. + */ + if ((original_fadt->revision == 2) && + (original_fadt->length == + sizeof(struct fadt_descriptor_rev2_minus))) { + /* + * Grab the entire generic address struct, plus the 1-byte reset value + * that immediately follows. + */ + ACPI_MEMCPY(&local_fadt->reset_register, + &(ACPI_CAST_PTR(struct fadt_descriptor_rev2_minus, + original_fadt))->reset_register, + sizeof(struct acpi_generic_address) + 1); + } else { + /* + * Since there isn't any equivalence in 1.0 and since it is highly + * likely that a 1.0 system has legacy support. + */ + local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES; + } + + /* + * Convert the V1.0 block addresses to V2.0 GAS structures + */ + acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, + local_fadt->pm1_evt_len, + (acpi_physical_address) local_fadt-> + V1_pm1a_evt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, + local_fadt->pm1_evt_len, + (acpi_physical_address) local_fadt-> + V1_pm1b_evt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, + local_fadt->pm1_cnt_len, + (acpi_physical_address) local_fadt-> + V1_pm1a_cnt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, + local_fadt->pm1_cnt_len, + (acpi_physical_address) local_fadt-> + V1_pm1b_cnt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, + local_fadt->pm2_cnt_len, + (acpi_physical_address) local_fadt-> + V1_pm2_cnt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, + local_fadt->pm_tm_len, + (acpi_physical_address) local_fadt-> + V1_pm_tmr_blk); + acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, 0, + (acpi_physical_address) local_fadt-> + V1_gpe0_blk); + acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, 0, + (acpi_physical_address) local_fadt-> + V1_gpe1_blk); + + /* Create separate GAS structs for the PM1 Enable registers */ + + acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, + (u8) ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len), + (acpi_physical_address) + (local_fadt->xpm1a_evt_blk.address + + ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); + + /* PM1B is optional; leave null if not present */ + + if (local_fadt->xpm1b_evt_blk.address) { + acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, + (u8) ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len), + (acpi_physical_address) + (local_fadt->xpm1b_evt_blk. + address + + ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len))); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_fadt2 + * + * PARAMETERS: local_fadt - Pointer to new FADT + * original_fadt - Pointer to old FADT + * + * RETURN: None, populates local_fadt + * + * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format. + * Handles optional "X" fields. + * + ******************************************************************************/ + +static void +acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, + struct fadt_descriptor *original_fadt) +{ + + /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ + + ACPI_MEMCPY(local_fadt, original_fadt, sizeof(struct fadt_descriptor)); + + /* + * "X" fields are optional extensions to the original V1.0 fields, so + * we must selectively expand V1.0 fields if the corresponding X field + * is zero. + */ + if (!(local_fadt->xfirmware_ctrl)) { + ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, + local_fadt->V1_firmware_ctrl); + } + + if (!(local_fadt->Xdsdt)) { + ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); + } + + if (!(local_fadt->xpm1a_evt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, + local_fadt->pm1_evt_len, + (acpi_physical_address) + local_fadt->V1_pm1a_evt_blk); + } + + if (!(local_fadt->xpm1b_evt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, + local_fadt->pm1_evt_len, + (acpi_physical_address) + local_fadt->V1_pm1b_evt_blk); + } + + if (!(local_fadt->xpm1a_cnt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, + local_fadt->pm1_cnt_len, + (acpi_physical_address) + local_fadt->V1_pm1a_cnt_blk); + } + + if (!(local_fadt->xpm1b_cnt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, + local_fadt->pm1_cnt_len, + (acpi_physical_address) + local_fadt->V1_pm1b_cnt_blk); + } + + if (!(local_fadt->xpm2_cnt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, + local_fadt->pm2_cnt_len, + (acpi_physical_address) + local_fadt->V1_pm2_cnt_blk); + } + + if (!(local_fadt->xpm_tmr_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, + local_fadt->pm_tm_len, + (acpi_physical_address) + local_fadt->V1_pm_tmr_blk); + } + + if (!(local_fadt->xgpe0_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, + 0, + (acpi_physical_address) + local_fadt->V1_gpe0_blk); + } + + if (!(local_fadt->xgpe1_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, + 0, + (acpi_physical_address) + local_fadt->V1_gpe1_blk); + } + + /* Create separate GAS structs for the PM1 Enable registers */ + + acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, + (u8) ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len), + (acpi_physical_address) + (local_fadt->xpm1a_evt_blk.address + + ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); + + acpi_gbl_xpm1a_enable.address_space_id = + local_fadt->xpm1a_evt_blk.address_space_id; + + /* PM1B is optional; leave null if not present */ + + if (local_fadt->xpm1b_evt_blk.address) { + acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, + (u8) ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len), + (acpi_physical_address) + (local_fadt->xpm1b_evt_blk. + address + + ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len))); + + acpi_gbl_xpm1b_enable.address_space_id = + local_fadt->xpm1b_evt_blk.address_space_id; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_table_fadt + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local + * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply + * copied to the local FADT. The ACPI CA software uses this + * local FADT. Thus a significant amount of special #ifdef + * type codeing is saved. + * + ******************************************************************************/ + +acpi_status acpi_tb_convert_table_fadt(void) +{ + struct fadt_descriptor *local_fadt; + struct acpi_table_desc *table_desc; + + ACPI_FUNCTION_TRACE(tb_convert_table_fadt); + + /* + * acpi_gbl_FADT is valid. Validate the FADT length. The table must be + * at least as long as the version 1.0 FADT + */ + if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev1)) { + ACPI_ERROR((AE_INFO, "FADT is invalid, too short: 0x%X", + acpi_gbl_FADT->length)); + return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); + } + + /* Allocate buffer for the ACPI 2.0(+) FADT */ + + local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor)); + if (!local_fadt) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { + if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor)) { + + /* Length is too short to be a V2.0 table */ + + ACPI_WARNING((AE_INFO, + "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table", + acpi_gbl_FADT->length, + acpi_gbl_FADT->revision)); + + acpi_tb_convert_fadt1(local_fadt, + (void *)acpi_gbl_FADT); + } else { + /* Valid V2.0 table */ + + acpi_tb_convert_fadt2(local_fadt, acpi_gbl_FADT); + } + } else { + /* Valid V1.0 table */ + + acpi_tb_convert_fadt1(local_fadt, (void *)acpi_gbl_FADT); + } + + /* Global FADT pointer will point to the new common V2.0 FADT */ + + acpi_gbl_FADT = local_fadt; + acpi_gbl_FADT->length = sizeof(struct fadt_descriptor); + + /* Free the original table */ + + table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_FADT].next; + acpi_tb_delete_single_table(table_desc); + + /* Install the new table */ + + table_desc->pointer = + ACPI_CAST_PTR(struct acpi_table_header, acpi_gbl_FADT); + table_desc->allocation = ACPI_MEM_ALLOCATED; + table_desc->length = sizeof(struct fadt_descriptor); + + /* Dump the entire FADT */ + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, + "Hex dump of common internal FADT, size %d (%X)\n", + acpi_gbl_FADT->length, acpi_gbl_FADT->length)); + + ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_FADT), + acpi_gbl_FADT->length); + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_build_common_facs + * + * PARAMETERS: table_info - Info for currently installed FACS + * + * RETURN: Status + * + * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal + * table format. + * + ******************************************************************************/ + +acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info) +{ + + ACPI_FUNCTION_TRACE(tb_build_common_facs); + + /* Absolute minimum length is 24, but the ACPI spec says 64 */ + + if (acpi_gbl_FACS->length < 24) { + ACPI_ERROR((AE_INFO, "Invalid FACS table length: 0x%X", + acpi_gbl_FACS->length)); + return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); + } + + if (acpi_gbl_FACS->length < 64) { + ACPI_WARNING((AE_INFO, + "FACS is shorter than the ACPI specification allows: 0x%X, using anyway", + acpi_gbl_FACS->length)); + } + + /* Copy fields to the new FACS */ + + acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock); + + if ((acpi_gbl_RSDP->revision < 2) || + (acpi_gbl_FACS->length < 32) || + (!(acpi_gbl_FACS->xfirmware_waking_vector))) { + + /* ACPI 1.0 FACS or short table or optional X_ field is zero */ + + acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR(u64, + & + (acpi_gbl_FACS-> + firmware_waking_vector)); + acpi_gbl_common_fACS.vector_width = 32; + } else { + /* ACPI 2.0 FACS with valid X_ field */ + + acpi_gbl_common_fACS.firmware_waking_vector = + &acpi_gbl_FACS->xfirmware_waking_vector; + acpi_gbl_common_fACS.vector_width = 64; + } + + return_ACPI_STATUS(AE_OK); +} diff --git a/trunk/drivers/acpi/tables/tbfadt.c b/trunk/drivers/acpi/tables/tbfadt.c deleted file mode 100644 index 807c7116e94b..000000000000 --- a/trunk/drivers/acpi/tables/tbfadt.c +++ /dev/null @@ -1,434 +0,0 @@ -/****************************************************************************** - * - * Module Name: tbfadt - FADT table utilities - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2007, R. Byron Moore - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#include -#include - -#define _COMPONENT ACPI_TABLES -ACPI_MODULE_NAME("tbfadt") - -/* Local prototypes */ -static void inline -acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, - u8 bit_width, u64 address); - -static void acpi_tb_convert_fadt(void); - -static void acpi_tb_validate_fadt(void); - -/* Table for conversion of FADT to common internal format and FADT validation */ - -typedef struct acpi_fadt_info { - char *name; - u8 target; - u8 source; - u8 length; - u8 type; - -} acpi_fadt_info; - -#define ACPI_FADT_REQUIRED 1 -#define ACPI_FADT_SEPARATE_LENGTH 2 - -static struct acpi_fadt_info fadt_info_table[] = { - {"Pm1aEventBlock", ACPI_FADT_OFFSET(xpm1a_event_block), - ACPI_FADT_OFFSET(pm1a_event_block), - ACPI_FADT_OFFSET(pm1_event_length), ACPI_FADT_REQUIRED}, - - {"Pm1bEventBlock", ACPI_FADT_OFFSET(xpm1b_event_block), - ACPI_FADT_OFFSET(pm1b_event_block), - ACPI_FADT_OFFSET(pm1_event_length), 0}, - - {"Pm1aControlBlock", ACPI_FADT_OFFSET(xpm1a_control_block), - ACPI_FADT_OFFSET(pm1a_control_block), - ACPI_FADT_OFFSET(pm1_control_length), ACPI_FADT_REQUIRED}, - - {"Pm1bControlBlock", ACPI_FADT_OFFSET(xpm1b_control_block), - ACPI_FADT_OFFSET(pm1b_control_block), - ACPI_FADT_OFFSET(pm1_control_length), 0}, - - {"Pm2ControlBlock", ACPI_FADT_OFFSET(xpm2_control_block), - ACPI_FADT_OFFSET(pm2_control_block), - ACPI_FADT_OFFSET(pm2_control_length), ACPI_FADT_SEPARATE_LENGTH}, - - {"PmTimerBlock", ACPI_FADT_OFFSET(xpm_timer_block), - ACPI_FADT_OFFSET(pm_timer_block), - ACPI_FADT_OFFSET(pm_timer_length), ACPI_FADT_REQUIRED}, - - {"Gpe0Block", ACPI_FADT_OFFSET(xgpe0_block), - ACPI_FADT_OFFSET(gpe0_block), - ACPI_FADT_OFFSET(gpe0_block_length), ACPI_FADT_SEPARATE_LENGTH}, - - {"Gpe1Block", ACPI_FADT_OFFSET(xgpe1_block), - ACPI_FADT_OFFSET(gpe1_block), - ACPI_FADT_OFFSET(gpe1_block_length), ACPI_FADT_SEPARATE_LENGTH} -}; - -#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) - -/******************************************************************************* - * - * FUNCTION: acpi_tb_init_generic_address - * - * PARAMETERS: generic_address - GAS struct to be initialized - * bit_width - Width of this register - * Address - Address of the register - * - * RETURN: None - * - * DESCRIPTION: Initialize a Generic Address Structure (GAS) - * See the ACPI specification for a full description and - * definition of this structure. - * - ******************************************************************************/ - -static void inline -acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, - u8 bit_width, u64 address) -{ - - /* - * The 64-bit Address field is non-aligned in the byte packed - * GAS struct. - */ - ACPI_MOVE_64_TO_64(&generic_address->address, &address); - - /* All other fields are byte-wide */ - - generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO; - generic_address->bit_width = bit_width; - generic_address->bit_offset = 0; - generic_address->access_width = 0; -} - -/******************************************************************************* - * - * FUNCTION: acpi_tb_parse_fadt - * - * PARAMETERS: table_index - Index for the FADT - * Flags - Flags - * - * RETURN: None - * - * DESCRIPTION: Initialize the FADT, DSDT and FACS tables - * (FADT contains the addresses of the DSDT and FACS) - * - ******************************************************************************/ - -void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) -{ - u32 length; - struct acpi_table_header *table; - - /* - * The FADT has multiple versions with different lengths, - * and it contains pointers to both the DSDT and FACS tables. - * - * Get a local copy of the FADT and convert it to a common format - * Map entire FADT, assumed to be smaller than one page. - */ - length = acpi_gbl_root_table_list.tables[table_index].length; - - table = - acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index]. - address, length); - if (!table) { - return; - } - - /* - * Validate the FADT checksum before we copy the table. Ignore - * checksum error as we want to try to get the DSDT and FACS. - */ - (void)acpi_tb_verify_checksum(table, length); - - /* Obtain a local copy of the FADT in common ACPI 2.0+ format */ - - acpi_tb_create_local_fadt(table, length); - - /* All done with the real FADT, unmap it */ - - acpi_os_unmap_memory(table, length); - - /* Obtain the DSDT and FACS tables via their addresses within the FADT */ - - acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, - flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); - - acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, - flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); -} - -/******************************************************************************* - * - * FUNCTION: acpi_tb_create_local_fadt - * - * PARAMETERS: Table - Pointer to BIOS FADT - * Length - Length of the table - * - * RETURN: None - * - * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. - * Performs validation on some important FADT fields. - * - ******************************************************************************/ - -void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) -{ - - /* - * Check if the FADT is larger than what we know about (ACPI 2.0 version). - * Truncate the table, but make some noise. - */ - if (length > sizeof(struct acpi_table_fadt)) { - ACPI_WARNING((AE_INFO, - "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%zX", - table->revision, (unsigned)length, - sizeof(struct acpi_table_fadt))); - } - - /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ - - ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); - - ACPI_MEMCPY(&acpi_gbl_FADT, table, - ACPI_MIN(length, sizeof(struct acpi_table_fadt))); - - /* - * 1) Convert the local copy of the FADT to the common internal format - * 2) Validate some of the important values within the FADT - */ - acpi_tb_convert_fadt(); - acpi_tb_validate_fadt(); -} - -/******************************************************************************* - * - * FUNCTION: acpi_tb_convert_fadt - * - * PARAMETERS: None, uses acpi_gbl_FADT - * - * RETURN: None - * - * DESCRIPTION: Converts all versions of the FADT to a common internal format. - * -> Expand all 32-bit addresses to 64-bit. - * - * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), - * and must contain a copy of the actual FADT. - * - * ACPICA will use the "X" fields of the FADT for all addresses. - * - * "X" fields are optional extensions to the original V1.0 fields. Even if - * they are present in the structure, they can be optionally not used by - * setting them to zero. Therefore, we must selectively expand V1.0 fields - * if the corresponding X field is zero. - * - * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding - * "X" fields. - * - * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by - * expanding the corresponding ACPI 1.0 field. - * - ******************************************************************************/ - -static void acpi_tb_convert_fadt(void) -{ - u8 pm1_register_length; - struct acpi_generic_address *target; - acpi_native_uint i; - - /* Update the local FADT table header length */ - - acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); - - /* Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary */ - - if (!acpi_gbl_FADT.Xfacs) { - acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; - } - - if (!acpi_gbl_FADT.Xdsdt) { - acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; - } - - /* - * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address - * structures as necessary. - */ - for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { - target = - ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, - fadt_info_table[i].target); - - /* Expand only if the X target is null */ - - if (!target->address) { - acpi_tb_init_generic_address(target, - *ACPI_ADD_PTR(u8, - &acpi_gbl_FADT, - fadt_info_table - [i].length), - (u64) * ACPI_ADD_PTR(u32, - &acpi_gbl_FADT, - fadt_info_table - [i]. - source)); - } - } - - /* - * Calculate separate GAS structs for the PM1 Enable registers. - * These addresses do not appear (directly) in the FADT, so it is - * useful to calculate them once, here. - * - * The PM event blocks are split into two register blocks, first is the - * PM Status Register block, followed immediately by the PM Enable Register - * block. Each is of length (pm1_event_length/2) - */ - pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length); - - /* The PM1A register block is required */ - - acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, - pm1_register_length, - (acpi_gbl_FADT.xpm1a_event_block.address + - pm1_register_length)); - /* Don't forget to copy space_id of the GAS */ - acpi_gbl_xpm1a_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id; - - /* The PM1B register block is optional, ignore if not present */ - - if (acpi_gbl_FADT.xpm1b_event_block.address) { - acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, - pm1_register_length, - (acpi_gbl_FADT.xpm1b_event_block. - address + pm1_register_length)); - /* Don't forget to copy space_id of the GAS */ - acpi_gbl_xpm1b_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id; - - } -} - -/****************************************************************************** - * - * FUNCTION: acpi_tb_validate_fadt - * - * PARAMETERS: Table - Pointer to the FADT to be validated - * - * RETURN: None - * - * DESCRIPTION: Validate various important fields within the FADT. If a problem - * is found, issue a message, but no status is returned. - * Used by both the table manager and the disassembler. - * - * Possible additional checks: - * (acpi_gbl_FADT.pm1_event_length >= 4) - * (acpi_gbl_FADT.pm1_control_length >= 2) - * (acpi_gbl_FADT.pm_timer_length >= 4) - * Gpe block lengths must be multiple of 2 - * - ******************************************************************************/ - -static void acpi_tb_validate_fadt(void) -{ - u32 *address32; - struct acpi_generic_address *address64; - u8 length; - acpi_native_uint i; - - /* Examine all of the 64-bit extended address fields (X fields) */ - - for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { - - /* Generate pointers to the 32-bit and 64-bit addresses and get the length */ - - address64 = - ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, - fadt_info_table[i].target); - address32 = - ACPI_ADD_PTR(u32, &acpi_gbl_FADT, - fadt_info_table[i].source); - length = - *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, - fadt_info_table[i].length); - - if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { - /* - * Field is required (Pm1a_event, Pm1a_control, pm_timer). - * Both the address and length must be non-zero. - */ - if (!address64->address || !length) { - ACPI_ERROR((AE_INFO, - "Required field \"%s\" has zero address and/or length: %8.8X%8.8X/%X", - fadt_info_table[i].name, - ACPI_FORMAT_UINT64(address64-> - address), - length)); - } - } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { - /* - * Field is optional (PM2Control, GPE0, GPE1) AND has its own - * length field. If present, both the address and length must be valid. - */ - if ((address64->address && !length) - || (!address64->address && length)) { - ACPI_WARNING((AE_INFO, - "Optional field \"%s\" has zero address or length: %8.8X%8.8X/%X", - fadt_info_table[i].name, - ACPI_FORMAT_UINT64(address64-> - address), - length)); - } - } - - /* If both 32- and 64-bit addresses are valid (non-zero), they must match */ - - if (address64->address && *address32 && - (address64->address != (u64) * address32)) { - ACPI_ERROR((AE_INFO, - "32/64X address mismatch in \"%s\": [%8.8X] [%8.8X%8.8X], using 64X", - fadt_info_table[i].name, *address32, - ACPI_FORMAT_UINT64(address64->address))); - } - } -} diff --git a/trunk/drivers/acpi/tables/tbfind.c b/trunk/drivers/acpi/tables/tbfind.c deleted file mode 100644 index 058c064948e1..000000000000 --- a/trunk/drivers/acpi/tables/tbfind.c +++ /dev/null @@ -1,126 +0,0 @@ -/****************************************************************************** - * - * Module Name: tbfind - find table - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2007, R. Byron Moore - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#include -#include - -#define _COMPONENT ACPI_TABLES -ACPI_MODULE_NAME("tbfind") - -/******************************************************************************* - * - * FUNCTION: acpi_tb_find_table - * - * PARAMETERS: Signature - String with ACPI table signature - * oem_id - String with the table OEM ID - * oem_table_id - String with the OEM Table ID - * table_index - Where the table index is returned - * - * RETURN: Status and table index - * - * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the - * Signature, OEM ID and OEM Table ID. Returns an index that can - * be used to get the table header or entire table. - * - ******************************************************************************/ -acpi_status -acpi_tb_find_table(char *signature, - char *oem_id, - char *oem_table_id, acpi_native_uint * table_index) -{ - acpi_native_uint i; - acpi_status status; - - ACPI_FUNCTION_TRACE(tb_find_table); - - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature), - signature, ACPI_NAME_SIZE)) { - - /* Not the requested table */ - - continue; - } - - /* Table with matching signature has been found */ - - if (!acpi_gbl_root_table_list.tables[i].pointer) { - - /* Table is not currently mapped, map it */ - - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list. - tables[i]); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - if (!acpi_gbl_root_table_list.tables[i].pointer) { - continue; - } - } - - /* Check for table match on all IDs */ - - if (!ACPI_MEMCMP - (acpi_gbl_root_table_list.tables[i].pointer->signature, - signature, ACPI_NAME_SIZE) && (!oem_id[0] - || - !ACPI_MEMCMP - (acpi_gbl_root_table_list. - tables[i].pointer->oem_id, - oem_id, ACPI_OEM_ID_SIZE)) - && (!oem_table_id[0] - || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i]. - pointer->oem_table_id, oem_table_id, - ACPI_OEM_TABLE_ID_SIZE))) { - *table_index = i; - - ACPI_DEBUG_PRINT((ACPI_DB_TABLES, - "Found table [%4.4s]\n", signature)); - return_ACPI_STATUS(AE_OK); - } - } - - return_ACPI_STATUS(AE_NOT_FOUND); -} diff --git a/trunk/drivers/acpi/tables/tbget.c b/trunk/drivers/acpi/tables/tbget.c new file mode 100644 index 000000000000..11e2d4454e05 --- /dev/null +++ b/trunk/drivers/acpi/tables/tbget.c @@ -0,0 +1,471 @@ +/****************************************************************************** + * + * Module Name: tbget - ACPI Table get* routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbget") + +/* Local prototypes */ +static acpi_status +acpi_tb_get_this_table(struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info); + +static acpi_status +acpi_tb_table_override(struct acpi_table_header *header, + struct acpi_table_desc *table_info); + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table + * + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * table_info - Where table info is returned + * + * RETURN: None + * + * DESCRIPTION: Get entire table of unknown size. + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_table(struct acpi_pointer *address, + struct acpi_table_desc *table_info) +{ + acpi_status status; + struct acpi_table_header header; + + ACPI_FUNCTION_TRACE(tb_get_table); + + /* Get the header in order to get signature and table size */ + + status = acpi_tb_get_table_header(address, &header); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the entire table */ + + status = acpi_tb_get_table_body(address, &header, table_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not get ACPI table (size %X)", + header.length)); + return_ACPI_STATUS(status); + } + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_header + * + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * return_header - Where the table header is returned + * + * RETURN: Status + * + * DESCRIPTION: Get an ACPI table header. Works in both physical or virtual + * addressing mode. Works with both physical or logical pointers. + * Table is either copied or mapped, depending on the pointer + * type and mode of the processor. + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_table_header(struct acpi_pointer *address, + struct acpi_table_header *return_header) +{ + acpi_status status = AE_OK; + struct acpi_table_header *header = NULL; + + ACPI_FUNCTION_TRACE(tb_get_table_header); + + /* + * Flags contains the current processor mode (Virtual or Physical + * addressing) The pointer_type is either Logical or Physical + */ + switch (address->pointer_type) { + case ACPI_PHYSMODE_PHYSPTR: + case ACPI_LOGMODE_LOGPTR: + + /* Pointer matches processor mode, copy the header */ + + ACPI_MEMCPY(return_header, address->pointer.logical, + sizeof(struct acpi_table_header)); + break; + + case ACPI_LOGMODE_PHYSPTR: + + /* Create a logical address for the physical pointer */ + + status = acpi_os_map_memory(address->pointer.physical, + sizeof(struct acpi_table_header), + (void *)&header); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X%8.8X for table header", + ACPI_FORMAT_UINT64(address->pointer. + physical))); + return_ACPI_STATUS(status); + } + + /* Copy header and delete mapping */ + + ACPI_MEMCPY(return_header, header, + sizeof(struct acpi_table_header)); + acpi_os_unmap_memory(header, sizeof(struct acpi_table_header)); + break; + + default: + + ACPI_ERROR((AE_INFO, "Invalid address flags %X", + address->pointer_type)); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n", + return_header->signature)); + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_body + * + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * Header - Header of the table to retrieve + * table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to + * replace the table with a newer version (table override.) + * Works in both physical or virtual + * addressing mode. Works with both physical or logical pointers. + * Table is either copied or mapped, depending on the pointer + * type and mode of the processor. + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_table_body(struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(tb_get_table_body); + + if (!table_info || !address) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Attempt table override. */ + + status = acpi_tb_table_override(header, table_info); + if (ACPI_SUCCESS(status)) { + + /* Table was overridden by the host OS */ + + return_ACPI_STATUS(status); + } + + /* No override, get the original table */ + + status = acpi_tb_get_this_table(address, header, table_info); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_table_override + * + * PARAMETERS: Header - Pointer to table header + * table_info - Return info if table is overridden + * + * RETURN: None + * + * DESCRIPTION: Attempts override of current table with a new one if provided + * by the host OS. + * + ******************************************************************************/ + +static acpi_status +acpi_tb_table_override(struct acpi_table_header *header, + struct acpi_table_desc *table_info) +{ + struct acpi_table_header *new_table; + acpi_status status; + struct acpi_pointer address; + + ACPI_FUNCTION_TRACE(tb_table_override); + + /* + * The OSL will examine the header and decide whether to override this + * table. If it decides to override, a table will be returned in new_table, + * which we will then copy. + */ + status = acpi_os_table_override(header, &new_table); + if (ACPI_FAILURE(status)) { + + /* Some severe error from the OSL, but we basically ignore it */ + + ACPI_EXCEPTION((AE_INFO, status, + "Could not override ACPI table")); + return_ACPI_STATUS(status); + } + + if (!new_table) { + + /* No table override */ + + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + /* + * We have a new table to override the old one. Get a copy of + * the new one. We know that the new table has a logical pointer. + */ + address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; + address.pointer.logical = new_table; + + status = acpi_tb_get_this_table(&address, new_table, table_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table")); + return_ACPI_STATUS(status); + } + + /* Copy the table info */ + + ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS", + table_info->pointer->signature)); + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_this_table + * + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * Header - Header of the table to retrieve + * table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual + * addressing mode. Works with both physical or logical pointers. + * Table is either copied or mapped, depending on the pointer + * type and mode of the processor. + * + ******************************************************************************/ + +static acpi_status +acpi_tb_get_this_table(struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info) +{ + struct acpi_table_header *full_table = NULL; + u8 allocation; + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE(tb_get_this_table); + + /* Validate minimum length */ + + if (header->length < sizeof(struct acpi_table_header)) { + ACPI_ERROR((AE_INFO, + "Table length (%X) is smaller than minimum (%zX)", + header->length, sizeof(struct acpi_table_header))); + + return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); + } + + /* + * Flags contains the current processor mode (Virtual or Physical + * addressing) The pointer_type is either Logical or Physical + */ + switch (address->pointer_type) { + case ACPI_PHYSMODE_PHYSPTR: + case ACPI_LOGMODE_LOGPTR: + + /* Pointer matches processor mode, copy the table to a new buffer */ + + full_table = ACPI_ALLOCATE(header->length); + if (!full_table) { + ACPI_ERROR((AE_INFO, + "Could not allocate table memory for [%4.4s] length %X", + header->signature, header->length)); + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Copy the entire table (including header) to the local buffer */ + + ACPI_MEMCPY(full_table, address->pointer.logical, + header->length); + + /* Save allocation type */ + + allocation = ACPI_MEM_ALLOCATED; + break; + + case ACPI_LOGMODE_PHYSPTR: + + /* + * Just map the table's physical memory + * into our address space. + */ + status = acpi_os_map_memory(address->pointer.physical, + (acpi_size) header->length, + ACPI_CAST_PTR(void, &full_table)); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X", + header->signature, + ACPI_FORMAT_UINT64(address->pointer. + physical), + header->length)); + return (status); + } + + /* Save allocation type */ + + allocation = ACPI_MEM_MAPPED; + break; + + default: + + ACPI_ERROR((AE_INFO, "Invalid address flags %X", + address->pointer_type)); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* + * Validate checksum for _most_ tables, + * even the ones whose signature we don't recognize + */ + if (table_info->type != ACPI_TABLE_ID_FACS) { + status = acpi_tb_verify_table_checksum(full_table); + +#if (!ACPI_CHECKSUM_ABORT) + if (ACPI_FAILURE(status)) { + + /* Ignore the error if configuration says so */ + + status = AE_OK; + } +#endif + } + + /* Return values */ + + table_info->pointer = full_table; + table_info->length = (acpi_size) header->length; + table_info->allocation = allocation; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n", + full_table->signature, + ACPI_FORMAT_UINT64(address->pointer.physical), + full_table)); + + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_ptr + * + * PARAMETERS: table_type - one of the defined table types + * Instance - Which table of this type + * return_table - pointer to location to place the pointer for + * return + * + * RETURN: Status + * + * DESCRIPTION: This function is called to get the pointer to an ACPI table. + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_table_ptr(acpi_table_type table_type, + u32 instance, struct acpi_table_header **return_table) +{ + struct acpi_table_desc *table_desc; + u32 i; + + ACPI_FUNCTION_TRACE(tb_get_table_ptr); + + if (table_type > ACPI_TABLE_ID_MAX) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Check for instance out of range of the current table count */ + + if (instance > acpi_gbl_table_lists[table_type].count) { + return_ACPI_STATUS(AE_NOT_EXIST); + } + + /* + * Walk the list to get the desired table + * Note: Instance is one-based + */ + table_desc = acpi_gbl_table_lists[table_type].next; + for (i = 1; i < instance; i++) { + table_desc = table_desc->next; + } + + /* We are now pointing to the requested table's descriptor */ + + *return_table = table_desc->pointer; + return_ACPI_STATUS(AE_OK); +} diff --git a/trunk/drivers/acpi/tables/tbgetall.c b/trunk/drivers/acpi/tables/tbgetall.c new file mode 100644 index 000000000000..ad982112e4c6 --- /dev/null +++ b/trunk/drivers/acpi/tables/tbgetall.c @@ -0,0 +1,311 @@ +/****************************************************************************** + * + * Module Name: tbgetall - Get all required ACPI tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbgetall") + +/* Local prototypes */ +static acpi_status +acpi_tb_get_primary_table(struct acpi_pointer *address, + struct acpi_table_desc *table_info); + +static acpi_status +acpi_tb_get_secondary_table(struct acpi_pointer *address, + acpi_string signature, + struct acpi_table_desc *table_info); + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_primary_table + * + * PARAMETERS: Address - Physical address of table to retrieve + * *table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Maps the physical address of table into a logical address + * + ******************************************************************************/ + +static acpi_status +acpi_tb_get_primary_table(struct acpi_pointer *address, + struct acpi_table_desc *table_info) +{ + acpi_status status; + struct acpi_table_header header; + + ACPI_FUNCTION_TRACE(tb_get_primary_table); + + /* Ignore a NULL address in the RSDT */ + + if (!address->pointer.value) { + return_ACPI_STATUS(AE_OK); + } + + /* Get the header in order to get signature and table size */ + + status = acpi_tb_get_table_header(address, &header); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Clear the table_info */ + + ACPI_MEMSET(table_info, 0, sizeof(struct acpi_table_desc)); + + /* + * Check the table signature and make sure it is recognized. + * Also checks the header checksum + */ + table_info->pointer = &header; + status = acpi_tb_recognize_table(table_info, ACPI_TABLE_PRIMARY); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the entire table */ + + status = acpi_tb_get_table_body(address, &header, table_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Install the table */ + + status = acpi_tb_install_table(table_info); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_secondary_table + * + * PARAMETERS: Address - Physical address of table to retrieve + * *table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Maps the physical address of table into a logical address + * + ******************************************************************************/ + +static acpi_status +acpi_tb_get_secondary_table(struct acpi_pointer *address, + acpi_string signature, + struct acpi_table_desc *table_info) +{ + acpi_status status; + struct acpi_table_header header; + + ACPI_FUNCTION_TRACE_STR(tb_get_secondary_table, signature); + + /* Get the header in order to match the signature */ + + status = acpi_tb_get_table_header(address, &header); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Signature must match request */ + + if (!ACPI_COMPARE_NAME(header.signature, signature)) { + ACPI_ERROR((AE_INFO, + "Incorrect table signature - wanted [%s] found [%4.4s]", + signature, header.signature)); + return_ACPI_STATUS(AE_BAD_SIGNATURE); + } + + /* + * Check the table signature and make sure it is recognized. + * Also checks the header checksum + */ + table_info->pointer = &header; + status = acpi_tb_recognize_table(table_info, ACPI_TABLE_SECONDARY); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the entire table */ + + status = acpi_tb_get_table_body(address, &header, table_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Install the table */ + + status = acpi_tb_install_table(table_info); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_required_tables + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must + * already be loaded and validated. + * + * Get the minimum set of ACPI tables, namely: + * + * 1) FADT (via RSDT in loop below) + * 2) FACS (via FADT) + * 3) DSDT (via FADT) + * + ******************************************************************************/ + +acpi_status acpi_tb_get_required_tables(void) +{ + acpi_status status = AE_OK; + u32 i; + struct acpi_table_desc table_info; + struct acpi_pointer address; + + ACPI_FUNCTION_TRACE(tb_get_required_tables); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%d ACPI tables in RSDT\n", + acpi_gbl_rsdt_table_count)); + + address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; + + /* + * Loop through all table pointers found in RSDT. + * This will NOT include the FACS and DSDT - we must get + * them after the loop. + * + * The only tables we are interested in getting here is the FADT and + * any SSDTs. + */ + for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { + + /* Get the table address from the common internal XSDT */ + + address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i]; + + /* + * Get the tables needed by this subsystem (FADT and any SSDTs). + * NOTE: All other tables are completely ignored at this time. + */ + status = acpi_tb_get_primary_table(&address, &table_info); + if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) { + ACPI_WARNING((AE_INFO, + "%s, while getting table at %8.8X%8.8X", + acpi_format_exception(status), + ACPI_FORMAT_UINT64(address.pointer. + value))); + } + } + + /* We must have a FADT to continue */ + + if (!acpi_gbl_FADT) { + ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + /* + * Convert the FADT to a common format. This allows earlier revisions of + * the table to coexist with newer versions, using common access code. + */ + status = acpi_tb_convert_table_fadt(); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not convert FADT to internal common format")); + return_ACPI_STATUS(status); + } + + /* Get the FACS (Pointed to by the FADT) */ + + address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl; + + status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not get/install the FACS")); + return_ACPI_STATUS(status); + } + + /* + * Create the common FACS pointer table + * (Contains pointers to the original table) + */ + status = acpi_tb_build_common_facs(&table_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get/install the DSDT (Pointed to by the FADT) */ + + address.pointer.value = acpi_gbl_FADT->Xdsdt; + + status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, "Could not get/install the DSDT")); + return_ACPI_STATUS(status); + } + + /* Set Integer Width (32/64) based upon DSDT revision */ + + acpi_ut_set_integer_width(acpi_gbl_DSDT->revision); + + /* Dump the entire DSDT */ + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, + "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n", + acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, + acpi_gbl_integer_bit_width)); + + ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_DSDT), + acpi_gbl_DSDT->length); + + /* Always delete the RSDP mapping, we are done with it */ + + acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_RSDP); + return_ACPI_STATUS(status); +} diff --git a/trunk/drivers/acpi/tables/tbinstal.c b/trunk/drivers/acpi/tables/tbinstal.c index 0e7b121a99ce..1668a232fb67 100644 --- a/trunk/drivers/acpi/tables/tbinstal.c +++ b/trunk/drivers/acpi/tables/tbinstal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,498 +42,510 @@ */ #include -#include #include #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbinstal") -/****************************************************************************** +/* Local prototypes */ +static acpi_status +acpi_tb_match_signature(char *signature, + struct acpi_table_desc *table_info, u8 search_type); + +/******************************************************************************* * - * FUNCTION: acpi_tb_verify_table + * FUNCTION: acpi_tb_match_signature * - * PARAMETERS: table_desc - table + * PARAMETERS: Signature - Table signature to match + * table_info - Return data + * search_type - Table type to match (primary/secondary) * * RETURN: Status * - * DESCRIPTION: this function is called to verify and map table + * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned" + * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match. * - *****************************************************************************/ -acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) + ******************************************************************************/ + +static acpi_status +acpi_tb_match_signature(char *signature, + struct acpi_table_desc *table_info, u8 search_type) { - acpi_status status = AE_OK; + acpi_native_uint i; - ACPI_FUNCTION_TRACE(tb_verify_table); + ACPI_FUNCTION_TRACE(tb_match_signature); - /* Map the table if necessary */ + /* Search for a signature match among the known table types */ - if (!table_desc->pointer) { - if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == - ACPI_TABLE_ORIGIN_MAPPED) { - table_desc->pointer = - acpi_os_map_memory(table_desc->address, - table_desc->length); - } - if (!table_desc->pointer) { - return_ACPI_STATUS(AE_NO_MEMORY); + for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { + if (!(acpi_gbl_table_data[i].flags & search_type)) { + continue; } - } - /* FACS is the odd table, has no standard ACPI header and no checksum */ + if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature, + acpi_gbl_table_data[i].sig_length)) { + + /* Found a signature match, return index if requested */ - if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) { + if (table_info) { + table_info->type = (u8) i; + } - /* Always calculate checksum, ignore bad checksum if requested */ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Table [%4.4s] is an ACPI table consumed by the core subsystem\n", + (char *)acpi_gbl_table_data[i]. + signature)); - status = - acpi_tb_verify_checksum(table_desc->pointer, - table_desc->length); + return_ACPI_STATUS(AE_OK); + } } - return_ACPI_STATUS(status); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n", + (char *)signature)); + + return_ACPI_STATUS(AE_TABLE_NOT_SUPPORTED); } /******************************************************************************* * - * FUNCTION: acpi_tb_add_table + * FUNCTION: acpi_tb_install_table * - * PARAMETERS: table_desc - Table descriptor - * table_index - Where the table index is returned + * PARAMETERS: table_info - Return value from acpi_tb_get_table_body * * RETURN: Status * - * DESCRIPTION: This function is called to add the ACPI table + * DESCRIPTION: Install the table into the global data structures. * ******************************************************************************/ -acpi_status -acpi_tb_add_table(struct acpi_table_desc *table_desc, - acpi_native_uint * table_index) +acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) { - acpi_native_uint i; - acpi_native_uint length; - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE(tb_add_table); + acpi_status status; - if (!table_desc->pointer) { - status = acpi_tb_verify_table(table_desc); - if (ACPI_FAILURE(status) || !table_desc->pointer) { - return_ACPI_STATUS(status); - } - } - - /* The table must be either an SSDT or a PSDT */ - - if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)) - && - (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))) - { - ACPI_ERROR((AE_INFO, - "Table has invalid signature [%4.4s], must be SSDT or PSDT", - table_desc->pointer->signature)); - return_ACPI_STATUS(AE_BAD_SIGNATURE); - } + ACPI_FUNCTION_TRACE(tb_install_table); - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + /* Lock tables while installing */ - /* Check if table is already registered */ - - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - if (!acpi_gbl_root_table_list.tables[i].pointer) { - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list. - tables[i]); - if (ACPI_FAILURE(status) - || !acpi_gbl_root_table_list.tables[i].pointer) { - continue; - } - } - - length = ACPI_MIN(table_desc->length, - acpi_gbl_root_table_list.tables[i].length); - if (ACPI_MEMCMP(table_desc->pointer, - acpi_gbl_root_table_list.tables[i].pointer, - length)) { - continue; - } - - /* Table is already registered */ - - acpi_tb_delete_table(table_desc); - *table_index = i; - goto release; + status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not acquire table mutex")); + return_ACPI_STATUS(status); } /* - * Add the table to the global table list + * Ignore a table that is already installed. For example, some BIOS + * ASL code will repeatedly attempt to load the same SSDT. */ - status = acpi_tb_store_table(table_desc->address, table_desc->pointer, - table_desc->length, table_desc->flags, - table_index); + status = acpi_tb_is_table_installed(table_info); + if (ACPI_FAILURE(status)) { + goto unlock_and_exit; + } + + /* Install the table into the global data structure */ + + status = acpi_tb_init_table_descriptor(table_info->type, table_info); if (ACPI_FAILURE(status)) { - goto release; + ACPI_EXCEPTION((AE_INFO, status, + "Could not install table [%4.4s]", + table_info->pointer->signature)); } - acpi_tb_print_table_header(table_desc->address, table_desc->pointer); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n", + acpi_gbl_table_data[table_info->type].name, + table_info->pointer)); - release: + unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_tb_resize_root_table_list + * FUNCTION: acpi_tb_recognize_table * - * PARAMETERS: None + * PARAMETERS: table_info - Return value from acpi_tb_get_table_body + * search_type - Table type to match (primary/secondary) * * RETURN: Status * - * DESCRIPTION: Expand the size of global table array + * DESCRIPTION: Check a table signature for a match against known table types + * + * NOTE: All table pointers are validated as follows: + * 1) Table pointer must point to valid physical memory + * 2) Signature must be 4 ASCII chars, even if we don't recognize the + * name + * 3) Table must be readable for length specified in the header + * 4) Table checksum must be valid (with the exception of the FACS + * which has no checksum for some odd reason) * ******************************************************************************/ -acpi_status acpi_tb_resize_root_table_list(void) +acpi_status +acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type) { - struct acpi_table_desc *tables; + struct acpi_table_header *table_header; + acpi_status status; - ACPI_FUNCTION_TRACE(tb_resize_root_table_list); + ACPI_FUNCTION_TRACE(tb_recognize_table); - /* allow_resize flag is a parameter to acpi_initialize_tables */ + /* Ensure that we have a valid table pointer */ - if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { - ACPI_ERROR((AE_INFO, - "Resize of Root Table Array is not allowed")); - return_ACPI_STATUS(AE_SUPPORT); + table_header = (struct acpi_table_header *)table_info->pointer; + if (!table_header) { + return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Increase the Table Array size */ - - tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size + - ACPI_ROOT_TABLE_SIZE_INCREMENT) - * sizeof(struct acpi_table_desc)); - if (!tables) { - ACPI_ERROR((AE_INFO, - "Could not allocate new root table array")); - return_ACPI_STATUS(AE_NO_MEMORY); + /* + * We only "recognize" a limited number of ACPI tables -- namely, the + * ones that are used by the subsystem (DSDT, FADT, etc.) + * + * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized. + * This can be any one of many valid ACPI tables, it just isn't one of + * the tables that is consumed by the core subsystem + */ + status = acpi_tb_match_signature(table_header->signature, + table_info, search_type); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - /* Copy and free the previous table array */ - - if (acpi_gbl_root_table_list.tables) { - ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, - acpi_gbl_root_table_list.size * - sizeof(struct acpi_table_desc)); - - if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { - ACPI_FREE(acpi_gbl_root_table_list.tables); - } + status = acpi_tb_validate_table_header(table_header); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - acpi_gbl_root_table_list.tables = tables; - acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT; - acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED; + /* Return the table type and length via the info struct */ - return_ACPI_STATUS(AE_OK); + table_info->length = (acpi_size) table_header->length; + return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_tb_store_table + * FUNCTION: acpi_tb_init_table_descriptor * - * PARAMETERS: Address - Table address - * Table - Table header - * Length - Table length - * Flags - flags + * PARAMETERS: table_type - The type of the table + * table_info - A table info struct * - * RETURN: Status and table index. + * RETURN: None. * - * DESCRIPTION: Add an ACPI table to the global table list + * DESCRIPTION: Install a table into the global data structs. * ******************************************************************************/ acpi_status -acpi_tb_store_table(acpi_physical_address address, - struct acpi_table_header *table, - u32 length, u8 flags, acpi_native_uint * table_index) +acpi_tb_init_table_descriptor(acpi_table_type table_type, + struct acpi_table_desc *table_info) { - acpi_status status = AE_OK; + struct acpi_table_list *list_head; + struct acpi_table_desc *table_desc; + acpi_status status; - /* Ensure that there is room for the table in the Root Table List */ + ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type); - if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) { - status = acpi_tb_resize_root_table_list(); - if (ACPI_FAILURE(status)) { - return (status); - } + /* Allocate a descriptor for this table */ + + table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); + if (!table_desc) { + return_ACPI_STATUS(AE_NO_MEMORY); } - /* Initialize added table */ - - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. - address = address; - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. - pointer = table; - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length = - length; - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. - owner_id = 0; - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags = - flags; - - ACPI_MOVE_32_TO_32(& - (acpi_gbl_root_table_list. - tables[acpi_gbl_root_table_list.count].signature), - table->signature); - - *table_index = acpi_gbl_root_table_list.count; - acpi_gbl_root_table_list.count++; - return (status); -} + /* Get a new owner ID for the table */ -/******************************************************************************* - * - * FUNCTION: acpi_tb_delete_table - * - * PARAMETERS: table_index - Table index - * - * RETURN: None - * - * DESCRIPTION: Delete one internal ACPI table - * - ******************************************************************************/ - -void acpi_tb_delete_table(struct acpi_table_desc *table_desc) -{ - /* Table must be mapped or allocated */ - if (!table_desc->pointer) { - return; - } - switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { - case ACPI_TABLE_ORIGIN_MAPPED: - acpi_os_unmap_memory(table_desc->pointer, table_desc->length); - break; - case ACPI_TABLE_ORIGIN_ALLOCATED: - ACPI_FREE(table_desc->pointer); - break; - default:; + status = acpi_ut_allocate_owner_id(&table_desc->owner_id); + if (ACPI_FAILURE(status)) { + goto error_exit1; } - table_desc->pointer = NULL; -} + /* Install the table into the global data structure */ -/******************************************************************************* - * - * FUNCTION: acpi_tb_terminate - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Delete all internal ACPI tables - * - ******************************************************************************/ + list_head = &acpi_gbl_table_lists[table_type]; -void acpi_tb_terminate(void) -{ - acpi_native_uint i; + /* + * Two major types of tables: 1) Only one instance is allowed. This + * includes most ACPI tables such as the DSDT. 2) Multiple instances of + * the table are allowed. This includes SSDT and PSDTs. + */ + if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) { + /* + * Only one table allowed, and a table has alread been installed + * at this location, so return an error. + */ + if (list_head->next) { + status = AE_ALREADY_EXISTS; + goto error_exit2; + } - ACPI_FUNCTION_TRACE(tb_terminate); + table_desc->next = list_head->next; + list_head->next = table_desc; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (table_desc->next) { + table_desc->next->prev = table_desc; + } - /* Delete the individual tables */ + list_head->count++; + } else { + /* + * Link the new table in to the list of tables of this type. + * Insert at the end of the list, order IS IMPORTANT. + * + * table_desc->Prev & Next are already NULL from calloc() + */ + list_head->count++; + + if (!list_head->next) { + list_head->next = table_desc; + } else { + table_desc->next = list_head->next; + + while (table_desc->next->next) { + table_desc->next = table_desc->next->next; + } - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); + table_desc->next->next = table_desc; + table_desc->prev = table_desc->next; + table_desc->next = NULL; + } } + /* Finish initialization of the table descriptor */ + + table_desc->loaded_into_namespace = FALSE; + table_desc->type = (u8) table_type; + table_desc->pointer = table_info->pointer; + table_desc->length = table_info->length; + table_desc->allocation = table_info->allocation; + table_desc->aml_start = (u8 *) (table_desc->pointer + 1), + table_desc->aml_length = (u32) + (table_desc->length - (u32) sizeof(struct acpi_table_header)); + /* - * Delete the root table array if allocated locally. Array cannot be - * mapped, so we don't need to check for that flag. + * Set the appropriate global pointer (if there is one) to point to the + * newly installed table */ - if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { - ACPI_FREE(acpi_gbl_root_table_list.tables); + if (acpi_gbl_table_data[table_type].global_ptr) { + *(acpi_gbl_table_data[table_type].global_ptr) = + table_info->pointer; } - acpi_gbl_root_table_list.tables = NULL; - acpi_gbl_root_table_list.flags = 0; - acpi_gbl_root_table_list.count = 0; + /* Return Data */ - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + table_info->owner_id = table_desc->owner_id; + table_info->installed_desc = table_desc; + return_ACPI_STATUS(AE_OK); + + /* Error exit with cleanup */ + + error_exit2: + + acpi_ut_release_owner_id(&table_desc->owner_id); + + error_exit1: + + ACPI_FREE(table_desc); + return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_tb_delete_namespace_by_owner + * FUNCTION: acpi_tb_delete_all_tables * - * PARAMETERS: table_index - Table index + * PARAMETERS: None. * - * RETURN: None + * RETURN: None. * - * DESCRIPTION: Delete all namespace objects created when this table was loaded. + * DESCRIPTION: Delete all internal ACPI tables * ******************************************************************************/ -void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index) +void acpi_tb_delete_all_tables(void) { - acpi_owner_id owner_id; + acpi_table_type type; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - owner_id = - acpi_gbl_root_table_list.tables[table_index].owner_id; - } else { - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return; + /* + * Free memory allocated for ACPI tables + * Memory can either be mapped or allocated + */ + for (type = 0; type < (ACPI_TABLE_ID_MAX + 1); type++) { + acpi_tb_delete_tables_by_type(type); } - - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - acpi_ns_delete_namespace_by_owner(owner_id); } /******************************************************************************* * - * FUNCTION: acpi_tb_allocate_owner_id + * FUNCTION: acpi_tb_delete_tables_by_type * - * PARAMETERS: table_index - Table index + * PARAMETERS: Type - The table type to be deleted * - * RETURN: Status + * RETURN: None. * - * DESCRIPTION: Allocates owner_id in table_desc + * DESCRIPTION: Delete an internal ACPI table + * Locks the ACPI table mutex * ******************************************************************************/ -acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index) +void acpi_tb_delete_tables_by_type(acpi_table_type type) { - acpi_status status = AE_BAD_PARAMETER; + struct acpi_table_desc *table_desc; + u32 count; + u32 i; - ACPI_FUNCTION_TRACE(tb_allocate_owner_id); + ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type); - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - status = acpi_ut_allocate_owner_id - (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); + if (type > ACPI_TABLE_ID_MAX) { + return_VOID; } - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); -} + if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) { + return; + } -/******************************************************************************* - * - * FUNCTION: acpi_tb_release_owner_id - * - * PARAMETERS: table_index - Table index - * - * RETURN: Status - * - * DESCRIPTION: Releases owner_id in table_desc - * - ******************************************************************************/ + /* Clear the appropriate "typed" global table pointer */ -acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index) -{ - acpi_status status = AE_BAD_PARAMETER; + switch (type) { + case ACPI_TABLE_ID_RSDP: + acpi_gbl_RSDP = NULL; + break; + + case ACPI_TABLE_ID_DSDT: + acpi_gbl_DSDT = NULL; + break; - ACPI_FUNCTION_TRACE(tb_release_owner_id); + case ACPI_TABLE_ID_FADT: + acpi_gbl_FADT = NULL; + break; + + case ACPI_TABLE_ID_FACS: + acpi_gbl_FACS = NULL; + break; + + case ACPI_TABLE_ID_XSDT: + acpi_gbl_XSDT = NULL; + break; + + case ACPI_TABLE_ID_SSDT: + case ACPI_TABLE_ID_PSDT: + default: + break; + } + + /* + * Free the table + * 1) Get the head of the list + */ + table_desc = acpi_gbl_table_lists[type].next; + count = acpi_gbl_table_lists[type].count; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - acpi_ut_release_owner_id(& - (acpi_gbl_root_table_list. - tables[table_index].owner_id)); - status = AE_OK; + /* + * 2) Walk the entire list, deleting both the allocated tables + * and the table descriptors + */ + for (i = 0; i < count; i++) { + table_desc = acpi_tb_uninstall_table(table_desc); } (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); + return_VOID; } /******************************************************************************* * - * FUNCTION: acpi_tb_get_owner_id + * FUNCTION: acpi_tb_delete_single_table * - * PARAMETERS: table_index - Table index - * owner_id - Where the table owner_id is returned + * PARAMETERS: table_info - A table info struct * - * RETURN: Status + * RETURN: None. * - * DESCRIPTION: returns owner_id for the ACPI table + * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where + * the table was allocated a buffer or was mapped. * ******************************************************************************/ -acpi_status -acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id) +void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc) { - acpi_status status = AE_BAD_PARAMETER; - ACPI_FUNCTION_TRACE(tb_get_owner_id); + /* Must have a valid table descriptor and pointer */ - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - *owner_id = - acpi_gbl_root_table_list.tables[table_index].owner_id; - status = AE_OK; + if ((!table_desc) || (!table_desc->pointer)) { + return; } - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); -} + /* Valid table, determine type of memory allocation */ -/******************************************************************************* - * - * FUNCTION: acpi_tb_is_table_loaded - * - * PARAMETERS: table_index - Table index - * - * RETURN: Table Loaded Flag - * - ******************************************************************************/ + switch (table_desc->allocation) { + case ACPI_MEM_NOT_ALLOCATED: + break; -u8 acpi_tb_is_table_loaded(acpi_native_uint table_index) -{ - u8 is_loaded = FALSE; + case ACPI_MEM_ALLOCATED: - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - is_loaded = (u8) - (acpi_gbl_root_table_list.tables[table_index]. - flags & ACPI_TABLE_IS_LOADED); - } + ACPI_FREE(table_desc->pointer); + break; - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return (is_loaded); + case ACPI_MEM_MAPPED: + + acpi_os_unmap_memory(table_desc->pointer, table_desc->length); + break; + + default: + break; + } } /******************************************************************************* * - * FUNCTION: acpi_tb_set_table_loaded_flag + * FUNCTION: acpi_tb_uninstall_table * - * PARAMETERS: table_index - Table index - * is_loaded - TRUE if table is loaded, FALSE otherwise + * PARAMETERS: table_info - A table info struct * - * RETURN: None + * RETURN: Pointer to the next table in the list (of same type) * - * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. + * DESCRIPTION: Free the memory associated with an internal ACPI table that + * is either installed or has never been installed. + * Table mutex should be locked. * ******************************************************************************/ -void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded) +struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc + *table_desc) { + struct acpi_table_desc *next_desc; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - if (is_loaded) { - acpi_gbl_root_table_list.tables[table_index].flags |= - ACPI_TABLE_IS_LOADED; - } else { - acpi_gbl_root_table_list.tables[table_index].flags &= - ~ACPI_TABLE_IS_LOADED; - } + ACPI_FUNCTION_TRACE_PTR(tb_uninstall_table, table_desc); + + if (!table_desc) { + return_PTR(NULL); } - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + /* Unlink the descriptor from the doubly linked list */ + + if (table_desc->prev) { + table_desc->prev->next = table_desc->next; + } else { + /* Is first on list, update list head */ + + acpi_gbl_table_lists[table_desc->type].next = table_desc->next; + } + + if (table_desc->next) { + table_desc->next->prev = table_desc->prev; + } + + /* Free the memory allocated for the table itself */ + + acpi_tb_delete_single_table(table_desc); + + /* Free the owner ID associated with this table */ + + acpi_ut_release_owner_id(&table_desc->owner_id); + + /* Free the table descriptor */ + + next_desc = table_desc->next; + ACPI_FREE(table_desc); + + /* Return pointer to the next descriptor */ + + return_PTR(next_desc); } diff --git a/trunk/drivers/acpi/tables/tbrsdt.c b/trunk/drivers/acpi/tables/tbrsdt.c new file mode 100644 index 000000000000..86a5fca9b739 --- /dev/null +++ b/trunk/drivers/acpi/tables/tbrsdt.c @@ -0,0 +1,307 @@ +/****************************************************************************** + * + * Module Name: tbrsdt - ACPI RSDT table utilities + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbrsdt") + +/******************************************************************************* + * + * FUNCTION: acpi_tb_verify_rsdp + * + * PARAMETERS: Address - RSDP (Pointer to RSDT) + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ +acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) +{ + struct acpi_table_desc table_info; + acpi_status status; + struct rsdp_descriptor *rsdp; + + ACPI_FUNCTION_TRACE(tb_verify_rsdp); + + switch (address->pointer_type) { + case ACPI_LOGICAL_POINTER: + + rsdp = address->pointer.logical; + break; + + case ACPI_PHYSICAL_POINTER: + /* + * Obtain access to the RSDP structure + */ + status = acpi_os_map_memory(address->pointer.physical, + sizeof(struct rsdp_descriptor), + ACPI_CAST_PTR(void, &rsdp)); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + break; + + default: + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Verify RSDP signature and checksum */ + + status = acpi_tb_validate_rsdp(rsdp); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + /* RSDP is ok. Init the table info */ + + table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp); + table_info.length = sizeof(struct rsdp_descriptor); + + if (address->pointer_type == ACPI_PHYSICAL_POINTER) { + table_info.allocation = ACPI_MEM_MAPPED; + } else { + table_info.allocation = ACPI_MEM_NOT_ALLOCATED; + } + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_RSDP, &table_info); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + /* Save the RSDP in a global for easy access */ + + acpi_gbl_RSDP = + ACPI_CAST_PTR(struct rsdp_descriptor, table_info.pointer); + return_ACPI_STATUS(status); + + /* Error exit */ + cleanup: + + if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) { + acpi_os_unmap_memory(rsdp, sizeof(struct rsdp_descriptor)); + } + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_rsdt_address + * + * PARAMETERS: out_address - Where the address is returned + * + * RETURN: None, Address + * + * DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the + * version of the RSDP and whether the XSDT pointer is valid + * + ******************************************************************************/ + +void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address) +{ + + ACPI_FUNCTION_ENTRY(); + + out_address->pointer_type = + acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; + + /* Use XSDT if it is present */ + + if ((acpi_gbl_RSDP->revision >= 2) && + acpi_gbl_RSDP->xsdt_physical_address) { + out_address->pointer.value = + acpi_gbl_RSDP->xsdt_physical_address; + acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT; + } else { + /* No XSDT, use the RSDT */ + + out_address->pointer.value = + acpi_gbl_RSDP->rsdt_physical_address; + acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_validate_rsdt + * + * PARAMETERS: table_ptr - Addressable pointer to the RSDT. + * + * RETURN: Status + * + * DESCRIPTION: Validate signature for the RSDT or XSDT + * + ******************************************************************************/ + +acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) +{ + char *signature; + + ACPI_FUNCTION_ENTRY(); + + /* Validate minimum length */ + + if (table_ptr->length < sizeof(struct acpi_table_header)) { + ACPI_ERROR((AE_INFO, + "RSDT/XSDT length (%X) is smaller than minimum (%zX)", + table_ptr->length, + sizeof(struct acpi_table_header))); + + return (AE_INVALID_TABLE_LENGTH); + } + + /* Search for appropriate signature, RSDT or XSDT */ + + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + signature = RSDT_SIG; + } else { + signature = XSDT_SIG; + } + + if (!ACPI_COMPARE_NAME(table_ptr->signature, signature)) { + + /* Invalid RSDT or XSDT signature */ + + ACPI_ERROR((AE_INFO, + "Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:")); + + ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20); + + ACPI_ERROR((AE_INFO, + "RSDT/XSDT signature at %X is invalid", + acpi_gbl_RSDP->rsdt_physical_address)); + + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + ACPI_ERROR((AE_INFO, "Looking for RSDT")); + } else { + ACPI_ERROR((AE_INFO, "Looking for XSDT")); + } + + ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48); + return (AE_BAD_SIGNATURE); + } + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_rsdt + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ + +acpi_status acpi_tb_get_table_rsdt(void) +{ + struct acpi_table_desc table_info; + acpi_status status; + struct acpi_pointer address; + + ACPI_FUNCTION_TRACE(tb_get_table_rsdt); + + /* Get the RSDT/XSDT via the RSDP */ + + acpi_tb_get_rsdt_address(&address); + + table_info.type = ACPI_TABLE_ID_XSDT; + status = acpi_tb_get_table(&address, &table_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not get the RSDT/XSDT")); + return_ACPI_STATUS(status); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "RSDP located at %p, points to RSDT physical=%8.8X%8.8X\n", + acpi_gbl_RSDP, + ACPI_FORMAT_UINT64(address.pointer.value))); + + /* Check the RSDT or XSDT signature */ + + status = acpi_tb_validate_rsdt(table_info.pointer); + if (ACPI_FAILURE(status)) { + goto error_cleanup; + } + + /* Get the number of tables defined in the RSDT or XSDT */ + + acpi_gbl_rsdt_table_count = acpi_tb_get_table_count(acpi_gbl_RSDP, + table_info.pointer); + + /* Convert and/or copy to an XSDT structure */ + + status = acpi_tb_convert_to_xsdt(&table_info); + if (ACPI_FAILURE(status)) { + goto error_cleanup; + } + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); + if (ACPI_FAILURE(status)) { + goto error_cleanup; + } + + acpi_gbl_XSDT = + ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); + return_ACPI_STATUS(status); + + error_cleanup: + + /* Free table allocated by acpi_tb_get_table */ + + acpi_tb_delete_single_table(&table_info); + + return_ACPI_STATUS(status); +} diff --git a/trunk/drivers/acpi/tables/tbutils.c b/trunk/drivers/acpi/tables/tbutils.c index 1da64b4518c0..209a401801e3 100644 --- a/trunk/drivers/acpi/tables/tbutils.c +++ b/trunk/drivers/acpi/tables/tbutils.c @@ -1,11 +1,11 @@ /****************************************************************************** * - * Module Name: tbutils - table utilities + * Module Name: tbutils - Table manipulation utilities * *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,119 +48,137 @@ ACPI_MODULE_NAME("tbutils") /* Local prototypes */ -static acpi_physical_address -acpi_tb_get_root_table_entry(u8 * table_entry, - acpi_native_uint table_entry_size); +#ifdef ACPI_OBSOLETE_FUNCTIONS +acpi_status +acpi_tb_handle_to_object(u16 table_id, struct acpi_table_desc **table_desc); +#endif /******************************************************************************* * - * FUNCTION: acpi_tb_tables_loaded + * FUNCTION: acpi_tb_is_table_installed + * + * PARAMETERS: new_table_desc - Descriptor for new table being installed * - * PARAMETERS: None + * RETURN: Status - AE_ALREADY_EXISTS if the table is already installed * - * RETURN: TRUE if required ACPI tables are loaded + * DESCRIPTION: Determine if an ACPI table is already installed * - * DESCRIPTION: Determine if the minimum required ACPI tables are present - * (FADT, FACS, DSDT) + * MUTEX: Table data structures should be locked * ******************************************************************************/ -u8 acpi_tb_tables_loaded(void) +acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) { + struct acpi_table_desc *table_desc; - if (acpi_gbl_root_table_list.count >= 3) { - return (TRUE); - } + ACPI_FUNCTION_TRACE(tb_is_table_installed); - return (FALSE); -} + /* Get the list descriptor and first table descriptor */ -/******************************************************************************* - * - * FUNCTION: acpi_tb_print_table_header - * - * PARAMETERS: Address - Table physical address - * Header - Table header - * - * RETURN: None - * - * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. - * - ******************************************************************************/ + table_desc = acpi_gbl_table_lists[new_table_desc->type].next; -void -acpi_tb_print_table_header(acpi_physical_address address, - struct acpi_table_header *header) -{ + /* Examine all installed tables of this type */ - if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { - - /* FACS only has signature and length fields of common table header */ - - ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X", - header->signature, (unsigned long)address, - header->length)); - } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) { - - /* RSDP has no common fields */ - - ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)", - (unsigned long)address, - (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> - revision > - 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, - header)->length : 20, - ACPI_CAST_PTR(struct acpi_table_rsdp, - header)->revision, - ACPI_CAST_PTR(struct acpi_table_rsdp, - header)->oem_id)); - } else { - /* Standard ACPI table with full common header */ - - ACPI_INFO((AE_INFO, - "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)", - header->signature, (unsigned long)address, - header->length, header->revision, header->oem_id, - header->oem_table_id, header->oem_revision, - header->asl_compiler_id, - header->asl_compiler_revision)); + while (table_desc) { + /* + * If the table lengths match, perform a full bytewise compare. This + * means that we will allow tables with duplicate oem_table_id(s), as + * long as the tables are different in some way. + * + * Checking if the table has been loaded into the namespace means that + * we don't check for duplicate tables during the initial installation + * of tables within the RSDT/XSDT. + */ + if ((table_desc->loaded_into_namespace) && + (table_desc->pointer->length == + new_table_desc->pointer->length) + && + (!ACPI_MEMCMP + (table_desc->pointer, new_table_desc->pointer, + new_table_desc->pointer->length))) { + + /* Match: this table is already installed */ + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, + "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n", + new_table_desc->pointer->signature, + new_table_desc->pointer->revision, + new_table_desc->pointer-> + oem_table_id)); + + new_table_desc->owner_id = table_desc->owner_id; + new_table_desc->installed_desc = table_desc; + + return_ACPI_STATUS(AE_ALREADY_EXISTS); + } + + /* Get next table on the list */ + + table_desc = table_desc->next; } + + return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_tb_validate_checksum + * FUNCTION: acpi_tb_validate_table_header * - * PARAMETERS: Table - ACPI table to verify - * Length - Length of entire table + * PARAMETERS: table_header - Logical pointer to the table * * RETURN: Status * - * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns - * exception on bad checksum. + * DESCRIPTION: Check an ACPI table header for validity + * + * NOTE: Table pointers are validated as follows: + * 1) Table pointer must point to valid physical memory + * 2) Signature must be 4 ASCII chars, even if we don't recognize the + * name + * 3) Table must be readable for length specified in the header + * 4) Table checksum must be valid (with the exception of the FACS + * which has no checksum because it contains variable fields) * ******************************************************************************/ -acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) +acpi_status +acpi_tb_validate_table_header(struct acpi_table_header *table_header) { - u8 checksum; + acpi_name signature; - /* Compute the checksum on the table */ + ACPI_FUNCTION_ENTRY(); + + /* Verify that this is a valid address */ - checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); + if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) { + ACPI_ERROR((AE_INFO, + "Cannot read table header at %p", table_header)); + + return (AE_BAD_ADDRESS); + } - /* Checksum ok? (should be zero) */ + /* Ensure that the signature is 4 ASCII characters */ - if (checksum) { - ACPI_WARNING((AE_INFO, - "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X", - table->signature, table->checksum, - (u8) (table->checksum - checksum))); + ACPI_MOVE_32_TO_32(&signature, table_header->signature); + if (!acpi_ut_valid_acpi_name(signature)) { + ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X", + signature)); -#if (ACPI_CHECKSUM_ABORT) + ACPI_DUMP_BUFFER(table_header, + sizeof(struct acpi_table_header)); + return (AE_BAD_SIGNATURE); + } - return (AE_BAD_CHECKSUM); -#endif + /* Validate the table length */ + + if (table_header->length < sizeof(struct acpi_table_header)) { + ACPI_ERROR((AE_INFO, + "Invalid length 0x%X in table with signature %4.4s", + (u32) table_header->length, + ACPI_CAST_PTR(char, &signature))); + + ACPI_DUMP_BUFFER(table_header, + sizeof(struct acpi_table_header)); + return (AE_BAD_HEADER); } return (AE_OK); @@ -168,320 +186,157 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) /******************************************************************************* * - * FUNCTION: acpi_tb_checksum + * FUNCTION: acpi_tb_sum_table * - * PARAMETERS: Buffer - Pointer to memory region to be checked - * Length - Length of this memory region + * PARAMETERS: Buffer - Buffer to sum + * Length - Size of the buffer * - * RETURN: Checksum (u8) + * RETURN: 8 bit sum of buffer * - * DESCRIPTION: Calculates circular checksum of memory region. + * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. * ******************************************************************************/ -u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) +u8 acpi_tb_sum_table(void *buffer, u32 length) { + acpi_native_uint i; u8 sum = 0; - u8 *end = buffer + length; - while (buffer < end) { - sum = (u8) (sum + *(buffer++)); + if (!buffer || !length) { + return (0); } - return sum; + for (i = 0; i < length; i++) { + sum = (u8) (sum + ((u8 *) buffer)[i]); + } + return (sum); } /******************************************************************************* * - * FUNCTION: acpi_tb_install_table + * FUNCTION: acpi_tb_generate_checksum * - * PARAMETERS: Address - Physical address of DSDT or FACS - * Flags - Flags - * Signature - Table signature, NULL if no need to - * match - * table_index - Index into root table array + * PARAMETERS: Table - Pointer to a valid ACPI table (with a + * standard ACPI header) * - * RETURN: None + * RETURN: 8 bit checksum of buffer * - * DESCRIPTION: Install an ACPI table into the global data structure. + * DESCRIPTION: Computes an 8 bit checksum of the table. * ******************************************************************************/ -void -acpi_tb_install_table(acpi_physical_address address, - u8 flags, char *signature, acpi_native_uint table_index) +u8 acpi_tb_generate_checksum(struct acpi_table_header * table) { - struct acpi_table_header *table; - - if (!address) { - ACPI_ERROR((AE_INFO, - "Null physical address for ACPI table [%s]", - signature)); - return; - } - - /* Map just the table header */ - - table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); - if (!table) { - return; - } - - /* If a particular signature is expected, signature must match */ - - if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { - ACPI_ERROR((AE_INFO, - "Invalid signature 0x%X for ACPI table [%s]", - *ACPI_CAST_PTR(u32, table->signature), signature)); - goto unmap_and_exit; - } - - /* Initialize the table entry */ - - acpi_gbl_root_table_list.tables[table_index].address = address; - acpi_gbl_root_table_list.tables[table_index].length = table->length; - acpi_gbl_root_table_list.tables[table_index].flags = flags; + u8 checksum; - ACPI_MOVE_32_TO_32(& - (acpi_gbl_root_table_list.tables[table_index]. - signature), table->signature); + /* Sum the entire table as-is */ - acpi_tb_print_table_header(address, table); + checksum = acpi_tb_sum_table(table, table->length); - if (table_index == ACPI_TABLE_INDEX_DSDT) { + /* Subtract off the existing checksum value in the table */ - /* Global integer width is based upon revision of the DSDT */ + checksum = (u8) (checksum - table->checksum); - acpi_ut_set_integer_width(table->revision); - } + /* Compute the final checksum */ - unmap_and_exit: - acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + checksum = (u8) (0 - checksum); + return (checksum); } /******************************************************************************* * - * FUNCTION: acpi_tb_get_root_table_entry + * FUNCTION: acpi_tb_set_checksum * - * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry - * table_entry_size - sizeof 32 or 64 (RSDT or XSDT) + * PARAMETERS: Table - Pointer to a valid ACPI table (with a + * standard ACPI header) * - * RETURN: Physical address extracted from the root table + * RETURN: None. Sets the table checksum field * - * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on - * both 32-bit and 64-bit platforms - * - * NOTE: acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on - * 64-bit platforms. + * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the + * checksum into the table header. * ******************************************************************************/ -static acpi_physical_address -acpi_tb_get_root_table_entry(u8 * table_entry, - acpi_native_uint table_entry_size) +void acpi_tb_set_checksum(struct acpi_table_header *table) { - u64 address64; - - /* - * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): - * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT - */ - if (table_entry_size == sizeof(u32)) { - /* - * 32-bit platform, RSDT: Return 32-bit table entry - * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return - */ - return ((acpi_physical_address) - (*ACPI_CAST_PTR(u32, table_entry))); - } else { - /* - * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return - * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit - */ - ACPI_MOVE_64_TO_64(&address64, table_entry); -#if ACPI_MACHINE_WIDTH == 32 - if (address64 > ACPI_UINT32_MAX) { - - /* Will truncate 64-bit address to 32 bits, issue warning */ - - ACPI_WARNING((AE_INFO, - "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating", - ACPI_FORMAT_UINT64(address64))); - } -#endif - return ((acpi_physical_address) (address64)); - } + table->checksum = acpi_tb_generate_checksum(table); } /******************************************************************************* * - * FUNCTION: acpi_tb_parse_root_table - * - * PARAMETERS: Rsdp - Pointer to the RSDP - * Flags - Flags + * FUNCTION: acpi_tb_verify_table_checksum * - * RETURN: Status + * PARAMETERS: *table_header - ACPI table to verify * - * DESCRIPTION: This function is called to parse the Root System Description - * Table (RSDT or XSDT) + * RETURN: 8 bit checksum of table * - * NOTE: Tables are mapped (not copied) for efficiency. The FACS must - * be mapped and cannot be copied because it contains the actual - * memory location of the ACPI Global Lock. + * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares + * it to the existing checksum value. * ******************************************************************************/ -acpi_status __init -acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) +acpi_status +acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) { - struct acpi_table_rsdp *rsdp; - acpi_native_uint table_entry_size; - acpi_native_uint i; - u32 table_count; - struct acpi_table_header *table; - acpi_physical_address address; - u32 length; - u8 *table_entry; - acpi_status status; - - ACPI_FUNCTION_TRACE(tb_parse_root_table); - - /* - * Map the entire RSDP and extract the address of the RSDT or XSDT - */ - rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp)); - if (!rsdp) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - acpi_tb_print_table_header(rsdp_address, - ACPI_CAST_PTR(struct acpi_table_header, - rsdp)); - - /* Differentiate between RSDT and XSDT root tables */ + u8 checksum; - if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { - /* - * Root table is an XSDT (64-bit physical addresses). We must use the - * XSDT if the revision is > 1 and the XSDT pointer is present, as per - * the ACPI specification. - */ - address = (acpi_physical_address) rsdp->xsdt_physical_address; - table_entry_size = sizeof(u64); - } else { - /* Root table is an RSDT (32-bit physical addresses) */ + ACPI_FUNCTION_TRACE(tb_verify_table_checksum); - address = (acpi_physical_address) rsdp->rsdt_physical_address; - table_entry_size = sizeof(u32); - } + /* Compute the checksum on the table */ - /* - * It is not possible to map more than one entry in some environments, - * so unmap the RSDP here before mapping other tables - */ - acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); + checksum = acpi_tb_generate_checksum(table_header); - /* Map the RSDT/XSDT table header to get the full table length */ + /* Checksum ok? */ - table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); - if (!table) { - return_ACPI_STATUS(AE_NO_MEMORY); + if (checksum == table_header->checksum) { + return_ACPI_STATUS(AE_OK); } - acpi_tb_print_table_header(address, table); - - /* Get the length of the full table, verify length and map entire table */ + ACPI_WARNING((AE_INFO, + "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", + table_header->signature, table_header->checksum, + checksum)); - length = table->length; - acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); - - if (length < sizeof(struct acpi_table_header)) { - ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", - length)); - return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); - } + return_ACPI_STATUS(AE_BAD_CHECKSUM); +} - table = acpi_os_map_memory(address, length); - if (!table) { - return_ACPI_STATUS(AE_NO_MEMORY); - } +#ifdef ACPI_OBSOLETE_FUNCTIONS +/******************************************************************************* + * + * FUNCTION: acpi_tb_handle_to_object + * + * PARAMETERS: table_id - Id for which the function is searching + * table_desc - Pointer to return the matching table + * descriptor. + * + * RETURN: Search the tables to find one with a matching table_id and + * return a pointer to that table descriptor. + * + ******************************************************************************/ - /* Validate the root table checksum */ +acpi_status +acpi_tb_handle_to_object(u16 table_id, + struct acpi_table_desc **return_table_desc) +{ + u32 i; + struct acpi_table_desc *table_desc; - status = acpi_tb_verify_checksum(table, length); - if (ACPI_FAILURE(status)) { - acpi_os_unmap_memory(table, length); - return_ACPI_STATUS(status); - } + ACPI_FUNCTION_NAME(tb_handle_to_object); - /* Calculate the number of tables described in the root table */ - - table_count = - (u32) ((table->length - - sizeof(struct acpi_table_header)) / table_entry_size); - - /* - * First two entries in the table array are reserved for the DSDT and FACS, - * which are not actually present in the RSDT/XSDT - they come from the FADT - */ - table_entry = - ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); - acpi_gbl_root_table_list.count = 2; - - /* - * Initialize the root table array from the RSDT/XSDT - */ - for (i = 0; i < table_count; i++) { - if (acpi_gbl_root_table_list.count >= - acpi_gbl_root_table_list.size) { - - /* There is no more room in the root table array, attempt resize */ - - status = acpi_tb_resize_root_table_list(); - if (ACPI_FAILURE(status)) { - ACPI_WARNING((AE_INFO, - "Truncating %u table entries!", - (unsigned) - (acpi_gbl_root_table_list.size - - acpi_gbl_root_table_list. - count))); - break; + for (i = 0; i < ACPI_TABLE_MAX; i++) { + table_desc = acpi_gbl_table_lists[i].next; + while (table_desc) { + if (table_desc->table_id == table_id) { + *return_table_desc = table_desc; + return (AE_OK); } - } - - /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. - address = - acpi_tb_get_root_table_entry(table_entry, table_entry_size); - - table_entry += table_entry_size; - acpi_gbl_root_table_list.count++; - } - - /* - * It is not possible to map more than one entry in some environments, - * so unmap the root table here before mapping other tables - */ - acpi_os_unmap_memory(table, length); - - /* - * Complete the initialization of the root table array by examining - * the header of each table - */ - for (i = 2; i < acpi_gbl_root_table_list.count; i++) { - acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. - address, flags, NULL, i); - - /* Special case for FADT - get the DSDT and FACS */ - - if (ACPI_COMPARE_NAME - (&acpi_gbl_root_table_list.tables[i].signature, - ACPI_SIG_FADT)) { - acpi_tb_parse_fadt(i, flags); + table_desc = table_desc->next; } } - return_ACPI_STATUS(AE_OK); + ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id)); + return (AE_BAD_PARAMETER); } +#endif diff --git a/trunk/drivers/acpi/tables/tbxface.c b/trunk/drivers/acpi/tables/tbxface.c index 807978d5381a..5ba9303293ad 100644 --- a/trunk/drivers/acpi/tables/tbxface.c +++ b/trunk/drivers/acpi/tables/tbxface.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,158 +49,80 @@ #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbxface") -/* Local prototypes */ -static acpi_status acpi_tb_load_namespace(void); - /******************************************************************************* * - * FUNCTION: acpi_allocate_root_table + * FUNCTION: acpi_load_tables * - * PARAMETERS: initial_table_count - Size of initial_table_array, in number of - * struct acpi_table_desc structures + * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and - * acpi_initialize_tables. + * DESCRIPTION: This function is called to load the ACPI tables from the + * provided RSDT * ******************************************************************************/ - -acpi_status acpi_allocate_root_table(u32 initial_table_count) +acpi_status acpi_load_tables(void) { + struct acpi_pointer rsdp_address; + acpi_status status; - acpi_gbl_root_table_list.size = initial_table_count; - acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE; + ACPI_FUNCTION_TRACE(acpi_load_tables); - return (acpi_tb_resize_root_table_list()); -} + /* Get the RSDP */ -/******************************************************************************* - * - * FUNCTION: acpi_initialize_tables - * - * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated - * struct acpi_table_desc structures. If NULL, the - * array is dynamically allocated. - * initial_table_count - Size of initial_table_array, in number of - * struct acpi_table_desc structures - * allow_realloc - Flag to tell Table Manager if resize of - * pre-allocated array is allowed. Ignored - * if initial_table_array is NULL. - * - * RETURN: Status - * - * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. - * - * NOTE: Allows static allocation of the initial table array in order - * to avoid the use of dynamic memory in confined environments - * such as the kernel boot sequence where it may not be available. - * - * If the host OS memory managers are initialized, use NULL for - * initial_table_array, and the table will be dynamically allocated. - * - ******************************************************************************/ + status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, + &rsdp_address); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP")); + goto error_exit; + } -acpi_status __init -acpi_initialize_tables(struct acpi_table_desc * initial_table_array, - u32 initial_table_count, u8 allow_resize) -{ - acpi_physical_address rsdp_address; - acpi_status status; + /* Map and validate the RSDP */ - ACPI_FUNCTION_TRACE(acpi_initialize_tables); + acpi_gbl_table_flags = rsdp_address.pointer_type; - /* - * Set up the Root Table Array - * Allocate the table array if requested - */ - if (!initial_table_array) { - status = acpi_allocate_root_table(initial_table_count); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } else { - /* Root Table Array has been statically allocated by the host */ - - ACPI_MEMSET(initial_table_array, 0, - initial_table_count * - sizeof(struct acpi_table_desc)); - - acpi_gbl_root_table_list.tables = initial_table_array; - acpi_gbl_root_table_list.size = initial_table_count; - acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN; - if (allow_resize) { - acpi_gbl_root_table_list.flags |= - ACPI_ROOT_ALLOW_RESIZE; - } + status = acpi_tb_verify_rsdp(&rsdp_address); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation")); + goto error_exit; } - /* Get the address of the RSDP */ + /* Get the RSDT via the RSDP */ - rsdp_address = acpi_os_get_root_pointer(); - if (!rsdp_address) { - return_ACPI_STATUS(AE_NOT_FOUND); + status = acpi_tb_get_table_rsdt(); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT")); + goto error_exit; } - /* - * Get the root table (RSDT or XSDT) and extract all entries to the local - * Root Table Array. This array contains the information of the RSDT/XSDT - * in a common, more useable format. - */ - status = - acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_reallocate_root_table - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the - * root list from the previously provided scratch area. Should - * be called once dynamic memory allocation is available in the - * kernel - * - ******************************************************************************/ -acpi_status acpi_reallocate_root_table(void) -{ - struct acpi_table_desc *tables; - acpi_size new_size; - - ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); + /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ - /* - * Only reallocate the root table if the host provided a static buffer - * for the table array in the call to acpi_initialize_tables. - */ - if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { - return_ACPI_STATUS(AE_SUPPORT); + status = acpi_tb_get_required_tables(); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not get all required tables (DSDT/FADT/FACS)")); + goto error_exit; } - new_size = - (acpi_gbl_root_table_list.count + - ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc); + ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); - /* Create new array and copy the old array */ + /* Load the namespace from the tables */ - tables = ACPI_ALLOCATE_ZEROED(new_size); - if (!tables) { - return_ACPI_STATUS(AE_NO_MEMORY); + status = acpi_ns_load_namespace(); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace")); + goto error_exit; } - ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size); - - acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count; - acpi_gbl_root_table_list.tables = tables; - acpi_gbl_root_table_list.flags = - ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; - return_ACPI_STATUS(AE_OK); + + error_exit: + ACPI_EXCEPTION((AE_INFO, status, "Could not load tables")); + return_ACPI_STATUS(status); } + +ACPI_EXPORT_SYMBOL(acpi_load_tables) + /******************************************************************************* * * FUNCTION: acpi_load_table @@ -219,405 +141,342 @@ acpi_status acpi_reallocate_root_table(void) acpi_status acpi_load_table(struct acpi_table_header *table_ptr) { acpi_status status; - acpi_native_uint table_index; - struct acpi_table_desc table_desc; + struct acpi_table_desc table_info; + struct acpi_pointer address; - if (!table_ptr) - return AE_BAD_PARAMETER; + ACPI_FUNCTION_TRACE(acpi_load_table); - ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); - table_desc.pointer = table_ptr; - table_desc.length = table_ptr->length; - table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; + if (!table_ptr) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } - /* - * Install the new table into the local data structures - */ - status = acpi_tb_add_table(&table_desc, &table_index); + /* Copy the table to a local buffer */ + + address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; + address.pointer.logical = table_ptr; + + status = acpi_tb_get_table_body(&address, table_ptr, &table_info); if (ACPI_FAILURE(status)) { - return status; + return_ACPI_STATUS(status); } - status = acpi_ns_load_table(table_index, acpi_gbl_root_node); - return status; -} -ACPI_EXPORT_SYMBOL(acpi_load_table) + /* Check signature for a valid table type */ -/****************************************************************************** - * - * FUNCTION: acpi_get_table_header - * - * PARAMETERS: Signature - ACPI signature of needed table - * Instance - Which instance (for SSDTs) - * out_table_header - The pointer to the table header to fill - * - * RETURN: Status and pointer to mapped table header - * - * DESCRIPTION: Finds an ACPI table header. - * - * NOTE: Caller is responsible in unmapping the header with - * acpi_os_unmap_memory - * - *****************************************************************************/ -acpi_status -acpi_get_table_header(char *signature, - acpi_native_uint instance, - struct acpi_table_header *out_table_header) -{ - acpi_native_uint i; - acpi_native_uint j; - struct acpi_table_header *header; + status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - /* Parameter validation */ + /* Install the new table into the local data structures */ - if (!signature || !out_table_header) { - return (AE_BAD_PARAMETER); - } + status = acpi_tb_install_table(&table_info); + if (ACPI_FAILURE(status)) { + if (status == AE_ALREADY_EXISTS) { - /* - * Walk the root table list - */ - for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { - if (!ACPI_COMPARE_NAME - (&(acpi_gbl_root_table_list.tables[i].signature), - signature)) { - continue; - } + /* Table already exists, no error */ - if (++j < instance) { - continue; + status = AE_OK; } - if (!acpi_gbl_root_table_list.tables[i].pointer) { - if ((acpi_gbl_root_table_list.tables[i]. - flags & ACPI_TABLE_ORIGIN_MASK) == - ACPI_TABLE_ORIGIN_MAPPED) { - header = - acpi_os_map_memory(acpi_gbl_root_table_list. - tables[i].address, - sizeof(struct - acpi_table_header)); - if (!header) { - return AE_NO_MEMORY; - } - ACPI_MEMCPY(out_table_header, header, - sizeof(struct acpi_table_header)); - acpi_os_unmap_memory(header, - sizeof(struct - acpi_table_header)); - } else { - return AE_NOT_FOUND; - } - } else { - ACPI_MEMCPY(out_table_header, - acpi_gbl_root_table_list.tables[i].pointer, - sizeof(struct acpi_table_header)); - } - return (AE_OK); + /* Free table allocated by acpi_tb_get_table_body */ + + acpi_tb_delete_single_table(&table_info); + return_ACPI_STATUS(status); } - return (AE_NOT_FOUND); -} + /* Convert the table to common format if necessary */ -ACPI_EXPORT_SYMBOL(acpi_get_table_header) + switch (table_info.type) { + case ACPI_TABLE_ID_FADT: + status = acpi_tb_convert_table_fadt(); + break; -/****************************************************************************** + case ACPI_TABLE_ID_FACS: + + status = acpi_tb_build_common_facs(&table_info); + break; + + default: + /* Load table into namespace if it contains executable AML */ + + status = + acpi_ns_load_table(table_info.installed_desc, + acpi_gbl_root_node); + break; + } + + if (ACPI_FAILURE(status)) { + + /* Uninstall table and free the buffer */ + + (void)acpi_tb_uninstall_table(table_info.installed_desc); + } + + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_load_table) + +/******************************************************************************* * * FUNCTION: acpi_unload_table_id * - * PARAMETERS: id - Owner ID of the table to be removed. + * PARAMETERS: table_type - Type of table to be unloaded + * id - Owner ID of the table to be removed. * * RETURN: Status * * DESCRIPTION: This routine is used to force the unload of a table (by id) * ******************************************************************************/ -acpi_status acpi_unload_table_id(acpi_owner_id id) +acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id) { - int i; - acpi_status status = AE_NOT_EXIST; + struct acpi_table_desc *table_desc; + acpi_status status; ACPI_FUNCTION_TRACE(acpi_unload_table); + /* Parameter validation */ + if (table_type > ACPI_TABLE_ID_MAX) + return_ACPI_STATUS(AE_BAD_PARAMETER); + /* Find table from the requested type list */ - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - if (id != acpi_gbl_root_table_list.tables[i].owner_id) { - continue; - } - /* - * Delete all namespace objects owned by this table. Note that these - * objects can appear anywhere in the namespace by virtue of the AML - * "Scope" operator. Thus, we need to track ownership by an ID, not - * simply a position within the hierarchy - */ - acpi_tb_delete_namespace_by_owner(i); - acpi_tb_release_owner_id(i); - acpi_tb_set_table_loaded_flag(i, FALSE); - } - return_ACPI_STATUS(status); + table_desc = acpi_gbl_table_lists[table_type].next; + while (table_desc && table_desc->owner_id != id) + table_desc = table_desc->next; + + if (!table_desc) + return_ACPI_STATUS(AE_NOT_EXIST); + + /* + * Delete all namespace objects owned by this table. Note that these + * objects can appear anywhere in the namespace by virtue of the AML + * "Scope" operator. Thus, we need to track ownership by an ID, not + * simply a position within the hierarchy + */ + acpi_ns_delete_namespace_by_owner(table_desc->owner_id); + + status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + + (void)acpi_tb_uninstall_table(table_desc); + + (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + + return_ACPI_STATUS(AE_OK); } ACPI_EXPORT_SYMBOL(acpi_unload_table_id) +#ifdef ACPI_FUTURE_USAGE /******************************************************************************* * - * FUNCTION: acpi_get_table + * FUNCTION: acpi_unload_table * - * PARAMETERS: Signature - ACPI signature of needed table - * Instance - Which instance (for SSDTs) - * out_table - Where the pointer to the table is returned + * PARAMETERS: table_type - Type of table to be unloaded * - * RETURN: Status and pointer to table + * RETURN: Status * - * DESCRIPTION: Finds and verifies an ACPI table. + * DESCRIPTION: This routine is used to force the unload of a table * - *****************************************************************************/ -acpi_status -acpi_get_table(char *signature, - acpi_native_uint instance, struct acpi_table_header ** out_table) + ******************************************************************************/ +acpi_status acpi_unload_table(acpi_table_type table_type) { - acpi_native_uint i; - acpi_native_uint j; - acpi_status status; + struct acpi_table_desc *table_desc; + + ACPI_FUNCTION_TRACE(acpi_unload_table); /* Parameter validation */ - if (!signature || !out_table) { - return (AE_BAD_PARAMETER); + if (table_type > ACPI_TABLE_ID_MAX) { + return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* - * Walk the root table list - */ - for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { - if (!ACPI_COMPARE_NAME - (&(acpi_gbl_root_table_list.tables[i].signature), - signature)) { - continue; - } - - if (++j < instance) { - continue; - } - - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); - if (ACPI_SUCCESS(status)) { - *out_table = acpi_gbl_root_table_list.tables[i].pointer; - } + /* Find all tables of the requested type */ - if (!acpi_gbl_permanent_mmap) { - acpi_gbl_root_table_list.tables[i].pointer = 0; - } + table_desc = acpi_gbl_table_lists[table_type].next; + if (!table_desc) { + return_ACPI_STATUS(AE_NOT_EXIST); + } - return (status); + while (table_desc) { + /* + * Delete all namespace objects owned by this table. Note that these + * objects can appear anywhere in the namespace by virtue of the AML + * "Scope" operator. Thus, we need to track ownership by an ID, not + * simply a position within the hierarchy + */ + acpi_ns_delete_namespace_by_owner(table_desc->owner_id); + table_desc = table_desc->next; } - return (AE_NOT_FOUND); + /* Delete (or unmap) all tables of this type */ + + acpi_tb_delete_tables_by_type(table_type); + return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_get_table) +ACPI_EXPORT_SYMBOL(acpi_unload_table) /******************************************************************************* * - * FUNCTION: acpi_get_table_by_index + * FUNCTION: acpi_get_table_header * - * PARAMETERS: table_index - Table index - * Table - Where the pointer to the table is returned + * PARAMETERS: table_type - one of the defined table types + * Instance - the non zero instance of the table, allows + * support for multiple tables of the same type + * see acpi_gbl_acpi_table_flag + * out_table_header - pointer to the struct acpi_table_header if successful * - * RETURN: Status and pointer to the table + * DESCRIPTION: This function is called to get an ACPI table header. The caller + * supplies an pointer to a data area sufficient to contain an ACPI + * struct acpi_table_header structure. * - * DESCRIPTION: Obtain a table by an index into the global table list. + * The header contains a length field that can be used to determine + * the size of the buffer needed to contain the entire table. This + * function is not valid for the RSD PTR table since it does not + * have a standard header and is fixed length. * ******************************************************************************/ acpi_status -acpi_get_table_by_index(acpi_native_uint table_index, - struct acpi_table_header ** table) +acpi_get_table_header(acpi_table_type table_type, + u32 instance, struct acpi_table_header *out_table_header) { + struct acpi_table_header *tbl_ptr; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_get_table_by_index); - - /* Parameter validation */ + ACPI_FUNCTION_TRACE(acpi_get_table_header); - if (!table) { + if ((instance == 0) || + (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - - /* Validate index */ + /* Check the table type and instance */ - if (table_index >= acpi_gbl_root_table_list.count) { - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + if ((table_type > ACPI_TABLE_ID_MAX) || + (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && + instance > 1)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - if (!acpi_gbl_root_table_list.tables[table_index].pointer) { + /* Get a pointer to the entire table */ - /* Table is not mapped, map it */ + status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list. - tables[table_index]); - if (ACPI_FAILURE(status)) { - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); - } + /* The function will return a NULL pointer if the table is not loaded */ + + if (tbl_ptr == NULL) { + return_ACPI_STATUS(AE_NOT_EXIST); } - *table = acpi_gbl_root_table_list.tables[table_index].pointer; - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(AE_OK); + /* Copy the header to the caller's buffer */ + + ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header), + ACPI_CAST_PTR(void, tbl_ptr), + sizeof(struct acpi_table_header)); + + return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) +ACPI_EXPORT_SYMBOL(acpi_get_table_header) +#endif /* ACPI_FUTURE_USAGE */ /******************************************************************************* * - * FUNCTION: acpi_tb_load_namespace + * FUNCTION: acpi_get_table * - * PARAMETERS: None + * PARAMETERS: table_type - one of the defined table types + * Instance - the non zero instance of the table, allows + * support for multiple tables of the same type + * see acpi_gbl_acpi_table_flag + * ret_buffer - pointer to a structure containing a buffer to + * receive the table * * RETURN: Status * - * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in - * the RSDT/XSDT. + * DESCRIPTION: This function is called to get an ACPI table. The caller + * supplies an out_buffer large enough to contain the entire ACPI + * table. The caller should call the acpi_get_table_header function + * first to determine the buffer size needed. Upon completion + * the out_buffer->Length field will indicate the number of bytes + * copied into the out_buffer->buf_ptr buffer. This table will be + * a complete table including the header. * ******************************************************************************/ -static acpi_status acpi_tb_load_namespace(void) +acpi_status +acpi_get_table(acpi_table_type table_type, + u32 instance, struct acpi_buffer *ret_buffer) { + struct acpi_table_header *tbl_ptr; acpi_status status; - struct acpi_table_header *table; - acpi_native_uint i; - - ACPI_FUNCTION_TRACE(tb_load_namespace); + acpi_size table_length; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + ACPI_FUNCTION_TRACE(acpi_get_table); - /* - * Load the namespace. The DSDT is required, but any SSDT and PSDT tables - * are optional. - */ - if (!acpi_gbl_root_table_list.count || - !ACPI_COMPARE_NAME(& - (acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT].signature), - ACPI_SIG_DSDT) - || - ACPI_FAILURE(acpi_tb_verify_table - (&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT]))) { - status = AE_NO_ACPI_TABLES; - goto unlock_and_exit; - } + /* Parameter validation */ - /* - * Find DSDT table - */ - status = - acpi_os_table_override(acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT].pointer, - &table); - if (ACPI_SUCCESS(status) && table) { - /* - * DSDT table has been found - */ - acpi_tb_delete_table(&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT]); - acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer = - table; - acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = - table->length; - acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = - ACPI_TABLE_ORIGIN_UNKNOWN; - - ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); - acpi_tb_print_table_header(0, table); + if (instance == 0) { + return_ACPI_STATUS(AE_BAD_PARAMETER); } - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT]); + status = acpi_ut_validate_buffer(ret_buffer); if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - /* A valid DSDT is required */ + /* Check the table type and instance */ - status = AE_NO_ACPI_TABLES; - goto unlock_and_exit; + if ((table_type > ACPI_TABLE_ID_MAX) || + (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && + instance > 1)) { + return_ACPI_STATUS(AE_BAD_PARAMETER); } - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + /* Get a pointer to the entire table */ - /* - * Load and parse tables. - */ - status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); + status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* - * Load any SSDT or PSDT tables. Note: Loop leaves tables locked + * acpi_tb_get_table_ptr will return a NULL pointer if the + * table is not loaded. */ - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - if ((!ACPI_COMPARE_NAME - (&(acpi_gbl_root_table_list.tables[i].signature), - ACPI_SIG_SSDT) - && - !ACPI_COMPARE_NAME(& - (acpi_gbl_root_table_list.tables[i]. - signature), ACPI_SIG_PSDT)) - || - ACPI_FAILURE(acpi_tb_verify_table - (&acpi_gbl_root_table_list.tables[i]))) { - continue; - } - - /* Ignore errors while loading tables, get as many as possible */ - - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - (void)acpi_ns_load_table(i, acpi_gbl_root_node); - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (tbl_ptr == NULL) { + return_ACPI_STATUS(AE_NOT_EXIST); } - ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); + /* Get the table length */ - unlock_and_exit: - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); -} + if (table_type == ACPI_TABLE_ID_RSDP) { -/******************************************************************************* - * - * FUNCTION: acpi_load_tables - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT - * - ******************************************************************************/ + /* RSD PTR is the only "table" without a header */ -acpi_status acpi_load_tables(void) -{ - acpi_status status; + table_length = sizeof(struct rsdp_descriptor); + } else { + table_length = (acpi_size) tbl_ptr->length; + } - ACPI_FUNCTION_TRACE(acpi_load_tables); + /* Validate/Allocate/Clear caller buffer */ - /* - * Load the namespace from the tables - */ - status = acpi_tb_load_namespace(); + status = acpi_ut_initialize_buffer(ret_buffer, table_length); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "While loading namespace from ACPI tables")); + return_ACPI_STATUS(status); } - return_ACPI_STATUS(status); + /* Copy the table to the buffer */ + + ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer), + ACPI_CAST_PTR(void, tbl_ptr), table_length); + + return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_load_tables) +ACPI_EXPORT_SYMBOL(acpi_get_table) diff --git a/trunk/drivers/acpi/tables/tbxfroot.c b/trunk/drivers/acpi/tables/tbxfroot.c index cf8fa514189f..da2648bbdbc0 100644 --- a/trunk/drivers/acpi/tables/tbxfroot.c +++ b/trunk/drivers/acpi/tables/tbxfroot.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,15 +48,16 @@ ACPI_MODULE_NAME("tbxfroot") /* Local prototypes */ -static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); +static acpi_status +acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags); -static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); +static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); /******************************************************************************* * * FUNCTION: acpi_tb_validate_rsdp * - * PARAMETERS: Rsdp - Pointer to unvalidated RSDP + * PARAMETERS: Rsdp - Pointer to unvalidated RSDP * * RETURN: Status * @@ -64,18 +65,14 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); * ******************************************************************************/ -static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) +acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) { ACPI_FUNCTION_ENTRY(); /* - * The signature and checksum must both be correct - * - * Note: Sometimes there exists more than one RSDP in memory; the valid - * RSDP has a valid checksum, all others have an invalid checksum. + * The signature and checksum must both be correct */ - if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1) - != 0) { + if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) { /* Nope, BAD Signature */ @@ -84,14 +81,14 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) /* Check the standard checksum */ - if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { + if (acpi_tb_sum_table(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { return (AE_BAD_CHECKSUM); } /* Check extended checksum if table version >= 2 */ if ((rsdp->revision >= 2) && - (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { + (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { return (AE_BAD_CHECKSUM); } @@ -100,123 +97,314 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) /******************************************************************************* * - * FUNCTION: acpi_tb_find_rsdp + * FUNCTION: acpi_tb_find_table * - * PARAMETERS: table_address - Where the table pointer is returned + * PARAMETERS: Signature - String with ACPI table signature + * oem_id - String with the table OEM ID + * oem_table_id - String with the OEM Table ID + * table_ptr - Where the table pointer is returned * - * RETURN: Status, RSDP physical address + * RETURN: Status * - * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor - * pointer structure. If it is found, set *RSDP to point to it. + * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the + * Signature, OEM ID and OEM Table ID. * - * NOTE1: The RSDP must be either in the first 1_k of the Extended - * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) - * Only a 32-bit physical address is necessary. + ******************************************************************************/ + +acpi_status +acpi_tb_find_table(char *signature, + char *oem_id, + char *oem_table_id, struct acpi_table_header ** table_ptr) +{ + acpi_status status; + struct acpi_table_header *table; + + ACPI_FUNCTION_TRACE(tb_find_table); + + /* Validate string lengths */ + + if ((ACPI_STRLEN(signature) > ACPI_NAME_SIZE) || + (ACPI_STRLEN(oem_id) > sizeof(table->oem_id)) || + (ACPI_STRLEN(oem_table_id) > sizeof(table->oem_table_id))) { + return_ACPI_STATUS(AE_AML_STRING_LIMIT); + } + + if (ACPI_COMPARE_NAME(signature, DSDT_SIG)) { + /* + * The DSDT pointer is contained in the FADT, not the RSDT. + * This code should suffice, because the only code that would perform + * a "find" on the DSDT is the data_table_region() AML opcode -- in + * which case, the DSDT is guaranteed to be already loaded. + * If this becomes insufficient, the FADT will have to be found first. + */ + if (!acpi_gbl_DSDT) { + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + table = acpi_gbl_DSDT; + } else { + /* Find the table */ + + status = acpi_get_firmware_table(signature, 1, + ACPI_LOGICAL_ADDRESSING, + &table); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } + + /* Check oem_id and oem_table_id */ + + if ((oem_id[0] && + ACPI_STRNCMP(oem_id, table->oem_id, + sizeof(table->oem_id))) || + (oem_table_id[0] && + ACPI_STRNCMP(oem_table_id, table->oem_table_id, + sizeof(table->oem_table_id)))) { + return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND); + } + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Found table [%4.4s]\n", + table->signature)); + + *table_ptr = table; + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* * - * NOTE2: This function is always available, regardless of the - * initialization state of the rest of ACPI. + * FUNCTION: acpi_get_firmware_table + * + * PARAMETERS: Signature - Any ACPI table signature + * Instance - the non zero instance of the table, allows + * support for multiple tables of the same type + * Flags - Physical/Virtual support + * table_pointer - Where a buffer containing the table is + * returned + * + * RETURN: Status + * + * DESCRIPTION: This function is called to get an ACPI table. A buffer is + * allocated for the table and returned in table_pointer. + * This table will be a complete table including the header. * ******************************************************************************/ -acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) +acpi_status +acpi_get_firmware_table(acpi_string signature, + u32 instance, + u32 flags, struct acpi_table_header **table_pointer) { - u8 *table_ptr; - u8 *mem_rover; - u32 physical_address; + acpi_status status; + struct acpi_pointer address; + struct acpi_table_header *header = NULL; + struct acpi_table_desc *table_info = NULL; + struct acpi_table_desc *rsdt_info; + u32 table_count; + u32 i; + u32 j; - ACPI_FUNCTION_TRACE(acpi_find_root_pointer); + ACPI_FUNCTION_TRACE(acpi_get_firmware_table); - /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ + /* + * Ensure that at least the table manager is initialized. We don't + * require that the entire ACPI subsystem is up for this interface. + * If we have a buffer, we must have a length too + */ + if ((instance == 0) || (!signature) || (!table_pointer)) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Ensure that we have a RSDP */ - table_ptr = acpi_os_map_memory((acpi_physical_address) - ACPI_EBDA_PTR_LOCATION, - ACPI_EBDA_PTR_LENGTH); - if (!table_ptr) { - ACPI_ERROR((AE_INFO, - "Could not map memory at %8.8X for length %X", - ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); + if (!acpi_gbl_RSDP) { + /* Get the RSDP */ + + status = acpi_os_get_root_pointer(flags, &address); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + /* Map and validate the RSDP */ + + if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { + status = acpi_os_map_memory(address.pointer.physical, + sizeof(struct + rsdp_descriptor), + (void *)&acpi_gbl_RSDP); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } else { + acpi_gbl_RSDP = address.pointer.logical; + } + + /* The RDSP signature and checksum must both be correct */ + + status = acpi_tb_validate_rsdp(acpi_gbl_RSDP); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } + + /* Get the RSDT address via the RSDP */ + + acpi_tb_get_rsdt_address(&address); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "RSDP located at %p, RSDT physical=%8.8X%8.8X\n", + acpi_gbl_RSDP, + ACPI_FORMAT_UINT64(address.pointer.value))); + + /* Insert processor_mode flags */ + + address.pointer_type |= flags; + + /* Get and validate the RSDT */ + + rsdt_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); + if (!rsdt_info) { return_ACPI_STATUS(AE_NO_MEMORY); } - ACPI_MOVE_16_TO_32(&physical_address, table_ptr); + status = acpi_tb_get_table(&address, rsdt_info); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + status = acpi_tb_validate_rsdt(rsdt_info->pointer); + if (ACPI_FAILURE(status)) { + goto cleanup; + } - /* Convert segment part to physical address */ + /* Allocate a scratch table header and table descriptor */ - physical_address <<= 4; - acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); + header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); + if (!header) { + status = AE_NO_MEMORY; + goto cleanup; + } - /* EBDA present? */ + table_info = ACPI_ALLOCATE(sizeof(struct acpi_table_desc)); + if (!table_info) { + status = AE_NO_MEMORY; + goto cleanup; + } - if (physical_address > 0x400) { + /* Get the number of table pointers within the RSDT */ + + table_count = + acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer); + address.pointer_type = acpi_gbl_table_flags | flags; + + /* + * Search the RSDT/XSDT for the correct instance of the + * requested table + */ + for (i = 0, j = 0; i < table_count; i++) { /* - * 1b) Search EBDA paragraphs (EBDA is required to be a - * minimum of 1_k length) + * Get the next table pointer, handle RSDT vs. XSDT + * RSDT pointers are 32 bits, XSDT pointers are 64 bits */ - table_ptr = acpi_os_map_memory((acpi_native_uint) - physical_address, - ACPI_EBDA_WINDOW_SIZE); - if (!table_ptr) { - ACPI_ERROR((AE_INFO, - "Could not map memory at %8.8X for length %X", - physical_address, ACPI_EBDA_WINDOW_SIZE)); + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + address.pointer.value = + (ACPI_CAST_PTR + (struct rsdt_descriptor, + rsdt_info->pointer))->table_offset_entry[i]; + } else { + address.pointer.value = + (ACPI_CAST_PTR + (struct xsdt_descriptor, + rsdt_info->pointer))->table_offset_entry[i]; + } + + /* Get the table header */ - return_ACPI_STATUS(AE_NO_MEMORY); + status = acpi_tb_get_table_header(&address, header); + if (ACPI_FAILURE(status)) { + goto cleanup; } - mem_rover = - acpi_tb_scan_memory_for_rsdp(table_ptr, - ACPI_EBDA_WINDOW_SIZE); - acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); + /* Compare table signatures and table instance */ - if (mem_rover) { + if (ACPI_COMPARE_NAME(header->signature, signature)) { - /* Return the physical address */ + /* An instance of the table was found */ - physical_address += - (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); + j++; + if (j >= instance) { - *table_address = physical_address; - return_ACPI_STATUS(AE_OK); + /* Found the correct instance, get the entire table */ + + status = + acpi_tb_get_table_body(&address, header, + table_info); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + *table_pointer = table_info->pointer; + goto cleanup; + } } } - /* - * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh - */ - table_ptr = acpi_os_map_memory((acpi_physical_address) - ACPI_HI_RSDP_WINDOW_BASE, - ACPI_HI_RSDP_WINDOW_SIZE); + /* Did not find the table */ - if (!table_ptr) { - ACPI_ERROR((AE_INFO, - "Could not map memory at %8.8X for length %X", - ACPI_HI_RSDP_WINDOW_BASE, - ACPI_HI_RSDP_WINDOW_SIZE)); + status = AE_NOT_EXIST; - return_ACPI_STATUS(AE_NO_MEMORY); + cleanup: + if (rsdt_info->pointer) { + acpi_os_unmap_memory(rsdt_info->pointer, + (acpi_size) rsdt_info->pointer->length); } + ACPI_FREE(rsdt_info); - mem_rover = - acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); - acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); + if (header) { + ACPI_FREE(header); + } + if (table_info) { + ACPI_FREE(table_info); + } + return_ACPI_STATUS(status); +} - if (mem_rover) { +ACPI_EXPORT_SYMBOL(acpi_get_firmware_table) - /* Return the physical address */ +/* TBD: Move to a new file */ +#if ACPI_MACHINE_WIDTH != 16 +/******************************************************************************* + * + * FUNCTION: acpi_find_root_pointer + * + * PARAMETERS: Flags - Logical/Physical addressing + * rsdp_address - Where to place the RSDP address + * + * RETURN: Status, Physical address of the RSDP + * + * DESCRIPTION: Find the RSDP + * + ******************************************************************************/ +acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) +{ + struct acpi_table_desc table_info; + acpi_status status; - physical_address = (u32) - (ACPI_HI_RSDP_WINDOW_BASE + - ACPI_PTR_DIFF(mem_rover, table_ptr)); + ACPI_FUNCTION_TRACE(acpi_find_root_pointer); - *table_address = physical_address; - return_ACPI_STATUS(AE_OK); - } + /* Get the RSDP */ - /* A valid RSDP was not found */ + status = acpi_tb_find_rsdp(&table_info, flags); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "RSDP structure not found - Flags=%X", flags)); - ACPI_ERROR((AE_INFO, "A valid RSDP was not found")); - return_ACPI_STATUS(AE_NOT_FOUND); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; + rsdp_address->pointer.physical = table_info.physical_address; + return_ACPI_STATUS(AE_OK); } ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) @@ -252,7 +440,7 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) status = acpi_tb_validate_rsdp(ACPI_CAST_PTR - (struct acpi_table_rsdp, mem_rover)); + (struct rsdp_descriptor, mem_rover)); if (ACPI_SUCCESS(status)) { /* Sig and checksum valid, we have found a real RSDP */ @@ -273,3 +461,189 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) start_address)); return_PTR(NULL); } + +/******************************************************************************* + * + * FUNCTION: acpi_tb_find_rsdp + * + * PARAMETERS: table_info - Where the table info is returned + * Flags - Current memory mode (logical vs. + * physical addressing) + * + * RETURN: Status, RSDP physical address + * + * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor + * pointer structure. If it is found, set *RSDP to point to it. + * + * NOTE1: The RSDP must be either in the first 1_k of the Extended + * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) + * Only a 32-bit physical address is necessary. + * + * NOTE2: This function is always available, regardless of the + * initialization state of the rest of ACPI. + * + ******************************************************************************/ + +static acpi_status +acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) +{ + u8 *table_ptr; + u8 *mem_rover; + u32 physical_address; + acpi_status status; + + ACPI_FUNCTION_TRACE(tb_find_rsdp); + + /* + * Scan supports either logical addressing or physical addressing + */ + if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { + + /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ + + status = acpi_os_map_memory((acpi_physical_address) + ACPI_EBDA_PTR_LOCATION, + ACPI_EBDA_PTR_LENGTH, + (void *)&table_ptr); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + ACPI_EBDA_PTR_LOCATION, + ACPI_EBDA_PTR_LENGTH)); + + return_ACPI_STATUS(status); + } + + ACPI_MOVE_16_TO_32(&physical_address, table_ptr); + + /* Convert segment part to physical address */ + + physical_address <<= 4; + acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); + + /* EBDA present? */ + + if (physical_address > 0x400) { + /* + * 1b) Search EBDA paragraphs (EBDA is required to be a + * minimum of 1_k length) + */ + status = acpi_os_map_memory((acpi_physical_address) + physical_address, + ACPI_EBDA_WINDOW_SIZE, + (void *)&table_ptr); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + physical_address, + ACPI_EBDA_WINDOW_SIZE)); + + return_ACPI_STATUS(status); + } + + mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr, + ACPI_EBDA_WINDOW_SIZE); + acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); + + if (mem_rover) { + + /* Return the physical address */ + + physical_address += + (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); + + table_info->physical_address = + (acpi_physical_address) physical_address; + return_ACPI_STATUS(AE_OK); + } + } + + /* + * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh + */ + status = acpi_os_map_memory((acpi_physical_address) + ACPI_HI_RSDP_WINDOW_BASE, + ACPI_HI_RSDP_WINDOW_SIZE, + (void *)&table_ptr); + + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + ACPI_HI_RSDP_WINDOW_BASE, + ACPI_HI_RSDP_WINDOW_SIZE)); + + return_ACPI_STATUS(status); + } + + mem_rover = + acpi_tb_scan_memory_for_rsdp(table_ptr, + ACPI_HI_RSDP_WINDOW_SIZE); + acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); + + if (mem_rover) { + + /* Return the physical address */ + + physical_address = (u32) + (ACPI_HI_RSDP_WINDOW_BASE + + ACPI_PTR_DIFF(mem_rover, table_ptr)); + + table_info->physical_address = + (acpi_physical_address) physical_address; + return_ACPI_STATUS(AE_OK); + } + } + + /* + * Physical addressing + */ + else { + /* 1a) Get the location of the EBDA */ + + ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION); + physical_address <<= 4; /* Convert segment to physical address */ + + /* EBDA present? */ + + if (physical_address > 0x400) { + /* + * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of + * 1_k length) + */ + mem_rover = + acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR + (physical_address), + ACPI_EBDA_WINDOW_SIZE); + if (mem_rover) { + + /* Return the physical address */ + + table_info->physical_address = + ACPI_TO_INTEGER(mem_rover); + return_ACPI_STATUS(AE_OK); + } + } + + /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ + + mem_rover = + acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR + (ACPI_HI_RSDP_WINDOW_BASE), + ACPI_HI_RSDP_WINDOW_SIZE); + if (mem_rover) { + + /* Found it, return the physical address */ + + table_info->physical_address = + ACPI_TO_INTEGER(mem_rover); + return_ACPI_STATUS(AE_OK); + } + } + + /* A valid RSDP was not found */ + + ACPI_ERROR((AE_INFO, "No valid RSDP was found")); + return_ACPI_STATUS(AE_NOT_FOUND); +} + +#endif diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index f76d3168c2b2..40ddb4dd9631 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -82,7 +82,7 @@ MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device, int type); -static int acpi_thermal_resume(struct acpi_device *device); +static int acpi_thermal_resume(struct acpi_device *device, int state); static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); @@ -1353,7 +1353,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) return 0; } -static int acpi_thermal_resume(struct acpi_device *device) +static int acpi_thermal_resume(struct acpi_device *device, int state) { struct acpi_thermal *tz = NULL; int i; diff --git a/trunk/drivers/acpi/utilities/utalloc.c b/trunk/drivers/acpi/utilities/utalloc.c index 55a764807499..f6cbc0b1bfd0 100644 --- a/trunk/drivers/acpi/utilities/utalloc.c +++ b/trunk/drivers/acpi/utilities/utalloc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,7 +42,6 @@ */ #include -#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utalloc") @@ -143,14 +142,6 @@ acpi_status acpi_ut_create_caches(void) acpi_status acpi_ut_delete_caches(void) { -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - char buffer[7]; - - if (acpi_gbl_display_final_mem_stats) { - ACPI_STRCPY(buffer, "MEMORY"); - acpi_db_display_statistics(buffer); - } -#endif (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); acpi_gbl_namespace_cache = NULL; diff --git a/trunk/drivers/acpi/utilities/utcache.c b/trunk/drivers/acpi/utilities/utcache.c index 870f6edeb5f2..1a1f8109159c 100644 --- a/trunk/drivers/acpi/utilities/utcache.c +++ b/trunk/drivers/acpi/utilities/utcache.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -289,14 +289,6 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) ACPI_MEM_TRACKING(cache->total_allocated++); -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - if ((cache->total_allocated - cache->total_freed) > - cache->max_occupied) { - cache->max_occupied = - cache->total_allocated - cache->total_freed; - } -#endif - /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */ status = acpi_ut_release_mutex(ACPI_MTX_CACHES); diff --git a/trunk/drivers/acpi/utilities/utcopy.c b/trunk/drivers/acpi/utilities/utcopy.c index 84d529db0a66..5e1a80d1bc36 100644 --- a/trunk/drivers/acpi/utilities/utcopy.c +++ b/trunk/drivers/acpi/utilities/utcopy.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -719,15 +719,6 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, acpi_ut_add_reference(source_desc->reference.object); break; - case ACPI_TYPE_REGION: - /* - * We copied the Region Handler, so we now must add a reference - */ - if (dest_desc->region.handler) { - acpi_ut_add_reference(dest_desc->region.handler); - } - break; - default: /* Nothing to do for other simple objects */ break; diff --git a/trunk/drivers/acpi/utilities/utdebug.c b/trunk/drivers/acpi/utilities/utdebug.c index 61ad4f2daee2..9e9054e155c1 100644 --- a/trunk/drivers/acpi/utilities/utdebug.c +++ b/trunk/drivers/acpi/utilities/utdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -181,7 +181,8 @@ acpi_ut_debug_print(u32 requested_debug_level, if (ACPI_LV_THREADS & acpi_dbg_level) { acpi_os_printf ("\n**** Context Switch from TID %lX to TID %lX ****\n\n", - (unsigned long)acpi_gbl_prev_thread_id, (unsigned long)thread_id); + (unsigned long) acpi_gbl_prev_thread_id, + (unsigned long) thread_id); } acpi_gbl_prev_thread_id = thread_id; @@ -194,7 +195,7 @@ acpi_ut_debug_print(u32 requested_debug_level, acpi_os_printf("%8s-%04ld ", module_name, line_number); if (ACPI_LV_THREADS & acpi_dbg_level) { - acpi_os_printf("[%04lX] ", (unsigned long)thread_id); + acpi_os_printf("[%04lX] ", thread_id); } acpi_os_printf("[%02ld] %-22.22s: ", diff --git a/trunk/drivers/acpi/utilities/utdelete.c b/trunk/drivers/acpi/utilities/utdelete.c index f777cebdc46d..9d3f1149ba21 100644 --- a/trunk/drivers/acpi/utilities/utdelete.c +++ b/trunk/drivers/acpi/utilities/utdelete.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -158,20 +158,16 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) "***** Mutex %p, OS Mutex %p\n", object, object->mutex.os_mutex)); - if (object->mutex.os_mutex == acpi_gbl_global_lock_mutex) { - - /* Global Lock has extra semaphore */ + if (object->mutex.os_mutex != ACPI_GLOBAL_LOCK) { + acpi_ex_unlink_mutex(object); + acpi_os_delete_mutex(object->mutex.os_mutex); + } else { + /* Global Lock "mutex" is actually a counting semaphore */ (void) acpi_os_delete_semaphore (acpi_gbl_global_lock_semaphore); acpi_gbl_global_lock_semaphore = NULL; - - acpi_os_delete_mutex(object->mutex.os_mutex); - acpi_gbl_global_lock_mutex = NULL; - } else { - acpi_ex_unlink_mutex(object); - acpi_os_delete_mutex(object->mutex.os_mutex); } break; diff --git a/trunk/drivers/acpi/utilities/uteval.c b/trunk/drivers/acpi/utilities/uteval.c index 13d5879cd98b..d6d7121583c0 100644 --- a/trunk/drivers/acpi/utilities/uteval.c +++ b/trunk/drivers/acpi/utilities/uteval.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utglobal.c b/trunk/drivers/acpi/utilities/utglobal.c index af33358a964b..014030af8b50 100644 --- a/trunk/drivers/acpi/utilities/utglobal.c +++ b/trunk/drivers/acpi/utilities/utglobal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,9 +46,89 @@ #include #include -ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) #define _COMPONENT ACPI_UTILITIES - ACPI_MODULE_NAME("utglobal") +ACPI_MODULE_NAME("utglobal") + +/******************************************************************************* + * + * FUNCTION: acpi_format_exception + * + * PARAMETERS: Status - The acpi_status code to be formatted + * + * RETURN: A string containing the exception text. A valid pointer is + * always returned. + * + * DESCRIPTION: This function translates an ACPI exception into an ASCII string. + * + ******************************************************************************/ +const char *acpi_format_exception(acpi_status status) +{ + acpi_status sub_status; + const char *exception = NULL; + + ACPI_FUNCTION_ENTRY(); + + /* + * Status is composed of two parts, a "type" and an actual code + */ + sub_status = (status & ~AE_CODE_MASK); + + switch (status & AE_CODE_MASK) { + case AE_CODE_ENVIRONMENTAL: + + if (sub_status <= AE_CODE_ENV_MAX) { + exception = acpi_gbl_exception_names_env[sub_status]; + } + break; + + case AE_CODE_PROGRAMMER: + + if (sub_status <= AE_CODE_PGM_MAX) { + exception = + acpi_gbl_exception_names_pgm[sub_status - 1]; + } + break; + + case AE_CODE_ACPI_TABLES: + + if (sub_status <= AE_CODE_TBL_MAX) { + exception = + acpi_gbl_exception_names_tbl[sub_status - 1]; + } + break; + + case AE_CODE_AML: + + if (sub_status <= AE_CODE_AML_MAX) { + exception = + acpi_gbl_exception_names_aml[sub_status - 1]; + } + break; + + case AE_CODE_CONTROL: + + if (sub_status <= AE_CODE_CTRL_MAX) { + exception = + acpi_gbl_exception_names_ctrl[sub_status - 1]; + } + break; + + default: + break; + } + + if (!exception) { + + /* Exception code was not recognized */ + + ACPI_ERROR((AE_INFO, + "Unknown exception code: 0x%8.8X", status)); + + exception = "UNKNOWN_STATUS_CODE"; + } + + return (ACPI_CAST_PTR(const char, exception)); +} /******************************************************************************* * @@ -83,6 +163,8 @@ u32 acpi_gbl_startup_flags = 0; u8 acpi_gbl_shutdown = TRUE; +const u8 acpi_gbl_decode_to8bit[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; + const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { "\\_S0_", "\\_S1_", @@ -99,47 +181,12 @@ const char *acpi_gbl_highest_dstate_names[4] = { "_S4D" }; -/******************************************************************************* - * - * FUNCTION: acpi_format_exception - * - * PARAMETERS: Status - The acpi_status code to be formatted - * - * RETURN: A string containing the exception text. A valid pointer is - * always returned. - * - * DESCRIPTION: This function translates an ACPI exception into an ASCII string - * It is here instead of utxface.c so it is always present. - * - ******************************************************************************/ - -const char *acpi_format_exception(acpi_status status) -{ - const char *exception = NULL; - - ACPI_FUNCTION_ENTRY(); - - exception = acpi_ut_validate_exception(status); - if (!exception) { - - /* Exception code was not recognized */ - - ACPI_ERROR((AE_INFO, - "Unknown exception code: 0x%8.8X", status)); - - exception = "UNKNOWN_STATUS_CODE"; - } - - return (ACPI_CAST_PTR(const char, exception)); -} - -ACPI_EXPORT_SYMBOL(acpi_format_exception) - /******************************************************************************* * * Namespace globals * ******************************************************************************/ + /* * Predefined ACPI Names (Built-in to the Interpreter) * @@ -233,6 +280,53 @@ char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position) return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); } +/******************************************************************************* + * + * Table name globals + * + * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes. + * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables + * that are not used by the subsystem are simply ignored. + * + * Do NOT add any table to this list that is not consumed directly by this + * subsystem (No MADT, ECDT, SBST, etc.) + * + ******************************************************************************/ + +struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1]; + +struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1] = { + /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ + + /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof(RSDP_SIG) - 1, + ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE} + , + /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *)&acpi_gbl_DSDT, + sizeof(DSDT_SIG) - 1, + ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE | + ACPI_TABLE_EXECUTABLE} + , + /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *)&acpi_gbl_FADT, + sizeof(FADT_SIG) - 1, + ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE} + , + /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *)&acpi_gbl_FACS, + sizeof(FACS_SIG) - 1, + ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE} + , + /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof(PSDT_SIG) - 1, + ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | + ACPI_TABLE_EXECUTABLE} + , + /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof(SSDT_SIG) - 1, + ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | + ACPI_TABLE_EXECUTABLE} + , + /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof(RSDT_SIG) - 1, + ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE} + , +}; + /****************************************************************************** * * Event and Hardware globals @@ -518,7 +612,7 @@ char *acpi_ut_get_node_name(void *object) /* Name must be a valid ACPI name */ if (!acpi_ut_valid_acpi_name(node->name.integer)) { - node->name.integer = acpi_ut_repair_name(node->name.ascii); + node->name.integer = acpi_ut_repair_name(node->name.integer); } /* Return the name */ @@ -657,6 +751,13 @@ void acpi_ut_init_globals(void) return; } + /* ACPI table structure */ + + for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { + acpi_gbl_table_lists[i].next = NULL; + acpi_gbl_table_lists[i].count = 0; + } + /* Mutex locked flags */ for (i = 0; i < ACPI_NUM_MUTEX; i++) { @@ -672,7 +773,6 @@ void acpi_ut_init_globals(void) /* GPE support */ - acpi_gpe_count = 0; acpi_gbl_gpe_xrupt_list_head = NULL; acpi_gbl_gpe_fadt_blocks[0] = NULL; acpi_gbl_gpe_fadt_blocks[1] = NULL; @@ -684,15 +784,25 @@ void acpi_ut_init_globals(void) acpi_gbl_exception_handler = NULL; acpi_gbl_init_handler = NULL; + /* Global "typed" ACPI table pointers */ + + acpi_gbl_RSDP = NULL; + acpi_gbl_XSDT = NULL; + acpi_gbl_FACS = NULL; + acpi_gbl_FADT = NULL; + acpi_gbl_DSDT = NULL; + /* Global Lock support */ acpi_gbl_global_lock_semaphore = NULL; - acpi_gbl_global_lock_mutex = NULL; acpi_gbl_global_lock_acquired = FALSE; + acpi_gbl_global_lock_thread_count = 0; acpi_gbl_global_lock_handle = 0; /* Miscellaneous variables */ + acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER; + acpi_gbl_rsdp_original_location = 0; acpi_gbl_cm_single_step = FALSE; acpi_gbl_db_terminate_threads = FALSE; acpi_gbl_shutdown = FALSE; @@ -727,13 +837,8 @@ void acpi_ut_init_globals(void) acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX; #endif -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - acpi_gbl_display_final_mem_stats = FALSE; -#endif - return_VOID; } ACPI_EXPORT_SYMBOL(acpi_dbg_level) ACPI_EXPORT_SYMBOL(acpi_dbg_layer) -ACPI_EXPORT_SYMBOL(acpi_gpe_count) diff --git a/trunk/drivers/acpi/utilities/utinit.c b/trunk/drivers/acpi/utilities/utinit.c index ad3c0d0a5cf8..ff76055eb7d6 100644 --- a/trunk/drivers/acpi/utilities/utinit.c +++ b/trunk/drivers/acpi/utilities/utinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,14 +44,119 @@ #include #include #include -#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utinit") /* Local prototypes */ +static void +acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset); + static void acpi_ut_terminate(void); +/******************************************************************************* + * + * FUNCTION: acpi_ut_fadt_register_error + * + * PARAMETERS: register_name - Pointer to string identifying register + * Value - Actual register contents value + * Offset - Byte offset in the FADT + * + * RETURN: AE_BAD_VALUE + * + * DESCRIPTION: Display failure message + * + ******************************************************************************/ + +static void +acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset) +{ + + ACPI_WARNING((AE_INFO, + "Invalid FADT value %s=%X at offset %X FADT=%p", + register_name, value, offset, acpi_gbl_FADT)); +} + +/****************************************************************************** + * + * FUNCTION: acpi_ut_validate_fadt + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Validate various ACPI registers in the FADT + * + ******************************************************************************/ + +acpi_status acpi_ut_validate_fadt(void) +{ + + /* + * Verify Fixed ACPI Description Table fields, + * but don't abort on any problems, just display error + */ + if (acpi_gbl_FADT->pm1_evt_len < 4) { + acpi_ut_fadt_register_error("PM1_EVT_LEN", + (u32) acpi_gbl_FADT->pm1_evt_len, + ACPI_FADT_OFFSET(pm1_evt_len)); + } + + if (!acpi_gbl_FADT->pm1_cnt_len) { + acpi_ut_fadt_register_error("PM1_CNT_LEN", 0, + ACPI_FADT_OFFSET(pm1_cnt_len)); + } + + if (!acpi_gbl_FADT->xpm1a_evt_blk.address) { + acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0, + ACPI_FADT_OFFSET(xpm1a_evt_blk. + address)); + } + + if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) { + acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0, + ACPI_FADT_OFFSET(xpm1a_cnt_blk. + address)); + } + + if (!acpi_gbl_FADT->xpm_tmr_blk.address) { + acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0, + ACPI_FADT_OFFSET(xpm_tmr_blk. + address)); + } + + if ((acpi_gbl_FADT->xpm2_cnt_blk.address && + !acpi_gbl_FADT->pm2_cnt_len)) { + acpi_ut_fadt_register_error("PM2_CNT_LEN", + (u32) acpi_gbl_FADT->pm2_cnt_len, + ACPI_FADT_OFFSET(pm2_cnt_len)); + } + + if (acpi_gbl_FADT->pm_tm_len < 4) { + acpi_ut_fadt_register_error("PM_TM_LEN", + (u32) acpi_gbl_FADT->pm_tm_len, + ACPI_FADT_OFFSET(pm_tm_len)); + } + + /* Length of GPE blocks must be a multiple of 2 */ + + if (acpi_gbl_FADT->xgpe0_blk.address && + (acpi_gbl_FADT->gpe0_blk_len & 1)) { + acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN", + (u32) acpi_gbl_FADT->gpe0_blk_len, + ACPI_FADT_OFFSET(gpe0_blk_len)); + } + + if (acpi_gbl_FADT->xgpe1_blk.address && + (acpi_gbl_FADT->gpe1_blk_len & 1)) { + acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN", + (u32) acpi_gbl_FADT->gpe1_blk_len, + ACPI_FADT_OFFSET(gpe1_blk_len)); + } + + return (AE_OK); +} + /****************************************************************************** * * FUNCTION: acpi_ut_terminate @@ -73,6 +178,7 @@ static void acpi_ut_terminate(void) ACPI_FUNCTION_TRACE(ut_terminate); + /* Free global tables, etc. */ /* Free global GPE blocks and related info structures */ gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; @@ -133,10 +239,6 @@ void acpi_ut_subsystem_shutdown(void) acpi_ns_terminate(); - /* Delete the ACPI tables */ - - acpi_tb_terminate(); - /* Close the globals */ acpi_ut_terminate(); diff --git a/trunk/drivers/acpi/utilities/utmath.c b/trunk/drivers/acpi/utilities/utmath.c index 0c56a0d20b29..19d74bedce27 100644 --- a/trunk/drivers/acpi/utilities/utmath.c +++ b/trunk/drivers/acpi/utilities/utmath.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utmisc.c b/trunk/drivers/acpi/utilities/utmisc.c index 50133fffe420..6d8a8211be90 100644 --- a/trunk/drivers/acpi/utilities/utmisc.c +++ b/trunk/drivers/acpi/utilities/utmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,78 +49,6 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") -/******************************************************************************* - * - * FUNCTION: acpi_ut_validate_exception - * - * PARAMETERS: Status - The acpi_status code to be formatted - * - * RETURN: A string containing the exception text. NULL if exception is - * not valid. - * - * DESCRIPTION: This function validates and translates an ACPI exception into - * an ASCII string. - * - ******************************************************************************/ -const char *acpi_ut_validate_exception(acpi_status status) -{ - acpi_status sub_status; - const char *exception = NULL; - - ACPI_FUNCTION_ENTRY(); - - /* - * Status is composed of two parts, a "type" and an actual code - */ - sub_status = (status & ~AE_CODE_MASK); - - switch (status & AE_CODE_MASK) { - case AE_CODE_ENVIRONMENTAL: - - if (sub_status <= AE_CODE_ENV_MAX) { - exception = acpi_gbl_exception_names_env[sub_status]; - } - break; - - case AE_CODE_PROGRAMMER: - - if (sub_status <= AE_CODE_PGM_MAX) { - exception = - acpi_gbl_exception_names_pgm[sub_status - 1]; - } - break; - - case AE_CODE_ACPI_TABLES: - - if (sub_status <= AE_CODE_TBL_MAX) { - exception = - acpi_gbl_exception_names_tbl[sub_status - 1]; - } - break; - - case AE_CODE_AML: - - if (sub_status <= AE_CODE_AML_MAX) { - exception = - acpi_gbl_exception_names_aml[sub_status - 1]; - } - break; - - case AE_CODE_CONTROL: - - if (sub_status <= AE_CODE_CTRL_MAX) { - exception = - acpi_gbl_exception_names_ctrl[sub_status - 1]; - } - break; - - default: - break; - } - - return (ACPI_CAST_PTR(const char, exception)); -} - /******************************************************************************* * * FUNCTION: acpi_ut_is_aml_table @@ -134,15 +62,14 @@ const char *acpi_ut_validate_exception(acpi_status status) * data tables that do not contain AML code. * ******************************************************************************/ - u8 acpi_ut_is_aml_table(struct acpi_table_header *table) { /* These are the only tables that contain executable AML */ - if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) { + if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) || + ACPI_COMPARE_NAME(table->signature, PSDT_SIG) || + ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) { return (TRUE); } @@ -491,7 +418,7 @@ u32 acpi_ut_dword_byte_swap(u32 value) void acpi_ut_set_integer_width(u8 revision) { - if (revision < 2) { + if (revision <= 1) { /* 32-bit case */ @@ -655,25 +582,26 @@ u8 acpi_ut_valid_acpi_name(u32 name) * ******************************************************************************/ -acpi_name acpi_ut_repair_name(char *name) +acpi_name acpi_ut_repair_name(acpi_name name) { - acpi_native_uint i; + char *name_ptr = ACPI_CAST_PTR(char, &name); char new_name[ACPI_NAME_SIZE]; + acpi_native_uint i; for (i = 0; i < ACPI_NAME_SIZE; i++) { - new_name[i] = name[i]; + new_name[i] = name_ptr[i]; /* * Replace a bad character with something printable, yet technically * still invalid. This prevents any collisions with existing "good" * names in the namespace. */ - if (!acpi_ut_valid_acpi_char(name[i], i)) { + if (!acpi_ut_valid_acpi_char(name_ptr[i], i)) { new_name[i] = '*'; } } - return (*(u32 *) new_name); + return (*ACPI_CAST_PTR(u32, new_name)); } /******************************************************************************* @@ -1068,13 +996,9 @@ acpi_ut_info(char *module_name, u32 line_number, char *format, ...) { va_list args; - /* - * Removed module_name, line_number, and acpica version, not needed - * for info output - */ - acpi_os_printf("ACPI: "); + acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number); va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf("\n"); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); } diff --git a/trunk/drivers/acpi/utilities/utmutex.c b/trunk/drivers/acpi/utilities/utmutex.c index cbad2ef5987d..180e73ceb6e2 100644 --- a/trunk/drivers/acpi/utilities/utmutex.c +++ b/trunk/drivers/acpi/utilities/utmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utobject.c b/trunk/drivers/acpi/utilities/utobject.c index 4696124759e1..ba7d8ac702df 100644 --- a/trunk/drivers/acpi/utilities/utobject.c +++ b/trunk/drivers/acpi/utilities/utobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utresrc.c b/trunk/drivers/acpi/utilities/utresrc.c index e8fe1ba6cc24..5a2de92831d3 100644 --- a/trunk/drivers/acpi/utilities/utresrc.c +++ b/trunk/drivers/acpi/utilities/utresrc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utstate.c b/trunk/drivers/acpi/utilities/utstate.c index edcaafad0a31..eaa13d05c859 100644 --- a/trunk/drivers/acpi/utilities/utstate.c +++ b/trunk/drivers/acpi/utilities/utstate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utxface.c b/trunk/drivers/acpi/utilities/utxface.c index de3276f4f468..3538f69c82a1 100644 --- a/trunk/drivers/acpi/utilities/utxface.c +++ b/trunk/drivers/acpi/utilities/utxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,7 +67,6 @@ acpi_status acpi_initialize_subsystem(void) ACPI_FUNCTION_TRACE(acpi_initialize_subsystem); - acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE; ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace()); /* Initialize the OS-Dependent layer */ @@ -128,6 +127,20 @@ acpi_status acpi_enable_subsystem(u32 flags) ACPI_FUNCTION_TRACE(acpi_enable_subsystem); + /* + * We must initialize the hardware before we can enable ACPI. + * The values from the FADT are validated here. + */ + if (!(flags & ACPI_NO_HARDWARE_INIT)) { + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "[Init] Initializing ACPI hardware\n")); + + status = acpi_hw_initialize(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } + /* Enable ACPI mode */ if (!(flags & ACPI_NO_ACPI_ENABLE)) { @@ -385,6 +398,7 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) { struct acpi_system_info *info_ptr; acpi_status status; + u32 i; ACPI_FUNCTION_TRACE(acpi_get_system_info); @@ -417,7 +431,9 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) /* Timer resolution - 24 or 32 bits */ - if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) { + if (!acpi_gbl_FADT) { + info_ptr->timer_resolution = 0; + } else if (acpi_gbl_FADT->tmr_val_ext == 0) { info_ptr->timer_resolution = 24; } else { info_ptr->timer_resolution = 32; @@ -433,6 +449,13 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) info_ptr->debug_layer = acpi_dbg_layer; info_ptr->debug_level = acpi_dbg_level; + /* Current status of the ACPI tables, per table type */ + + info_ptr->num_table_types = ACPI_TABLE_ID_MAX + 1; + for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { + info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count; + } + return_ACPI_STATUS(AE_OK); } diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index e0b97add8c63..3d54680d0333 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -32,7 +32,6 @@ #include #include -#include #include #include @@ -57,12 +56,6 @@ #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) #define ACPI_VIDEO_HEAD_END (~0u) -#define MAX_NAME_LEN 20 - -#define ACPI_VIDEO_DISPLAY_CRT 1 -#define ACPI_VIDEO_DISPLAY_TV 2 -#define ACPI_VIDEO_DISPLAY_DVI 3 -#define ACPI_VIDEO_DISPLAY_LCD 4 #define _COMPONENT ACPI_VIDEO_COMPONENT ACPI_MODULE_NAME("acpi_video") @@ -73,14 +66,16 @@ MODULE_LICENSE("GPL"); static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_remove(struct acpi_device *device, int type); +static int acpi_video_bus_match(struct acpi_device *device, + struct acpi_driver *driver); static struct acpi_driver acpi_video_bus = { .name = ACPI_VIDEO_DRIVER_NAME, .class = ACPI_VIDEO_CLASS, - .ids = ACPI_VIDEO_HID, .ops = { .add = acpi_video_bus_add, .remove = acpi_video_bus_remove, + .match = acpi_video_bus_match, }, }; @@ -138,21 +133,20 @@ struct acpi_video_device_flags { u8 crt:1; u8 lcd:1; u8 tvout:1; - u8 dvi:1; u8 bios:1; u8 unknown:1; - u8 reserved:2; + u8 reserved:3; }; struct acpi_video_device_cap { u8 _ADR:1; /*Return the unique ID */ u8 _BCL:1; /*Query list of brightness control levels supported */ u8 _BCM:1; /*Set the brightness level */ - u8 _BQC:1; /* Get current brightness level */ u8 _DDC:1; /*Return the EDID for this device */ u8 _DCS:1; /*Return status of output device */ u8 _DGS:1; /*Query graphics state */ u8 _DSS:1; /*Device state set */ + u8 _reserved:1; }; struct acpi_video_device_brightness { @@ -169,8 +163,6 @@ struct acpi_video_device { struct acpi_video_bus *video; struct acpi_device *dev; struct acpi_video_device_brightness *brightness; - struct backlight_device *backlight; - struct backlight_properties *data; }; /* bus */ @@ -265,35 +257,11 @@ static void acpi_video_device_bind(struct acpi_video_bus *video, struct acpi_video_device *device); static int acpi_video_device_enumerate(struct acpi_video_bus *video); static int acpi_video_switch_output(struct acpi_video_bus *video, int event); -static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, - int level); -static int acpi_video_device_lcd_get_level_current( - struct acpi_video_device *device, - unsigned long *level); static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event); static void acpi_video_switch_brightness(struct acpi_video_device *device, int event); -/*backlight device sysfs support*/ -static int acpi_video_get_brightness(struct backlight_device *bd) -{ - unsigned long cur_level; - struct acpi_video_device *vd = - (struct acpi_video_device *)class_get_devdata(&bd->class_dev); - acpi_video_device_lcd_get_level_current(vd, &cur_level); - return (int) cur_level; -} - -static int acpi_video_set_brightness(struct backlight_device *bd) -{ - int request_level = bd->props->brightness; - struct acpi_video_device *vd = - (struct acpi_video_device *)class_get_devdata(&bd->class_dev); - acpi_video_device_lcd_set_level(vd, request_level); - return 0; -} - /* -------------------------------------------------------------------------- Video Management -------------------------------------------------------------------------- */ @@ -531,7 +499,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) acpi_integer status; acpi_handle h_dummy1; int i; - u32 max_level = 0; union acpi_object *obj = NULL; struct acpi_video_device_brightness *br = NULL; @@ -547,8 +514,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { device->cap._BCM = 1; } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) - device->cap._BQC = 1; if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { device->cap._DDC = 1; } @@ -585,8 +550,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) continue; } br->levels[count] = (u32) o->integer.value; - if (br->levels[count] > max_level) - max_level = br->levels[count]; count++; } out: @@ -605,37 +568,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) kfree(obj); - if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ - unsigned long tmp; - static int count = 0; - char *name; - struct backlight_properties *acpi_video_data; - - name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); - if (!name) - return; - - acpi_video_data = kzalloc( - sizeof(struct backlight_properties), - GFP_KERNEL); - if (!acpi_video_data){ - kfree(name); - return; - } - acpi_video_data->owner = THIS_MODULE; - acpi_video_data->get_brightness = - acpi_video_get_brightness; - acpi_video_data->update_status = - acpi_video_set_brightness; - sprintf(name, "acpi_video%d", count++); - device->data = acpi_video_data; - acpi_video_data->max_brightness = max_level; - acpi_video_device_lcd_get_level_current(device, &tmp); - acpi_video_data->brightness = (int)tmp; - device->backlight = backlight_device_register(name, - NULL, device, acpi_video_data); - kfree(name); - } return; } @@ -736,8 +668,6 @@ static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) seq_printf(seq, "LCD\n"); else if (dev->flags.tvout) seq_printf(seq, "TVOUT\n"); - else if (dev->flags.dvi) - seq_printf(seq, "DVI\n"); else seq_printf(seq, "UNKNOWN\n"); @@ -1312,16 +1242,6 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) -------------------------------------------------------------------------- */ /* device interface */ -static struct acpi_video_device_attrib* -acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) -{ - int count; - - for(count = 0; count < video->attached_count; count++) - if((video->attached_array[count].value.int_val & 0xffff) == device_id) - return &(video->attached_array[count].value.attrib); - return NULL; -} static int acpi_video_bus_get_one_device(struct acpi_device *device, @@ -1330,7 +1250,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, unsigned long device_id; int status; struct acpi_video_device *data; - struct acpi_video_device_attrib* attribute; + if (!device || !video) return -EINVAL; @@ -1351,30 +1271,20 @@ acpi_video_bus_get_one_device(struct acpi_device *device, data->video = video; data->dev = device; - attribute = acpi_video_get_device_attr(video, device_id); - - if((attribute != NULL) && attribute->device_id_scheme) { - switch (attribute->display_type) { - case ACPI_VIDEO_DISPLAY_CRT: - data->flags.crt = 1; - break; - case ACPI_VIDEO_DISPLAY_TV: - data->flags.tvout = 1; - break; - case ACPI_VIDEO_DISPLAY_DVI: - data->flags.dvi = 1; - break; - case ACPI_VIDEO_DISPLAY_LCD: - data->flags.lcd = 1; - break; - default: - data->flags.unknown = 1; - break; - } - if(attribute->bios_can_detect) - data->flags.bios = 1; - } else + switch (device_id & 0xffff) { + case 0x0100: + data->flags.crt = 1; + break; + case 0x0400: + data->flags.lcd = 1; + break; + case 0x0200: + data->flags.tvout = 1; + break; + default: data->flags.unknown = 1; + break; + } acpi_video_device_bind(video, data); acpi_video_device_find_cap(data); @@ -1678,10 +1588,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) status = acpi_remove_notify_handler(device->dev->handle, ACPI_DEVICE_NOTIFY, acpi_video_device_notify); - if (device->backlight){ - backlight_device_unregister(device->backlight); - kfree(device->data); - } + return 0; } @@ -1883,6 +1790,39 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) return 0; } +static int +acpi_video_bus_match(struct acpi_device *device, struct acpi_driver *driver) +{ + acpi_handle h_dummy1; + acpi_handle h_dummy2; + acpi_handle h_dummy3; + + + if (!device || !driver) + return -EINVAL; + + /* Since there is no HID, CID for ACPI Video drivers, we have + * to check well known required nodes for each feature we support. + */ + + /* Does this device able to support video switching ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2))) + return 0; + + /* Does this device able to retrieve a video ROM ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1))) + return 0; + + /* Does this device able to configure which video head to be POSTed ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3))) + return 0; + + return -ENODEV; +} + static int __init acpi_video_init(void) { int result = 0; diff --git a/trunk/drivers/base/class.c b/trunk/drivers/base/class.c index 96def1ddba19..8bf2ca2e56b5 100644 --- a/trunk/drivers/base/class.c +++ b/trunk/drivers/base/class.c @@ -364,7 +364,7 @@ char *make_class_name(const char *name, struct kobject *kobj) class_name = kmalloc(size, GFP_KERNEL); if (!class_name) - return NULL; + return ERR_PTR(-ENOMEM); strcpy(class_name, name); strcat(class_name, ":"); @@ -411,11 +411,8 @@ static int make_deprecated_class_device_links(struct class_device *class_dev) return 0; class_name = make_class_name(class_dev->class->name, &class_dev->kobj); - if (class_name) - error = sysfs_create_link(&class_dev->dev->kobj, - &class_dev->kobj, class_name); - else - error = -ENOMEM; + error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, + class_name); kfree(class_name); return error; } @@ -428,8 +425,7 @@ static void remove_deprecated_class_device_links(struct class_device *class_dev) return; class_name = make_class_name(class_dev->class->name, &class_dev->kobj); - if (class_name) - sysfs_remove_link(&class_dev->dev->kobj, class_name); + sysfs_remove_link(&class_dev->dev->kobj, class_name); kfree(class_name); } #else @@ -867,12 +863,9 @@ int class_device_rename(struct class_device *class_dev, char *new_name) if (class_dev->dev) { new_class_name = make_class_name(class_dev->class->name, &class_dev->kobj); - if (new_class_name) - sysfs_create_link(&class_dev->dev->kobj, - &class_dev->kobj, new_class_name); - if (old_class_name) - sysfs_remove_link(&class_dev->dev->kobj, - old_class_name); + sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, + new_class_name); + sysfs_remove_link(&class_dev->dev->kobj, old_class_name); } #endif class_device_put(class_dev); diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index e13614241c9e..67b79a7592a9 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -95,8 +95,6 @@ static void device_release(struct kobject * kobj) if (dev->release) dev->release(dev); - else if (dev->type && dev->type->release) - dev->type->release(dev); else if (dev->class && dev->class->dev_release) dev->class->dev_release(dev); else { @@ -156,47 +154,25 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, "MINOR=%u", MINOR(dev->devt)); } - if (dev->driver) +#ifdef CONFIG_SYSFS_DEPRECATED + /* add bus name (same as SUBSYSTEM, deprecated) */ + if (dev->bus) add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, - "DRIVER=%s", dev->driver->name); + "PHYSDEVBUS=%s", dev->bus->name); +#endif + /* add driver name (PHYSDEV* values are deprecated)*/ + if (dev->driver) { + add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "DRIVER=%s", dev->driver->name); #ifdef CONFIG_SYSFS_DEPRECATED - if (dev->class) { - struct device *parent = dev->parent; - - /* find first bus device in parent chain */ - while (parent && !parent->bus) - parent = parent->parent; - if (parent && parent->bus) { - const char *path; - - path = kobject_get_path(&parent->kobj, GFP_KERNEL); - add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "PHYSDEVPATH=%s", path); - kfree(path); - - add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "PHYSDEVBUS=%s", parent->bus->name); - - if (parent->driver) - add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "PHYSDEVDRIVER=%s", parent->driver->name); - } - } else if (dev->bus) { add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, - "PHYSDEVBUS=%s", dev->bus->name); - - if (dev->driver) - add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "PHYSDEVDRIVER=%s", dev->driver->name); - } + "PHYSDEVDRIVER=%s", dev->driver->name); #endif + } /* terminate, set to next free slot, shrink available space */ envp[i] = NULL; @@ -208,25 +184,19 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, if (dev->bus && dev->bus->uevent) { /* have the bus specific function add its stuff */ retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size); - if (retval) - pr_debug ("%s: bus uevent() returned %d\n", + if (retval) { + pr_debug ("%s - uevent() returned %d\n", __FUNCTION__, retval); + } } if (dev->class && dev->class->dev_uevent) { /* have the class specific function add its stuff */ retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); - if (retval) - pr_debug("%s: class uevent() returned %d\n", - __FUNCTION__, retval); - } - - if (dev->type && dev->type->uevent) { - /* have the device type specific fuction add its stuff */ - retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size); - if (retval) - pr_debug("%s: dev_type uevent() returned %d\n", - __FUNCTION__, retval); + if (retval) { + pr_debug("%s - dev_uevent() returned %d\n", + __FUNCTION__, retval); + } } return retval; @@ -277,50 +247,37 @@ static void device_remove_groups(struct device *dev) static int device_add_attrs(struct device *dev) { struct class *class = dev->class; - struct device_type *type = dev->type; int error = 0; int i; - if (class && class->dev_attrs) { + if (!class) + return 0; + + if (class->dev_attrs) { for (i = 0; attr_name(class->dev_attrs[i]); i++) { error = device_create_file(dev, &class->dev_attrs[i]); if (error) break; } - if (error) - while (--i >= 0) - device_remove_file(dev, &class->dev_attrs[i]); } - - if (type && type->attrs) { - for (i = 0; attr_name(type->attrs[i]); i++) { - error = device_create_file(dev, &type->attrs[i]); - if (error) - break; - } - if (error) - while (--i >= 0) - device_remove_file(dev, &type->attrs[i]); - } - + if (error) + while (--i >= 0) + device_remove_file(dev, &class->dev_attrs[i]); return error; } static void device_remove_attrs(struct device *dev) { struct class *class = dev->class; - struct device_type *type = dev->type; int i; - if (class && class->dev_attrs) { + if (!class) + return; + + if (class->dev_attrs) { for (i = 0; attr_name(class->dev_attrs[i]); i++) device_remove_file(dev, &class->dev_attrs[i]); } - - if (type && type->attrs) { - for (i = 0; attr_name(type->attrs[i]); i++) - device_remove_file(dev, &type->attrs[i]); - } } @@ -433,23 +390,22 @@ void device_initialize(struct device *dev) } #ifdef CONFIG_SYSFS_DEPRECATED -static struct kobject * get_device_parent(struct device *dev, - struct device *parent) +static int setup_parent(struct device *dev, struct device *parent) { /* Set the parent to the class, not the parent device */ /* this keeps sysfs from having a symlink to make old udevs happy */ if (dev->class) - return &dev->class->subsys.kset.kobj; + dev->kobj.parent = &dev->class->subsys.kset.kobj; else if (parent) - return &parent->kobj; + dev->kobj.parent = &parent->kobj; - return NULL; + return 0; } #else -static struct kobject * virtual_device_parent(struct device *dev) +static int virtual_device_parent(struct device *dev) { if (!dev->class) - return ERR_PTR(-ENODEV); + return -ENODEV; if (!dev->class->virtual_dir) { static struct kobject *virtual_dir = NULL; @@ -459,31 +415,25 @@ static struct kobject * virtual_device_parent(struct device *dev) dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); } - return dev->class->virtual_dir; + dev->kobj.parent = dev->class->virtual_dir; + return 0; } -static struct kobject * get_device_parent(struct device *dev, - struct device *parent) +static int setup_parent(struct device *dev, struct device *parent) { + int error; + /* if this is a class device, and has no parent, create one */ if ((dev->class) && (parent == NULL)) { - return virtual_device_parent(dev); + error = virtual_device_parent(dev); + if (error) + return error; } else if (parent) - return &parent->kobj; - return NULL; -} + dev->kobj.parent = &parent->kobj; -#endif -static int setup_parent(struct device *dev, struct device *parent) -{ - struct kobject *kobj; - kobj = get_device_parent(dev, parent); - if (IS_ERR(kobj)) - return PTR_ERR(kobj); - if (kobj) - dev->kobj.parent = kobj; return 0; } +#endif /** * device_add - add device to device hierarchy. @@ -570,13 +520,9 @@ int device_add(struct device *dev) &dev->kobj, dev->bus_id); #ifdef CONFIG_SYSFS_DEPRECATED if (parent) { - sysfs_create_link(&dev->kobj, &dev->parent->kobj, - "device"); - class_name = make_class_name(dev->class->name, - &dev->kobj); - if (class_name) - sysfs_create_link(&dev->parent->kobj, - &dev->kobj, class_name); + sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); + class_name = make_class_name(dev->class->name, &dev->kobj); + sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); } #endif } @@ -589,8 +535,7 @@ int device_add(struct device *dev) goto PMError; if ((error = bus_add_device(dev))) goto BusError; - if (!dev->uevent_suppress) - kobject_uevent(&dev->kobj, KOBJ_ADD); + kobject_uevent(&dev->kobj, KOBJ_ADD); if ((error = bus_attach_device(dev))) goto AttachError; if (parent) @@ -720,9 +665,7 @@ void device_del(struct device * dev) if (parent) { char *class_name = make_class_name(dev->class->name, &dev->kobj); - if (class_name) - sysfs_remove_link(&dev->parent->kobj, - class_name); + sysfs_remove_link(&dev->parent->kobj, class_name); kfree(class_name); sysfs_remove_link(&dev->kobj, "device"); } @@ -1025,25 +968,20 @@ static int device_move_class_links(struct device *dev, class_name = make_class_name(dev->class->name, &dev->kobj); if (!class_name) { - error = -ENOMEM; + error = PTR_ERR(class_name); + class_name = NULL; goto out; } if (old_parent) { sysfs_remove_link(&dev->kobj, "device"); sysfs_remove_link(&old_parent->kobj, class_name); } - if (new_parent) { - error = sysfs_create_link(&dev->kobj, &new_parent->kobj, - "device"); - if (error) - goto out; - error = sysfs_create_link(&new_parent->kobj, &dev->kobj, - class_name); - if (error) - sysfs_remove_link(&dev->kobj, "device"); - } - else - error = 0; + error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device"); + if (error) + goto out; + error = sysfs_create_link(&new_parent->kobj, &dev->kobj, class_name); + if (error) + sysfs_remove_link(&dev->kobj, "device"); out: kfree(class_name); return error; @@ -1055,28 +993,29 @@ static int device_move_class_links(struct device *dev, /** * device_move - moves a device to a new parent * @dev: the pointer to the struct device to be moved - * @new_parent: the new parent of the device (can by NULL) + * @new_parent: the new parent of the device */ int device_move(struct device *dev, struct device *new_parent) { int error; struct device *old_parent; - struct kobject *new_parent_kobj; dev = get_device(dev); if (!dev) return -EINVAL; + if (!device_is_registered(dev)) { + error = -EINVAL; + goto out; + } new_parent = get_device(new_parent); - new_parent_kobj = get_device_parent (dev, new_parent); - if (IS_ERR(new_parent_kobj)) { - error = PTR_ERR(new_parent_kobj); - put_device(new_parent); + if (!new_parent) { + error = -EINVAL; goto out; } pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id, - new_parent ? new_parent->bus_id : ""); - error = kobject_move(&dev->kobj, new_parent_kobj); + new_parent->bus_id); + error = kobject_move(&dev->kobj, &new_parent->kobj); if (error) { put_device(new_parent); goto out; @@ -1085,8 +1024,7 @@ int device_move(struct device *dev, struct device *new_parent) dev->parent = new_parent; if (old_parent) klist_remove(&dev->knode_parent); - if (new_parent) - klist_add_tail(&dev->knode_parent, &new_parent->klist_children); + klist_add_tail(&dev->knode_parent, &new_parent->klist_children); if (!dev->class) goto out_put; error = device_move_class_links(dev, old_parent, new_parent); @@ -1094,8 +1032,7 @@ int device_move(struct device *dev, struct device *new_parent) /* We ignore errors on cleanup since we're hosed anyway... */ device_move_class_links(dev, new_parent, old_parent); if (!kobject_move(&dev->kobj, &old_parent->kobj)) { - if (new_parent) - klist_remove(&dev->knode_parent); + klist_remove(&dev->knode_parent); if (old_parent) klist_add_tail(&dev->knode_parent, &old_parent->klist_children); diff --git a/trunk/drivers/base/dd.c b/trunk/drivers/base/dd.c index b5bf243d9cd6..510e7884975f 100644 --- a/trunk/drivers/base/dd.c +++ b/trunk/drivers/base/dd.c @@ -86,12 +86,8 @@ static void driver_sysfs_remove(struct device *dev) */ int device_bind_driver(struct device *dev) { - int ret; - - ret = driver_sysfs_add(dev); - if (!ret) - driver_bound(dev); - return ret; + driver_bound(dev); + return driver_sysfs_add(dev); } struct stupid_thread_structure { @@ -140,17 +136,18 @@ static int really_probe(void *void_data) driver_sysfs_remove(dev); dev->driver = NULL; - if (ret != -ENODEV && ret != -ENXIO) { + if (ret == -ENODEV || ret == -ENXIO) { + /* Driver matched, but didn't support device + * or device not found. + * Not an error; keep going. + */ + ret = 0; + } else { /* driver matched but the probe failed */ printk(KERN_WARNING "%s: probe of %s failed with error %d\n", drv->name, dev->bus_id, ret); } - /* - * Ignore errors returned by ->probe so that the next driver can try - * its luck. - */ - ret = 0; done: kfree(data); atomic_dec(&probe_count); diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index c0a979a5074b..64558f45e6bc 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -35,7 +35,7 @@ enum { FW_STATUS_READY_NOHOTPLUG, }; -static int loading_timeout = 60; /* In seconds */ +static int loading_timeout = 10; /* In seconds */ /* fw_lock could be moved to 'struct firmware_priv' but since it is just * guarding for corner cases a global lock should be OK */ diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index 30480f6f2af2..f9c903ba9fcd 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -611,15 +611,8 @@ EXPORT_SYMBOL_GPL(platform_bus_type); int __init platform_bus_init(void) { - int error; - - error = device_register(&platform_bus); - if (error) - return error; - error = bus_register(&platform_bus_type); - if (error) - device_unregister(&platform_bus); - return error; + device_register(&platform_bus); + return bus_register(&platform_bus_type); } #ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index d08bb4ee1307..9e43e39dc35c 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -610,13 +610,6 @@ config HVC_RTAS help IBM Console device driver which makes use of RTAS -config HVC_BEAT - bool "Toshiba's Beat Hypervisor Console support" - depends on PPC_CELLEB - select HVC_DRIVER - help - Toshiba's Cell Reference Set Beat Console device driver - config HVCS tristate "IBM Hypervisor Virtual Console Server support" depends on PPC_PSERIES diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 0326ca1a848a..fc110637ced6 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_RIO) += rio/ generic_serial.o obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o -obj-$(CONFIG_HVC_BEAT) += hvc_beat.o obj-$(CONFIG_HVC_DRIVER) += hvc_console.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o diff --git a/trunk/drivers/char/drm/drmP.h b/trunk/drivers/char/drm/drmP.h index 85d99e21e188..6dcdceb81203 100644 --- a/trunk/drivers/char/drm/drmP.h +++ b/trunk/drivers/char/drm/drmP.h @@ -532,13 +532,11 @@ typedef struct drm_mm_node { int free; unsigned long start; unsigned long size; - struct drm_mm *mm; void *private; } drm_mm_node_t; typedef struct drm_mm { - struct list_head fl_entry; - struct list_head ml_entry; + drm_mm_node_t root_node; } drm_mm_t; /** @@ -845,6 +843,9 @@ extern void drm_mem_init(void); extern int drm_mem_info(char *buf, char **start, off_t offset, int request, int *eof, void *data); extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); +extern void *drm_ioremap(unsigned long offset, unsigned long size, + drm_device_t * dev); +extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev); extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type); extern int drm_free_agp(DRM_AGP_MEM * handle, int pages); @@ -1052,18 +1053,33 @@ extern void drm_sysfs_device_remove(struct class_device *class_dev); extern drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, unsigned long size, unsigned alignment); -void drm_mm_put_block(drm_mm_node_t * cur); +extern void drm_mm_put_block(drm_mm_t *mm, drm_mm_node_t *cur); extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size, unsigned alignment, int best_match); extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size); extern void drm_mm_takedown(drm_mm_t *mm); -extern int drm_mm_clean(drm_mm_t *mm); -extern unsigned long drm_mm_tail_space(drm_mm_t *mm); -extern int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size); -extern int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size); -extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); -extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); +/* Inline replacements for DRM_IOREMAP macros */ +static __inline__ void drm_core_ioremap(struct drm_map *map, + struct drm_device *dev) +{ + map->handle = drm_ioremap(map->offset, map->size, dev); +} + +#if 0 +static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, + struct drm_device *dev) +{ + map->handle = drm_ioremap_nocache(map->offset, map->size, dev); +} +#endif /* 0 */ + +static __inline__ void drm_core_ioremapfree(struct drm_map *map, + struct drm_device *dev) +{ + if (map->handle && map->size) + drm_ioremapfree(map->handle, map->size, dev); +} static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned int token) diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c index a6828cc14e58..9f65f5697ba8 100644 --- a/trunk/drivers/char/drm/drm_bufs.c +++ b/trunk/drivers/char/drm/drm_bufs.c @@ -79,14 +79,14 @@ static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, if (!use_hashed_handle) { int ret; - hash->key = user_token >> PAGE_SHIFT; + hash->key = user_token; ret = drm_ht_insert_item(&dev->map_hash, hash); if (ret != -EINVAL) return ret; } return drm_ht_just_insert_please(&dev->map_hash, hash, user_token, 32 - PAGE_SHIFT - 3, - 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT); + PAGE_SHIFT, DRM_MAP_HASH_OFFSET); } /** @@ -178,11 +178,11 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, } } if (map->type == _DRM_REGISTERS) - map->handle = ioremap(map->offset, map->size); + map->handle = drm_ioremap(map->offset, map->size, dev); break; case _DRM_SHM: - map->handle = vmalloc_user(map->size); + map->handle = vmalloc_32(map->size); DRM_DEBUG("%lu %d %p\n", map->size, drm_order(map->size), map->handle); if (!map->handle) { @@ -238,7 +238,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); if (!list) { if (map->type == _DRM_REGISTERS) - iounmap(map->handle); + drm_ioremapfree(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } @@ -255,14 +255,14 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, ret = drm_map_handle(dev, &list->hash, user_token, 0); if (ret) { if (map->type == _DRM_REGISTERS) - iounmap(map->handle); + drm_ioremapfree(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); drm_free(list, sizeof(*list), DRM_MEM_MAPS); mutex_unlock(&dev->struct_mutex); return ret; } - list->user_token = list->hash.key << PAGE_SHIFT; + list->user_token = list->hash.key; mutex_unlock(&dev->struct_mutex); *maplist = list; @@ -347,8 +347,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) if (r_list->map == map) { list_del(list); - drm_ht_remove_key(&dev->map_hash, - r_list->user_token >> PAGE_SHIFT); + drm_ht_remove_key(&dev->map_hash, r_list->user_token); drm_free(list, sizeof(*list), DRM_MEM_MAPS); break; } @@ -363,7 +362,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) switch (map->type) { case _DRM_REGISTERS: - iounmap(map->handle); + drm_ioremapfree(map->handle, map->size, dev); /* FALLTHROUGH */ case _DRM_FRAME_BUFFER: if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { diff --git a/trunk/drivers/char/drm/drm_memory.c b/trunk/drivers/char/drm/drm_memory.c index 92a867082376..5681cae1d404 100644 --- a/trunk/drivers/char/drm/drm_memory.c +++ b/trunk/drivers/char/drm/drm_memory.c @@ -79,6 +79,28 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) } #if __OS_HAS_AGP +/* + * Find the drm_map that covers the range [offset, offset+size). + */ +static drm_map_t *drm_lookup_map(unsigned long offset, + unsigned long size, drm_device_t * dev) +{ + struct list_head *list; + drm_map_list_t *r_list; + drm_map_t *map; + + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *) list; + map = r_list->map; + if (!map) + continue; + if (map->offset <= offset + && (offset + size) <= (map->offset + map->size)) + return map; + } + return NULL; +} + static void *agp_remap(unsigned long offset, unsigned long size, drm_device_t * dev) { @@ -147,6 +169,13 @@ int drm_unbind_agp(DRM_AGP_MEM * handle) } #else /* __OS_HAS_AGP */ + +static inline drm_map_t *drm_lookup_map(unsigned long offset, + unsigned long size, drm_device_t * dev) +{ + return NULL; +} + static inline void *agp_remap(unsigned long offset, unsigned long size, drm_device_t * dev) { @@ -155,28 +184,57 @@ static inline void *agp_remap(unsigned long offset, unsigned long size, #endif /* agp */ -#endif /* debug_memory */ +void *drm_ioremap(unsigned long offset, unsigned long size, + drm_device_t * dev) +{ + if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { + drm_map_t *map = drm_lookup_map(offset, size, dev); + + if (map && map->type == _DRM_AGP) + return agp_remap(offset, size, dev); + } + return ioremap(offset, size); +} +EXPORT_SYMBOL(drm_ioremap); -void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) +#if 0 +void *drm_ioremap_nocache(unsigned long offset, + unsigned long size, drm_device_t * dev) { - if (drm_core_has_AGP(dev) && - dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) - map->handle = agp_remap(map->offset, map->size, dev); - else - map->handle = ioremap(map->offset, map->size); + if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { + drm_map_t *map = drm_lookup_map(offset, size, dev); + + if (map && map->type == _DRM_AGP) + return agp_remap(offset, size, dev); + } + return ioremap_nocache(offset, size); } -EXPORT_SYMBOL(drm_core_ioremap); +#endif /* 0 */ -void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev) +void drm_ioremapfree(void *pt, unsigned long size, + drm_device_t * dev) { - if (!map->handle || !map->size) - return; - - if (drm_core_has_AGP(dev) && - dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) - vunmap(map->handle); - else - iounmap(map->handle); + /* + * This is a bit ugly. It would be much cleaner if the DRM API would use separate + * routines for handling mappings in the AGP space. Hopefully this can be done in + * a future revision of the interface... + */ + if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture + && ((unsigned long)pt >= VMALLOC_START + && (unsigned long)pt < VMALLOC_END)) { + unsigned long offset; + drm_map_t *map; + + offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK); + map = drm_lookup_map(offset, size, dev); + if (map && map->type == _DRM_AGP) { + vunmap(pt); + return; + } + } + + iounmap(pt); } -EXPORT_SYMBOL(drm_core_ioremapfree); +EXPORT_SYMBOL(drm_ioremapfree); +#endif /* debug_memory */ diff --git a/trunk/drivers/char/drm/drm_memory.h b/trunk/drivers/char/drm/drm_memory.h index 63e425b5ea82..f1b97aff10cf 100644 --- a/trunk/drivers/char/drm/drm_memory.h +++ b/trunk/drivers/char/drm/drm_memory.h @@ -56,6 +56,26 @@ # endif #endif +static inline unsigned long drm_follow_page(void *vaddr) +{ + pgd_t *pgd = pgd_offset_k((unsigned long)vaddr); + pud_t *pud = pud_offset(pgd, (unsigned long)vaddr); + pmd_t *pmd = pmd_offset(pud, (unsigned long)vaddr); + pte_t *ptep = pte_offset_kernel(pmd, (unsigned long)vaddr); + return pte_pfn(*ptep) << PAGE_SHIFT; +} + #else /* __OS_HAS_AGP */ +static inline unsigned long drm_follow_page(void *vaddr) +{ + return 0; +} + #endif + +void *drm_ioremap(unsigned long offset, unsigned long size, + drm_device_t * dev); + +void drm_ioremapfree(void *pt, unsigned long size, + drm_device_t * dev); diff --git a/trunk/drivers/char/drm/drm_memory_debug.h b/trunk/drivers/char/drm/drm_memory_debug.h index 6463271deea8..74581af806e1 100644 --- a/trunk/drivers/char/drm/drm_memory_debug.h +++ b/trunk/drivers/char/drm/drm_memory_debug.h @@ -205,6 +205,76 @@ void drm_free (void *pt, size_t size, int area) { } } +void *drm_ioremap (unsigned long offset, unsigned long size, + drm_device_t * dev) { + void *pt; + + if (!size) { + DRM_MEM_ERROR(DRM_MEM_MAPPINGS, + "Mapping 0 bytes at 0x%08lx\n", offset); + return NULL; + } + + if (!(pt = drm_ioremap(offset, size, dev))) { + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; + spin_unlock(&drm_mem_lock); + return NULL; + } + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; + drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; + spin_unlock(&drm_mem_lock); + return pt; +} + +#if 0 +void *drm_ioremap_nocache (unsigned long offset, unsigned long size, + drm_device_t * dev) { + void *pt; + + if (!size) { + DRM_MEM_ERROR(DRM_MEM_MAPPINGS, + "Mapping 0 bytes at 0x%08lx\n", offset); + return NULL; + } + + if (!(pt = drm_ioremap_nocache(offset, size, dev))) { + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; + spin_unlock(&drm_mem_lock); + return NULL; + } + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; + drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; + spin_unlock(&drm_mem_lock); + return pt; +} +#endif /* 0 */ + +void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { + int alloc_count; + int free_count; + + if (!pt) + DRM_MEM_ERROR(DRM_MEM_MAPPINGS, + "Attempt to free NULL pointer\n"); + else + drm_ioremapfree(pt, size, dev); + + spin_lock(&drm_mem_lock); + drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size; + free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count; + alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; + spin_unlock(&drm_mem_lock); + if (free_count > alloc_count) { + DRM_MEM_ERROR(DRM_MEM_MAPPINGS, + "Excess frees: %d frees, %d allocs\n", + free_count, alloc_count); + } +} + #if __OS_HAS_AGP DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) { diff --git a/trunk/drivers/char/drm/drm_mm.c b/trunk/drivers/char/drm/drm_mm.c index 9b46b85027d0..617526bd5b0c 100644 --- a/trunk/drivers/char/drm/drm_mm.c +++ b/trunk/drivers/char/drm/drm_mm.c @@ -42,131 +42,36 @@ */ #include "drmP.h" -#include - -unsigned long drm_mm_tail_space(drm_mm_t *mm) -{ - struct list_head *tail_node; - drm_mm_node_t *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, drm_mm_node_t, ml_entry); - if (!entry->free) - return 0; - - return entry->size; -} - -int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size) -{ - struct list_head *tail_node; - drm_mm_node_t *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, drm_mm_node_t, ml_entry); - if (!entry->free) - return -ENOMEM; - - if (entry->size <= size) - return -ENOMEM; - - entry->size -= size; - return 0; -} - - -static int drm_mm_create_tail_node(drm_mm_t *mm, - unsigned long start, - unsigned long size) -{ - drm_mm_node_t *child; - - child = (drm_mm_node_t *) - drm_alloc(sizeof(*child), DRM_MEM_MM); - if (!child) - return -ENOMEM; - - child->free = 1; - child->size = size; - child->start = start; - child->mm = mm; - - list_add_tail(&child->ml_entry, &mm->ml_entry); - list_add_tail(&child->fl_entry, &mm->fl_entry); - - return 0; -} - - -int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size) -{ - struct list_head *tail_node; - drm_mm_node_t *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, drm_mm_node_t, ml_entry); - if (!entry->free) { - return drm_mm_create_tail_node(mm, entry->start + entry->size, size); - } - entry->size += size; - return 0; -} - -static drm_mm_node_t *drm_mm_split_at_start(drm_mm_node_t *parent, - unsigned long size) -{ - drm_mm_node_t *child; - - child = (drm_mm_node_t *) - drm_alloc(sizeof(*child), DRM_MEM_MM); - if (!child) - return NULL; - - INIT_LIST_HEAD(&child->fl_entry); - - child->free = 0; - child->size = size; - child->start = parent->start; - child->mm = parent->mm; - - list_add_tail(&child->ml_entry, &parent->ml_entry); - INIT_LIST_HEAD(&child->fl_entry); - - parent->size -= size; - parent->start += size; - return child; -} - - drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, unsigned long size, unsigned alignment) { - drm_mm_node_t *align_splitoff = NULL; drm_mm_node_t *child; - unsigned tmp = 0; if (alignment) - tmp = parent->start % alignment; - - if (tmp) { - align_splitoff = drm_mm_split_at_start(parent, alignment - tmp); - if (!align_splitoff) - return NULL; - } + size += alignment - 1; if (parent->size == size) { list_del_init(&parent->fl_entry); parent->free = 0; return parent; } else { - child = drm_mm_split_at_start(parent, size); - } + child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); + if (!child) + return NULL; + + INIT_LIST_HEAD(&child->ml_entry); + INIT_LIST_HEAD(&child->fl_entry); - if (align_splitoff) - drm_mm_put_block(align_splitoff); + child->free = 0; + child->size = size; + child->start = parent->start; + list_add_tail(&child->ml_entry, &parent->ml_entry); + parent->size -= size; + parent->start += size; + } return child; } @@ -175,12 +80,12 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, * Otherwise add to the free stack. */ -void drm_mm_put_block(drm_mm_node_t * cur) +void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) { - drm_mm_t *mm = cur->mm; + drm_mm_node_t *list_root = &mm->root_node; struct list_head *cur_head = &cur->ml_entry; - struct list_head *root_head = &mm->ml_entry; + struct list_head *root_head = &list_root->ml_entry; drm_mm_node_t *prev_node = NULL; drm_mm_node_t *next_node; @@ -211,7 +116,7 @@ void drm_mm_put_block(drm_mm_node_t * cur) } if (!merged) { cur->free = 1; - list_add(&cur->fl_entry, &mm->fl_entry); + list_add(&cur->fl_entry, &list_root->fl_entry); } else { list_del(&cur->ml_entry); drm_free(cur, sizeof(*cur), DRM_MEM_MM); @@ -223,30 +128,20 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm, unsigned alignment, int best_match) { struct list_head *list; - const struct list_head *free_stack = &mm->fl_entry; + const struct list_head *free_stack = &mm->root_node.fl_entry; drm_mm_node_t *entry; drm_mm_node_t *best; unsigned long best_size; - unsigned wasted; best = NULL; best_size = ~0UL; + if (alignment) + size += alignment - 1; + list_for_each(list, free_stack) { entry = list_entry(list, drm_mm_node_t, fl_entry); - wasted = 0; - - if (entry->size < size) - continue; - - if (alignment) { - register unsigned tmp = entry->start % alignment; - if (tmp) - wasted += alignment - tmp; - } - - - if (entry->size >= size + wasted) { + if (entry->size >= size) { if (!best_match) return entry; if (size < best_size) { @@ -259,32 +154,40 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm, return best; } -int drm_mm_clean(drm_mm_t * mm) +int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) { - struct list_head *head = &mm->ml_entry; + drm_mm_node_t *child; - return (head->next->next == head); -} + INIT_LIST_HEAD(&mm->root_node.ml_entry); + INIT_LIST_HEAD(&mm->root_node.fl_entry); + child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); + if (!child) + return -ENOMEM; -int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) -{ - INIT_LIST_HEAD(&mm->ml_entry); - INIT_LIST_HEAD(&mm->fl_entry); + INIT_LIST_HEAD(&child->ml_entry); + INIT_LIST_HEAD(&child->fl_entry); + + child->start = start; + child->size = size; + child->free = 1; - return drm_mm_create_tail_node(mm, start, size); + list_add(&child->fl_entry, &mm->root_node.fl_entry); + list_add(&child->ml_entry, &mm->root_node.ml_entry); + + return 0; } EXPORT_SYMBOL(drm_mm_init); void drm_mm_takedown(drm_mm_t * mm) { - struct list_head *bnode = mm->fl_entry.next; + struct list_head *bnode = mm->root_node.fl_entry.next; drm_mm_node_t *entry; entry = list_entry(bnode, drm_mm_node_t, fl_entry); - if (entry->ml_entry.next != &mm->ml_entry || - entry->fl_entry.next != &mm->fl_entry) { + if (entry->ml_entry.next != &mm->root_node.ml_entry || + entry->fl_entry.next != &mm->root_node.fl_entry) { DRM_ERROR("Memory manager not clean. Delaying takedown\n"); return; } diff --git a/trunk/drivers/char/drm/drm_pciids.h b/trunk/drivers/char/drm/drm_pciids.h index ad54b845978b..09398d5fbd3f 100644 --- a/trunk/drivers/char/drm/drm_pciids.h +++ b/trunk/drivers/char/drm/drm_pciids.h @@ -226,14 +226,12 @@ {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \ + {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} #define i810_PCI_IDS \ diff --git a/trunk/drivers/char/drm/drm_proc.c b/trunk/drivers/char/drm/drm_proc.c index 7fd0da712142..62d5fe15f046 100644 --- a/trunk/drivers/char/drm/drm_proc.c +++ b/trunk/drivers/char/drm/drm_proc.c @@ -500,7 +500,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, for (pt = dev->vmalist; pt; pt = pt->next) { if (!(vma = pt->vma)) continue; - DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", + DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx", pt->pid, vma->vm_start, vma->vm_end, @@ -510,7 +510,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, vma->vm_flags & VM_MAYSHARE ? 's' : 'p', vma->vm_flags & VM_LOCKED ? 'l' : '-', vma->vm_flags & VM_IO ? 'i' : '-', - vma->vm_pgoff); + vma->vm_pgoff << PAGE_SHIFT); #if defined(__i386__) pgprot = pgprot_val(vma->vm_page_prot); diff --git a/trunk/drivers/char/drm/drm_sman.c b/trunk/drivers/char/drm/drm_sman.c index e15db6d6bea9..19c81d2e13d0 100644 --- a/trunk/drivers/char/drm/drm_sman.c +++ b/trunk/drivers/char/drm/drm_sman.c @@ -101,9 +101,10 @@ static void *drm_sman_mm_allocate(void *private, unsigned long size, static void drm_sman_mm_free(void *private, void *ref) { + drm_mm_t *mm = (drm_mm_t *) private; drm_mm_node_t *node = (drm_mm_node_t *) ref; - drm_mm_put_block(node); + drm_mm_put_block(mm, node); } static void drm_sman_mm_destroy(void *private) diff --git a/trunk/drivers/char/drm/drm_vm.c b/trunk/drivers/char/drm/drm_vm.c index 54a632848955..b9cfc077f6bc 100644 --- a/trunk/drivers/char/drm/drm_vm.c +++ b/trunk/drivers/char/drm/drm_vm.c @@ -70,7 +70,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, if (!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error; - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) + if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) goto vm_nopage_error; r_list = drm_hash_entry(hash, drm_map_list_t, hash); @@ -227,7 +227,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) map->size); DRM_DEBUG("mtrr_del = %d\n", retcode); } - iounmap(map->handle); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: vfree(map->handle); @@ -463,8 +463,8 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) lock_kernel(); dev = priv->head->dev; dma = dev->dma; - DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff); + DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", + vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); /* Length must match exact page count */ if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { @@ -537,8 +537,8 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) unsigned long offset = 0; drm_hash_item_t *hash; - DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff); + DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", + vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); if (!priv->authenticated) return -EACCES; @@ -547,7 +547,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) * the AGP mapped at physical address 0 * --BenH. */ - if (!vma->vm_pgoff + if (!(vma->vm_pgoff << PAGE_SHIFT) #if __OS_HAS_AGP && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) @@ -555,7 +555,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) ) return drm_mmap_dma(filp, vma); - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) { + if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) { DRM_ERROR("Could not find map\n"); return -EINVAL; } diff --git a/trunk/drivers/char/drm/i810_dma.c b/trunk/drivers/char/drm/i810_dma.c index 60cb4e45a75e..fa2de70f7401 100644 --- a/trunk/drivers/char/drm/i810_dma.c +++ b/trunk/drivers/char/drm/i810_dma.c @@ -219,7 +219,8 @@ static int i810_dma_cleanup(drm_device_t * dev) (drm_i810_private_t *) dev->dev_private; if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); + drm_ioremapfree((void *)dev_priv->ring.virtual_start, + dev_priv->ring.Size, dev); } if (dev_priv->hw_status_page) { pci_free_consistent(dev->pdev, PAGE_SIZE, @@ -235,9 +236,9 @@ static int i810_dma_cleanup(drm_device_t * dev) for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[i]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - if (buf_priv->kernel_virtual && buf->total) - drm_core_ioremapfree(&buf_priv->map, dev); + drm_ioremapfree(buf_priv->kernel_virtual, + buf->total, dev); } } return 0; @@ -310,15 +311,8 @@ static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv) *buf_priv->in_use = I810_BUF_FREE; - buf_priv->map.offset = buf->bus_address; - buf_priv->map.size = buf->total; - buf_priv->map.type = _DRM_AGP; - buf_priv->map.flags = 0; - buf_priv->map.mtrr = 0; - - drm_core_ioremap(&buf_priv->map, dev); - buf_priv->kernel_virtual = buf_priv->map.handle; - + buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, + buf->total, dev); } return 0; } @@ -369,24 +363,18 @@ static int i810_dma_initialize(drm_device_t * dev, dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; - dev_priv->ring.map.offset = dev->agp->base + init->ring_start; - dev_priv->ring.map.size = init->ring_size; - dev_priv->ring.map.type = _DRM_AGP; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; + dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + + init->ring_start, + init->ring_size, dev); - drm_core_ioremap(&dev_priv->ring.map, dev); - - if (dev_priv->ring.map.handle == NULL) { + if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *)dev_priv; i810_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; dev_priv->w = init->w; diff --git a/trunk/drivers/char/drm/i810_drv.h b/trunk/drivers/char/drm/i810_drv.h index e6df49f4928a..e8cf3ff606f0 100644 --- a/trunk/drivers/char/drm/i810_drv.h +++ b/trunk/drivers/char/drm/i810_drv.h @@ -61,7 +61,6 @@ typedef struct drm_i810_buf_priv { int currently_mapped; void *virtual; void *kernel_virtual; - drm_local_map_t map; } drm_i810_buf_priv_t; typedef struct _drm_i810_ring_buffer { @@ -73,7 +72,6 @@ typedef struct _drm_i810_ring_buffer { int head; int tail; int space; - drm_local_map_t map; } drm_i810_ring_buffer_t; typedef struct drm_i810_private { diff --git a/trunk/drivers/char/drm/i830_dma.c b/trunk/drivers/char/drm/i830_dma.c index 95224455ec0c..4f0e5746ab33 100644 --- a/trunk/drivers/char/drm/i830_dma.c +++ b/trunk/drivers/char/drm/i830_dma.c @@ -223,7 +223,8 @@ static int i830_dma_cleanup(drm_device_t * dev) (drm_i830_private_t *) dev->dev_private; if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); + drm_ioremapfree((void *)dev_priv->ring.virtual_start, + dev_priv->ring.Size, dev); } if (dev_priv->hw_status_page) { pci_free_consistent(dev->pdev, PAGE_SIZE, @@ -241,7 +242,8 @@ static int i830_dma_cleanup(drm_device_t * dev) drm_buf_t *buf = dma->buflist[i]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; if (buf_priv->kernel_virtual && buf->total) - drm_core_ioremapfree(&buf_priv->map, dev); + drm_ioremapfree(buf_priv->kernel_virtual, + buf->total, dev); } } return 0; @@ -318,14 +320,8 @@ static int i830_freelist_init(drm_device_t * dev, drm_i830_private_t * dev_priv) *buf_priv->in_use = I830_BUF_FREE; - buf_priv->map.offset = buf->bus_address; - buf_priv->map.size = buf->total; - buf_priv->map.type = _DRM_AGP; - buf_priv->map.flags = 0; - buf_priv->map.mtrr = 0; - - drm_core_ioremap(&buf_priv->map, dev); - buf_priv->kernel_virtual = buf_priv->map.handle; + buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, + buf->total, dev); } return 0; } @@ -377,24 +373,18 @@ static int i830_dma_initialize(drm_device_t * dev, dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; - dev_priv->ring.map.offset = dev->agp->base + init->ring_start; - dev_priv->ring.map.size = init->ring_size; - dev_priv->ring.map.type = _DRM_AGP; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; - - drm_core_ioremap(&dev_priv->ring.map, dev); + dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + + init->ring_start, + init->ring_size, dev); - if (dev_priv->ring.map.handle == NULL) { + if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *)dev_priv; i830_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; dev_priv->w = init->w; diff --git a/trunk/drivers/char/drm/i830_drv.h b/trunk/drivers/char/drm/i830_drv.h index e91f94afb4bb..85bc5be6f916 100644 --- a/trunk/drivers/char/drm/i830_drv.h +++ b/trunk/drivers/char/drm/i830_drv.h @@ -68,7 +68,6 @@ typedef struct drm_i830_buf_priv { int currently_mapped; void __user *virtual; void *kernel_virtual; - drm_local_map_t map; } drm_i830_buf_priv_t; typedef struct _drm_i830_ring_buffer { @@ -80,7 +79,6 @@ typedef struct _drm_i830_ring_buffer { int head; int tail; int space; - drm_local_map_t map; } drm_i830_ring_buffer_t; typedef struct drm_i830_private { diff --git a/trunk/drivers/char/drm/via_dma.c b/trunk/drivers/char/drm/via_dma.c index c0539c6299cf..a691ae74129d 100644 --- a/trunk/drivers/char/drm/via_dma.c +++ b/trunk/drivers/char/drm/via_dma.c @@ -190,11 +190,6 @@ static int via_initialize(drm_device_t * dev, return DRM_ERR(EFAULT); } - if (dev_priv->chipset == VIA_DX9_0) { - DRM_ERROR("AGP DMA is not supported on this chip\n"); - return DRM_ERR(EINVAL); - } - dev_priv->ring.map.offset = dev->agp->base + init->offset; dev_priv->ring.map.size = init->size; dev_priv->ring.map.type = 0; @@ -485,7 +480,6 @@ static int via_hook_segment(drm_via_private_t * dev_priv, VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); - VIA_READ(VIA_REG_TRANSPACE); } } return paused; @@ -563,9 +557,8 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); - DRM_WRITEMEMORYBARRIER(); + VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK); - VIA_READ(VIA_REG_TRANSPACE); } static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) diff --git a/trunk/drivers/char/drm/via_dmablit.c b/trunk/drivers/char/drm/via_dmablit.c index 2054d5773717..806f9ce5f47b 100644 --- a/trunk/drivers/char/drm/via_dmablit.c +++ b/trunk/drivers/char/drm/via_dmablit.c @@ -218,9 +218,7 @@ via_fire_dmablit(drm_device_t *dev, drm_via_sg_info_t *vsg, int engine) VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE); VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0); VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start); - DRM_WRITEMEMORYBARRIER(); VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS); - VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04); } /* diff --git a/trunk/drivers/char/drm/via_drv.h b/trunk/drivers/char/drm/via_drv.h index 8b8778d4a423..d21b5b75da0f 100644 --- a/trunk/drivers/char/drm/via_drv.h +++ b/trunk/drivers/char/drm/via_drv.h @@ -29,10 +29,10 @@ #define DRIVER_NAME "via" #define DRIVER_DESC "VIA Unichrome / Pro" -#define DRIVER_DATE "20061227" +#define DRIVER_DATE "20060529" #define DRIVER_MAJOR 2 -#define DRIVER_MINOR 11 +#define DRIVER_MINOR 10 #define DRIVER_PATCHLEVEL 0 #include "via_verifier.h" @@ -79,7 +79,7 @@ typedef struct drm_via_private { char pci_buf[VIA_PCI_BUF_SIZE]; const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; uint32_t num_fire_offsets; - int chipset; + int pro_group_a; drm_via_irq_t via_irqs[VIA_NUM_IRQS]; unsigned num_irqs; maskarray_t *irq_masks; @@ -96,9 +96,8 @@ typedef struct drm_via_private { } drm_via_private_t; enum via_family { - VIA_OTHER = 0, /* Baseline */ - VIA_PRO_GROUP_A, /* Another video engine and DMA commands */ - VIA_DX9_0 /* Same video as pro_group_a, but 3D is unsupported */ + VIA_OTHER = 0, + VIA_PRO_GROUP_A, }; /* VIA MMIO register access */ diff --git a/trunk/drivers/char/drm/via_irq.c b/trunk/drivers/char/drm/via_irq.c index 1ac5941ad237..c33d068cde19 100644 --- a/trunk/drivers/char/drm/via_irq.c +++ b/trunk/drivers/char/drm/via_irq.c @@ -258,16 +258,12 @@ void via_driver_irq_preinstall(drm_device_t * dev) dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE; dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; - if (dev_priv->chipset == VIA_PRO_GROUP_A || - dev_priv->chipset == VIA_DX9_0) { - dev_priv->irq_masks = via_pro_group_a_irqs; - dev_priv->num_irqs = via_num_pro_group_a; - dev_priv->irq_map = via_irqmap_pro_group_a; - } else { - dev_priv->irq_masks = via_unichrome_irqs; - dev_priv->num_irqs = via_num_unichrome; - dev_priv->irq_map = via_irqmap_unichrome; - } + dev_priv->irq_masks = (dev_priv->pro_group_a) ? + via_pro_group_a_irqs : via_unichrome_irqs; + dev_priv->num_irqs = (dev_priv->pro_group_a) ? + via_num_pro_group_a : via_num_unichrome; + dev_priv->irq_map = (dev_priv->pro_group_a) ? + via_irqmap_pro_group_a : via_irqmap_unichrome; for (i = 0; i < dev_priv->num_irqs; ++i) { atomic_set(&cur_irq->irq_received, 0); diff --git a/trunk/drivers/char/drm/via_map.c b/trunk/drivers/char/drm/via_map.c index 4e3fc072aa3b..782011e0a58d 100644 --- a/trunk/drivers/char/drm/via_map.c +++ b/trunk/drivers/char/drm/via_map.c @@ -106,7 +106,8 @@ int via_driver_load(drm_device_t *dev, unsigned long chipset) dev->dev_private = (void *)dev_priv; - dev_priv->chipset = chipset; + if (chipset == VIA_PRO_GROUP_A) + dev_priv->pro_group_a = 1; ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); if (ret) { diff --git a/trunk/drivers/char/drm/via_verifier.c b/trunk/drivers/char/drm/via_verifier.c index 2e7e08078287..70c897c88766 100644 --- a/trunk/drivers/char/drm/via_verifier.c +++ b/trunk/drivers/char/drm/via_verifier.c @@ -306,7 +306,6 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) unsigned long lo = ~0, hi = 0, tmp; uint32_t *addr, *pitch, *height, tex; unsigned i; - int npot; if (end > 9) end = 9; @@ -317,15 +316,12 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) &(cur_seq->t_addr[tex = cur_seq->texture][start]); pitch = &(cur_seq->pitch[tex][start]); height = &(cur_seq->height[tex][start]); - npot = cur_seq->tex_npot[tex]; + for (i = start; i <= end; ++i) { tmp = *addr++; if (tmp < lo) lo = tmp; - if (i == 0 && npot) - tmp += (*height++ * *pitch++); - else - tmp += (*height++ << *pitch++); + tmp += (*height++ << *pitch++); if (tmp > hi) hi = tmp; } @@ -447,21 +443,13 @@ investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq) return 0; case check_texture_addr3: cur_seq->unfinished = tex_address; - tmp = ((cmd >> 24) - HC_SubA_HTXnL0Pit); - if (tmp == 0 && - (cmd & HC_HTXnEnPit_MASK)) { - cur_seq->pitch[cur_seq->texture][tmp] = - (cmd & HC_HTXnLnPit_MASK); - cur_seq->tex_npot[cur_seq->texture] = 1; - } else { - cur_seq->pitch[cur_seq->texture][tmp] = - (cmd & HC_HTXnLnPitE_MASK) >> HC_HTXnLnPitE_SHIFT; - cur_seq->tex_npot[cur_seq->texture] = 0; - if (cmd & 0x000FFFFF) { - DRM_ERROR - ("Unimplemented texture level 0 pitch mode.\n"); - return 2; - } + tmp = ((cmd >> 24) - 0x2B); + cur_seq->pitch[cur_seq->texture][tmp] = + (cmd & 0x00F00000) >> 20; + if (!tmp && (cmd & 0x000FFFFF)) { + DRM_ERROR + ("Unimplemented texture level 0 pitch mode.\n"); + return 2; } return 0; case check_texture_addr4: @@ -973,13 +961,7 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, uint32_t cmd; const uint32_t *buf_end = buf + (size >> 2); verifier_state_t state = state_command; - int cme_video; - int supported_3d; - - cme_video = (dev_priv->chipset == VIA_PRO_GROUP_A || - dev_priv->chipset == VIA_DX9_0); - - supported_3d = dev_priv->chipset != VIA_DX9_0; + int pro_group_a = dev_priv->pro_group_a; hc_state->dev = dev; hc_state->unfinished = no_sequence; @@ -1004,21 +986,17 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, state = via_check_vheader6(&buf, buf_end); break; case state_command: - if ((HALCYON_HEADER2 == (cmd = *buf)) && - supported_3d) + if (HALCYON_HEADER2 == (cmd = *buf)) state = state_header2; else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) state = state_header1; - else if (cme_video + else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) state = state_vheader5; - else if (cme_video + else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) state = state_vheader6; - else if ((cmd == HALCYON_HEADER2) && !supported_3d) { - DRM_ERROR("Accelerated 3D is not supported on this chipset yet.\n"); - state = state_error; - } else { + else { DRM_ERROR ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", cmd); diff --git a/trunk/drivers/char/drm/via_verifier.h b/trunk/drivers/char/drm/via_verifier.h index b77f59df0278..256590fcc22a 100644 --- a/trunk/drivers/char/drm/via_verifier.h +++ b/trunk/drivers/char/drm/via_verifier.h @@ -43,7 +43,6 @@ typedef struct { uint32_t tex_level_lo[2]; uint32_t tex_level_hi[2]; uint32_t tex_palette_size[2]; - uint32_t tex_npot[2]; drm_via_sequence_t unfinished; int agp_texture; int multitex; diff --git a/trunk/drivers/char/hvc_beat.c b/trunk/drivers/char/hvc_beat.c deleted file mode 100644 index 6f019f19be71..000000000000 --- a/trunk/drivers/char/hvc_beat.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Beat hypervisor console driver - * - * (C) Copyright 2006 TOSHIBA CORPORATION - * - * This code is based on drivers/char/hvc_rtas.c: - * (C) Copyright IBM Corporation 2001-2005 - * (C) Copyright Red Hat, Inc. 2005 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hvc_console.h" - -extern int64_t beat_get_term_char(uint64_t, uint64_t *, uint64_t *, uint64_t *); -extern int64_t beat_put_term_char(uint64_t, uint64_t, uint64_t, uint64_t); - -struct hvc_struct *hvc_beat_dev = NULL; - -/* bug: only one queue is available regardless of vtermno */ -static int hvc_beat_get_chars(uint32_t vtermno, char *buf, int cnt) -{ - static unsigned char q[sizeof(unsigned long) * 2] - __attribute__((aligned(sizeof(unsigned long)))); - static int qlen = 0; - unsigned long got; - -again: - if (qlen) { - if (qlen > cnt) { - memcpy(buf, q, cnt); - qlen -= cnt; - memmove(q + cnt, q, qlen); - return cnt; - } else { /* qlen <= cnt */ - int r; - - memcpy(buf, q, qlen); - r = qlen; - qlen = 0; - return r; - } - } - if (beat_get_term_char(vtermno, &got, - ((unsigned long *)q), ((unsigned long *)q) + 1) == 0) { - qlen = got; - goto again; - } - return 0; -} - -static int hvc_beat_put_chars(uint32_t vtermno, const char *buf, int cnt) -{ - unsigned long kb[2]; - int rest, nlen; - - for (rest = cnt; rest > 0; rest -= nlen) { - nlen = (rest > 16) ? 16 : rest; - memcpy(kb, buf, nlen); - beat_put_term_char(vtermno, rest, kb[0], kb[1]); - rest -= nlen; - } - return cnt; -} - -static struct hv_ops hvc_beat_get_put_ops = { - .get_chars = hvc_beat_get_chars, - .put_chars = hvc_beat_put_chars, -}; - -static int hvc_beat_useit = 1; - -static int hvc_beat_config(char *p) -{ - hvc_beat_useit = simple_strtoul(p, NULL, 0); - return 0; -} - -static int hvc_beat_console_init(void) -{ - if (hvc_beat_useit && machine_is_compatible("Beat")) { - hvc_instantiate(0, 0, &hvc_beat_get_put_ops); - } - return 0; -} - -/* temp */ -static int hvc_beat_init(void) -{ - struct hvc_struct *hp; - - if (!firmware_has_feature(FW_FEATURE_BEAT)) - return -ENODEV; - - hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16); - if (IS_ERR(hp)) - return PTR_ERR(hp); - hvc_beat_dev = hp; - return 0; -} - -static void __exit hvc_beat_exit(void) -{ - if (hvc_beat_dev) - hvc_remove(hvc_beat_dev); -} - -module_init(hvc_beat_init); -module_exit(hvc_beat_exit); - -__setup("hvc_beat=", hvc_beat_config); - -console_initcall(hvc_beat_console_init); diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index a7b33d2f5991..f1afd26a509f 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -1802,7 +1802,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) return -ENODEV; } - if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) addr_space = IPMI_MEM_ADDR_SPACE; else addr_space = IPMI_IO_ADDR_SPACE; @@ -1848,19 +1848,19 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) info->irq_setup = NULL; } - if (spmi->addr.bit_width) { + if (spmi->addr.register_bit_width) { /* A (hopefully) properly formed register bit width. */ - info->io.regspacing = spmi->addr.bit_width / 8; + info->io.regspacing = spmi->addr.register_bit_width / 8; } else { info->io.regspacing = DEFAULT_REGSPACING; } info->io.regsize = info->io.regspacing; - info->io.regshift = spmi->addr.bit_offset; + info->io.regshift = spmi->addr.register_bit_offset; - if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { info->io_setup = mem_setup; info->io.addr_type = IPMI_IO_ADDR_SPACE; - } else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) { + } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) { info->io_setup = port_setup; info->io.addr_type = IPMI_MEM_ADDR_SPACE; } else { @@ -1888,8 +1888,10 @@ static __devinit void acpi_find_bmc(void) return; for (i = 0; ; i++) { - status = acpi_get_table(ACPI_SIG_SPMI, i+1, - (struct acpi_table_header **)&spmi); + status = acpi_get_firmware_table("SPMI", i+1, + ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) + &spmi); if (status != AE_OK) return; diff --git a/trunk/drivers/char/tpm/tpm_bios.c b/trunk/drivers/char/tpm/tpm_bios.c index 7fca5f470beb..a611972024e6 100644 --- a/trunk/drivers/char/tpm/tpm_bios.c +++ b/trunk/drivers/char/tpm/tpm_bios.c @@ -372,8 +372,10 @@ static int read_log(struct tpm_bios_log *log) } /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ - status = acpi_get_table(ACPI_SIG_TCPA, 1, - (struct acpi_table_header **)&buff); + status = acpi_get_firmware_table(ACPI_TCPA_SIG, 1, + ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) + &buff); if (ACPI_FAILURE(status)) { printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n", @@ -407,7 +409,7 @@ static int read_log(struct tpm_bios_log *log) log->bios_event_log_end = log->bios_event_log + len; - virt = acpi_os_map_memory(start, len); + acpi_os_map_memory(start, len, (void *) &virt); memcpy(log->bios_event_log, virt, len); diff --git a/trunk/drivers/char/watchdog/booke_wdt.c b/trunk/drivers/char/watchdog/booke_wdt.c index 0e23f29f71ab..488902231cc2 100644 --- a/trunk/drivers/char/watchdog/booke_wdt.c +++ b/trunk/drivers/char/watchdog/booke_wdt.c @@ -35,7 +35,7 @@ #ifdef CONFIG_FSL_BOOKE #define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz , reset=~40sec */ #else -#define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */ +#define WDT_PERIOD_DEFAULT 4 /* Refer to the PPC40x and PPC4xx manuals */ #endif /* for timing information */ u32 booke_wdt_enabled = 0; @@ -47,14 +47,6 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT; #define WDTP(x) (TCR_WP(x)) #endif -/* - * booke_wdt_ping: - */ -static __inline__ void booke_wdt_ping(void) -{ - mtspr(SPRN_TSR, TSR_ENW|TSR_WIS); -} - /* * booke_wdt_enable: */ @@ -62,14 +54,20 @@ static __inline__ void booke_wdt_enable(void) { u32 val; - /* clear status before enabling watchdog */ - booke_wdt_ping(); val = mfspr(SPRN_TCR); val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); mtspr(SPRN_TCR, val); } +/* + * booke_wdt_ping: + */ +static __inline__ void booke_wdt_ping(void) +{ + mtspr(SPRN_TSR, TSR_ENW|TSR_WIS); +} + /* * booke_wdt_write: */ diff --git a/trunk/drivers/firmware/pcdp.c b/trunk/drivers/firmware/pcdp.c index 2b4b76e8bd72..c2ad72fefd9d 100644 --- a/trunk/drivers/firmware/pcdp.c +++ b/trunk/drivers/firmware/pcdp.c @@ -26,7 +26,7 @@ setup_serial_console(struct pcdp_uart *uart) static char options[64], *p = options; char parity; - mmio = (uart->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); + mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); p += sprintf(p, "console=uart,%s,0x%lx", mmio ? "mmio" : "io", uart->addr.address); if (uart->baud) { diff --git a/trunk/drivers/i2c/chips/isp1301_omap.c b/trunk/drivers/i2c/chips/isp1301_omap.c index 9fafadb92510..ccdf3e90862b 100644 --- a/trunk/drivers/i2c/chips/isp1301_omap.c +++ b/trunk/drivers/i2c/chips/isp1301_omap.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index ec03341d2bd8..3f828052f8d2 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -167,13 +167,6 @@ config BLK_DEV_IDECS Support for Compact Flash cards, outboard IDE disks, tape drives, and CD-ROM drives connected through a PCMCIA card. -config BLK_DEV_DELKIN - tristate "Cardbus IDE support (Delkin/ASKA/Workbit)" - depends on CARDBUS && PCI - help - Support for Delkin, ASKA, and Workbit Cardbus CompactFlash - Adapters. This may also work for similar SD and XD adapters. - config BLK_DEV_IDECD tristate "Include IDE/ATAPI CDROM support" ---help--- @@ -271,13 +264,6 @@ config BLK_DEV_IDESCSI If both this SCSI emulation and native ATAPI support are compiled into the kernel, the native support will be used. -config BLK_DEV_IDEACPI - bool "IDE ACPI support" - depends on ACPI - ---help--- - Implement ACPI support for generic IDE devices. On modern - machines ACPI support is required to properly handle ACPI S3 states. - config IDE_TASK_IOCTL bool "IDE Taskfile Access" help @@ -620,11 +606,6 @@ config BLK_DEV_PIIX the kernel to change PIO, DMA and UDMA speeds and to configure the chip to optimum performance. -config BLK_DEV_IT8213 - tristate "IT8213 IDE support" - help - This driver adds support for the ITE 8213 IDE controller. - config BLK_DEV_IT821X tristate "IT821X IDE support" help @@ -761,11 +742,6 @@ config BLK_DEV_VIA82CXXX This allows the kernel to change PIO, DMA and UDMA speeds and to configure the chip to optimum performance. -config BLK_DEV_TC86C001 - tristate "Toshiba TC86C001 support" - help - This driver adds support for Toshiba TC86C001 GOKU-S chip. - endif config BLK_DEV_IDE_PMAC diff --git a/trunk/drivers/ide/Makefile b/trunk/drivers/ide/Makefile index d9f029e8ff74..569fae717503 100644 --- a/trunk/drivers/ide/Makefile +++ b/trunk/drivers/ide/Makefile @@ -22,7 +22,6 @@ ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o ide-core-$(CONFIG_PROC_FS) += ide-proc.o ide-core-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o -ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o # built-in only drivers from arm/ ide-core-$(CONFIG_IDE_ARM) += arm/ide_arm.o diff --git a/trunk/drivers/ide/ide-acpi.c b/trunk/drivers/ide/ide-acpi.c deleted file mode 100644 index 17aea65d7dd2..000000000000 --- a/trunk/drivers/ide/ide-acpi.c +++ /dev/null @@ -1,697 +0,0 @@ -/* - * ide-acpi.c - * Provides ACPI support for IDE drives. - * - * Copyright (C) 2005 Intel Corp. - * Copyright (C) 2005 Randy Dunlap - * Copyright (C) 2006 SUSE Linux Products GmbH - * Copyright (C) 2006 Hannes Reinecke - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define REGS_PER_GTF 7 -struct taskfile_array { - u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ -}; - -struct GTM_buffer { - u32 PIO_speed0; - u32 DMA_speed0; - u32 PIO_speed1; - u32 DMA_speed1; - u32 GTM_flags; -}; - -struct ide_acpi_drive_link { - ide_drive_t *drive; - acpi_handle obj_handle; - u8 idbuff[512]; -}; - -struct ide_acpi_hwif_link { - ide_hwif_t *hwif; - acpi_handle obj_handle; - struct GTM_buffer gtm; - struct ide_acpi_drive_link master; - struct ide_acpi_drive_link slave; -}; - -#undef DEBUGGING -/* note: adds function name and KERN_DEBUG */ -#ifdef DEBUGGING -#define DEBPRINT(fmt, args...) \ - printk(KERN_DEBUG "%s: " fmt, __FUNCTION__, ## args) -#else -#define DEBPRINT(fmt, args...) do {} while (0) -#endif /* DEBUGGING */ - -extern int ide_noacpi; -extern int ide_noacpitfs; -extern int ide_noacpionboot; - -/** - * ide_get_dev_handle - finds acpi_handle and PCI device.function - * @dev: device to locate - * @handle: returned acpi_handle for @dev - * @pcidevfn: return PCI device.func for @dev - * - * Returns the ACPI object handle to the corresponding PCI device. - * - * Returns 0 on success, <0 on error. - */ -static int ide_get_dev_handle(struct device *dev, acpi_handle *handle, - acpi_integer *pcidevfn) -{ - struct pci_dev *pdev = to_pci_dev(dev); - unsigned int bus, devnum, func; - acpi_integer addr; - acpi_handle dev_handle; - struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER, - .pointer = NULL}; - acpi_status status; - struct acpi_device_info *dinfo = NULL; - int ret = -ENODEV; - - bus = pdev->bus->number; - devnum = PCI_SLOT(pdev->devfn); - func = PCI_FUNC(pdev->devfn); - /* ACPI _ADR encoding for PCI bus: */ - addr = (acpi_integer)(devnum << 16 | func); - - DEBPRINT("ENTER: pci %02x:%02x.%01x\n", bus, devnum, func); - - dev_handle = DEVICE_ACPI_HANDLE(dev); - if (!dev_handle) { - DEBPRINT("no acpi handle for device\n"); - goto err; - } - - status = acpi_get_object_info(dev_handle, &buffer); - if (ACPI_FAILURE(status)) { - DEBPRINT("get_object_info for device failed\n"); - goto err; - } - dinfo = buffer.pointer; - if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && - dinfo->address == addr) { - *pcidevfn = addr; - *handle = dev_handle; - } else { - DEBPRINT("get_object_info for device has wrong " - " address: %llu, should be %u\n", - dinfo ? (unsigned long long)dinfo->address : -1ULL, - (unsigned int)addr); - goto err; - } - - DEBPRINT("for dev=0x%x.%x, addr=0x%llx, *handle=0x%p\n", - devnum, func, (unsigned long long)addr, *handle); - ret = 0; -err: - kfree(dinfo); - return ret; -} - -/** - * ide_acpi_hwif_get_handle - Get ACPI object handle for a given hwif - * @hwif: device to locate - * - * Retrieves the object handle for a given hwif. - * - * Returns handle on success, 0 on error. - */ -static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) -{ - struct device *dev = hwif->gendev.parent; - acpi_handle dev_handle; - acpi_integer pcidevfn; - acpi_handle chan_handle; - int err; - - DEBPRINT("ENTER: device %s\n", hwif->name); - - if (!dev) { - DEBPRINT("no PCI device for %s\n", hwif->name); - return NULL; - } - - err = ide_get_dev_handle(dev, &dev_handle, &pcidevfn); - if (err < 0) { - DEBPRINT("ide_get_dev_handle failed (%d)\n", err); - return NULL; - } - - /* get child objects of dev_handle == channel objects, - * + _their_ children == drive objects */ - /* channel is hwif->channel */ - chan_handle = acpi_get_child(dev_handle, hwif->channel); - DEBPRINT("chan adr=%d: handle=0x%p\n", - hwif->channel, chan_handle); - - return chan_handle; -} - -/** - * ide_acpi_drive_get_handle - Get ACPI object handle for a given drive - * @drive: device to locate - * - * Retrieves the object handle of a given drive. According to the ACPI - * spec the drive is a child of the hwif. - * - * Returns handle on success, 0 on error. - */ -static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - int port; - acpi_handle drive_handle; - - if (!hwif->acpidata) - return NULL; - - if (!hwif->acpidata->obj_handle) - return NULL; - - port = hwif->channel ? drive->dn - 2: drive->dn; - - DEBPRINT("ENTER: %s at channel#: %d port#: %d\n", - drive->name, hwif->channel, port); - - - /* TBD: could also check ACPI object VALID bits */ - drive_handle = acpi_get_child(hwif->acpidata->obj_handle, port); - DEBPRINT("drive %s handle 0x%p\n", drive->name, drive_handle); - - return drive_handle; -} - -/** - * do_drive_get_GTF - get the drive bootup default taskfile settings - * @drive: the drive for which the taskfile settings should be retrieved - * @gtf_length: number of bytes of _GTF data returned at @gtf_address - * @gtf_address: buffer containing _GTF taskfile arrays - * - * The _GTF method has no input parameters. - * It returns a variable number of register set values (registers - * hex 1F1..1F7, taskfiles). - * The is not known in advance, so have ACPI-CA - * allocate the buffer as needed and return it, then free it later. - * - * The returned @gtf_length and @gtf_address are only valid if the - * function return value is 0. - */ -static int do_drive_get_GTF(ide_drive_t *drive, - unsigned int *gtf_length, unsigned long *gtf_address, - unsigned long *obj_loc) -{ - acpi_status status; - struct acpi_buffer output; - union acpi_object *out_obj; - ide_hwif_t *hwif = HWIF(drive); - struct device *dev = hwif->gendev.parent; - int err = -ENODEV; - int port; - - *gtf_length = 0; - *gtf_address = 0UL; - *obj_loc = 0UL; - - if (ide_noacpi) - return 0; - - if (!dev) { - DEBPRINT("no PCI device for %s\n", hwif->name); - goto out; - } - - if (!hwif->acpidata) { - DEBPRINT("no ACPI data for %s\n", hwif->name); - goto out; - } - - port = hwif->channel ? drive->dn - 2: drive->dn; - - if (!drive->acpidata) { - if (port == 0) { - drive->acpidata = &hwif->acpidata->master; - hwif->acpidata->master.drive = drive; - } else { - drive->acpidata = &hwif->acpidata->slave; - hwif->acpidata->slave.drive = drive; - } - } - - DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n", - hwif->name, dev->bus_id, port, hwif->channel); - - if (!drive->present) { - DEBPRINT("%s drive %d:%d not present\n", - hwif->name, hwif->channel, port); - goto out; - } - - /* Get this drive's _ADR info. if not already known. */ - if (!drive->acpidata->obj_handle) { - drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); - if (!drive->acpidata->obj_handle) { - DEBPRINT("No ACPI object found for %s\n", - drive->name); - goto out; - } - } - - /* Setting up output buffer */ - output.length = ACPI_ALLOCATE_BUFFER; - output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ - - /* _GTF has no input parameters */ - err = -EIO; - status = acpi_evaluate_object(drive->acpidata->obj_handle, "_GTF", - NULL, &output); - if (ACPI_FAILURE(status)) { - printk(KERN_DEBUG - "%s: Run _GTF error: status = 0x%x\n", - __FUNCTION__, status); - goto out; - } - - if (!output.length || !output.pointer) { - DEBPRINT("Run _GTF: " - "length or ptr is NULL (0x%llx, 0x%p)\n", - (unsigned long long)output.length, - output.pointer); - goto out; - } - - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) { - DEBPRINT("Run _GTF: error: " - "expected object type of ACPI_TYPE_BUFFER, " - "got 0x%x\n", out_obj->type); - err = -ENOENT; - kfree(output.pointer); - goto out; - } - - if (!out_obj->buffer.length || !out_obj->buffer.pointer || - out_obj->buffer.length % REGS_PER_GTF) { - printk(KERN_ERR - "%s: unexpected GTF length (%d) or addr (0x%p)\n", - __FUNCTION__, out_obj->buffer.length, - out_obj->buffer.pointer); - err = -ENOENT; - kfree(output.pointer); - goto out; - } - - *gtf_length = out_obj->buffer.length; - *gtf_address = (unsigned long)out_obj->buffer.pointer; - *obj_loc = (unsigned long)out_obj; - DEBPRINT("returning gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n", - *gtf_length, *gtf_address, *obj_loc); - err = 0; -out: - return err; -} - -/** - * taskfile_load_raw - send taskfile registers to drive - * @drive: drive to which output is sent - * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) - * - * Outputs IDE taskfile to the drive. - */ -static int taskfile_load_raw(ide_drive_t *drive, - const struct taskfile_array *gtf) -{ - ide_task_t args; - int err = 0; - - DEBPRINT("(0x1f1-1f7): hex: " - "%02x %02x %02x %02x %02x %02x %02x\n", - gtf->tfa[0], gtf->tfa[1], gtf->tfa[2], - gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]); - - memset(&args, 0, sizeof(ide_task_t)); - args.command_type = IDE_DRIVE_TASK_NO_DATA; - args.data_phase = TASKFILE_IN; - args.handler = &task_no_data_intr; - - /* convert gtf to IDE Taskfile */ - args.tfRegister[1] = gtf->tfa[0]; /* 0x1f1 */ - args.tfRegister[2] = gtf->tfa[1]; /* 0x1f2 */ - args.tfRegister[3] = gtf->tfa[2]; /* 0x1f3 */ - args.tfRegister[4] = gtf->tfa[3]; /* 0x1f4 */ - args.tfRegister[5] = gtf->tfa[4]; /* 0x1f5 */ - args.tfRegister[6] = gtf->tfa[5]; /* 0x1f6 */ - args.tfRegister[7] = gtf->tfa[6]; /* 0x1f7 */ - - if (ide_noacpitfs) { - DEBPRINT("_GTF execution disabled\n"); - return err; - } - - err = ide_raw_taskfile(drive, &args, NULL); - if (err) - printk(KERN_ERR "%s: ide_raw_taskfile failed: %u\n", - __FUNCTION__, err); - - return err; -} - -/** - * do_drive_set_taskfiles - write the drive taskfile settings from _GTF - * @drive: the drive to which the taskfile command should be sent - * @gtf_length: total number of bytes of _GTF taskfiles - * @gtf_address: location of _GTF taskfile arrays - * - * Write {gtf_address, length gtf_length} in groups of - * REGS_PER_GTF bytes. - */ -static int do_drive_set_taskfiles(ide_drive_t *drive, - unsigned int gtf_length, - unsigned long gtf_address) -{ - int rc = -ENODEV, err; - int gtf_count = gtf_length / REGS_PER_GTF; - int ix; - struct taskfile_array *gtf; - - if (ide_noacpi) - return 0; - - DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn); - - if (!drive->present) - goto out; - if (!gtf_count) /* shouldn't be here */ - goto out; - - DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n", - gtf_length, gtf_length, gtf_count, gtf_address); - - if (gtf_length % REGS_PER_GTF) { - printk(KERN_ERR "%s: unexpected GTF length (%d)\n", - __FUNCTION__, gtf_length); - goto out; - } - - rc = 0; - for (ix = 0; ix < gtf_count; ix++) { - gtf = (struct taskfile_array *) - (gtf_address + ix * REGS_PER_GTF); - - /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ - err = taskfile_load_raw(drive, gtf); - if (err) - rc = err; - } - -out: - return rc; -} - -/** - * ide_acpi_exec_tfs - get then write drive taskfile settings - * @drive: the drive for which the taskfile settings should be - * written. - * - * According to the ACPI spec this should be called after _STM - * has been evaluated for the interface. Some ACPI vendors interpret - * that as a hard requirement and modify the taskfile according - * to the Identify Drive information passed down with _STM. - * So one should really make sure to call this only after _STM has - * been executed. - */ -int ide_acpi_exec_tfs(ide_drive_t *drive) -{ - int ret; - unsigned int gtf_length; - unsigned long gtf_address; - unsigned long obj_loc; - - if (ide_noacpi) - return 0; - - DEBPRINT("call get_GTF, drive=%s port=%d\n", drive->name, drive->dn); - - ret = do_drive_get_GTF(drive, >f_length, >f_address, &obj_loc); - if (ret < 0) { - DEBPRINT("get_GTF error (%d)\n", ret); - return ret; - } - - DEBPRINT("call set_taskfiles, drive=%s\n", drive->name); - - ret = do_drive_set_taskfiles(drive, gtf_length, gtf_address); - kfree((void *)obj_loc); - if (ret < 0) { - DEBPRINT("set_taskfiles error (%d)\n", ret); - } - - DEBPRINT("ret=%d\n", ret); - - return ret; -} -EXPORT_SYMBOL_GPL(ide_acpi_exec_tfs); - -/** - * ide_acpi_get_timing - get the channel (controller) timings - * @hwif: target IDE interface (channel) - * - * This function executes the _GTM ACPI method for the target channel. - * - */ -void ide_acpi_get_timing(ide_hwif_t *hwif) -{ - acpi_status status; - struct acpi_buffer output; - union acpi_object *out_obj; - - if (ide_noacpi) - return; - - DEBPRINT("ENTER:\n"); - - if (!hwif->acpidata) { - DEBPRINT("no ACPI data for %s\n", hwif->name); - return; - } - - /* Setting up output buffer for _GTM */ - output.length = ACPI_ALLOCATE_BUFFER; - output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ - - /* _GTM has no input parameters */ - status = acpi_evaluate_object(hwif->acpidata->obj_handle, "_GTM", - NULL, &output); - - DEBPRINT("_GTM status: %d, outptr: 0x%p, outlen: 0x%llx\n", - status, output.pointer, - (unsigned long long)output.length); - - if (ACPI_FAILURE(status)) { - DEBPRINT("Run _GTM error: status = 0x%x\n", status); - return; - } - - if (!output.length || !output.pointer) { - DEBPRINT("Run _GTM: length or ptr is NULL (0x%llx, 0x%p)\n", - (unsigned long long)output.length, - output.pointer); - kfree(output.pointer); - return; - } - - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) { - kfree(output.pointer); - DEBPRINT("Run _GTM: error: " - "expected object type of ACPI_TYPE_BUFFER, " - "got 0x%x\n", out_obj->type); - return; - } - - if (!out_obj->buffer.length || !out_obj->buffer.pointer || - out_obj->buffer.length != sizeof(struct GTM_buffer)) { - kfree(output.pointer); - printk(KERN_ERR - "%s: unexpected _GTM length (0x%x)[should be 0x%zx] or " - "addr (0x%p)\n", - __FUNCTION__, out_obj->buffer.length, - sizeof(struct GTM_buffer), out_obj->buffer.pointer); - return; - } - - memcpy(&hwif->acpidata->gtm, out_obj->buffer.pointer, - sizeof(struct GTM_buffer)); - - DEBPRINT("_GTM info: ptr: 0x%p, len: 0x%x, exp.len: 0x%Zx\n", - out_obj->buffer.pointer, out_obj->buffer.length, - sizeof(struct GTM_buffer)); - - DEBPRINT("_GTM fields: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", - hwif->acpidata->gtm.PIO_speed0, - hwif->acpidata->gtm.DMA_speed0, - hwif->acpidata->gtm.PIO_speed1, - hwif->acpidata->gtm.DMA_speed1, - hwif->acpidata->gtm.GTM_flags); - - kfree(output.pointer); -} -EXPORT_SYMBOL_GPL(ide_acpi_get_timing); - -/** - * ide_acpi_push_timing - set the channel (controller) timings - * @hwif: target IDE interface (channel) - * - * This function executes the _STM ACPI method for the target channel. - * - * _STM requires Identify Drive data, which has to passed as an argument. - * Unfortunately hd_driveid is a mangled version which we can't readily - * use; hence we'll get the information afresh. - */ -void ide_acpi_push_timing(ide_hwif_t *hwif) -{ - acpi_status status; - struct acpi_object_list input; - union acpi_object in_params[3]; - struct ide_acpi_drive_link *master = &hwif->acpidata->master; - struct ide_acpi_drive_link *slave = &hwif->acpidata->slave; - - if (ide_noacpi) - return; - - DEBPRINT("ENTER:\n"); - - if (!hwif->acpidata) { - DEBPRINT("no ACPI data for %s\n", hwif->name); - return; - } - - /* Give the GTM buffer + drive Identify data to the channel via the - * _STM method: */ - /* setup input parameters buffer for _STM */ - input.count = 3; - input.pointer = in_params; - in_params[0].type = ACPI_TYPE_BUFFER; - in_params[0].buffer.length = sizeof(struct GTM_buffer); - in_params[0].buffer.pointer = (u8 *)&hwif->acpidata->gtm; - in_params[1].type = ACPI_TYPE_BUFFER; - in_params[1].buffer.length = sizeof(struct hd_driveid); - in_params[1].buffer.pointer = (u8 *)&master->idbuff; - in_params[2].type = ACPI_TYPE_BUFFER; - in_params[2].buffer.length = sizeof(struct hd_driveid); - in_params[2].buffer.pointer = (u8 *)&slave->idbuff; - /* Output buffer: _STM has no output */ - - status = acpi_evaluate_object(hwif->acpidata->obj_handle, "_STM", - &input, NULL); - - if (ACPI_FAILURE(status)) { - DEBPRINT("Run _STM error: status = 0x%x\n", status); - } - DEBPRINT("_STM status: %d\n", status); -} -EXPORT_SYMBOL_GPL(ide_acpi_push_timing); - -/** - * ide_acpi_init - initialize the ACPI link for an IDE interface - * @hwif: target IDE interface (channel) - * - * The ACPI spec is not quite clear when the drive identify buffer - * should be obtained. Calling IDENTIFY DEVICE during shutdown - * is not the best of ideas as the drive might already being put to - * sleep. And obviously we can't call it during resume. - * So we get the information during startup; but this means that - * any changes during run-time will be lost after resume. - */ -void ide_acpi_init(ide_hwif_t *hwif) -{ - int unit; - int err; - struct ide_acpi_drive_link *master; - struct ide_acpi_drive_link *slave; - - hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL); - if (!hwif->acpidata) - return; - - hwif->acpidata->obj_handle = ide_acpi_hwif_get_handle(hwif); - if (!hwif->acpidata->obj_handle) { - DEBPRINT("no ACPI object for %s found\n", hwif->name); - kfree(hwif->acpidata); - hwif->acpidata = NULL; - return; - } - - /* - * The ACPI spec mandates that we send information - * for both drives, regardless whether they are connected - * or not. - */ - hwif->acpidata->master.drive = &hwif->drives[0]; - hwif->drives[0].acpidata = &hwif->acpidata->master; - master = &hwif->acpidata->master; - - hwif->acpidata->slave.drive = &hwif->drives[1]; - hwif->drives[1].acpidata = &hwif->acpidata->slave; - slave = &hwif->acpidata->slave; - - - /* - * Send IDENTIFY for each drive - */ - if (master->drive->present) { - err = taskfile_lib_get_identify(master->drive, master->idbuff); - if (err) { - DEBPRINT("identify device %s failed (%d)\n", - master->drive->name, err); - } - } - - if (slave->drive->present) { - err = taskfile_lib_get_identify(slave->drive, slave->idbuff); - if (err) { - DEBPRINT("identify device %s failed (%d)\n", - slave->drive->name, err); - } - } - - if (ide_noacpionboot) { - DEBPRINT("ACPI methods disabled on boot\n"); - return; - } - - /* - * ACPI requires us to call _STM on startup - */ - ide_acpi_get_timing(hwif); - ide_acpi_push_timing(hwif); - - for (unit = 0; unit < MAX_DRIVES; ++unit) { - ide_drive_t *drive = &hwif->drives[unit]; - - if (drive->present) { - /* Execute ACPI startup code */ - ide_acpi_exec_tfs(drive); - } - } -} -EXPORT_SYMBOL_GPL(ide_acpi_init); diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index 176bbc850d6b..5a5c565a32a8 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -1384,9 +1384,6 @@ static int hwif_init(ide_hwif_t *hwif) done: init_gendisk(hwif); - - ide_acpi_init(hwif); - hwif->present = 1; /* success */ return 1; diff --git a/trunk/drivers/ide/ide.c b/trunk/drivers/ide/ide.c index c750f6ce770a..6c9bd5165bdb 100644 --- a/trunk/drivers/ide/ide.c +++ b/trunk/drivers/ide/ide.c @@ -187,12 +187,6 @@ int noautodma = 1; EXPORT_SYMBOL(noautodma); -#ifdef CONFIG_BLK_DEV_IDEACPI -int ide_noacpi = 0; -int ide_noacpitfs = 1; -int ide_noacpionboot = 1; -#endif - /* * This is declared extern in ide.h, for access by other IDE modules: */ @@ -1220,15 +1214,10 @@ EXPORT_SYMBOL(system_bus_clock); static int generic_ide_suspend(struct device *dev, pm_message_t mesg) { ide_drive_t *drive = dev->driver_data; - ide_hwif_t *hwif = HWIF(drive); struct request rq; struct request_pm_state rqpm; ide_task_t args; - /* Call ACPI _GTM only once */ - if (!(drive->dn % 2)) - ide_acpi_get_timing(hwif); - memset(&rq, 0, sizeof(rq)); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); @@ -1246,17 +1235,10 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) static int generic_ide_resume(struct device *dev) { ide_drive_t *drive = dev->driver_data; - ide_hwif_t *hwif = HWIF(drive); struct request rq; struct request_pm_state rqpm; ide_task_t args; - /* Call ACPI _STM only once */ - if (!(drive->dn % 2)) - ide_acpi_push_timing(hwif); - - ide_acpi_exec_tfs(drive); - memset(&rq, 0, sizeof(rq)); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); @@ -1561,24 +1543,6 @@ static int __init ide_setup(char *s) } #endif /* CONFIG_BLK_DEV_IDEPCI */ -#ifdef CONFIG_BLK_DEV_IDEACPI - if (!strcmp(s, "ide=noacpi")) { - //printk(" : Disable IDE ACPI support.\n"); - ide_noacpi = 1; - return 1; - } - if (!strcmp(s, "ide=acpigtf")) { - //printk(" : Enable IDE ACPI _GTF support.\n"); - ide_noacpitfs = 0; - return 1; - } - if (!strcmp(s, "ide=acpionboot")) { - //printk(" : Call IDE ACPI methods on boot.\n"); - ide_noacpionboot = 0; - return 1; - } -#endif /* CONFIG_BLK_DEV_IDEACPI */ - /* * Look for drive options: "hdx=" */ diff --git a/trunk/drivers/ide/pci/Makefile b/trunk/drivers/ide/pci/Makefile index 6591ff4753cb..fef08960aa4c 100644 --- a/trunk/drivers/ide/pci/Makefile +++ b/trunk/drivers/ide/pci/Makefile @@ -9,10 +9,9 @@ obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o -obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o -obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o +#obj-$(CONFIG_BLK_DEV_HPT37X) += hpt37x.o obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o @@ -27,7 +26,6 @@ obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o -obj-$(CONFIG_BLK_DEV_TC86C001) += tc86c001.o obj-$(CONFIG_BLK_DEV_TRIFLEX) += triflex.o obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o diff --git a/trunk/drivers/ide/pci/delkin_cb.c b/trunk/drivers/ide/pci/delkin_cb.c deleted file mode 100644 index e2672fc65d30..000000000000 --- a/trunk/drivers/ide/pci/delkin_cb.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * linux/drivers/ide/pci/delkin_cb.c - * - * Created 20 Oct 2004 by Mark Lord - * - * Basic support for Delkin/ASKA/Workbit Cardbus CompactFlash adapter - * - * Modeled after the 16-bit PCMCIA driver: ide-cs.c - * - * This is slightly peculiar, in that it is a PCI driver, - * but is NOT an IDE PCI driver -- the IDE layer does not directly - * support hot insertion/removal of PCI interfaces, so this driver - * is unable to use the IDE PCI interfaces. Instead, it uses the - * same interfaces as the ide-cs (PCMCIA) driver uses. - * On the plus side, the driver is also smaller/simpler this way. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * No chip documentation has yet been found, - * so these configuration values were pulled from - * a running Win98 system using "debug". - * This gives around 3MByte/second read performance, - * which is about 2/3 of what the chip is capable of. - * - * There is also a 4KByte mmio region on the card, - * but its purpose has yet to be reverse-engineered. - */ -static const u8 setup[] = { - 0x00, 0x05, 0xbe, 0x01, 0x20, 0x8f, 0x00, 0x00, - 0xa4, 0x1f, 0xb3, 0x1b, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa4, 0x83, 0x02, 0x13, -}; - -static int __devinit -delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) -{ - unsigned long base; - hw_regs_t hw; - ide_hwif_t *hwif = NULL; - ide_drive_t *drive; - int i, rc; - - rc = pci_enable_device(dev); - if (rc) { - printk(KERN_ERR "delkin_cb: pci_enable_device failed (%d)\n", rc); - return rc; - } - rc = pci_request_regions(dev, "delkin_cb"); - if (rc) { - printk(KERN_ERR "delkin_cb: pci_request_regions failed (%d)\n", rc); - pci_disable_device(dev); - return rc; - } - base = pci_resource_start(dev, 0); - outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ - inb(base + 0x17); /* read status to clear interrupts */ - for (i = 0; i < sizeof(setup); ++i) { - if (setup[i]) - outb(setup[i], base + i); - } - pci_release_regions(dev); /* IDE layer handles regions itself */ - - memset(&hw, 0, sizeof(hw)); - ide_std_init_ports(&hw, base + 0x10, base + 0x1e); - hw.irq = dev->irq; - hw.chipset = ide_pci; /* this enables IRQ sharing */ - - rc = ide_register_hw_with_fixup(&hw, &hwif, ide_undecoded_slave); - if (rc < 0) { - printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc); - pci_disable_device(dev); - return -ENODEV; - } - pci_set_drvdata(dev, hwif); - hwif->pci_dev = dev; - drive = &hwif->drives[0]; - if (drive->present) { - drive->io_32bit = 1; - drive->unmask = 1; - } - return 0; -} - -static void -delkin_cb_remove (struct pci_dev *dev) -{ - ide_hwif_t *hwif = pci_get_drvdata(dev); - - if (hwif) - ide_unregister(hwif->index); - pci_disable_device(dev); -} - -static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { - { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, delkin_cb_pci_tbl); - -static struct pci_driver driver = { - .name = "Delkin-ASKA-Workbit Cardbus IDE", - .id_table = delkin_cb_pci_tbl, - .probe = delkin_cb_probe, - .remove = delkin_cb_remove, -}; - -static int -delkin_cb_init (void) -{ - return pci_module_init(&driver); -} - -static void -delkin_cb_exit (void) -{ - pci_unregister_driver(&driver); -} - -module_init(delkin_cb_init); -module_exit(delkin_cb_exit); - -MODULE_AUTHOR("Mark Lord"); -MODULE_DESCRIPTION("Basic support for Delkin/ASKA/Workbit Cardbus IDE"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/ide/pci/hpt366.c b/trunk/drivers/ide/pci/hpt366.c index 05be8fadda7a..b486442dd5d7 100644 --- a/trunk/drivers/ide/pci/hpt366.c +++ b/trunk/drivers/ide/pci/hpt366.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 1.01 Dec 23, 2006 + * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 * * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -60,10 +60,13 @@ * channel caused the cached register value to get out of sync with the * actual one, the channels weren't serialized, the turnaround shouldn't * be done on 66 MHz PCI bus - * - disable UltraATA/100 for HPT370 by default as the 33 MHz clock being used - * does not allow for this speed anyway - * - avoid touching disabled channels (e.g. HPT371/N are single channel chips, - * their primary channel is kind of virtual, it isn't tied to any pins) + * - avoid calibrating PLL twice as the second time results in a wrong PCI + * frequency and thus in the wrong timings for the secondary channel + * - disable UltraATA/133 for HPT372 by default (50 MHz DPLL clock do not + * allow for this speed anyway) + * - add support for HPT302N and HPT371N clocking (the same as for HPT372N) + * - HPT371/N are single channel chips, so avoid touching the primary channel + * which exists only virtually (there's no pins for it) * - fix/remove bad/unused timing tables and use one set of tables for the whole * HPT37x chip family; save space by introducing the separate transfer mode * table in which the mode lookup is done @@ -73,47 +76,11 @@ * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead * - pass to init_chipset() handlers a copy of the IDE PCI device structure as * they tamper with its fields - * - pass to the init_setup handlers a copy of the ide_pci_device_t structure - * since they may tamper with its fields - * - prefix the driver startup messages with the real chip name - * - claim the extra 240 bytes of I/O space for all chips - * - optimize the rate masking/filtering and the drive list lookup code - * - use pci_get_slot() to get to the function 1 of HPT36x/374 - * - cache offset of the channel's misc. control registers (MCRs) being used - * throughout the driver - * - only touch the relevant MCR when detecting the cable type on HPT374's - * function 1 - * - rename all the register related variables consistently - * - move all the interrupt twiddling code from the speedproc handlers into - * init_hwif_hpt366(), also grouping all the DMA related code together there - * - merge two HPT37x speedproc handlers, fix the PIO timing register mask and - * separate the UltraDMA and MWDMA masks there to avoid changing PIO timings - * when setting an UltraDMA mode - * - fix hpt3xx_tune_drive() to set the PIO mode requested, not always select - * the best possible one - * - clean up DMA timeout handling for HPT370 - * - switch to using the enumeration type to differ between the numerous chip - * variants, matching PCI device/revision ID with the chip type early, at the - * init_setup stage - * - extend the hpt_info structure to hold the DPLL and PCI clock frequencies, - * stop duplicating it for each channel by storing the pointer in the pci_dev - * structure: first, at the init_setup stage, point it to a static "template" - * with only the chip type and its specific base DPLL frequency, the highest - * supported DMA mode, and the chip settings table pointer filled, then, at - * the init_chipset stage, allocate per-chip instance and fill it with the - * rest of the necessary information - * - get rid of the constant thresholds in the HPT37x PCI clock detection code, - * switch to calculating PCI clock frequency based on the chip's base DPLL - * frequency - * - switch to using the DPLL clock and enable UltraATA/133 mode by default on - * anything newer than HPT370/A - * - fold PCI clock detection and DPLL setup code into init_chipset_hpt366(), - * also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips; - * unify HPT36x/37x timing setup code and the speedproc handlers by joining - * the register setting lists into the table indexed by the clock selected - * Sergei Shtylyov, or + * + * */ + #include #include #include @@ -365,159 +332,93 @@ static u32 sixty_six_base_hpt37x[] = { }; #define HPT366_DEBUG_DRIVE_INFO 0 -#define HPT374_ALLOW_ATA133_6 1 -#define HPT371_ALLOW_ATA133_6 1 -#define HPT302_ALLOW_ATA133_6 1 -#define HPT372_ALLOW_ATA133_6 1 -#define HPT370_ALLOW_ATA100_5 0 +#define HPT374_ALLOW_ATA133_6 0 +#define HPT371_ALLOW_ATA133_6 0 +#define HPT302_ALLOW_ATA133_6 0 +#define HPT372_ALLOW_ATA133_6 0 +#define HPT370_ALLOW_ATA100_5 1 #define HPT366_ALLOW_ATA66_4 1 #define HPT366_ALLOW_ATA66_3 1 #define HPT366_MAX_DEVS 8 -/* Supported ATA clock frequencies */ -enum ata_clock { - ATA_CLOCK_25MHZ, - ATA_CLOCK_33MHZ, - ATA_CLOCK_40MHZ, - ATA_CLOCK_50MHZ, - ATA_CLOCK_66MHZ, - NUM_ATA_CLOCKS -}; +#define F_LOW_PCI_33 0x23 +#define F_LOW_PCI_40 0x29 +#define F_LOW_PCI_50 0x2d +#define F_LOW_PCI_66 0x42 /* - * Hold all the HighPoint chip information in one place. + * Hold all the highpoint quirks and revision information in one + * place. */ -struct hpt_info { - u8 chip_type; /* Chip type */ +struct hpt_info +{ u8 max_mode; /* Speeds allowed */ - u8 dpll_clk; /* DPLL clock in MHz */ - u8 pci_clk; /* PCI clock in MHz */ - u32 **settings; /* Chipset settings table */ -}; - -/* Supported HighPoint chips */ -enum { - HPT36x, - HPT370, - HPT370A, - HPT374, - HPT372, - HPT372A, - HPT302, - HPT371, - HPT372N, - HPT302N, - HPT371N -}; - -static u32 *hpt36x_settings[NUM_ATA_CLOCKS] = { - twenty_five_base_hpt36x, - thirty_three_base_hpt36x, - forty_base_hpt36x, - NULL, - NULL -}; - -static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = { - NULL, - thirty_three_base_hpt37x, - NULL, - fifty_base_hpt37x, - sixty_six_base_hpt37x -}; - -static struct hpt_info hpt36x __devinitdata = { - .chip_type = HPT36x, - .max_mode = (HPT366_ALLOW_ATA66_4 || HPT366_ALLOW_ATA66_3) ? 2 : 1, - .dpll_clk = 0, /* no DPLL */ - .settings = hpt36x_settings -}; - -static struct hpt_info hpt370 __devinitdata = { - .chip_type = HPT370, - .max_mode = HPT370_ALLOW_ATA100_5 ? 3 : 2, - .dpll_clk = 48, - .settings = hpt37x_settings -}; - -static struct hpt_info hpt370a __devinitdata = { - .chip_type = HPT370A, - .max_mode = HPT370_ALLOW_ATA100_5 ? 3 : 2, - .dpll_clk = 48, - .settings = hpt37x_settings -}; - -static struct hpt_info hpt374 __devinitdata = { - .chip_type = HPT374, - .max_mode = HPT374_ALLOW_ATA133_6 ? 4 : 3, - .dpll_clk = 48, - .settings = hpt37x_settings -}; - -static struct hpt_info hpt372 __devinitdata = { - .chip_type = HPT372, - .max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3, - .dpll_clk = 55, - .settings = hpt37x_settings -}; - -static struct hpt_info hpt372a __devinitdata = { - .chip_type = HPT372A, - .max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3, - .dpll_clk = 66, - .settings = hpt37x_settings + int revision; /* Chipset revision */ + int flags; /* Chipset properties */ +#define PLL_MODE 1 +#define IS_3xxN 2 +#define PCI_66MHZ 4 + /* Speed table */ + u32 *speed; }; -static struct hpt_info hpt302 __devinitdata = { - .chip_type = HPT302, - .max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3, - .dpll_clk = 66, - .settings = hpt37x_settings -}; - -static struct hpt_info hpt371 __devinitdata = { - .chip_type = HPT371, - .max_mode = HPT371_ALLOW_ATA133_6 ? 4 : 3, - .dpll_clk = 66, - .settings = hpt37x_settings -}; - -static struct hpt_info hpt372n __devinitdata = { - .chip_type = HPT372N, - .max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3, - .dpll_clk = 77, - .settings = hpt37x_settings -}; - -static struct hpt_info hpt302n __devinitdata = { - .chip_type = HPT302N, - .max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3, - .dpll_clk = 77, -}; - -static struct hpt_info hpt371n __devinitdata = { - .chip_type = HPT371N, - .max_mode = HPT371_ALLOW_ATA133_6 ? 4 : 3, - .dpll_clk = 77, - .settings = hpt37x_settings -}; +/* + * This wants fixing so that we do everything not by classrev + * (which breaks on the newest chips) but by creating an + * enumeration of chip variants and using that + */ -static int check_in_drive_list(ide_drive_t *drive, const char **list) +static __devinit u32 hpt_revision (struct pci_dev *dev) { - struct hd_driveid *id = drive->id; - - while (*list) - if (!strcmp(*list++,id->model)) - return 1; - return 0; + u32 class_rev; + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; + + switch(dev->device) { + /* Remap new 372N onto 372 */ + case PCI_DEVICE_ID_TTI_HPT372N: + class_rev = PCI_DEVICE_ID_TTI_HPT372; break; + case PCI_DEVICE_ID_TTI_HPT374: + class_rev = PCI_DEVICE_ID_TTI_HPT374; break; + case PCI_DEVICE_ID_TTI_HPT371: + class_rev = PCI_DEVICE_ID_TTI_HPT371; break; + case PCI_DEVICE_ID_TTI_HPT302: + class_rev = PCI_DEVICE_ID_TTI_HPT302; break; + case PCI_DEVICE_ID_TTI_HPT372: + class_rev = PCI_DEVICE_ID_TTI_HPT372; break; + default: + break; + } + return class_rev; } -static u8 hpt3xx_ratemask(ide_drive_t *drive) -{ - struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev); - u8 mode = info->max_mode; +static int check_in_drive_lists(ide_drive_t *drive, const char **list); +static u8 hpt3xx_ratemask (ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + struct hpt_info *info = ide_get_hwifdata(hwif); + u8 mode = 0; + + /* FIXME: TODO - move this to set info->mode once at boot */ + + if (info->revision >= 8) { /* HPT374 */ + mode = (HPT374_ALLOW_ATA133_6) ? 4 : 3; + } else if (info->revision >= 7) { /* HPT371 */ + mode = (HPT371_ALLOW_ATA133_6) ? 4 : 3; + } else if (info->revision >= 6) { /* HPT302 */ + mode = (HPT302_ALLOW_ATA133_6) ? 4 : 3; + } else if (info->revision >= 5) { /* HPT372 */ + mode = (HPT372_ALLOW_ATA133_6) ? 4 : 3; + } else if (info->revision >= 4) { /* HPT370A */ + mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2; + } else if (info->revision >= 3) { /* HPT370 */ + mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2; + mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : mode; + } else { /* HPT366 and HPT368 */ + mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : 2; + } if (!eighty_ninty_three(drive) && mode) mode = min(mode, (u8)1); return mode; @@ -528,61 +429,75 @@ static u8 hpt3xx_ratemask(ide_drive_t *drive) * either PIO or UDMA modes 0,4,5 */ -static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed) +static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed) { - struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev); - u8 chip_type = info->chip_type; + ide_hwif_t *hwif = drive->hwif; + struct hpt_info *info = ide_get_hwifdata(hwif); u8 mode = hpt3xx_ratemask(drive); if (drive->media != ide_disk) return min(speed, (u8)XFER_PIO_4); - switch (mode) { + switch(mode) { case 0x04: - speed = min_t(u8, speed, XFER_UDMA_6); + speed = min(speed, (u8)XFER_UDMA_6); break; case 0x03: - speed = min_t(u8, speed, XFER_UDMA_5); - if (chip_type >= HPT374) + speed = min(speed, (u8)XFER_UDMA_5); + if (info->revision >= 5) break; - if (!check_in_drive_list(drive, bad_ata100_5)) - goto check_bad_ata33; - /* fall thru */ + if (check_in_drive_lists(drive, bad_ata100_5)) + speed = min(speed, (u8)XFER_UDMA_4); + break; case 0x02: - speed = min_t(u8, speed, XFER_UDMA_4); - - /* - * CHECK ME, Does this need to be changed to HPT374 ?? - */ - if (chip_type >= HPT370) - goto check_bad_ata33; - if (HPT366_ALLOW_ATA66_4 && - !check_in_drive_list(drive, bad_ata66_4)) - goto check_bad_ata33; - - speed = min_t(u8, speed, XFER_UDMA_3); - if (HPT366_ALLOW_ATA66_3 && - !check_in_drive_list(drive, bad_ata66_3)) - goto check_bad_ata33; - /* fall thru */ - case 0x01: - speed = min_t(u8, speed, XFER_UDMA_2); - - check_bad_ata33: - if (chip_type >= HPT370A) + speed = min(speed, (u8)XFER_UDMA_4); + /* + * CHECK ME, Does this need to be set to 5 ?? + */ + if (info->revision >= 3) break; - if (!check_in_drive_list(drive, bad_ata33)) + if ((check_in_drive_lists(drive, bad_ata66_4)) || + (!(HPT366_ALLOW_ATA66_4))) + speed = min(speed, (u8)XFER_UDMA_3); + if ((check_in_drive_lists(drive, bad_ata66_3)) || + (!(HPT366_ALLOW_ATA66_3))) + speed = min(speed, (u8)XFER_UDMA_2); + break; + case 0x01: + speed = min(speed, (u8)XFER_UDMA_2); + /* + * CHECK ME, Does this need to be set to 5 ?? + */ + if (info->revision >= 3) break; - /* fall thru */ + if (check_in_drive_lists(drive, bad_ata33)) + speed = min(speed, (u8)XFER_MW_DMA_2); + break; case 0x00: default: - speed = min_t(u8, speed, XFER_MW_DMA_2); + speed = min(speed, (u8)XFER_MW_DMA_2); break; } return speed; } -static u32 get_speed_setting(u8 speed, struct hpt_info *info) +static int check_in_drive_lists (ide_drive_t *drive, const char **list) +{ + struct hd_driveid *id = drive->id; + + if (quirk_drives == list) { + while (*list) + if (strstr(id->model, *list++)) + return 1; + } else { + while (*list) + if (!strcmp(*list++,id->model)) + return 1; + } + return 0; +} + +static u32 pci_bus_clock_list(u8 speed, u32 *chipset_table) { int i; @@ -595,161 +510,228 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info) for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++) if (xfer_speeds[i] == speed) break; - /* - * NOTE: info->settings only points to the pointer - * to the list of the actual register values - */ - return (*info->settings)[i]; + return chipset_table[i]; } static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - struct hpt_info *info = pci_get_drvdata(dev); - u8 speed = hpt3xx_ratefilter(drive, xferspeed); - u8 itr_addr = drive->dn ? 0x44 : 0x40; - u32 itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 : - (speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff); - u32 new_itr = get_speed_setting(speed, info); - u32 old_itr = 0; + ide_hwif_t *hwif = drive->hwif; + struct pci_dev *dev = hwif->pci_dev; + struct hpt_info *info = ide_get_hwifdata(hwif); + u8 speed = hpt3xx_ratefilter(drive, xferspeed); + u8 regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40; + u8 regfast = (hwif->channel) ? 0x55 : 0x51; + u8 drive_fast = 0; + u32 reg1 = 0, reg2 = 0; /* - * Disable on-chip PIO FIFO/buffer (and PIO MST mode as well) - * to avoid problems handling I/O errors later + * Disable the "fast interrupt" prediction. */ - pci_read_config_dword(dev, itr_addr, &old_itr); - new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask); - new_itr &= ~0xc0000000; + pci_read_config_byte(dev, regfast, &drive_fast); + if (drive_fast & 0x80) + pci_write_config_byte(dev, regfast, drive_fast & ~0x80); - pci_write_config_dword(dev, itr_addr, new_itr); + reg2 = pci_bus_clock_list(speed, info->speed); + + /* + * Disable on-chip PIO FIFO/buffer + * (to avoid problems handling I/O errors later) + */ + pci_read_config_dword(dev, regtime, ®1); + if (speed >= XFER_MW_DMA_0) { + reg2 = (reg2 & ~0xc0000000) | (reg1 & 0xc0000000); + } else { + reg2 = (reg2 & ~0x30070000) | (reg1 & 0x30070000); + } + reg2 &= ~0x80000000; + + pci_write_config_dword(dev, regtime, reg2); return ide_config_drive_speed(drive, speed); } -static int hpt37x_tune_chipset(ide_drive_t *drive, u8 xferspeed) +static int hpt370_tune_chipset(ide_drive_t *drive, u8 xferspeed) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - struct hpt_info *info = pci_get_drvdata(dev); - u8 speed = hpt3xx_ratefilter(drive, xferspeed); - u8 itr_addr = 0x40 + (drive->dn * 4); - u32 itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 : - (speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff); - u32 new_itr = get_speed_setting(speed, info); - u32 old_itr = 0; - - pci_read_config_dword(dev, itr_addr, &old_itr); - new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask); + ide_hwif_t *hwif = drive->hwif; + struct pci_dev *dev = hwif->pci_dev; + struct hpt_info *info = ide_get_hwifdata(hwif); + u8 speed = hpt3xx_ratefilter(drive, xferspeed); + u8 regfast = (drive->hwif->channel) ? 0x55 : 0x51; + u8 drive_pci = 0x40 + (drive->dn * 4); + u8 new_fast = 0, drive_fast = 0; + u32 list_conf = 0, drive_conf = 0; + u32 conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000; + + /* + * Disable the "fast interrupt" prediction. + * don't holdoff on interrupts. (== 0x01 despite what the docs say) + */ + pci_read_config_byte(dev, regfast, &drive_fast); + new_fast = drive_fast; + if (new_fast & 0x02) + new_fast &= ~0x02; + +#ifdef HPT_DELAY_INTERRUPT + if (new_fast & 0x01) + new_fast &= ~0x01; +#else + if ((new_fast & 0x01) == 0) + new_fast |= 0x01; +#endif + if (new_fast != drive_fast) + pci_write_config_byte(dev, regfast, new_fast); + + list_conf = pci_bus_clock_list(speed, info->speed); + + pci_read_config_dword(dev, drive_pci, &drive_conf); + list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); if (speed < XFER_MW_DMA_0) - new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ - pci_write_config_dword(dev, itr_addr, new_itr); + list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ + pci_write_config_dword(dev, drive_pci, list_conf); return ide_config_drive_speed(drive, speed); } -static int hpt3xx_tune_chipset(ide_drive_t *drive, u8 speed) +static int hpt372_tune_chipset(ide_drive_t *drive, u8 xferspeed) { - ide_hwif_t *hwif = HWIF(drive); - struct hpt_info *info = pci_get_drvdata(hwif->pci_dev); + ide_hwif_t *hwif = drive->hwif; + struct pci_dev *dev = hwif->pci_dev; + struct hpt_info *info = ide_get_hwifdata(hwif); + u8 speed = hpt3xx_ratefilter(drive, xferspeed); + u8 regfast = (drive->hwif->channel) ? 0x55 : 0x51; + u8 drive_fast = 0, drive_pci = 0x40 + (drive->dn * 4); + u32 list_conf = 0, drive_conf = 0; + u32 conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000; + + /* + * Disable the "fast interrupt" prediction. + * don't holdoff on interrupts. (== 0x01 despite what the docs say) + */ + pci_read_config_byte(dev, regfast, &drive_fast); + drive_fast &= ~0x07; + pci_write_config_byte(dev, regfast, drive_fast); + + list_conf = pci_bus_clock_list(speed, info->speed); + pci_read_config_dword(dev, drive_pci, &drive_conf); + list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); + if (speed < XFER_MW_DMA_0) + list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ + pci_write_config_dword(dev, drive_pci, list_conf); + + return ide_config_drive_speed(drive, speed); +} - if (info->chip_type >= HPT370) - return hpt37x_tune_chipset(drive, speed); +static int hpt3xx_tune_chipset (ide_drive_t *drive, u8 speed) +{ + ide_hwif_t *hwif = drive->hwif; + struct hpt_info *info = ide_get_hwifdata(hwif); + + if (info->revision >= 8) + return hpt372_tune_chipset(drive, speed); /* not a typo */ + else if (info->revision >= 5) + return hpt372_tune_chipset(drive, speed); + else if (info->revision >= 3) + return hpt370_tune_chipset(drive, speed); else /* hpt368: hpt_minimum_revision(dev, 2) */ return hpt36x_tune_chipset(drive, speed); } -static void hpt3xx_tune_drive(ide_drive_t *drive, u8 pio) +static void hpt3xx_tune_drive (ide_drive_t *drive, u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio); + pio = ide_get_best_pio_mode(drive, 255, pio, NULL); + (void) hpt3xx_tune_chipset(drive, (XFER_PIO_0 + pio)); } /* * This allows the configuration of ide_pci chipset registers * for cards that learn about the drive's UDMA, DMA, PIO capabilities - * after the drive is reported by the OS. Initially designed for + * after the drive is reported by the OS. Initially for designed for * HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc. * + * check_in_drive_lists(drive, bad_ata66_4) + * check_in_drive_lists(drive, bad_ata66_3) + * check_in_drive_lists(drive, bad_ata33) + * */ -static int config_chipset_for_dma(ide_drive_t *drive) +static int config_chipset_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive)); + ide_hwif_t *hwif = drive->hwif; + struct hpt_info *info = ide_get_hwifdata(hwif); if (!speed) return 0; + /* If we don't have any timings we can't do a lot */ + if (info->speed == NULL) + return 0; + (void) hpt3xx_tune_chipset(drive, speed); return ide_dma_enable(drive); } -static int hpt3xx_quirkproc(ide_drive_t *drive) +static int hpt3xx_quirkproc (ide_drive_t *drive) { - struct hd_driveid *id = drive->id; - const char **list = quirk_drives; - - while (*list) - if (strstr(id->model, *list++)) - return 1; - return 0; + return ((int) check_in_drive_lists(drive, quirk_drives)); } -static void hpt3xx_intrproc(ide_drive_t *drive) +static void hpt3xx_intrproc (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); + ide_hwif_t *hwif = drive->hwif; if (drive->quirk_list) return; /* drives in the quirk_list may not like intr setups/cleanups */ - hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); + hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG); } -static void hpt3xx_maskproc(ide_drive_t *drive, int mask) +static void hpt3xx_maskproc (ide_drive_t *drive, int mask) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - struct hpt_info *info = pci_get_drvdata(dev); + ide_hwif_t *hwif = drive->hwif; + struct hpt_info *info = ide_get_hwifdata(hwif); + struct pci_dev *dev = hwif->pci_dev; if (drive->quirk_list) { - if (info->chip_type >= HPT370) { - u8 scr1 = 0; - - pci_read_config_byte(dev, 0x5a, &scr1); - if (((scr1 & 0x10) >> 4) != mask) { - if (mask) - scr1 |= 0x10; - else - scr1 &= ~0x10; - pci_write_config_byte(dev, 0x5a, scr1); - } + if (info->revision >= 3) { + u8 reg5a = 0; + pci_read_config_byte(dev, 0x5a, ®5a); + if (((reg5a & 0x10) >> 4) != mask) + pci_write_config_byte(dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10)); } else { - if (mask) + if (mask) { disable_irq(hwif->irq); - else - enable_irq (hwif->irq); + } else { + enable_irq(hwif->irq); + } } - } else - hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2), - IDE_CONTROL_REG); + } else { + if (IDE_CONTROL_REG) + hwif->OUTB(mask ? (drive->ctl | 2) : + (drive->ctl & ~2), + IDE_CONTROL_REG); + } } -static int hpt366_config_drive_xfer_rate(ide_drive_t *drive) +static int hpt366_config_drive_xfer_rate (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); + ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; drive->init_speed = 0; if ((id->capability & 1) && drive->autodma) { - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); + + if (ide_use_dma(drive)) { + if (config_chipset_for_dma(drive)) + return hwif->ide_dma_on(drive); + } goto fast_ata_pio; } else if ((id->capability & 8) || (id->field_valid & 2)) { fast_ata_pio: - hpt3xx_tune_drive(drive, 255); + hpt3xx_tune_drive(drive, 5); return hwif->ide_dma_off_quietly(drive); } /* IORDY not supported */ @@ -757,48 +739,31 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive) } /* - * This is specific to the HPT366 UDMA chipset + * This is specific to the HPT366 UDMA bios chipset * by HighPoint|Triones Technologies, Inc. */ -static int hpt366_ide_dma_lostirq(ide_drive_t *drive) +static int hpt366_ide_dma_lostirq (ide_drive_t *drive) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 mcr1 = 0, mcr3 = 0, scr1 = 0; - - pci_read_config_byte(dev, 0x50, &mcr1); - pci_read_config_byte(dev, 0x52, &mcr3); - pci_read_config_byte(dev, 0x5a, &scr1); - printk("%s: (%s) mcr1=0x%02x, mcr3=0x%02x, scr1=0x%02x\n", - drive->name, __FUNCTION__, mcr1, mcr3, scr1); - if (scr1 & 0x10) - pci_write_config_byte(dev, 0x5a, scr1 & ~0x10); + struct pci_dev *dev = HWIF(drive)->pci_dev; + u8 reg50h = 0, reg52h = 0, reg5ah = 0; + + pci_read_config_byte(dev, 0x50, ®50h); + pci_read_config_byte(dev, 0x52, ®52h); + pci_read_config_byte(dev, 0x5a, ®5ah); + printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n", + drive->name, __FUNCTION__, reg50h, reg52h, reg5ah); + if (reg5ah & 0x10) + pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10); return __ide_dma_lostirq(drive); } -static void hpt370_clear_engine(ide_drive_t *drive) +static void hpt370_clear_engine (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - - pci_write_config_byte(hwif->pci_dev, hwif->select_data, 0x37); + u8 regstate = HWIF(drive)->channel ? 0x54 : 0x50; + pci_write_config_byte(HWIF(drive)->pci_dev, regstate, 0x37); udelay(10); } -static void hpt370_irq_timeout(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u16 bfifo = 0; - u8 dma_cmd; - - pci_read_config_word(hwif->pci_dev, hwif->select_data + 2, &bfifo); - printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff); - - /* get DMA command mode */ - dma_cmd = hwif->INB(hwif->dma_command); - /* stop DMA */ - hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command); - hpt370_clear_engine(drive); -} - static void hpt370_ide_dma_start(ide_drive_t *drive) { #ifdef HPT_RESET_STATE_ENGINE @@ -807,35 +772,64 @@ static void hpt370_ide_dma_start(ide_drive_t *drive) ide_dma_start(drive); } -static int hpt370_ide_dma_end(ide_drive_t *drive) +static int hpt370_ide_dma_end (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = hwif->INB(hwif->dma_status); + u8 dma_stat = hwif->INB(hwif->dma_status); if (dma_stat & 0x01) { /* wait a little */ udelay(20); dma_stat = hwif->INB(hwif->dma_status); - if (dma_stat & 0x01) - hpt370_irq_timeout(drive); } + if ((dma_stat & 0x01) != 0) + /* fallthrough */ + (void) HWIF(drive)->ide_dma_timeout(drive); + return __ide_dma_end(drive); } -static int hpt370_ide_dma_timeout(ide_drive_t *drive) +static void hpt370_lostirq_timeout (ide_drive_t *drive) { - hpt370_irq_timeout(drive); + ide_hwif_t *hwif = HWIF(drive); + u8 bfifo = 0, reginfo = hwif->channel ? 0x56 : 0x52; + u8 dma_stat = 0, dma_cmd = 0; + + pci_read_config_byte(HWIF(drive)->pci_dev, reginfo, &bfifo); + printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo); + hpt370_clear_engine(drive); + /* get dma command mode */ + dma_cmd = hwif->INB(hwif->dma_command); + /* stop dma */ + hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command); + dma_stat = hwif->INB(hwif->dma_status); + /* clear errors */ + hwif->OUTB(dma_stat | 0x6, hwif->dma_status); +} + +static int hpt370_ide_dma_timeout (ide_drive_t *drive) +{ + hpt370_lostirq_timeout(drive); + hpt370_clear_engine(drive); return __ide_dma_timeout(drive); } +static int hpt370_ide_dma_lostirq (ide_drive_t *drive) +{ + hpt370_lostirq_timeout(drive); + hpt370_clear_engine(drive); + return __ide_dma_lostirq(drive); +} + /* returns 1 if DMA IRQ issued, 0 otherwise */ static int hpt374_ide_dma_test_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u16 bfifo = 0; - u8 dma_stat; + u8 reginfo = hwif->channel ? 0x56 : 0x52; + u8 dma_stat; - pci_read_config_word(hwif->pci_dev, hwif->select_data + 2, &bfifo); + pci_read_config_word(hwif->pci_dev, reginfo, &bfifo); if (bfifo & 0x1FF) { // printk("%s: %d bytes in FIFO\n", drive->name, bfifo); return 0; @@ -843,7 +837,7 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive) dma_stat = hwif->INB(hwif->dma_status); /* return 1 if INTR asserted */ - if (dma_stat & 4) + if ((dma_stat & 4) == 4) return 1; if (!drive->waiting_for_dma) @@ -852,17 +846,17 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive) return 0; } -static int hpt374_ide_dma_end(ide_drive_t *drive) +static int hpt374_ide_dma_end (ide_drive_t *drive) { + struct pci_dev *dev = HWIF(drive)->pci_dev; ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 mcr = 0, mcr_addr = hwif->select_data; - u8 bwsr = 0, mask = hwif->channel ? 0x02 : 0x01; - - pci_read_config_byte(dev, 0x6a, &bwsr); - pci_read_config_byte(dev, mcr_addr, &mcr); - if (bwsr & mask) - pci_write_config_byte(dev, mcr_addr, mcr | 0x30); + u8 msc_stat = 0, mscreg = hwif->channel ? 0x54 : 0x50; + u8 bwsr_stat = 0, bwsr_mask = hwif->channel ? 0x02 : 0x01; + + pci_read_config_byte(dev, 0x6a, &bwsr_stat); + pci_read_config_byte(dev, mscreg, &msc_stat); + if ((bwsr_stat & bwsr_mask) == bwsr_mask) + pci_write_config_byte(dev, mscreg, msc_stat|0x30); return __ide_dma_end(drive); } @@ -872,37 +866,40 @@ static int hpt374_ide_dma_end(ide_drive_t *drive) * @mode: clocking mode (0x21 for write, 0x23 otherwise) * * Switch the DPLL clock on the HPT3xxN devices. This is a right mess. + * NOTE: avoid touching the disabled primary channel on HPT371N -- it + * doesn't physically exist anyway... */ static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode) { - u8 scr2 = hwif->INB(hwif->dma_master + 0x7b); + u8 mcr1, scr2 = hwif->INB(hwif->dma_master + 0x7b); if ((scr2 & 0x7f) == mode) return; + /* MISC. control register 1 has the channel enable bit... */ + mcr1 = hwif->INB(hwif->dma_master + 0x70); + /* Tristate the bus */ - hwif->OUTB(0x80, hwif->dma_master + 0x73); + if (mcr1 & 0x04) + hwif->OUTB(0x80, hwif->dma_master + 0x73); hwif->OUTB(0x80, hwif->dma_master + 0x77); /* Switch clock and reset channels */ hwif->OUTB(mode, hwif->dma_master + 0x7b); hwif->OUTB(0xc0, hwif->dma_master + 0x79); - /* - * Reset the state machines. - * NOTE: avoid accidentally enabling the disabled channels. - */ - hwif->OUTB(hwif->INB(hwif->dma_master + 0x70) | 0x32, - hwif->dma_master + 0x70); - hwif->OUTB(hwif->INB(hwif->dma_master + 0x74) | 0x32, - hwif->dma_master + 0x74); + /* Reset state machines */ + if (mcr1 & 0x04) + hwif->OUTB(0x37, hwif->dma_master + 0x70); + hwif->OUTB(0x37, hwif->dma_master + 0x74); /* Complete reset */ hwif->OUTB(0x00, hwif->dma_master + 0x79); /* Reconnect channels to bus */ - hwif->OUTB(0x00, hwif->dma_master + 0x73); + if (mcr1 & 0x04) + hwif->OUTB(0x00, hwif->dma_master + 0x73); hwif->OUTB(0x00, hwif->dma_master + 0x77); } @@ -917,12 +914,14 @@ static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode) static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq) { - hpt3xxn_set_clock(HWIF(drive), rq_data_dir(rq) ? 0x23 : 0x21); + ide_hwif_t *hwif = HWIF(drive); + u8 wantclock = rq_data_dir(rq) ? 0x23 : 0x21; + + hpt3xxn_set_clock(hwif, wantclock); } /* * Set/get power state for a drive. - * NOTE: affects both drives on each channel. * * When we turn the power back on, we need to re-initialize things. */ @@ -930,18 +929,26 @@ static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq) static int hpt3xx_busproc(ide_drive_t *drive, int state) { - ide_hwif_t *hwif = HWIF(drive); + ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = hwif->pci_dev; - u8 mcr_addr = hwif->select_data + 2; - u8 resetmask = hwif->channel ? 0x80 : 0x40; - u8 bsr2 = 0; - u16 mcr = 0; + u8 tristate, resetmask, bus_reg = 0; + u16 tri_reg = 0; hwif->bus_state = state; + if (hwif->channel) { + /* secondary channel */ + tristate = 0x56; + resetmask = 0x80; + } else { + /* primary channel */ + tristate = 0x52; + resetmask = 0x40; + } + /* Grab the status. */ - pci_read_config_word(dev, mcr_addr, &mcr); - pci_read_config_byte(dev, 0x59, &bsr2); + pci_read_config_word(dev, tristate, &tri_reg); + pci_read_config_byte(dev, 0x59, &bus_reg); /* * Set the state. We don't set it if we don't need to do so. @@ -949,22 +956,22 @@ static int hpt3xx_busproc(ide_drive_t *drive, int state) */ switch (state) { case BUSSTATE_ON: - if (!(bsr2 & resetmask)) + if (!(bus_reg & resetmask)) return 0; hwif->drives[0].failures = hwif->drives[1].failures = 0; - pci_write_config_byte(dev, 0x59, bsr2 & ~resetmask); - pci_write_config_word(dev, mcr_addr, mcr & ~TRISTATE_BIT); + pci_write_config_byte(dev, 0x59, bus_reg & ~resetmask); + pci_write_config_word(dev, tristate, tri_reg & ~TRISTATE_BIT); return 0; case BUSSTATE_OFF: - if ((bsr2 & resetmask) && !(mcr & TRISTATE_BIT)) + if ((bus_reg & resetmask) && !(tri_reg & TRISTATE_BIT)) return 0; - mcr &= ~TRISTATE_BIT; + tri_reg &= ~TRISTATE_BIT; break; case BUSSTATE_TRISTATE: - if ((bsr2 & resetmask) && (mcr & TRISTATE_BIT)) + if ((bus_reg & resetmask) && (tri_reg & TRISTATE_BIT)) return 0; - mcr |= TRISTATE_BIT; + tri_reg |= TRISTATE_BIT; break; default: return -EINVAL; @@ -973,320 +980,268 @@ static int hpt3xx_busproc(ide_drive_t *drive, int state) hwif->drives[0].failures = hwif->drives[0].max_failures + 1; hwif->drives[1].failures = hwif->drives[1].max_failures + 1; - pci_write_config_word(dev, mcr_addr, mcr); - pci_write_config_byte(dev, 0x59, bsr2 | resetmask); + pci_write_config_word(dev, tristate, tri_reg); + pci_write_config_byte(dev, 0x59, bus_reg | resetmask); return 0; } -/** - * hpt37x_calibrate_dpll - calibrate the DPLL - * @dev: PCI device - * - * Perform a calibration cycle on the DPLL. - * Returns 1 if this succeeds - */ -static int __devinit hpt37x_calibrate_dpll(struct pci_dev *dev, u16 f_low, u16 f_high) +static void __devinit hpt366_clocking(ide_hwif_t *hwif) { - u32 dpll = (f_high << 16) | f_low | 0x100; - u8 scr2; - int i; + u32 reg1 = 0; + struct hpt_info *info = ide_get_hwifdata(hwif); - pci_write_config_dword(dev, 0x5c, dpll); + pci_read_config_dword(hwif->pci_dev, 0x40, ®1); - /* Wait for oscillator ready */ - for(i = 0; i < 0x5000; ++i) { - udelay(50); - pci_read_config_byte(dev, 0x5b, &scr2); - if (scr2 & 0x80) + /* detect bus speed by looking at control reg timing: */ + switch((reg1 >> 8) & 7) { + case 5: + info->speed = forty_base_hpt36x; + break; + case 9: + info->speed = twenty_five_base_hpt36x; + break; + case 7: + default: + info->speed = thirty_three_base_hpt36x; break; } - /* See if it stays ready (we'll just bail out if it's not yet) */ - for(i = 0; i < 0x1000; ++i) { - pci_read_config_byte(dev, 0x5b, &scr2); - /* DPLL destabilized? */ - if(!(scr2 & 0x80)) - return 0; - } - /* Turn off tuning, we have the DPLL set */ - pci_read_config_dword (dev, 0x5c, &dpll); - pci_write_config_dword(dev, 0x5c, (dpll & ~0x100)); - return 1; } -static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name) +static void __devinit hpt37x_clocking(ide_hwif_t *hwif) { - struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL); - unsigned long io_base = pci_resource_start(dev, 4); - u8 pci_clk, dpll_clk = 0; /* PCI and DPLL clock in MHz */ - enum ata_clock clock; - - if (info == NULL) { - printk(KERN_ERR "%s: out of memory!\n", name); - return -ENOMEM; - } - + struct hpt_info *info = ide_get_hwifdata(hwif); + struct pci_dev *dev = hwif->pci_dev; + int adjust, i; + u16 freq = 0; + u32 pll, temp = 0; + u8 reg5bh = 0, mcr1 = 0; + /* - * Copy everything from a static "template" structure - * to just allocated per-chip hpt_info structure. + * default to pci clock. make sure MA15/16 are set to output + * to prevent drives having problems with 40-pin cables. Needed + * for some drives such as IBM-DTLA which will not enter ready + * state on reset when PDIAG is a input. + * + * ToDo: should we set 0x21 when using PLL mode ? */ - *info = *(struct hpt_info *)pci_get_drvdata(dev); + pci_write_config_byte(dev, 0x5b, 0x23); /* - * FIXME: Not portable. Also, why do we enable the ROM in the first place? - * We don't seem to be using it. + * We'll have to read f_CNT value in order to determine + * the PCI clock frequency according to the following ratio: + * + * f_CNT = Fpci * 192 / Fdpll + * + * First try reading the register in which the HighPoint BIOS + * saves f_CNT value before reprogramming the DPLL from its + * default setting (which differs for the various chips). + * NOTE: This register is only accessible via I/O space. + * + * In case the signature check fails, we'll have to resort to + * reading the f_CNT register itself in hopes that nobody has + * touched the DPLL yet... */ - if (dev->resource[PCI_ROM_RESOURCE].start) - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); - pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); - pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); + temp = inl(pci_resource_start(dev, 4) + 0x90); + if ((temp & 0xFFFFF000) != 0xABCDE000) { + printk(KERN_WARNING "HPT37X: no clock data saved by BIOS\n"); + + /* Calculate the average value of f_CNT */ + for (temp = i = 0; i < 128; i++) { + pci_read_config_word(dev, 0x78, &freq); + temp += freq & 0x1ff; + mdelay(1); + } + freq = temp / 128; + } else + freq = temp & 0x1ff; /* - * First, try to estimate the PCI clock frequency... + * HPT3xxN chips use different PCI clock information. + * Currently we always set up the PLL for them. */ - if (info->chip_type >= HPT370) { - u8 scr1 = 0; - u16 f_cnt = 0; - u32 temp = 0; - - /* Interrupt force enable. */ - pci_read_config_byte(dev, 0x5a, &scr1); - if (scr1 & 0x10) - pci_write_config_byte(dev, 0x5a, scr1 & ~0x10); - - /* - * HighPoint does this for HPT372A. - * NOTE: This register is only writeable via I/O space. - */ - if (info->chip_type == HPT372A) - outb(0x0e, io_base + 0x9c); - - /* - * Default to PCI clock. Make sure MA15/16 are set to output - * to prevent drives having problems with 40-pin cables. - */ - pci_write_config_byte(dev, 0x5b, 0x23); - /* - * We'll have to read f_CNT value in order to determine - * the PCI clock frequency according to the following ratio: - * - * f_CNT = Fpci * 192 / Fdpll - * - * First try reading the register in which the HighPoint BIOS - * saves f_CNT value before reprogramming the DPLL from its - * default setting (which differs for the various chips). - * NOTE: This register is only accessible via I/O space. - * - * In case the signature check fails, we'll have to resort to - * reading the f_CNT register itself in hopes that nobody has - * touched the DPLL yet... - */ - temp = inl(io_base + 0x90); - if ((temp & 0xFFFFF000) != 0xABCDE000) { - int i; - - printk(KERN_WARNING "%s: no clock data saved by BIOS\n", - name); - - /* Calculate the average value of f_CNT. */ - for (temp = i = 0; i < 128; i++) { - pci_read_config_word(dev, 0x78, &f_cnt); - temp += f_cnt & 0x1ff; - mdelay(1); - } - f_cnt = temp / 128; - } else - f_cnt = temp & 0x1ff; - - dpll_clk = info->dpll_clk; - pci_clk = (f_cnt * dpll_clk) / 192; - - /* Clamp PCI clock to bands. */ - if (pci_clk < 40) - pci_clk = 33; - else if(pci_clk < 45) - pci_clk = 40; - else if(pci_clk < 55) - pci_clk = 50; + if (info->flags & IS_3xxN) { + if(freq < 0x55) + pll = F_LOW_PCI_33; + else if(freq < 0x70) + pll = F_LOW_PCI_40; + else if(freq < 0x7F) + pll = F_LOW_PCI_50; else - pci_clk = 66; - - printk(KERN_INFO "%s: DPLL base: %d MHz, f_CNT: %d, " - "assuming %d MHz PCI\n", name, dpll_clk, f_cnt, pci_clk); - } else { - u32 itr1 = 0; - - pci_read_config_dword(dev, 0x40, &itr1); + pll = F_LOW_PCI_66; - /* Detect PCI clock by looking at cmd_high_time. */ - switch((itr1 >> 8) & 0x07) { - case 0x09: - pci_clk = 40; - break; - case 0x05: - pci_clk = 25; - break; - case 0x07: - default: - pci_clk = 33; - break; + printk(KERN_INFO "HPT3xxN detected, FREQ: %d, PLL: %d\n", freq, pll); + } + else + { + if(freq < 0x9C) + pll = F_LOW_PCI_33; + else if(freq < 0xb0) + pll = F_LOW_PCI_40; + else if(freq <0xc8) + pll = F_LOW_PCI_50; + else + pll = F_LOW_PCI_66; + + if (pll == F_LOW_PCI_33) { + info->speed = thirty_three_base_hpt37x; + printk(KERN_DEBUG "HPT37X: using 33MHz PCI clock\n"); + } else if (pll == F_LOW_PCI_40) { + /* Unsupported */ + } else if (pll == F_LOW_PCI_50) { + info->speed = fifty_base_hpt37x; + printk(KERN_DEBUG "HPT37X: using 50MHz PCI clock\n"); + } else { + info->speed = sixty_six_base_hpt37x; + printk(KERN_DEBUG "HPT37X: using 66MHz PCI clock\n"); } } - /* Let's assume we'll use PCI clock for the ATA clock... */ - switch (pci_clk) { - case 25: - clock = ATA_CLOCK_25MHZ; - break; - case 33: - default: - clock = ATA_CLOCK_33MHZ; - break; - case 40: - clock = ATA_CLOCK_40MHZ; - break; - case 50: - clock = ATA_CLOCK_50MHZ; - break; - case 66: - clock = ATA_CLOCK_66MHZ; - break; - } + if (pll == F_LOW_PCI_66) + info->flags |= PCI_66MHZ; /* - * Only try the DPLL if we don't have a table for the PCI clock that - * we are running at for HPT370/A, always use it for anything newer... + * only try the pll if we don't have a table for the clock + * speed that we're running at. NOTE: the internal PLL will + * result in slow reads when using a 33MHz PCI clock. we also + * don't like to use the PLL because it will cause glitches + * on PRST/SRST when the HPT state engine gets reset. * - * NOTE: Using the internal DPLL results in slow reads on 33 MHz PCI. - * We also don't like using the DPLL because this causes glitches - * on PRST-/SRST- when the state engine gets reset... + * ToDo: Use 66MHz PLL when ATA133 devices are present on a + * 372 device so we can get ATA133 support */ - if (info->chip_type >= HPT374 || info->settings[clock] == NULL) { - u16 f_low, delta = pci_clk < 50 ? 2 : 4; - int adjust; - - /* - * Select 66 MHz DPLL clock only if UltraATA/133 mode is - * supported/enabled, use 50 MHz DPLL clock otherwise... - */ - if (info->max_mode == 0x04) { - dpll_clk = 66; - clock = ATA_CLOCK_66MHZ; - } else if (dpll_clk) { /* HPT36x chips don't have DPLL */ - dpll_clk = 50; - clock = ATA_CLOCK_50MHZ; - } + if (info->speed) + goto init_hpt37X_done; - if (info->settings[clock] == NULL) { - printk(KERN_ERR "%s: unknown bus timing!\n", name); - kfree(info); - return -EIO; + info->flags |= PLL_MODE; + + /* + * Adjust the PLL based upon the PCI clock, enable it, and + * wait for stabilization... + */ + adjust = 0; + freq = (pll < F_LOW_PCI_50) ? 2 : 4; + while (adjust++ < 6) { + pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 | + pll | 0x100); + + /* wait for clock stabilization */ + for (i = 0; i < 0x50000; i++) { + pci_read_config_byte(dev, 0x5b, ®5bh); + if (reg5bh & 0x80) { + /* spin looking for the clock to destabilize */ + for (i = 0; i < 0x1000; ++i) { + pci_read_config_byte(dev, 0x5b, + ®5bh); + if ((reg5bh & 0x80) == 0) + goto pll_recal; + } + pci_read_config_dword(dev, 0x5c, &pll); + pci_write_config_dword(dev, 0x5c, + pll & ~0x100); + pci_write_config_byte(dev, 0x5b, 0x21); + + info->speed = fifty_base_hpt37x; + printk("HPT37X: using 50MHz internal PLL\n"); + goto init_hpt37X_done; + } } +pll_recal: + if (adjust & 1) + pll -= (adjust >> 1); + else + pll += (adjust >> 1); + } - /* Select the DPLL clock. */ - pci_write_config_byte(dev, 0x5b, 0x21); - - /* - * Adjust the DPLL based upon PCI clock, enable it, - * and wait for stabilization... - */ - f_low = (pci_clk * 48) / dpll_clk; - - for (adjust = 0; adjust < 8; adjust++) { - if(hpt37x_calibrate_dpll(dev, f_low, f_low + delta)) - break; +init_hpt37X_done: + if (!info->speed) + printk(KERN_ERR "HPT37x%s: unknown bus timing [%d %d].\n", + (info->flags & IS_3xxN) ? "N" : "", pll, freq); + /* + * Reset the state engines. + * NOTE: avoid accidentally enabling the primary channel on HPT371N. + */ + pci_read_config_byte(dev, 0x50, &mcr1); + if (mcr1 & 0x04) + pci_write_config_byte(dev, 0x50, 0x37); + pci_write_config_byte(dev, 0x54, 0x37); + udelay(100); +} - /* - * See if it'll settle at a fractionally different clock - */ - if (adjust & 1) - f_low -= adjust >> 1; - else - f_low += adjust >> 1; - } - if (adjust == 8) { - printk(KERN_ERR "%s: DPLL did not stabilize!\n", name); - kfree(info); - return -EIO; - } +static int __devinit init_hpt37x(struct pci_dev *dev) +{ + u8 reg5ah; - printk("%s: using %d MHz DPLL clock\n", name, dpll_clk); - } else { - /* Mark the fact that we're not using the DPLL. */ - dpll_clk = 0; + pci_read_config_byte(dev, 0x5a, ®5ah); + /* interrupt force enable */ + pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10)); + return 0; +} - printk("%s: using %d MHz PCI clock\n", name, pci_clk); - } +static int __devinit init_hpt366(struct pci_dev *dev) +{ + u32 reg1 = 0; + u8 drive_fast = 0; /* - * Advance the table pointer to a slot which points to the list - * of the register values settings matching the clock being used. + * Disable the "fast interrupt" prediction. */ - info->settings += clock; - - /* Store the clock frequencies. */ - info->dpll_clk = dpll_clk; - info->pci_clk = pci_clk; - - /* Point to this chip's own instance of the hpt_info structure. */ - pci_set_drvdata(dev, info); - - if (info->chip_type >= HPT370) { - u8 mcr1, mcr4; + pci_read_config_byte(dev, 0x51, &drive_fast); + if (drive_fast & 0x80) + pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); + pci_read_config_dword(dev, 0x40, ®1); + + return 0; +} - /* - * Reset the state engines. - * NOTE: Avoid accidentally enabling the disabled channels. - */ - pci_read_config_byte (dev, 0x50, &mcr1); - pci_read_config_byte (dev, 0x54, &mcr4); - pci_write_config_byte(dev, 0x50, (mcr1 | 0x32)); - pci_write_config_byte(dev, 0x54, (mcr4 | 0x32)); - udelay(100); - } +static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name) +{ + int ret = 0; /* - * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in - * the MISC. register to stretch the UltraDMA Tss timing. - * NOTE: This register is only writeable via I/O space. + * FIXME: Not portable. Also, why do we enable the ROM in the first place? + * We don't seem to be using it. */ - if (info->chip_type == HPT371N && clock == ATA_CLOCK_66MHZ) + if (dev->resource[PCI_ROM_RESOURCE].start) + pci_write_config_dword(dev, PCI_ROM_ADDRESS, + dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); + + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); + pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); + pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); - outb(inb(io_base + 0x9c) | 0x04, io_base + 0x9c); + if (hpt_revision(dev) >= 3) + ret = init_hpt37x(dev); + else + ret = init_hpt366(dev); + + if (ret) + return ret; return dev->irq; } static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) { - struct pci_dev *dev = hwif->pci_dev; - struct hpt_info *info = pci_get_drvdata(dev); + struct pci_dev *dev = hwif->pci_dev; + struct hpt_info *info = ide_get_hwifdata(hwif); + u8 ata66 = 0, regmask = (hwif->channel) ? 0x01 : 0x02; int serialize = HPT_SERIALIZE_IO; - u8 scr1 = 0, ata66 = (hwif->channel) ? 0x01 : 0x02; - u8 chip_type = info->chip_type; - u8 new_mcr, old_mcr = 0; - - /* Cache the channel's MISC. control registers' offset */ - hwif->select_data = hwif->channel ? 0x54 : 0x50; - + hwif->tuneproc = &hpt3xx_tune_drive; hwif->speedproc = &hpt3xx_tune_chipset; hwif->quirkproc = &hpt3xx_quirkproc; hwif->intrproc = &hpt3xx_intrproc; hwif->maskproc = &hpt3xx_maskproc; - hwif->busproc = &hpt3xx_busproc; - + /* * HPT3xxN chips have some complications: * * - on 33 MHz PCI we must clock switch * - on 66 MHz PCI we must NOT use the PCI clock */ - if (chip_type >= HPT372N && info->dpll_clk && info->pci_clk < 66) { + if ((info->flags & (IS_3xxN | PCI_66MHZ)) == IS_3xxN) { /* * Clock is shared between the channels, * so we'll have to serialize them... :-( @@ -1295,171 +1250,200 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) hwif->rw_disk = &hpt3xxn_rw_disk; } - /* Serialize access to this device if needed */ - if (serialize && hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; - - /* - * Disable the "fast interrupt" prediction. Don't hold off - * on interrupts. (== 0x01 despite what the docs say) - */ - pci_read_config_byte(dev, hwif->select_data + 1, &old_mcr); - - if (info->chip_type >= HPT374) - new_mcr = old_mcr & ~0x07; - else if (info->chip_type >= HPT370) { - new_mcr = old_mcr; - new_mcr &= ~0x02; - -#ifdef HPT_DELAY_INTERRUPT - new_mcr &= ~0x01; -#else - new_mcr |= 0x01; -#endif - } else /* HPT366 and HPT368 */ - new_mcr = old_mcr & ~0x80; - - if (new_mcr != old_mcr) - pci_write_config_byte(dev, hwif->select_data + 1, new_mcr); - - if (!hwif->dma_base) { - hwif->drives[0].autotune = hwif->drives[1].autotune = 1; - return; - } - - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - /* * The HPT37x uses the CBLID pins as outputs for MA15/MA16 - * address lines to access an external EEPROM. To read valid + * address lines to access an external eeprom. To read valid * cable detect state the pins must be enabled as inputs. */ - if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) { + if (info->revision >= 8 && (PCI_FUNC(dev->devfn) & 1)) { /* * HPT374 PCI function 1 * - set bit 15 of reg 0x52 to enable TCBLID as input * - set bit 15 of reg 0x56 to enable FCBLID as input */ - u8 mcr_addr = hwif->select_data + 2; - u16 mcr; - - pci_read_config_word (dev, mcr_addr, &mcr); - pci_write_config_word(dev, mcr_addr, (mcr | 0x8000)); + u16 mcr3, mcr6; + pci_read_config_word(dev, 0x52, &mcr3); + pci_read_config_word(dev, 0x56, &mcr6); + pci_write_config_word(dev, 0x52, mcr3 | 0x8000); + pci_write_config_word(dev, 0x56, mcr6 | 0x8000); /* now read cable id register */ - pci_read_config_byte (dev, 0x5a, &scr1); - pci_write_config_word(dev, mcr_addr, mcr); - } else if (chip_type >= HPT370) { + pci_read_config_byte(dev, 0x5a, &ata66); + pci_write_config_word(dev, 0x52, mcr3); + pci_write_config_word(dev, 0x56, mcr6); + } else if (info->revision >= 3) { /* * HPT370/372 and 374 pcifn 0 - * - clear bit 0 of reg 0x5b to enable P/SCBLID as inputs + * - clear bit 0 of 0x5b to enable P/SCBLID as inputs */ - u8 scr2 = 0; - - pci_read_config_byte (dev, 0x5b, &scr2); - pci_write_config_byte(dev, 0x5b, (scr2 & ~1)); + u8 scr2; + pci_read_config_byte(dev, 0x5b, &scr2); + pci_write_config_byte(dev, 0x5b, scr2 & ~1); /* now read cable id register */ - pci_read_config_byte (dev, 0x5a, &scr1); - pci_write_config_byte(dev, 0x5b, scr2); - } else - pci_read_config_byte (dev, 0x5a, &scr1); + pci_read_config_byte(dev, 0x5a, &ata66); + pci_write_config_byte(dev, 0x5b, scr2); + } else { + pci_read_config_byte(dev, 0x5a, &ata66); + } - if (!hwif->udma_four) - hwif->udma_four = (scr1 & ata66) ? 0 : 1; +#ifdef DEBUG + printk("HPT366: reg5ah=0x%02x ATA-%s Cable Port%d\n", + ata66, (ata66 & regmask) ? "33" : "66", + PCI_FUNC(hwif->pci_dev->devfn)); +#endif /* DEBUG */ - hwif->ide_dma_check = &hpt366_config_drive_xfer_rate; + /* Serialize access to this device */ + if (serialize && hwif->mate) + hwif->serialized = hwif->mate->serialized = 1; - if (chip_type >= HPT374) { - hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq; - hwif->ide_dma_end = &hpt374_ide_dma_end; - } else if (chip_type >= HPT370) { - hwif->dma_start = &hpt370_ide_dma_start; - hwif->ide_dma_end = &hpt370_ide_dma_end; - hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; - } else - hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq; + /* + * Set up ioctl for power status. + * NOTE: power affects both drives on each channel. + */ + hwif->busproc = &hpt3xx_busproc; + + if (!hwif->dma_base) { + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + return; + } + + hwif->ultra_mask = 0x7f; + hwif->mwdma_mask = 0x07; + + if (!(hwif->udma_four)) + hwif->udma_four = ((ata66 & regmask) ? 0 : 1); + hwif->ide_dma_check = &hpt366_config_drive_xfer_rate; + + if (info->revision >= 8) { + hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq; + hwif->ide_dma_end = &hpt374_ide_dma_end; + } else if (info->revision >= 5) { + hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq; + hwif->ide_dma_end = &hpt374_ide_dma_end; + } else if (info->revision >= 3) { + hwif->dma_start = &hpt370_ide_dma_start; + hwif->ide_dma_end = &hpt370_ide_dma_end; + hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; + hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq; + } else if (info->revision >= 2) + hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq; + else + hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq; if (!noautodma) hwif->autodma = 1; - hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; } static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase) { - struct pci_dev *dev = hwif->pci_dev; - u8 masterdma = 0, slavedma = 0; - u8 dma_new = 0, dma_old = 0; + struct hpt_info *info = ide_get_hwifdata(hwif); + u8 masterdma = 0, slavedma = 0; + u8 dma_new = 0, dma_old = 0; + u8 primary = hwif->channel ? 0x4b : 0x43; + u8 secondary = hwif->channel ? 0x4f : 0x47; unsigned long flags; if (!dmabase) return; - dma_old = hwif->INB(dmabase + 2); + if(info->speed == NULL) { + printk(KERN_WARNING "hpt366: no known IDE timings, disabling DMA.\n"); + return; + } + + dma_old = hwif->INB(dmabase+2); local_irq_save(flags); dma_new = dma_old; - pci_read_config_byte(dev, hwif->channel ? 0x4b : 0x43, &masterdma); - pci_read_config_byte(dev, hwif->channel ? 0x4f : 0x47, &slavedma); + pci_read_config_byte(hwif->pci_dev, primary, &masterdma); + pci_read_config_byte(hwif->pci_dev, secondary, &slavedma); if (masterdma & 0x30) dma_new |= 0x20; - if ( slavedma & 0x30) dma_new |= 0x40; + if (slavedma & 0x30) dma_new |= 0x40; if (dma_new != dma_old) - hwif->OUTB(dma_new, dmabase + 2); + hwif->OUTB(dma_new, dmabase+2); local_irq_restore(flags); ide_setup_dma(hwif, dmabase, 8); } -static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d) +/* + * We "borrow" this hook in order to set the data structures + * up early enough before dma or init_hwif calls are made. + */ + +static void __devinit init_iops_hpt366(ide_hwif_t *hwif) { - struct pci_dev *dev2; + struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL); + struct pci_dev *dev = hwif->pci_dev; + u16 did = dev->device; + u8 rid = 0; - if (PCI_FUNC(dev->devfn) & 1) - return -ENODEV; + if(info == NULL) { + printk(KERN_WARNING "hpt366: out of memory.\n"); + return; + } + ide_set_hwifdata(hwif, info); - pci_set_drvdata(dev, &hpt374); + /* Avoid doing the same thing twice. */ + if (hwif->channel && hwif->mate) { + memcpy(info, ide_get_hwifdata(hwif->mate), sizeof(struct hpt_info)); + return; + } + + pci_read_config_byte(dev, PCI_CLASS_REVISION, &rid); - if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) { - int ret; + if (( did == PCI_DEVICE_ID_TTI_HPT366 && rid == 6) || + ((did == PCI_DEVICE_ID_TTI_HPT372 || + did == PCI_DEVICE_ID_TTI_HPT302 || + did == PCI_DEVICE_ID_TTI_HPT371) && rid > 1) || + did == PCI_DEVICE_ID_TTI_HPT372N) + info->flags |= IS_3xxN; + + info->revision = hpt_revision(dev); + + if (info->revision >= 3) + hpt37x_clocking(hwif); + else + hpt366_clocking(hwif); +} - pci_set_drvdata(dev2, &hpt374); +static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d) +{ + struct pci_dev *findev = NULL; + + if (PCI_FUNC(dev->devfn) & 1) + return -ENODEV; - if (dev2->irq != dev->irq) { - /* FIXME: we need a core pci_set_interrupt() */ - dev2->irq = dev->irq; - printk(KERN_WARNING "%s: PCI config space interrupt " - "fixed.\n", d->name); + while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) { + if ((findev->vendor == dev->vendor) && + (findev->device == dev->device) && + ((findev->devfn - dev->devfn) == 1) && + (PCI_FUNC(findev->devfn) & 1)) { + if (findev->irq != dev->irq) { + /* FIXME: we need a core pci_set_interrupt() */ + findev->irq = dev->irq; + printk(KERN_WARNING "%s: pci-config space interrupt " + "fixed.\n", d->name); + } + return ide_setup_pci_devices(dev, findev, d); } - ret = ide_setup_pci_devices(dev, dev2, d); - if (ret < 0) - pci_dev_put(dev2); - return ret; } return ide_setup_pci_device(dev, d); } -static int __devinit init_setup_hpt372n(struct pci_dev *dev, ide_pci_device_t *d) +static int __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d) { - pci_set_drvdata(dev, &hpt372n); - return ide_setup_pci_device(dev, d); } static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d) { - struct hpt_info *info; - u8 rev = 0, mcr1 = 0; - - pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - - if (rev > 1) { - d->name = "HPT371N"; - - info = &hpt371n; - } else - info = &hpt371; + u8 mcr1 = 0; /* * HPT371 chips physically have only one channel, the secondary one, @@ -1469,94 +1453,59 @@ static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d) */ pci_read_config_byte(dev, 0x50, &mcr1); if (mcr1 & 0x04) - pci_write_config_byte(dev, 0x50, mcr1 & ~0x04); - - pci_set_drvdata(dev, info); - - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_hpt372a(struct pci_dev *dev, ide_pci_device_t *d) -{ - struct hpt_info *info; - u8 rev = 0; - - pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - - if (rev > 1) { - d->name = "HPT372N"; - - info = &hpt372n; - } else - info = &hpt372a; - pci_set_drvdata(dev, info); - - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_hpt302(struct pci_dev *dev, ide_pci_device_t *d) -{ - struct hpt_info *info; - u8 rev = 0; - - pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - - if (rev > 1) { - d->name = "HPT302N"; - - info = &hpt302n; - } else - info = &hpt302; - pci_set_drvdata(dev, info); + pci_write_config_byte(dev, 0x50, (mcr1 & ~0x04)); return ide_setup_pci_device(dev, d); } static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) { - struct pci_dev *dev2; - u8 rev = 0; - static char *chipset_names[] = { "HPT366", "HPT366", "HPT368", - "HPT370", "HPT370A", "HPT372", - "HPT372N" }; - static struct hpt_info *info[] = { &hpt36x, &hpt36x, &hpt36x, - &hpt370, &hpt370a, &hpt372, - &hpt372n }; + struct pci_dev *findev = NULL; + u8 pin1 = 0, pin2 = 0; + unsigned int class_rev; + char *chipset_names[] = {"HPT366", "HPT366", "HPT368", + "HPT370", "HPT370A", "HPT372", + "HPT372N" }; if (PCI_FUNC(dev->devfn) & 1) return -ENODEV; - pci_read_config_byte(dev, PCI_REVISION_ID, &rev); + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; - if (rev > 6) - rev = 6; + if(dev->device == PCI_DEVICE_ID_TTI_HPT372N) + class_rev = 6; - d->name = chipset_names[rev]; - - pci_set_drvdata(dev, info[rev]); - - if (rev > 2) - goto init_single; + if(class_rev <= 6) + d->name = chipset_names[class_rev]; + + switch(class_rev) { + case 6: + case 5: + case 4: + case 3: + goto init_single; + default: + break; + } d->channels = 1; - if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) { - u8 pin1 = 0, pin2 = 0; - int ret; - - pci_set_drvdata(dev2, info[rev]); - - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1); - pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2); - if (pin1 != pin2 && dev->irq == dev2->irq) { - d->bootable = ON_BOARD; - printk("%s: onboard version of chipset, pin1=%d pin2=%d\n", - d->name, pin1, pin2); + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1); + while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) { + if ((findev->vendor == dev->vendor) && + (findev->device == dev->device) && + ((findev->devfn - dev->devfn) == 1) && + (PCI_FUNC(findev->devfn) & 1)) { + pci_read_config_byte(findev, PCI_INTERRUPT_PIN, &pin2); + if ((pin1 != pin2) && (dev->irq == findev->irq)) { + d->bootable = ON_BOARD; + printk("%s: onboard version of chipset, " + "pin1=%d pin2=%d\n", d->name, + pin1, pin2); + } + return ide_setup_pci_devices(dev, findev, d); } - ret = ide_setup_pci_devices(dev, dev2, d); - if (ret < 0) - pci_dev_put(dev2); - return ret; } init_single: return ide_setup_pci_device(dev, d); @@ -1567,68 +1516,64 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .name = "HPT366", .init_setup = init_setup_hpt366, .init_chipset = init_chipset_hpt366, + .init_iops = init_iops_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, .bootable = OFF_BOARD, .extra = 240 },{ /* 1 */ .name = "HPT372A", - .init_setup = init_setup_hpt372a, + .init_setup = init_setup_hpt37x, .init_chipset = init_chipset_hpt366, + .init_iops = init_iops_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, .bootable = OFF_BOARD, - .extra = 240 },{ /* 2 */ .name = "HPT302", - .init_setup = init_setup_hpt302, + .init_setup = init_setup_hpt37x, .init_chipset = init_chipset_hpt366, + .init_iops = init_iops_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, .bootable = OFF_BOARD, - .extra = 240 },{ /* 3 */ .name = "HPT371", .init_setup = init_setup_hpt371, .init_chipset = init_chipset_hpt366, + .init_iops = init_iops_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, .bootable = OFF_BOARD, - .extra = 240 },{ /* 4 */ .name = "HPT374", .init_setup = init_setup_hpt374, .init_chipset = init_chipset_hpt366, + .init_iops = init_iops_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, .channels = 2, /* 4 */ .autodma = AUTODMA, - .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, .bootable = OFF_BOARD, - .extra = 240 },{ /* 5 */ .name = "HPT372N", - .init_setup = init_setup_hpt372n, + .init_setup = init_setup_hpt37x, .init_chipset = init_chipset_hpt366, + .init_iops = init_iops_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, .channels = 2, /* 4 */ .autodma = AUTODMA, - .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, .bootable = OFF_BOARD, - .extra = 240 } }; diff --git a/trunk/drivers/ide/pci/it8213.c b/trunk/drivers/ide/pci/it8213.c deleted file mode 100644 index 63248b6909fa..000000000000 --- a/trunk/drivers/ide/pci/it8213.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * ITE 8213 IDE driver - * - * Copyright (C) 2006 Jack Lee - * Copyright (C) 2006 Alan Cox - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* - * it8213_ratemask - Compute available modes - * @drive: IDE drive - * - * Compute the available speeds for the devices on the interface. This - * is all modes to ATA133 clipped by drive cable setup. - */ - -static u8 it8213_ratemask (ide_drive_t *drive) -{ - u8 mode = 4; - if (!eighty_ninty_three(drive)) - mode = min_t(u8, mode, 1); - return mode; -} - -/** - * it8213_dma_2_pio - return the PIO mode matching DMA - * @xfer_rate: transfer speed - * - * Returns the nearest equivalent PIO timing for the PIO or DMA - * mode requested by the controller. - */ - -static u8 it8213_dma_2_pio (u8 xfer_rate) { - switch(xfer_rate) { - case XFER_UDMA_6: - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - case XFER_MW_DMA_2: - case XFER_PIO_4: - return 4; - case XFER_MW_DMA_1: - case XFER_PIO_3: - return 3; - case XFER_SW_DMA_2: - case XFER_PIO_2: - return 2; - case XFER_MW_DMA_0: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: - default: - return 0; - } -} - -/* - * it8213_tuneproc - tune a drive - * @drive: drive to tune - * @pio: desired PIO mode - * - * Set the interface PIO mode. - */ - -static void it8213_tuneproc (ide_drive_t *drive, u8 pio) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - int is_slave = drive->dn & 1; - int master_port = 0x40; - int slave_port = 0x44; - unsigned long flags; - u16 master_data; - u8 slave_data; - static DEFINE_SPINLOCK(tune_lock); - int control = 0; - - static const u8 timings[][2]= { - { 0, 0 }, - { 0, 0 }, - { 1, 0 }, - { 2, 1 }, - { 2, 3 }, }; - - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - - spin_lock_irqsave(&tune_lock, flags); - pci_read_config_word(dev, master_port, &master_data); - - if (pio > 1) - control |= 1; /* Programmable timing on */ - if (drive->media != ide_disk) - control |= 4; /* ATAPI */ - if (pio > 2) - control |= 2; /* IORDY */ - if (is_slave) { - master_data |= 0x4000; - master_data &= ~0x0070; - if (pio > 1) - master_data = master_data | (control << 4); - pci_read_config_byte(dev, slave_port, &slave_data); - slave_data = slave_data & 0xf0; - slave_data = slave_data | (timings[pio][0] << 2) | timings[pio][1]; - } else { - master_data &= ~0x3307; - if (pio > 1) - master_data = master_data | control; - master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); - } - pci_write_config_word(dev, master_port, master_data); - if (is_slave) - pci_write_config_byte(dev, slave_port, slave_data); - spin_unlock_irqrestore(&tune_lock, flags); -} - -/** - * it8213_tune_chipset - set controller timings - * @drive: Drive to set up - * @xferspeed: speed we want to achieve - * - * Tune the ITE chipset for the desired mode. If we can't achieve - * the desired mode then tune for a lower one, but ultimately - * make the thing work. - */ - -static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 maslave = 0x40; - u8 speed = ide_rate_filter(it8213_ratemask(drive), xferspeed); - int a_speed = 3 << (drive->dn * 4); - int u_flag = 1 << drive->dn; - int v_flag = 0x01 << drive->dn; - int w_flag = 0x10 << drive->dn; - int u_speed = 0; - u16 reg4042, reg4a; - u8 reg48, reg54, reg55; - - pci_read_config_word(dev, maslave, ®4042); - pci_read_config_byte(dev, 0x48, ®48); - pci_read_config_word(dev, 0x4a, ®4a); - pci_read_config_byte(dev, 0x54, ®54); - pci_read_config_byte(dev, 0x55, ®55); - - switch(speed) { - case XFER_UDMA_6: - case XFER_UDMA_4: - case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; - case XFER_UDMA_5: - case XFER_UDMA_3: - case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; - case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; - break; - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_SW_DMA_2: - break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - break; - default: - return -1; - } - - if (speed >= XFER_UDMA_0) { - if (!(reg48 & u_flag)) - pci_write_config_byte(dev, 0x48, reg48 | u_flag); - if (speed >= XFER_UDMA_5) { - pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag); - } else { - pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); - } - - if ((reg4a & a_speed) != u_speed) - pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed); - if (speed > XFER_UDMA_2) { - if (!(reg54 & v_flag)) - pci_write_config_byte(dev, 0x54, reg54 | v_flag); - } else - pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); - } else { - if (reg48 & u_flag) - pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); - if (reg4a & a_speed) - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); - if (reg54 & v_flag) - pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); - if (reg55 & w_flag) - pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); - } - it8213_tuneproc(drive, it8213_dma_2_pio(speed)); - return ide_config_drive_speed(drive, speed); -} - -/* - * config_chipset_for_dma - configure for DMA - * @drive: drive to configure - * - * Called by the IDE layer when it wants the timings set up. - */ - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, it8213_ratemask(drive)); - - if (!speed) - return 0; - - it8213_tune_chipset(drive, speed); - - return ide_dma_enable(drive); -} - -/** - * it8213_configure_drive_for_dma - set up for DMA transfers - * @drive: drive we are going to set up - * - * Set up the drive for DMA, tune the controller and drive as - * required. If the drive isn't suitable for DMA or we hit - * other problems then we will drop down to PIO and set up - * PIO appropriately - */ - -static int it8213_config_drive_for_dma (ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - hwif->speedproc(drive, XFER_PIO_0 - + ide_get_best_pio_mode(drive, 255, 4, NULL)); - - return hwif->ide_dma_off_quietly(drive); -} - -/** - * init_hwif_it8213 - set up hwif structs - * @hwif: interface to set up - * - * We do the basic set up of the interface structure. The IT8212 - * requires several custom handlers so we override the default - * ide DMA handlers appropriately - */ - -static void __devinit init_hwif_it8213(ide_hwif_t *hwif) -{ - u8 reg42h = 0, ata66 = 0; - - hwif->speedproc = &it8213_tune_chipset; - hwif->tuneproc = &it8213_tuneproc; - - hwif->autodma = 0; - - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - - if (!hwif->dma_base) - return; - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x06; - hwif->swdma_mask = 0x04; - - pci_read_config_byte(hwif->pci_dev, 0x42, ®42h); - ata66 = (reg42h & 0x02) ? 0 : 1; - - hwif->ide_dma_check = &it8213_config_drive_for_dma; - if (!(hwif->udma_four)) - hwif->udma_four = ata66; - - /* - * The BIOS often doesn't set up DMA on this controller - * so we always do it. - */ - if (!noautodma) - hwif->autodma = 1; - - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - - -#define DECLARE_ITE_DEV(name_str) \ - { \ - .name = name_str, \ - .init_hwif = init_hwif_it8213, \ - .channels = 1, \ - .autodma = AUTODMA, \ - .enablebits = {{0x41,0x80,0x80}}, \ - .bootable = ON_BOARD, \ - } - -static ide_pci_device_t it8213_chipsets[] __devinitdata = { - /* 0 */ DECLARE_ITE_DEV("IT8213"), -}; - - -/** - * it8213_init_one - pci layer discovery entry - * @dev: PCI device - * @id: ident table entry - * - * Called by the PCI code when it finds an ITE8213 controller. As - * this device follows the standard interfaces we can use the - * standard helper functions to do almost all the work for us. - */ - -static int __devinit it8213_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_setup_pci_device(dev, &it8213_chipsets[id->driver_data]); - return 0; -} - - -static struct pci_device_id it8213_pci_tbl[] = { - { PCI_VENDOR_ID_ITE, 0x8213, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { 0, }, -}; - -MODULE_DEVICE_TABLE(pci, it8213_pci_tbl); - -static struct pci_driver driver = { - .name = "ITE8213_IDE", - .id_table = it8213_pci_tbl, - .probe = it8213_init_one, -}; - -static int __init it8213_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(it8213_ide_init); - -MODULE_AUTHOR("Jack Lee, Alan Cox"); -MODULE_DESCRIPTION("PCI driver module for the ITE 8213"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/ide/pci/pdc202xx_new.c b/trunk/drivers/ide/pci/pdc202xx_new.c index 236a03144a27..77a9aaa7dab9 100644 --- a/trunk/drivers/ide/pci/pdc202xx_new.c +++ b/trunk/drivers/ide/pci/pdc202xx_new.c @@ -92,6 +92,26 @@ static u8 pdcnew_ratemask(ide_drive_t *drive) return mode; } +static int check_in_drive_lists(ide_drive_t *drive, const char **list) +{ + struct hd_driveid *id = drive->id; + + if (pdc_quirk_drives == list) { + while (*list) { + if (strstr(id->model, *list++)) { + return 2; + } + } + } else { + while (*list) { + if (!strcmp(*list++,id->model)) { + return 1; + } + } + } + return 0; +} + /** * get_indexed_reg - Get indexed register * @hwif: for the port address @@ -229,6 +249,13 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed) return err; } +/* 0 1 2 3 4 5 6 7 8 + * 960, 480, 390, 300, 240, 180, 120, 90, 60 + * 180, 150, 120, 90, 60 + * DMA_Speed + * 180, 120, 90, 90, 90, 60, 30 + * 11, 5, 4, 3, 2, 1, 0 + */ static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio) { pio = ide_get_best_pio_mode(drive, pio, 4, NULL); @@ -286,10 +313,12 @@ static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) drive->init_speed = 0; - if ((id->capability & 1) && drive->autodma) { + if (id && (id->capability & 1) && drive->autodma) { - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); + if (ide_use_dma(drive)) { + if (config_chipset_for_dma(drive)) + return hwif->ide_dma_on(drive); + } goto fast_ata_pio; @@ -304,12 +333,21 @@ static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) static int pdcnew_quirkproc(ide_drive_t *drive) { - const char **list, *model = drive->id->model; + return check_in_drive_lists(drive, pdc_quirk_drives); +} - for (list = pdc_quirk_drives; *list != NULL; list++) - if (strstr(model, *list) != NULL) - return 2; - return 0; +static int pdcnew_ide_dma_lostirq(ide_drive_t *drive) +{ + if (HWIF(drive)->resetproc != NULL) + HWIF(drive)->resetproc(drive); + return __ide_dma_lostirq(drive); +} + +static int pdcnew_ide_dma_timeout(ide_drive_t *drive) +{ + if (HWIF(drive)->resetproc != NULL) + HWIF(drive)->resetproc(drive); + return __ide_dma_timeout(drive); } static void pdcnew_reset(ide_drive_t *drive) @@ -561,6 +599,8 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->err_stops_fifo = 1; hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; + hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq; + hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout; if (!hwif->udma_four) hwif->udma_four = pdcnew_cable_detect(hwif) ? 0 : 1; diff --git a/trunk/drivers/ide/pci/pdc202xx_old.c b/trunk/drivers/ide/pci/pdc202xx_old.c index 730e8d1ec2f5..143239c093d5 100644 --- a/trunk/drivers/ide/pci/pdc202xx_old.c +++ b/trunk/drivers/ide/pci/pdc202xx_old.c @@ -123,6 +123,26 @@ static u8 pdc202xx_ratemask (ide_drive_t *drive) return mode; } +static int check_in_drive_lists (ide_drive_t *drive, const char **list) +{ + struct hd_driveid *id = drive->id; + + if (pdc_quirk_drives == list) { + while (*list) { + if (strstr(id->model, *list++)) { + return 2; + } + } + } else { + while (*list) { + if (!strcmp(*list++,id->model)) { + return 1; + } + } + } + return 0; +} + static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); @@ -357,12 +377,7 @@ static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive) static int pdc202xx_quirkproc (ide_drive_t *drive) { - const char **list, *model = drive->id->model; - - for (list = pdc_quirk_drives; *list != NULL; list++) - if (strstr(model, *list) != NULL) - return 2; - return 0; + return ((int) check_in_drive_lists(drive, pdc_quirk_drives)); } static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) diff --git a/trunk/drivers/ide/pci/piix.c b/trunk/drivers/ide/pci/piix.c index 52cfc2ac22c1..edb37f3d558d 100644 --- a/trunk/drivers/ide/pci/piix.c +++ b/trunk/drivers/ide/pci/piix.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/piix.c Version 0.46 December 3, 2006 + * linux/drivers/ide/pci/piix.c Version 0.45 May 12, 2006 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick @@ -163,7 +163,7 @@ static u8 piix_ratemask (ide_drive_t *drive) * if the drive cannot see an 80pin cable. */ if (!eighty_ninty_three(drive)) - mode = min_t(u8, mode, 1); + mode = min(mode, (u8)1); return mode; } @@ -216,7 +216,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - int is_slave = drive->dn & 1; + int is_slave = (&hwif->drives[1] == drive); int master_port = hwif->channel ? 0x42 : 0x40; int slave_port = 0x44; unsigned long flags; @@ -225,7 +225,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) static DEFINE_SPINLOCK(tune_lock); int control = 0; - /* ISP RTC */ + /* ISP RTC */ static const u8 timings[][2]= { { 0, 0 }, { 0, 0 }, @@ -233,7 +233,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) { 2, 1 }, { 2, 3 }, }; - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + pio = ide_get_best_pio_mode(drive, pio, 5, NULL); /* * Master vs slave is synchronized above us but the slave register is @@ -243,24 +243,25 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) spin_lock_irqsave(&tune_lock, flags); pci_read_config_word(dev, master_port, &master_data); - if (pio > 1) + if (pio >= 2) control |= 1; /* Programmable timing on */ if (drive->media == ide_disk) control |= 4; /* Prefetch, post write */ - if (pio > 2) + if (pio >= 3) control |= 2; /* IORDY */ if (is_slave) { - master_data |= 0x4000; - master_data &= ~0x0070; + master_data = master_data | 0x4000; if (pio > 1) { /* enable PPE, IE and TIME */ master_data = master_data | (control << 4); + } else { + master_data &= ~0x0070; } pci_read_config_byte(dev, slave_port, &slave_data); slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); } else { - master_data &= ~0x3307; + master_data = master_data & 0xccf8; if (pio > 1) { /* enable PPE, IE and TIME */ master_data = master_data | control; @@ -538,19 +539,13 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = { /* 0 */ DECLARE_PIIX_DEV("PIIXa"), /* 1 */ DECLARE_PIIX_DEV("PIIXb"), - /* 2 */ - { /* - * MPIIX actually has only a single IDE channel mapped to - * the primary or secondary ports depending on the value - * of the bit 14 of the IDETIM register at offset 0x6c - */ + { /* 2 */ .name = "MPIIX", .init_hwif = init_hwif_piix, .channels = 2, .autodma = NODMA, - .enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}}, + .enablebits = {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}}, .bootable = ON_BOARD, - .flags = IDEPCI_FLAG_ISA_PORTS }, /* 3 */ DECLARE_PIIX_DEV("PIIX3"), diff --git a/trunk/drivers/ide/pci/slc90e66.c b/trunk/drivers/ide/pci/slc90e66.c index 2663ddbd9b67..90e79c0844d2 100644 --- a/trunk/drivers/ide/pci/slc90e66.c +++ b/trunk/drivers/ide/pci/slc90e66.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/slc90e66.c Version 0.13 December 30, 2006 + * linux/drivers/ide/pci/slc90e66.c Version 0.12 May 12, 2006 * * Copyright (C) 2000-2002 Andre Hedrick * Copyright (C) 2006 MontaVista Software, Inc. @@ -26,7 +26,7 @@ static u8 slc90e66_ratemask (ide_drive_t *drive) u8 mode = 2; if (!eighty_ninty_three(drive)) - mode = min_t(u8, mode, 1); + mode = min(mode, (u8)1); return mode; } @@ -65,47 +65,36 @@ static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - int is_slave = drive->dn & 1; + int is_slave = (&hwif->drives[1] == drive); int master_port = hwif->channel ? 0x42 : 0x40; int slave_port = 0x44; unsigned long flags; u16 master_data; u8 slave_data; - int control = 0; - /* ISP RTC */ + /* ISP RTC */ static const u8 timings[][2]= { - { 0, 0 }, - { 0, 0 }, - { 1, 0 }, - { 2, 1 }, - { 2, 3 }, }; + { 0, 0 }, + { 0, 0 }, + { 1, 0 }, + { 2, 1 }, + { 2, 3 }, }; - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + pio = ide_get_best_pio_mode(drive, pio, 5, NULL); spin_lock_irqsave(&ide_lock, flags); pci_read_config_word(dev, master_port, &master_data); - - if (pio > 1) - control |= 1; /* Programmable timing on */ - if (drive->media == ide_disk) - control |= 4; /* Prefetch, post write */ - if (pio > 2) - control |= 2; /* IORDY */ if (is_slave) { - master_data |= 0x4000; - master_data &= ~0x0070; - if (pio > 1) { + master_data = master_data | 0x4000; + if (pio > 1) /* enable PPE, IE and TIME */ - master_data = master_data | (control << 4); - } + master_data = master_data | 0x0070; pci_read_config_byte(dev, slave_port, &slave_data); slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); } else { - master_data &= ~0x3307; - if (pio > 1) { + master_data = master_data & 0xccf8; + if (pio > 1) /* enable PPE, IE and TIME */ - master_data = master_data | control; - } + master_data = master_data | 0x0007; master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); } pci_write_config_word(dev, master_port, master_data); @@ -184,7 +173,7 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) drive->init_speed = 0; - if ((id->capability & 1) && drive->autodma) { + if (id && (id->capability & 1) && drive->autodma) { if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive)) return hwif->ide_dma_on(drive); @@ -212,7 +201,7 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) hwif->irq = hwif->channel ? 15 : 14; hwif->speedproc = &slc90e66_tune_chipset; - hwif->tuneproc = &slc90e66_tune_drive; + hwif->tuneproc = &slc90e66_tune_drive; pci_read_config_byte(hwif->pci_dev, 0x47, ®47); @@ -224,16 +213,14 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) hwif->atapi_dma = 1; hwif->ultra_mask = 0x1f; - hwif->mwdma_mask = 0x06; - hwif->swdma_mask = 0x04; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; - if (!hwif->udma_four) { + if (!(hwif->udma_four)) /* bit[0(1)]: 0:80, 1:40 */ hwif->udma_four = (reg47 & mask) ? 0 : 1; - } hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate; - if (!noautodma) hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; diff --git a/trunk/drivers/ide/pci/tc86c001.c b/trunk/drivers/ide/pci/tc86c001.c deleted file mode 100644 index 2ad72bbda342..000000000000 --- a/trunk/drivers/ide/pci/tc86c001.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * drivers/ide/pci/tc86c001.c Version 1.00 Dec 12, 2006 - * - * Copyright (C) 2002 Toshiba Corporation - * Copyright (C) 2005-2006 MontaVista Software, Inc. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include - -static inline u8 tc86c001_ratemask(ide_drive_t *drive) -{ - return eighty_ninty_three(drive) ? 2 : 1; -} - -static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00); - u16 mode, scr = hwif->INW(scr_port); - - speed = ide_rate_filter(tc86c001_ratemask(drive), speed); - - switch (speed) { - case XFER_UDMA_4: mode = 0x00c0; break; - case XFER_UDMA_3: mode = 0x00b0; break; - case XFER_UDMA_2: mode = 0x00a0; break; - case XFER_UDMA_1: mode = 0x0090; break; - case XFER_UDMA_0: mode = 0x0080; break; - case XFER_MW_DMA_2: mode = 0x0070; break; - case XFER_MW_DMA_1: mode = 0x0060; break; - case XFER_MW_DMA_0: mode = 0x0050; break; - case XFER_PIO_4: mode = 0x0400; break; - case XFER_PIO_3: mode = 0x0300; break; - case XFER_PIO_2: mode = 0x0200; break; - case XFER_PIO_1: mode = 0x0100; break; - case XFER_PIO_0: - default: mode = 0x0000; break; - } - - scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f; - scr |= mode; - hwif->OUTW(scr, scr_port); - - return ide_config_drive_speed(drive, speed); -} - -static void tc86c001_tune_drive(ide_drive_t *drive, u8 pio) -{ - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void) tc86c001_tune_chipset(drive, XFER_PIO_0 + pio); -} - -/* - * HACKITY HACK - * - * This is a workaround for the limitation 5 of the TC86C001 IDE controller: - * if a DMA transfer terminates prematurely, the controller leaves the device's - * interrupt request (INTRQ) pending and does not generate a PCI interrupt (or - * set the interrupt bit in the DMA status register), thus no PCI interrupt - * will occur until a DMA transfer has been successfully completed. - * - * We work around this by initiating dummy, zero-length DMA transfer on - * a DMA timeout expiration. I found no better way to do this with the current - * IDE core than to temporarily replace a higher level driver's timer expiry - * handler with our own backing up to that handler in case our recovery fails. - */ -static int tc86c001_timer_expiry(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - ide_expiry_t *expiry = ide_get_hwifdata(hwif); - ide_hwgroup_t *hwgroup = HWGROUP(drive); - u8 dma_stat = hwif->INB(hwif->dma_status); - - /* Restore a higher level driver's expiry handler first. */ - hwgroup->expiry = expiry; - - if ((dma_stat & 5) == 1) { /* DMA active and no interrupt */ - unsigned long sc_base = hwif->config_data; - unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04); - u8 dma_cmd = hwif->INB(hwif->dma_command); - - printk(KERN_WARNING "%s: DMA interrupt possibly stuck, " - "attempting recovery...\n", drive->name); - - /* Stop DMA */ - hwif->OUTB(dma_cmd & ~0x01, hwif->dma_command); - - /* Setup the dummy DMA transfer */ - hwif->OUTW(0, sc_base + 0x0a); /* Sector Count */ - hwif->OUTW(0, twcr_port); /* Transfer Word Count 1 or 2 */ - - /* Start the dummy DMA transfer */ - hwif->OUTB(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */ - hwif->OUTB(0x01, hwif->dma_command); /* set START_STOPBM */ - - /* - * If an interrupt was pending, it should come thru shortly. - * If not, a higher level driver's expiry handler should - * eventually cause some kind of recovery from the DMA stall. - */ - return WAIT_MIN_SLEEP; - } - - /* Chain to the restored expiry handler if DMA wasn't active. */ - if (likely(expiry != NULL)) - return expiry(drive); - - /* If there was no handler, "emulate" that for ide_timer_expiry()... */ - return -1; -} - -static void tc86c001_dma_start(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - ide_hwgroup_t *hwgroup = HWGROUP(drive); - unsigned long sc_base = hwif->config_data; - unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04); - unsigned long nsectors = hwgroup->rq->nr_sectors; - - /* - * We have to manually load the sector count and size into - * the appropriate system control registers for DMA to work - * with LBA48 and ATAPI devices... - */ - hwif->OUTW(nsectors, sc_base + 0x0a); /* Sector Count */ - hwif->OUTW(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */ - - /* Install our timeout expiry hook, saving the current handler... */ - ide_set_hwifdata(hwif, hwgroup->expiry); - hwgroup->expiry = &tc86c001_timer_expiry; - - ide_dma_start(drive); -} - -static int tc86c001_busproc(ide_drive_t *drive, int state) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned long sc_base = hwif->config_data; - u16 scr1; - - /* System Control 1 Register bit 11 (ATA Hard Reset) read */ - scr1 = hwif->INW(sc_base + 0x00); - - switch (state) { - case BUSSTATE_ON: - if (!(scr1 & 0x0800)) - return 0; - scr1 &= ~0x0800; - - hwif->drives[0].failures = hwif->drives[1].failures = 0; - break; - case BUSSTATE_OFF: - if (scr1 & 0x0800) - return 0; - scr1 |= 0x0800; - - hwif->drives[0].failures = hwif->drives[0].max_failures + 1; - hwif->drives[1].failures = hwif->drives[1].max_failures + 1; - break; - default: - return -EINVAL; - } - - /* System Control 1 Register bit 11 (ATA Hard Reset) write */ - hwif->OUTW(scr1, sc_base + 0x00); - return 0; -} - -static int config_chipset_for_dma(ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, tc86c001_ratemask(drive)); - - if (!speed) - return 0; - - (void) tc86c001_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - tc86c001_tune_drive(drive, 255); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) -{ - unsigned long sc_base = pci_resource_start(hwif->pci_dev, 5); - u16 scr1 = hwif->INW(sc_base + 0x00);; - - /* System Control 1 Register bit 15 (Soft Reset) set */ - hwif->OUTW(scr1 | 0x8000, sc_base + 0x00); - - /* System Control 1 Register bit 14 (FIFO Reset) set */ - hwif->OUTW(scr1 | 0x4000, sc_base + 0x00); - - /* System Control 1 Register: reset clear */ - hwif->OUTW(scr1 & ~0xc000, sc_base + 0x00); - - /* Store the system control register base for convenience... */ - hwif->config_data = sc_base; - - hwif->tuneproc = &tc86c001_tune_drive; - hwif->speedproc = &tc86c001_tune_chipset; - hwif->busproc = &tc86c001_busproc; - - hwif->drives[0].autotune = hwif->drives[1].autotune = 1; - - if (!hwif->dma_base) - return; - - /* - * Sector Count Control Register bits 0 and 1 set: - * software sets Sector Count Register for master and slave device - */ - hwif->OUTW(0x0003, sc_base + 0x0c); - - /* Sector Count Register limit */ - hwif->rqsize = 0xffff; - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x1f; - hwif->mwdma_mask = 0x07; - - hwif->ide_dma_check = &tc86c001_config_drive_xfer_rate; - hwif->dma_start = &tc86c001_dma_start; - - if (!hwif->udma_four) { - /* - * System Control 1 Register bit 13 (PDIAGN): - * 0=80-pin cable, 1=40-pin cable - */ - scr1 = hwif->INW(sc_base + 0x00); - hwif->udma_four = (scr1 & 0x2000) ? 0 : 1; - } - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; -} - -static unsigned int __devinit init_chipset_tc86c001(struct pci_dev *dev, - const char *name) -{ - int err = pci_request_region(dev, 5, name); - - if (err) - printk(KERN_ERR "%s: system control regs already in use", name); - return err; -} - -static ide_pci_device_t tc86c001_chipset __devinitdata = { - .name = "TC86C001", - .init_chipset = init_chipset_tc86c001, - .init_hwif = init_hwif_tc86c001, - .channels = 1, - .autodma = AUTODMA, - .bootable = OFF_BOARD -}; - -static int __devinit tc86c001_init_one(struct pci_dev *dev, - const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &tc86c001_chipset); -} - -static struct pci_device_id tc86c001_pci_tbl[] = { - { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, tc86c001_pci_tbl); - -static struct pci_driver driver = { - .name = "TC86C001", - .id_table = tc86c001_pci_tbl, - .probe = tc86c001_init_one -}; - -static int __init tc86c001_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} -module_init(tc86c001_ide_init); - -MODULE_AUTHOR("MontaVista Software, Inc. "); -MODULE_DESCRIPTION("PCI driver module for TC86C001 IDE"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/ide/setup-pci.c b/trunk/drivers/ide/setup-pci.c index a52c80fe7d3e..695e23904d30 100644 --- a/trunk/drivers/ide/setup-pci.c +++ b/trunk/drivers/ide/setup-pci.c @@ -783,11 +783,10 @@ static LIST_HEAD(ide_pci_drivers); * Returns are the same as for pci_register_driver */ -int __ide_pci_register_driver(struct pci_driver *driver, struct module *module, - const char *mod_name) +int __ide_pci_register_driver(struct pci_driver *driver, struct module *module) { if(!pre_init) - return __pci_register_driver(driver, module, mod_name); + return __pci_register_driver(driver, module); driver->driver.owner = module; list_add_tail(&driver->node, &ide_pci_drivers); return 0; @@ -863,6 +862,6 @@ void __init ide_scan_pcibus (int scan_direction) { list_del(l); d = list_entry(l, struct pci_driver, node); - __pci_register_driver(d, d->driver.owner, d->driver.mod_name); + __pci_register_driver(d, d->driver.owner); } } diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c index af5ee2ec4499..705eb1d0e554 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -958,17 +958,16 @@ struct ipoib_dev_priv *ipoib_intf_alloc(const char *name) return netdev_priv(dev); } -static ssize_t show_pkey(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_pkey(struct class_device *cdev, char *buf) { - struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev)); + struct ipoib_dev_priv *priv = + netdev_priv(container_of(cdev, struct net_device, class_dev)); return sprintf(buf, "0x%04x\n", priv->pkey); } -static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); +static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); -static ssize_t create_child(struct device *dev, - struct device_attribute *attr, +static ssize_t create_child(struct class_device *cdev, const char *buf, size_t count) { int pkey; @@ -986,14 +985,14 @@ static ssize_t create_child(struct device *dev, */ pkey |= 0x8000; - ret = ipoib_vlan_add(to_net_dev(dev), pkey); + ret = ipoib_vlan_add(container_of(cdev, struct net_device, class_dev), + pkey); return ret ? ret : count; } -static DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child); +static CLASS_DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child); -static ssize_t delete_child(struct device *dev, - struct device_attribute *attr, +static ssize_t delete_child(struct class_device *cdev, const char *buf, size_t count) { int pkey; @@ -1005,16 +1004,18 @@ static ssize_t delete_child(struct device *dev, if (pkey < 0 || pkey > 0xffff) return -EINVAL; - ret = ipoib_vlan_delete(to_net_dev(dev), pkey); + ret = ipoib_vlan_delete(container_of(cdev, struct net_device, class_dev), + pkey); return ret ? ret : count; } -static DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child); +static CLASS_DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child); int ipoib_add_pkey_attr(struct net_device *dev) { - return device_create_file(&dev->dev, &dev_attr_pkey); + return class_device_create_file(&dev->class_dev, + &class_device_attr_pkey); } static struct net_device *ipoib_add_port(const char *format, @@ -1082,9 +1083,11 @@ static struct net_device *ipoib_add_port(const char *format, if (ipoib_add_pkey_attr(priv->dev)) goto sysfs_failed; - if (device_create_file(&priv->dev->dev, &dev_attr_create_child)) + if (class_device_create_file(&priv->dev->class_dev, + &class_device_attr_create_child)) goto sysfs_failed; - if (device_create_file(&priv->dev->dev, &dev_attr_delete_child)) + if (class_device_create_file(&priv->dev->class_dev, + &class_device_attr_delete_child)) goto sysfs_failed; return priv->dev; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 085eafe6667c..f887780e8093 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -42,15 +42,15 @@ #include "ipoib.h" -static ssize_t show_parent(struct device *d, struct device_attribute *attr, - char *buf) +static ssize_t show_parent(struct class_device *class_dev, char *buf) { - struct net_device *dev = to_net_dev(d); + struct net_device *dev = + container_of(class_dev, struct net_device, class_dev); struct ipoib_dev_priv *priv = netdev_priv(dev); return sprintf(buf, "%s\n", priv->parent->name); } -static DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL); +static CLASS_DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL); int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) { @@ -118,7 +118,8 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) if (ipoib_add_pkey_attr(priv->dev)) goto sysfs_failed; - if (device_create_file(&priv->dev->dev, &dev_attr_parent)) + if (class_device_create_file(&priv->dev->class_dev, + &class_device_attr_parent)) goto sysfs_failed; list_add_tail(&priv->list, &ppriv->child_intfs); diff --git a/trunk/drivers/input/serio/serio.c b/trunk/drivers/input/serio/serio.c index 17c8c63cbe1a..f0ce822c1028 100644 --- a/trunk/drivers/input/serio/serio.c +++ b/trunk/drivers/input/serio/serio.c @@ -45,7 +45,7 @@ EXPORT_SYMBOL(serio_interrupt); EXPORT_SYMBOL(__serio_register_port); EXPORT_SYMBOL(serio_unregister_port); EXPORT_SYMBOL(serio_unregister_child_port); -EXPORT_SYMBOL(__serio_register_driver); +EXPORT_SYMBOL(serio_register_driver); EXPORT_SYMBOL(serio_unregister_driver); EXPORT_SYMBOL(serio_open); EXPORT_SYMBOL(serio_close); @@ -789,14 +789,12 @@ static void serio_attach_driver(struct serio_driver *drv) drv->driver.name, error); } -int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) +int serio_register_driver(struct serio_driver *drv) { int manual_bind = drv->manual_bind; int error; drv->driver.bus = &serio_bus; - drv->driver.owner = owner; - drv->driver.mod_name = mod_name; /* * Temporarily disable automatic binding because probing diff --git a/trunk/drivers/macintosh/windfarm_core.c b/trunk/drivers/macintosh/windfarm_core.c index 94c117ef20c1..e947af982f93 100644 --- a/trunk/drivers/macintosh/windfarm_core.c +++ b/trunk/drivers/macintosh/windfarm_core.c @@ -94,6 +94,8 @@ static int wf_thread_func(void *data) DBG("wf: thread started\n"); while(!kthread_should_stop()) { + try_to_freeze(); + if (time_after_eq(jiffies, next)) { wf_notify(WF_EVENT_TICK, NULL); if (wf_overtemp) { @@ -116,8 +118,8 @@ static int wf_thread_func(void *data) if (delay <= HZ) schedule_timeout_interruptible(delay); - /* there should be no non-suspend signal, but oh well */ - if (signal_pending(current) && !try_to_freeze()) { + /* there should be no signal, but oh well */ + if (signal_pending(current)) { printk(KERN_WARNING "windfarm: thread got sigl !\n"); break; } diff --git a/trunk/drivers/media/video/zc0301/zc0301_sensor.h b/trunk/drivers/media/video/zc0301/zc0301_sensor.h index 3daf049a288a..4363a915b1f4 100644 --- a/trunk/drivers/media/video/zc0301/zc0301_sensor.h +++ b/trunk/drivers/media/video/zc0301/zc0301_sensor.h @@ -75,6 +75,7 @@ static const struct usb_device_id zc0301_id_table[] = { \ { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ { ZC0301_USB_DEVICE(0x055f, 0xd003, 0xff), }, /* TAS5130 */ \ { ZC0301_USB_DEVICE(0x055f, 0xd004, 0xff), }, /* TAS5130 */ \ + { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ { ZC0301_USB_DEVICE(0x0ac8, 0x301b, 0xff), }, /* PB-0330/HV7131 */ \ { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \ diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index 89bba277da5f..00db31c314e0 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -69,25 +69,6 @@ config TIFM_7XX1 To compile this driver as a module, choose M here: the module will be called tifm_7xx1. -config ASUS_LAPTOP - tristate "Asus Laptop Extras (EXPERIMENTAL)" - depends on X86 - depends on ACPI - depends on EXPERIMENTAL && !ACPI_ASUS - depends on LEDS_CLASS - depends on BACKLIGHT_CLASS_DEVICE - ---help--- - This is the new Linux driver for Asus laptops. It may also support some - MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate - standard ACPI events that go through /proc/acpi/events. It also adds - support for video output switching, LCD backlight control, Bluetooth and - Wlan control, and most importantly, allows you to blink those fancy LEDs. - - For more information and a userspace daemon for handling the extra - buttons see . - - If you have an ACPI-compatible ASUS laptop, say Y or M here. - config MSI_LAPTOP tristate "MSI Laptop Extras" depends on X86 diff --git a/trunk/drivers/misc/Makefile b/trunk/drivers/misc/Makefile index 35da53c409c0..c9e98ab021c5 100644 --- a/trunk/drivers/misc/Makefile +++ b/trunk/drivers/misc/Makefile @@ -6,7 +6,6 @@ obj- := misc.o # Dummy rule to force built-in.o to be made obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o -obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o diff --git a/trunk/drivers/misc/asus-laptop.c b/trunk/drivers/misc/asus-laptop.c deleted file mode 100644 index 861c39935f99..000000000000 --- a/trunk/drivers/misc/asus-laptop.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * asus-laptop.c - Asus Laptop Support - * - * - * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor - * Copyright (C) 2006 Corentin Chary - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * The development page for this driver is located at - * http://sourceforge.net/projects/acpi4asus/ - * - * Credits: - * Pontus Fuchs - Helper functions, cleanup - * Johann Wiesner - Small compile fixes - * John Belmonte - ACPI code for Toshiba laptop was a good starting point. - * Eric Burghard - LED display support for W1N - * Josh Green - Light Sens support - * Thomas Tuttle - His first patch for led support was very helpfull - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ASUS_LAPTOP_VERSION "0.40" - -#define ASUS_HOTK_NAME "Asus Laptop Support" -#define ASUS_HOTK_CLASS "hotkey" -#define ASUS_HOTK_DEVICE_NAME "Hotkey" -#define ASUS_HOTK_HID "ATK0100" -#define ASUS_HOTK_FILE "asus-laptop" -#define ASUS_HOTK_PREFIX "\\_SB.ATKD." - -/* - * Some events we use, same for all Asus - */ -#define ATKD_BR_UP 0x10 -#define ATKD_BR_DOWN 0x20 -#define ATKD_LCD_ON 0x33 -#define ATKD_LCD_OFF 0x34 - -/* - * Known bits returned by \_SB.ATKD.HWRS - */ -#define WL_HWRS 0x80 -#define BT_HWRS 0x100 - -/* - * Flags for hotk status - * WL_ON and BT_ON are also used for wireless_status() - */ -#define WL_ON 0x01 //internal Wifi -#define BT_ON 0x02 //internal Bluetooth -#define MLED_ON 0x04 //mail LED -#define TLED_ON 0x08 //touchpad LED -#define RLED_ON 0x10 //Record LED -#define PLED_ON 0x20 //Phone LED -#define LCD_ON 0x40 //LCD backlight - -#define ASUS_LOG ASUS_HOTK_FILE ": " -#define ASUS_ERR KERN_ERR ASUS_LOG -#define ASUS_WARNING KERN_WARNING ASUS_LOG -#define ASUS_NOTICE KERN_NOTICE ASUS_LOG -#define ASUS_INFO KERN_INFO ASUS_LOG -#define ASUS_DEBUG KERN_DEBUG ASUS_LOG - -MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary"); -MODULE_DESCRIPTION(ASUS_HOTK_NAME); -MODULE_LICENSE("GPL"); - -#define ASUS_HANDLE(object, paths...) \ - static acpi_handle object##_handle = NULL; \ - static char *object##_paths[] = { paths } - -/* LED */ -ASUS_HANDLE(mled_set, ASUS_HOTK_PREFIX "MLED"); -ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED"); -ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED"); /* W1JC */ -ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED"); /* A7J */ - -/* LEDD */ -ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM"); - -/* Bluetooth and WLAN - * WLED and BLED are not handled like other XLED, because in some dsdt - * they also control the WLAN/Bluetooth device. - */ -ASUS_HANDLE(wl_switch, ASUS_HOTK_PREFIX "WLED"); -ASUS_HANDLE(bt_switch, ASUS_HOTK_PREFIX "BLED"); -ASUS_HANDLE(wireless_status, ASUS_HOTK_PREFIX "RSTS"); /* All new models */ - -/* Brightness */ -ASUS_HANDLE(brightness_set, ASUS_HOTK_PREFIX "SPLV"); -ASUS_HANDLE(brightness_get, ASUS_HOTK_PREFIX "GPLV"); - -/* Backlight */ -ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ - "\\_SB.PCI0.ISA.EC0._Q10", /* A1x */ - "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */ - "\\_SB.PCI0.PX40.EC0.Q10", /* M1A */ - "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */ - "\\_SB.PCI0.PX40.Q10", /* S1x */ - "\\Q10"); /* A2x, L2D, L3D, M2E */ - -/* Display */ -ASUS_HANDLE(display_set, ASUS_HOTK_PREFIX "SDSP"); -ASUS_HANDLE(display_get, "\\_SB.PCI0.P0P1.VGA.GETD", /* A6B, A6K A6R A7D F3JM L4R M6R A3G - M6A M6V VX-1 V6J V6V W3Z */ - "\\_SB.PCI0.P0P2.VGA.GETD", /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V - S5A M5A z33A W1Jc W2V */ - "\\_SB.PCI0.P0P3.VGA.GETD", /* A6V A6Q */ - "\\_SB.PCI0.P0PA.VGA.GETD", /* A6T, A6M */ - "\\_SB.PCI0.PCI1.VGAC.NMAP", /* L3C */ - "\\_SB.PCI0.VGA.GETD", /* Z96F */ - "\\ACTD", /* A2D */ - "\\ADVG", /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */ - "\\DNXT", /* P30 */ - "\\INFB", /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */ - "\\SSTE"); /* A3F A6F A3N A3L M6N W3N W6A */ - -ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */ -ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL"); /* Z71A Z71V */ - -/* - * This is the main structure, we can use it to store anything interesting - * about the hotk device - */ -struct asus_hotk { - char *name; //laptop name - struct acpi_device *device; //the device we are in - acpi_handle handle; //the handle of the hotk device - char status; //status of the hotk, for LEDs, ... - u32 ledd_status; //status of the LED display - u8 light_level; //light sensor level - u8 light_switch; //light sensor switch value - u16 event_count[128]; //count for each event TODO make this better -}; - -/* - * This header is made available to allow proper configuration given model, - * revision number , ... this info cannot go in struct asus_hotk because it is - * available before the hotk - */ -static struct acpi_table_header *asus_info; - -/* The actual device the driver binds to */ -static struct asus_hotk *hotk; - -/* - * The hotkey driver declaration - */ -static int asus_hotk_add(struct acpi_device *device); -static int asus_hotk_remove(struct acpi_device *device, int type); -static struct acpi_driver asus_hotk_driver = { - .name = ASUS_HOTK_NAME, - .class = ASUS_HOTK_CLASS, - .ids = ASUS_HOTK_HID, - .ops = { - .add = asus_hotk_add, - .remove = asus_hotk_remove, - }, -}; - -/* The backlight device /sys/class/backlight */ -static struct backlight_device *asus_backlight_device; - -/* - * The backlight class declaration - */ -static int read_brightness(struct backlight_device *bd); -static int update_bl_status(struct backlight_device *bd); -static struct backlight_properties asusbl_data = { - .owner = THIS_MODULE, - .get_brightness = read_brightness, - .update_status = update_bl_status, - .max_brightness = 15, -}; - -/* These functions actually update the LED's, and are called from a - * workqueue. By doing this as separate work rather than when the LED - * subsystem asks, we avoid messing with the Asus ACPI stuff during a - * potentially bad time, such as a timer interrupt. */ -static struct workqueue_struct *led_workqueue; - -#define ASUS_LED(object, ledname) \ - static void object##_led_set(struct led_classdev *led_cdev, \ - enum led_brightness value); \ - static void object##_led_update(struct work_struct *ignored); \ - static int object##_led_wk; \ - DECLARE_WORK(object##_led_work, object##_led_update); \ - static struct led_classdev object##_led = { \ - .name = "asus:" ledname, \ - .brightness_set = object##_led_set, \ - } - -ASUS_LED(mled, "mail"); -ASUS_LED(tled, "touchpad"); -ASUS_LED(rled, "record"); -ASUS_LED(pled, "phone"); - -/* - * This function evaluates an ACPI method, given an int as parameter, the - * method is searched within the scope of the handle, can be NULL. The output - * of the method is written is output, which can also be NULL - * - * returns 1 if write is successful, 0 else. - */ -static int write_acpi_int(acpi_handle handle, const char *method, int val, - struct acpi_buffer *output) -{ - struct acpi_object_list params; //list of input parameters (an int here) - union acpi_object in_obj; //the only param we use - acpi_status status; - - params.count = 1; - params.pointer = &in_obj; - in_obj.type = ACPI_TYPE_INTEGER; - in_obj.integer.value = val; - - status = acpi_evaluate_object(handle, (char *)method, ¶ms, output); - return (status == AE_OK); -} - -static int read_acpi_int(acpi_handle handle, const char *method, int *val, - struct acpi_object_list *params) -{ - struct acpi_buffer output; - union acpi_object out_obj; - acpi_status status; - - output.length = sizeof(out_obj); - output.pointer = &out_obj; - - status = acpi_evaluate_object(handle, (char *)method, params, &output); - *val = out_obj.integer.value; - return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER); -} - -static int read_wireless_status(int mask) -{ - int status; - - if (!wireless_status_handle) - return (hotk->status & mask) ? 1 : 0; - - if (read_acpi_int(wireless_status_handle, NULL, &status, NULL)) { - return (status & mask) ? 1 : 0; - } else - printk(ASUS_WARNING "Error reading Wireless status\n"); - - return (hotk->status & mask) ? 1 : 0; -} - -/* Generic LED functions */ -static int read_status(int mask) -{ - /* There is a special method for both wireless devices */ - if (mask == BT_ON || mask == WL_ON) - return read_wireless_status(mask); - - return (hotk->status & mask) ? 1 : 0; -} - -static void write_status(acpi_handle handle, int out, int mask, int invert) -{ - hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask); - - if (invert) /* invert target value */ - out = !out & 0x1; - - if (handle && !write_acpi_int(handle, NULL, out, NULL)) - printk(ASUS_WARNING " write failed\n"); -} - -/* /sys/class/led handlers */ -#define ASUS_LED_HANDLER(object, mask, invert) \ - static void object##_led_set(struct led_classdev *led_cdev, \ - enum led_brightness value) \ - { \ - object##_led_wk = value; \ - queue_work(led_workqueue, &object##_led_work); \ - } \ - static void object##_led_update(struct work_struct *ignored) \ - { \ - int value = object##_led_wk; \ - write_status(object##_set_handle, value, (mask), (invert)); \ - } - -ASUS_LED_HANDLER(mled, MLED_ON, 1); -ASUS_LED_HANDLER(pled, PLED_ON, 0); -ASUS_LED_HANDLER(rled, RLED_ON, 0); -ASUS_LED_HANDLER(tled, TLED_ON, 0); - -static int get_lcd_state(void) -{ - return read_status(LCD_ON); -} - -static int set_lcd_state(int value) -{ - int lcd = 0; - acpi_status status = 0; - - lcd = value ? 1 : 0; - - if (lcd == get_lcd_state()) - return 0; - - if (lcd_switch_handle) { - status = acpi_evaluate_object(lcd_switch_handle, - NULL, NULL, NULL); - - if (ACPI_FAILURE(status)) - printk(ASUS_WARNING "Error switching LCD\n"); - } - - write_status(NULL, lcd, LCD_ON, 0); - return 0; -} - -static void lcd_blank(int blank) -{ - struct backlight_device *bd = asus_backlight_device; - - if (bd) { - down(&bd->sem); - if (likely(bd->props)) { - bd->props->power = blank; - if (likely(bd->props->update_status)) - bd->props->update_status(bd); - } - up(&bd->sem); - } -} - -static int read_brightness(struct backlight_device *bd) -{ - int value; - - if (!read_acpi_int(brightness_get_handle, NULL, &value, NULL)) - printk(ASUS_WARNING "Error reading brightness\n"); - - return value; -} - -static int set_brightness(struct backlight_device *bd, int value) -{ - int ret = 0; - - value = (0 < value) ? ((15 < value) ? 15 : value) : 0; - /* 0 <= value <= 15 */ - - if (!write_acpi_int(brightness_set_handle, NULL, value, NULL)) { - printk(ASUS_WARNING "Error changing brightness\n"); - ret = -EIO; - } - - return ret; -} - -static int update_bl_status(struct backlight_device *bd) -{ - int rv; - int value = bd->props->brightness; - - rv = set_brightness(bd, value); - if (rv) - return rv; - - value = (bd->props->power == FB_BLANK_UNBLANK) ? 1 : 0; - return set_lcd_state(value); -} - -/* - * Platform device handlers - */ - -/* - * We write our info in page, we begin at offset off and cannot write more - * than count bytes. We set eof to 1 if we handle those 2 values. We return the - * number of bytes written in page - */ -static ssize_t show_infos(struct device *dev, - struct device_attribute *attr, char *page) -{ - int len = 0; - int temp; - char buf[16]; //enough for all info - /* - * We use the easy way, we don't care of off and count, so we don't set eof - * to 1 - */ - - len += sprintf(page, ASUS_HOTK_NAME " " ASUS_LAPTOP_VERSION "\n"); - len += sprintf(page + len, "Model reference : %s\n", hotk->name); - /* - * The SFUN method probably allows the original driver to get the list - * of features supported by a given model. For now, 0x0100 or 0x0800 - * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card. - * The significance of others is yet to be found. - */ - if (read_acpi_int(hotk->handle, "SFUN", &temp, NULL)) - len += - sprintf(page + len, "SFUN value : 0x%04x\n", temp); - /* - * Another value for userspace: the ASYM method returns 0x02 for - * battery low and 0x04 for battery critical, its readings tend to be - * more accurate than those provided by _BST. - * Note: since not all the laptops provide this method, errors are - * silently ignored. - */ - if (read_acpi_int(hotk->handle, "ASYM", &temp, NULL)) - len += - sprintf(page + len, "ASYM value : 0x%04x\n", temp); - if (asus_info) { - snprintf(buf, 16, "%d", asus_info->length); - len += sprintf(page + len, "DSDT length : %s\n", buf); - snprintf(buf, 16, "%d", asus_info->checksum); - 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 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 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); - snprintf(buf, 16, "%x", asus_info->asl_compiler_revision); - len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf); - } - - return len; -} - -static int parse_arg(const char *buf, unsigned long count, int *val) -{ - if (!count) - return 0; - if (count > 31) - return -EINVAL; - if (sscanf(buf, "%i", val) != 1) - return -EINVAL; - return count; -} - -static ssize_t store_status(const char *buf, size_t count, - acpi_handle handle, int mask, int invert) -{ - int rv, value; - int out = 0; - - rv = parse_arg(buf, count, &value); - if (rv > 0) - out = value ? 1 : 0; - - write_status(handle, out, mask, invert); - - return rv; -} - -/* - * LEDD display - */ -static ssize_t show_ledd(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "0x%08x\n", hotk->ledd_status); -} - -static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int rv, value; - - rv = parse_arg(buf, count, &value); - if (rv > 0) { - if (!write_acpi_int(ledd_set_handle, NULL, value, NULL)) - printk(ASUS_WARNING "LED display write failed\n"); - else - hotk->ledd_status = (u32) value; - } - return rv; -} - -/* - * WLAN - */ -static ssize_t show_wlan(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", read_status(WL_ON)); -} - -static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - return store_status(buf, count, wl_switch_handle, WL_ON, 0); -} - -/* - * Bluetooth - */ -static ssize_t show_bluetooth(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", read_status(BT_ON)); -} - -static ssize_t store_bluetooth(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - return store_status(buf, count, bt_switch_handle, BT_ON, 0); -} - -/* - * Display - */ -static void set_display(int value) -{ - /* no sanity check needed for now */ - if (!write_acpi_int(display_set_handle, NULL, value, NULL)) - printk(ASUS_WARNING "Error setting display\n"); - return; -} - -static int read_display(void) -{ - int value = 0; - - /* In most of the case, we know how to set the display, but sometime - we can't read it */ - if (display_get_handle) { - if (!read_acpi_int(display_get_handle, NULL, &value, NULL)) - printk(ASUS_WARNING "Error reading display status\n"); - } - - value &= 0x0F; /* needed for some models, shouldn't hurt others */ - - return value; -} - -/* - * Now, *this* one could be more user-friendly, but so far, no-one has - * complained. The significance of bits is the same as in store_disp() - */ -static ssize_t show_disp(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", read_display()); -} - -/* - * Experimental support for display switching. As of now: 1 should activate - * the LCD output, 2 should do for CRT, 4 for TV-Out and 8 for DVI. - * Any combination (bitwise) of these will suffice. I never actually tested 4 - * displays hooked up simultaneously, so be warned. See the acpi4asus README - * for more info. - */ -static ssize_t store_disp(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int rv, value; - - rv = parse_arg(buf, count, &value); - if (rv > 0) - set_display(value); - return rv; -} - -/* - * Light Sens - */ -static void set_light_sens_switch(int value) -{ - if (!write_acpi_int(ls_switch_handle, NULL, value, NULL)) - printk(ASUS_WARNING "Error setting light sensor switch\n"); - hotk->light_switch = value; -} - -static ssize_t show_lssw(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", hotk->light_switch); -} - -static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int rv, value; - - rv = parse_arg(buf, count, &value); - if (rv > 0) - set_light_sens_switch(value ? 1 : 0); - - return rv; -} - -static void set_light_sens_level(int value) -{ - if (!write_acpi_int(ls_level_handle, NULL, value, NULL)) - printk(ASUS_WARNING "Error setting light sensor level\n"); - hotk->light_level = value; -} - -static ssize_t show_lslvl(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", hotk->light_level); -} - -static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int rv, value; - - rv = parse_arg(buf, count, &value); - if (rv > 0) { - value = (0 < value) ? ((15 < value) ? 15 : value) : 0; - /* 0 <= value <= 15 */ - set_light_sens_level(value); - } - - return rv; -} - -static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) -{ - /* TODO Find a better way to handle events count. */ - if (!hotk) - return; - - /* - * We need to tell the backlight device when the backlight power is - * switched - */ - if (event == ATKD_LCD_ON) { - write_status(NULL, 1, LCD_ON, 0); - lcd_blank(FB_BLANK_UNBLANK); - } else if (event == ATKD_LCD_OFF) { - write_status(NULL, 0, LCD_ON, 0); - lcd_blank(FB_BLANK_POWERDOWN); - } - - acpi_bus_generate_event(hotk->device, event, - hotk->event_count[event % 128]++); - - return; -} - -#define ASUS_CREATE_DEVICE_ATTR(_name) \ - struct device_attribute dev_attr_##_name = { \ - .attr = { \ - .name = __stringify(_name), \ - .mode = 0, \ - .owner = THIS_MODULE }, \ - .show = NULL, \ - .store = NULL, \ - } - -#define ASUS_SET_DEVICE_ATTR(_name, _mode, _show, _store) \ - do { \ - dev_attr_##_name.attr.mode = _mode; \ - dev_attr_##_name.show = _show; \ - dev_attr_##_name.store = _store; \ - } while(0) - -static ASUS_CREATE_DEVICE_ATTR(infos); -static ASUS_CREATE_DEVICE_ATTR(wlan); -static ASUS_CREATE_DEVICE_ATTR(bluetooth); -static ASUS_CREATE_DEVICE_ATTR(display); -static ASUS_CREATE_DEVICE_ATTR(ledd); -static ASUS_CREATE_DEVICE_ATTR(ls_switch); -static ASUS_CREATE_DEVICE_ATTR(ls_level); - -static struct attribute *asuspf_attributes[] = { - &dev_attr_infos.attr, - &dev_attr_wlan.attr, - &dev_attr_bluetooth.attr, - &dev_attr_display.attr, - &dev_attr_ledd.attr, - &dev_attr_ls_switch.attr, - &dev_attr_ls_level.attr, - NULL -}; - -static struct attribute_group asuspf_attribute_group = { - .attrs = asuspf_attributes -}; - -static struct platform_driver asuspf_driver = { - .driver = { - .name = ASUS_HOTK_FILE, - .owner = THIS_MODULE, - } -}; - -static struct platform_device *asuspf_device; - -static void asus_hotk_add_fs(void) -{ - ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL); - - if (wl_switch_handle) - ASUS_SET_DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan); - - if (bt_switch_handle) - ASUS_SET_DEVICE_ATTR(bluetooth, 0644, - show_bluetooth, store_bluetooth); - - if (display_set_handle && display_get_handle) - ASUS_SET_DEVICE_ATTR(display, 0644, show_disp, store_disp); - else if (display_set_handle) - ASUS_SET_DEVICE_ATTR(display, 0200, NULL, store_disp); - - if (ledd_set_handle) - ASUS_SET_DEVICE_ATTR(ledd, 0644, show_ledd, store_ledd); - - if (ls_switch_handle && ls_level_handle) { - ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl); - ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw); - } -} - -static int asus_handle_init(char *name, acpi_handle * handle, - char **paths, int num_paths) -{ - int i; - acpi_status status; - - for (i = 0; i < num_paths; i++) { - status = acpi_get_handle(NULL, paths[i], handle); - if (ACPI_SUCCESS(status)) - return 0; - } - - *handle = NULL; - return -ENODEV; -} - -#define ASUS_HANDLE_INIT(object) \ - asus_handle_init(#object, &object##_handle, object##_paths, \ - ARRAY_SIZE(object##_paths)) - -/* - * 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(void) -{ - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *model = NULL; - int bsts_result, hwrs_result; - char *string = NULL; - acpi_status status; - - /* - * 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_SIG_DSDT, 1, &asus_info); - if (ACPI_FAILURE(status)) - printk(ASUS_WARNING "Couldn't get the DSDT table header\n"); - - /* We have to write 0 on init this far for all ASUS models */ - if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { - printk(ASUS_ERR "Hotkey initialization failed\n"); - return -ENODEV; - } - - /* This needs to be called for some laptops to init properly */ - if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result, NULL)) - printk(ASUS_WARNING "Error calling BSTS\n"); - else if (bsts_result) - printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n", - bsts_result); - - /* - * Try to match the object returned by INIT to the specific model. - * Handle every possible object (or the lack of thereof) the DSDT - * writers might throw at us. When in trouble, we pass NULL to - * asus_model_match() and try something completely different. - */ - if (buffer.pointer) { - model = buffer.pointer; - switch (model->type) { - case ACPI_TYPE_STRING: - string = model->string.pointer; - break; - case ACPI_TYPE_BUFFER: - string = model->buffer.pointer; - break; - default: - string = ""; - break; - } - } - hotk->name = kstrdup(string, GFP_KERNEL); - if (!hotk->name) - return -ENOMEM; - - if (*string) - printk(ASUS_NOTICE " %s model detected\n", string); - - ASUS_HANDLE_INIT(mled_set); - ASUS_HANDLE_INIT(tled_set); - ASUS_HANDLE_INIT(rled_set); - ASUS_HANDLE_INIT(pled_set); - - ASUS_HANDLE_INIT(ledd_set); - - /* - * The HWRS method return informations about the hardware. - * 0x80 bit is for WLAN, 0x100 for Bluetooth. - * The significance of others is yet to be found. - * If we don't find the method, we assume the device are present. - */ - if (!read_acpi_int(hotk->handle, "HRWS", &hwrs_result, NULL)) - hwrs_result = WL_HWRS | BT_HWRS; - - if (hwrs_result & WL_HWRS) - ASUS_HANDLE_INIT(wl_switch); - if (hwrs_result & BT_HWRS) - ASUS_HANDLE_INIT(bt_switch); - - ASUS_HANDLE_INIT(wireless_status); - - ASUS_HANDLE_INIT(brightness_set); - ASUS_HANDLE_INIT(brightness_get); - - ASUS_HANDLE_INIT(lcd_switch); - - ASUS_HANDLE_INIT(display_set); - ASUS_HANDLE_INIT(display_get); - - /* There is a lot of models with "ALSL", but a few get - a real light sens, so we need to check it. */ - if (ASUS_HANDLE_INIT(ls_switch)) - ASUS_HANDLE_INIT(ls_level); - - kfree(model); - - return AE_OK; -} - -static int asus_hotk_check(void) -{ - int result = 0; - - result = acpi_bus_get_status(hotk->device); - if (result) - return result; - - if (hotk->device->status.present) { - result = asus_hotk_get_info(); - } else { - printk(ASUS_ERR "Hotkey device not present, aborting\n"); - return -EINVAL; - } - - return result; -} - -static int asus_hotk_found; - -static int asus_hotk_add(struct acpi_device *device) -{ - acpi_status status = AE_OK; - int result; - - if (!device) - return -EINVAL; - - printk(ASUS_NOTICE "Asus Laptop Support version %s\n", - ASUS_LAPTOP_VERSION); - - hotk = kmalloc(sizeof(struct asus_hotk), GFP_KERNEL); - if (!hotk) - return -ENOMEM; - memset(hotk, 0, sizeof(struct asus_hotk)); - - hotk->handle = device->handle; - strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); - strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); - acpi_driver_data(device) = hotk; - hotk->device = device; - - result = asus_hotk_check(); - if (result) - goto end; - - asus_hotk_add_fs(); - - /* - * We install the handler, it will receive the hotk in parameter, so, we - * could add other data to the hotk struct - */ - status = acpi_install_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY, - asus_hotk_notify, hotk); - if (ACPI_FAILURE(status)) - printk(ASUS_ERR "Error installing notify handler\n"); - - asus_hotk_found = 1; - - /* WLED and BLED are on by default */ - write_status(bt_switch_handle, 1, BT_ON, 0); - write_status(wl_switch_handle, 1, WL_ON, 0); - - /* LCD Backlight is on by default */ - write_status(NULL, 1, LCD_ON, 0); - - /* LED display is off by default */ - hotk->ledd_status = 0xFFF; - - /* Set initial values of light sensor and level */ - hotk->light_switch = 1; /* Default to light sensor disabled */ - hotk->light_level = 0; /* level 5 for sensor sensitivity */ - - if (ls_switch_handle) - set_light_sens_switch(hotk->light_switch); - - if (ls_level_handle) - set_light_sens_level(hotk->light_level); - - end: - if (result) { - kfree(hotk->name); - kfree(hotk); - } - - return result; -} - -static int asus_hotk_remove(struct acpi_device *device, int type) -{ - acpi_status status = 0; - - if (!device || !acpi_driver_data(device)) - return -EINVAL; - - status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY, - asus_hotk_notify); - if (ACPI_FAILURE(status)) - printk(ASUS_ERR "Error removing notify handler\n"); - - kfree(hotk->name); - kfree(hotk); - - return 0; -} - -static void asus_backlight_exit(void) -{ - if (asus_backlight_device) - backlight_device_unregister(asus_backlight_device); -} - -#define ASUS_LED_UNREGISTER(object) \ - if(object##_led.class_dev \ - && !IS_ERR(object##_led.class_dev)) \ - led_classdev_unregister(&object##_led) - -static void asus_led_exit(void) -{ - ASUS_LED_UNREGISTER(mled); - ASUS_LED_UNREGISTER(tled); - ASUS_LED_UNREGISTER(pled); - ASUS_LED_UNREGISTER(rled); - - destroy_workqueue(led_workqueue); -} - -static void __exit asus_laptop_exit(void) -{ - asus_backlight_exit(); - asus_led_exit(); - - acpi_bus_unregister_driver(&asus_hotk_driver); - sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); - platform_device_unregister(asuspf_device); - platform_driver_unregister(&asuspf_driver); -} - -static int asus_backlight_init(struct device *dev) -{ - struct backlight_device *bd; - - if (brightness_set_handle && lcd_switch_handle) { - bd = backlight_device_register(ASUS_HOTK_FILE, dev, - NULL, &asusbl_data); - if (IS_ERR(bd)) { - printk(ASUS_ERR - "Could not register asus backlight device\n"); - asus_backlight_device = NULL; - return PTR_ERR(bd); - } - - asus_backlight_device = bd; - - down(&bd->sem); - if (likely(bd->props)) { - bd->props->brightness = read_brightness(NULL); - bd->props->power = FB_BLANK_UNBLANK; - if (likely(bd->props->update_status)) - bd->props->update_status(bd); - } - up(&bd->sem); - } - return 0; -} - -static int asus_led_register(acpi_handle handle, - struct led_classdev *ldev, struct device *dev) -{ - if (!handle) - return 0; - - return led_classdev_register(dev, ldev); -} - -#define ASUS_LED_REGISTER(object, device) \ - asus_led_register(object##_set_handle, &object##_led, device) - -static int asus_led_init(struct device *dev) -{ - int rv; - - rv = ASUS_LED_REGISTER(mled, dev); - if (rv) - return rv; - - rv = ASUS_LED_REGISTER(tled, dev); - if (rv) - return rv; - - rv = ASUS_LED_REGISTER(rled, dev); - if (rv) - return rv; - - rv = ASUS_LED_REGISTER(pled, dev); - if (rv) - return rv; - - led_workqueue = create_singlethread_workqueue("led_workqueue"); - if (!led_workqueue) - return -ENOMEM; - - return 0; -} - -static int __init asus_laptop_init(void) -{ - struct device *dev; - int result; - - if (acpi_disabled) - return -ENODEV; - - if (!acpi_specific_hotkey_enabled) { - printk(ASUS_ERR "Using generic hotkey driver\n"); - return -ENODEV; - } - - result = acpi_bus_register_driver(&asus_hotk_driver); - if (result < 0) - return result; - - /* - * This is a bit of a kludge. We only want this module loaded - * for ASUS systems, but there's currently no way to probe the - * ACPI namespace for ASUS HIDs. So we just return failure if - * we didn't find one, which will cause the module to be - * unloaded. - */ - if (!asus_hotk_found) { - acpi_bus_unregister_driver(&asus_hotk_driver); - return -ENODEV; - } - - dev = acpi_get_physical_device(hotk->device->handle); - - result = asus_backlight_init(dev); - if (result) - goto fail_backlight; - - result = asus_led_init(dev); - if (result) - goto fail_led; - - /* Register platform stuff */ - result = platform_driver_register(&asuspf_driver); - if (result) - goto fail_platform_driver; - - asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1); - if (!asuspf_device) { - result = -ENOMEM; - goto fail_platform_device1; - } - - result = platform_device_add(asuspf_device); - if (result) - goto fail_platform_device2; - - result = sysfs_create_group(&asuspf_device->dev.kobj, - &asuspf_attribute_group); - if (result) - goto fail_sysfs; - - return 0; - - fail_sysfs: - platform_device_del(asuspf_device); - - fail_platform_device2: - platform_device_put(asuspf_device); - - fail_platform_device1: - platform_driver_unregister(&asuspf_driver); - - fail_platform_driver: - asus_led_exit(); - - fail_led: - asus_backlight_exit(); - - fail_backlight: - - return result; -} - -module_init(asus_laptop_init); -module_exit(asus_laptop_exit); diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index 716a47210aa3..80bdcf846234 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -792,7 +792,8 @@ static void poll_vortex(struct net_device *dev) { struct vortex_private *vp = netdev_priv(dev); unsigned long flags; - local_irq_save(flags); + local_save_flags(flags); + local_irq_disable(); (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev); local_irq_restore(flags); } diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index ad92b6a76ee6..8aa8dd02b910 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -190,7 +190,7 @@ config MII config MACB tristate "Atmel MACB support" - depends on NET_ETHERNET && (AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263) + depends on NET_ETHERNET && AVR32 select MII help The Atmel MACB ethernet interface is found on many AT32 and AT91 @@ -235,6 +235,16 @@ config BMAC To compile this driver as a module, choose M here: the module will be called bmac. +config OAKNET + tristate "National DP83902AV (Oak ethernet) support" + depends on NET_ETHERNET && PPC && BROKEN + select CRC32 + help + Say Y if your machine has this type of Ethernet network card. + + To compile this driver as a module, choose M here: the module + will be called oaknet. + config ARIADNE tristate "Ariadne support" depends on NET_ETHERNET && ZORRO @@ -1145,6 +1155,21 @@ config SEEQ8005 . The module will be called seeq8005. +config SKMC + tristate "SKnet MCA support" + depends on NET_ETHERNET && MCA && BROKEN + ---help--- + These are Micro Channel Ethernet adapters. You need to say Y to "MCA + support" in order to use this driver. Supported cards are the SKnet + Junior MC2 and the SKnet MC2(+). The driver automatically + distinguishes between the two cards. Note that using multiple boards + of different type hasn't been tested with this driver. Say Y if you + have one of these Ethernet adapters. + + To compile this driver as a module, choose M here and read + . The module + will be called sk_mca. + config NE2_MCA tristate "NE/2 (ne2000 MCA version) support" depends on NET_ETHERNET && MCA_LEGACY @@ -1763,18 +1788,6 @@ config LAN_SAA9730 workstations. See . -config SC92031 - tristate "Silan SC92031 PCI Fast Ethernet Adapter driver (EXPERIMENTAL)" - depends on NET_PCI && PCI && EXPERIMENTAL - select CRC32 - ---help--- - This is a driver for the Fast Ethernet PCI network cards based on - the Silan SC92031 chip (sometimes also called Rsltek 8139D). If you - have one of these, say Y here. - - To compile this driver as a module, choose M here: the module - will be called sc92031. This is recommended. - config NET_POCKET bool "Pocket and portable adapters" depends on NET_ETHERNET && PARPORT @@ -2379,24 +2392,6 @@ config CHELSIO_T1_NAPI NAPI is a driver API designed to reduce CPU and interrupt load when the driver is receiving lots of packets from the card. -config CHELSIO_T3 - tristate "Chelsio Communications T3 10Gb Ethernet support" - depends on PCI - help - This driver supports Chelsio T3-based gigabit and 10Gb Ethernet - adapters. - - For general information about Chelsio and our products, visit - our website at . - - For customer support, please visit our customer support page at - . - - Please send feedback to . - - To compile this driver as a module, choose M here: the module - will be called cxgb3. - config EHEA tristate "eHEA Ethernet support" depends on IBMEBUS @@ -2493,13 +2488,6 @@ config NETXEN_NIC help This enables the support for NetXen's Gigabit Ethernet card. -config PASEMI_MAC - tristate "PA Semi 1/10Gbit MAC" - depends on PPC64 && PCI - help - This driver supports the on-chip 1/10Gbit Ethernet controller on - PA Semi's PWRficient line of chips. - endmenu source "drivers/net/tokenring/Kconfig" @@ -2553,7 +2541,6 @@ config DEFXX config SKFP tristate "SysKonnect FDDI PCI support" depends on FDDI && PCI - select BITREVERSE ---help--- Say Y here if you have a SysKonnect FDDI PCI adapter. The following adapters are supported by this driver: diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 0878e3df5174..4c0d4e5ce42b 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_E1000) += e1000/ obj-$(CONFIG_IBM_EMAC) += ibm_emac/ obj-$(CONFIG_IXGB) += ixgb/ obj-$(CONFIG_CHELSIO_T1) += chelsio/ -obj-$(CONFIG_CHELSIO_T3) += cxgb3/ obj-$(CONFIG_EHEA) += ehea/ obj-$(CONFIG_BONDING) += bonding/ obj-$(CONFIG_GIANFAR) += gianfar_driver.o @@ -37,6 +36,8 @@ obj-$(CONFIG_CASSINI) += cassini.o obj-$(CONFIG_MACE) += mace.o obj-$(CONFIG_BMAC) += bmac.o +obj-$(CONFIG_OAKNET) += oaknet.o 8390.o + obj-$(CONFIG_DGRS) += dgrs.o obj-$(CONFIG_VORTEX) += 3c59x.o obj-$(CONFIG_TYPHOON) += typhoon.o @@ -136,6 +137,7 @@ obj-$(CONFIG_AT1700) += at1700.o obj-$(CONFIG_EL1) += 3c501.o obj-$(CONFIG_EL16) += 3c507.o obj-$(CONFIG_ELMC) += 3c523.o +obj-$(CONFIG_SKMC) += sk_mca.o obj-$(CONFIG_IBMLANA) += ibmlana.o obj-$(CONFIG_ELMC_II) += 3c527.o obj-$(CONFIG_EL3) += 3c509.o @@ -158,7 +160,6 @@ obj-$(CONFIG_APRICOT) += 82596.o obj-$(CONFIG_LASI_82596) += lasi_82596.o obj-$(CONFIG_MVME16x_NET) += 82596.o obj-$(CONFIG_BVME6000_NET) += 82596.o -obj-$(CONFIG_SC92031) += sc92031.o # This is also a 82596 and should probably be merged obj-$(CONFIG_LP486E) += lp486e.o @@ -195,7 +196,6 @@ obj-$(CONFIG_SMC91X) += smc91x.o obj-$(CONFIG_SMC911X) += smc911x.o obj-$(CONFIG_DM9000) += dm9000.o obj-$(CONFIG_FEC_8XX) += fec_8xx/ -obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o obj-$(CONFIG_MACB) += macb.o diff --git a/trunk/drivers/net/Space.c b/trunk/drivers/net/Space.c index dd8ed456c8b2..9305eb9b1b98 100644 --- a/trunk/drivers/net/Space.c +++ b/trunk/drivers/net/Space.c @@ -59,6 +59,7 @@ extern struct net_device *wavelan_probe(int unit); extern struct net_device *arlan_probe(int unit); extern struct net_device *el16_probe(int unit); extern struct net_device *elmc_probe(int unit); +extern struct net_device *skmca_probe(int unit); extern struct net_device *elplus_probe(int unit); extern struct net_device *ac3200_probe(int unit); extern struct net_device *es_probe(int unit); @@ -151,6 +152,9 @@ static struct devprobe2 mca_probes[] __initdata = { #endif #ifdef CONFIG_ELMC_II /* 3c527 */ {mc32_probe, 0}, +#endif +#ifdef CONFIG_SKMC /* SKnet Microchannel */ + {skmca_probe, 0}, #endif {NULL, 0}, }; diff --git a/trunk/drivers/net/amd8111e.c b/trunk/drivers/net/amd8111e.c index 9c399aaefbdd..18896f24d407 100644 --- a/trunk/drivers/net/amd8111e.c +++ b/trunk/drivers/net/amd8111e.c @@ -1334,7 +1334,8 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id) static void amd8111e_poll(struct net_device *dev) { unsigned long flags; - local_irq_save(flags); + local_save_flags(flags); + local_irq_disable(); amd8111e_interrupt(0, dev); local_irq_restore(flags); } diff --git a/trunk/drivers/net/arm/at91_ether.c b/trunk/drivers/net/arm/at91_ether.c index 1621b8fe35cf..fada15d959de 100644 --- a/trunk/drivers/net/arm/at91_ether.c +++ b/trunk/drivers/net/arm/at91_ether.c @@ -641,7 +641,7 @@ static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo { strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); strlcpy(info->version, DRV_VERSION, sizeof(info->version)); - strlcpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info)); + strlcpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info)); } static const struct ethtool_ops at91ether_ethtool_ops = { diff --git a/trunk/drivers/net/arm/etherh.c b/trunk/drivers/net/arm/etherh.c index 72c41f5907f2..f3faa4fe58e7 100644 --- a/trunk/drivers/net/arm/etherh.c +++ b/trunk/drivers/net/arm/etherh.c @@ -587,7 +587,7 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i { strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); strlcpy(info->version, DRV_VERSION, sizeof(info->version)); - strlcpy(info->bus_info, dev->dev.parent->bus_id, + strlcpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info)); } diff --git a/trunk/drivers/net/b44.c b/trunk/drivers/net/b44.c index 5ff7882297d6..303a8d94ad4b 100644 --- a/trunk/drivers/net/b44.c +++ b/trunk/drivers/net/b44.c @@ -721,7 +721,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) struct ring_info *src_map, *dest_map; struct rx_header *rh; int dest_idx; - __le32 ctrl; + u32 ctrl; dest_idx = dest_idx_unmasked & (B44_RX_RING_SIZE - 1); dest_desc = &bp->rx_ring[dest_idx]; @@ -783,7 +783,7 @@ static int b44_rx(struct b44 *bp, int budget) RX_PKT_BUF_SZ, PCI_DMA_FROMDEVICE); rh = (struct rx_header *) skb->data; - len = le16_to_cpu(rh->len); + len = cpu_to_le16(rh->len); if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) || (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) { drop_it: @@ -799,7 +799,7 @@ static int b44_rx(struct b44 *bp, int budget) do { udelay(2); barrier(); - len = le16_to_cpu(rh->len); + len = cpu_to_le16(rh->len); } while (len == 0 && i++ < 5); if (len == 0) goto drop_it; @@ -2061,7 +2061,7 @@ static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int b44_read_eeprom(struct b44 *bp, u8 *data) { long i; - __le16 *ptr = (__le16 *) data; + u16 *ptr = (u16 *) data; for (i = 0; i < 128; i += 2) ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i)); diff --git a/trunk/drivers/net/b44.h b/trunk/drivers/net/b44.h index 18fc13336628..4944507fad23 100644 --- a/trunk/drivers/net/b44.h +++ b/trunk/drivers/net/b44.h @@ -308,8 +308,8 @@ #define MII_TLEDCTRL_ENABLE 0x0040 struct dma_desc { - __le32 ctrl; - __le32 addr; + u32 ctrl; + u32 addr; }; /* There are only 12 bits in the DMA engine for descriptor offsetting @@ -327,9 +327,9 @@ struct dma_desc { #define RX_COPY_THRESHOLD 256 struct rx_header { - __le16 len; - __le16 flags; - __le16 pad[12]; + u16 len; + u16 flags; + u16 pad[12]; }; #define RX_HEADER_LEN 28 diff --git a/trunk/drivers/net/bmac.c b/trunk/drivers/net/bmac.c index c143304dcff5..4528ce9c4e43 100644 --- a/trunk/drivers/net/bmac.c +++ b/trunk/drivers/net/bmac.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -141,6 +140,7 @@ static unsigned char *bmac_emergency_rxbuf; + (N_RX_RING + N_TX_RING + 4) * sizeof(struct dbdma_cmd) \ + sizeof(struct sk_buff_head)) +static unsigned char bitrev(unsigned char b); static int bmac_open(struct net_device *dev); static int bmac_close(struct net_device *dev); static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev); @@ -586,6 +586,18 @@ bmac_construct_rxbuff(struct sk_buff *skb, volatile struct dbdma_cmd *cp) virt_to_bus(addr), 0); } +/* Bit-reverse one byte of an ethernet hardware address. */ +static unsigned char +bitrev(unsigned char b) +{ + int d = 0, i; + + for (i = 0; i < 8; ++i, b >>= 1) + d = (d << 1) | (b & 1); + return d; +} + + static void bmac_init_tx_ring(struct bmac_data *bp) { @@ -1212,8 +1224,8 @@ bmac_get_station_address(struct net_device *dev, unsigned char *ea) { reset_and_select_srom(dev); data = read_srom(dev, i + EnetAddressOffset/2, SROMAddressBits); - ea[2*i] = bitrev8(data & 0x0ff); - ea[2*i+1] = bitrev8((data >> 8) & 0x0ff); + ea[2*i] = bitrev(data & 0x0ff); + ea[2*i+1] = bitrev((data >> 8) & 0x0ff); } } @@ -1303,7 +1315,7 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i rev = addr[0] == 0 && addr[1] == 0xA0; for (j = 0; j < 6; ++j) - dev->dev_addr[j] = rev ? bitrev8(addr[j]): addr[j]; + dev->dev_addr[j] = rev? bitrev(addr[j]): addr[j]; /* Enable chip without interrupts for now */ bmac_enable_and_reset_chip(dev); diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 5a96d7611af1..ee7b75b976b5 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -39,9 +39,12 @@ #include #define BCM_VLAN 1 #endif +#ifdef NETIF_F_TSO #include #include #include +#define BCM_TSO 1 +#endif #include #include #include @@ -1725,7 +1728,7 @@ bnx2_tx_int(struct bnx2 *bp) tx_buf = &bp->tx_buf_ring[sw_ring_cons]; skb = tx_buf->skb; - +#ifdef BCM_TSO /* partial BD completions possible with TSO packets */ if (skb_is_gso(skb)) { u16 last_idx, last_ring_idx; @@ -1741,7 +1744,7 @@ bnx2_tx_int(struct bnx2 *bp) break; } } - +#endif pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping), skb_headlen(skb), PCI_DMA_TODEVICE); @@ -4511,6 +4514,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } +#ifdef BCM_TSO if ((mss = skb_shinfo(skb)->gso_size) && (skb->len > (bp->dev->mtu + ETH_HLEN))) { u32 tcp_opt_len, ip_tcp_len; @@ -4543,6 +4547,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) } } else +#endif { mss = 0; } @@ -5539,8 +5544,10 @@ static const struct ethtool_ops bnx2_ethtool_ops = { .set_tx_csum = ethtool_op_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, +#ifdef BCM_TSO .get_tso = ethtool_op_get_tso, .set_tso = bnx2_set_tso, +#endif .self_test_count = bnx2_self_test_count, .self_test = bnx2_self_test, .get_strings = bnx2_get_strings, @@ -5947,7 +5954,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) * responding after a while. * * AMD believes this incompatibility is unique to the 5706, and - * prefers to locally disable MSI rather than globally disabling it. + * prefers to locally disable MSI rather than globally disabling it + * using pci_msi_quirk. */ if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) { struct pci_dev *amd_8132 = NULL; @@ -6096,7 +6104,9 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef BCM_VLAN dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; #endif +#ifdef BCM_TSO dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; +#endif netif_carrier_off(bp->dev); diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index d3801a00d3d5..6482aed4bb7c 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -4704,7 +4704,6 @@ static int bond_check_params(struct bond_params *params) static struct lock_class_key bonding_netdev_xmit_lock_key; /* Create a new bond based on the specified name and bonding parameters. - * If name is NULL, obtain a suitable "bond%d" name for us. * Caller must NOT hold rtnl_lock; we need to release it here before we * set up our sysfs entries. */ @@ -4714,8 +4713,7 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond int res; rtnl_lock(); - bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", - ether_setup); + bond_dev = alloc_netdev(sizeof(struct bonding), name, ether_setup); if (!bond_dev) { printk(KERN_ERR DRV_NAME ": %s: eek! can't alloc netdev!\n", @@ -4724,12 +4722,6 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond goto out_rtnl; } - if (!name) { - res = dev_alloc_name(bond_dev, "bond%d"); - if (res < 0) - goto out_netdev; - } - /* bond_init() must be called after dev_alloc_name() (for the * /proc files), but before register_netdevice(), because we * need to set function pointers. @@ -4756,19 +4748,14 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond rtnl_unlock(); /* allows sysfs registration of net device */ res = bond_create_sysfs_entry(bond_dev->priv); - if (res < 0) { - rtnl_lock(); - goto out_bond; - } - - return 0; - + goto done; out_bond: bond_deinit(bond_dev); out_netdev: free_netdev(bond_dev); out_rtnl: rtnl_unlock(); +done: return res; } @@ -4776,6 +4763,7 @@ static int __init bonding_init(void) { int i; int res; + char new_bond_name[8]; /* Enough room for 999 bonds at init. */ printk(KERN_INFO "%s", version); @@ -4788,7 +4776,8 @@ static int __init bonding_init(void) bond_create_proc_dir(); #endif for (i = 0; i < max_bonds; i++) { - res = bond_create(NULL, &bonding_defaults, NULL); + sprintf(new_bond_name, "bond%d",i); + res = bond_create(new_bond_name,&bonding_defaults, NULL); if (res) goto err; } diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index 878f7aabeeac..ced9ed8f995a 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -39,7 +39,8 @@ /* #define BONDING_DEBUG 1 */ #include "bonding.h" -#define to_dev(obj) container_of(obj,struct device,kobj) +#define to_class_dev(obj) container_of(obj,struct class_device,kobj) +#define to_net_dev(class) container_of(class, struct net_device, class_dev) #define to_bond(cd) ((struct bonding *)(to_net_dev(cd)->priv)) /*---------------------------- Declarations -------------------------------*/ @@ -153,7 +154,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t * If it's > expected, then there's a file open, * and we have to fail. */ - if (atomic_read(&bond->dev->dev.kobj.kref.refcount) + if (atomic_read(&bond->dev->class_dev.kobj.kref.refcount) > expected_refcount){ rtnl_unlock(); printk(KERN_INFO DRV_NAME @@ -200,13 +201,13 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla int ret = 0; /* first, create a link from the slave back to the master */ - ret = sysfs_create_link(&(slave->dev.kobj), &(master->dev.kobj), + ret = sysfs_create_link(&(slave->class_dev.kobj), &(master->class_dev.kobj), "master"); if (ret) return ret; /* next, create a link from the master to the slave */ sprintf(linkname,"slave_%s",slave->name); - ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj), + ret = sysfs_create_link(&(master->class_dev.kobj), &(slave->class_dev.kobj), linkname); return ret; @@ -216,21 +217,20 @@ void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *s { char linkname[IFNAMSIZ+7]; - sysfs_remove_link(&(slave->dev.kobj), "master"); + sysfs_remove_link(&(slave->class_dev.kobj), "master"); sprintf(linkname,"slave_%s",slave->name); - sysfs_remove_link(&(master->dev.kobj), linkname); + sysfs_remove_link(&(master->class_dev.kobj), linkname); } /* * Show the slaves in the current bond. */ -static ssize_t bonding_show_slaves(struct device *d, - struct device_attribute *attr, char *buf) +static ssize_t bonding_show_slaves(struct class_device *cd, char *buf) { struct slave *slave; int i, res = 0; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); read_lock_bh(&bond->lock); bond_for_each_slave(bond, slave, i) { @@ -254,16 +254,14 @@ static ssize_t bonding_show_slaves(struct device *d, * up for this to succeed. * This function is largely the same flow as bonding_update_bonds(). */ -static ssize_t bonding_store_slaves(struct device *d, - struct device_attribute *attr, - const char *buffer, size_t count) +static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer, size_t count) { char command[IFNAMSIZ + 1] = { 0, }; char *ifname; int i, res, found, ret = count; struct slave *slave; struct net_device *dev = NULL; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); /* Quick sanity check -- is the bond interface up? */ if (!(bond->dev->flags & IFF_UP)) { @@ -389,28 +387,25 @@ static ssize_t bonding_store_slaves(struct device *d, return ret; } -static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves); +static CLASS_DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves); /* * Show and set the bonding mode. The bond interface must be down to * change the mode. */ -static ssize_t bonding_show_mode(struct device *d, - struct device_attribute *attr, char *buf) +static ssize_t bonding_show_mode(struct class_device *cd, char *buf) { - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); return sprintf(buf, "%s %d\n", bond_mode_tbl[bond->params.mode].modename, bond->params.mode) + 1; } -static ssize_t bonding_store_mode(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size_t count) { int new_value, ret = count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (bond->dev->flags & IFF_UP) { printk(KERN_ERR DRV_NAME @@ -443,18 +438,16 @@ static ssize_t bonding_store_mode(struct device *d, out: return ret; } -static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode); +static CLASS_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode); /* * Show and set the bonding transmit hash method. The bond interface must be down to * change the xmit hash policy. */ -static ssize_t bonding_show_xmit_hash(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_xmit_hash(struct class_device *cd, char *buf) { int count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if ((bond->params.mode != BOND_MODE_XOR) && (bond->params.mode != BOND_MODE_8023AD)) { @@ -469,12 +462,10 @@ static ssize_t bonding_show_xmit_hash(struct device *d, return count; } -static ssize_t bonding_store_xmit_hash(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf, size_t count) { int new_value, ret = count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (bond->dev->flags & IFF_UP) { printk(KERN_ERR DRV_NAME @@ -510,28 +501,24 @@ static ssize_t bonding_store_xmit_hash(struct device *d, out: return ret; } -static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash); +static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash); /* * Show and set arp_validate. */ -static ssize_t bonding_show_arp_validate(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_arp_validate(struct class_device *cd, char *buf) { - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); return sprintf(buf, "%s %d\n", arp_validate_tbl[bond->params.arp_validate].modename, bond->params.arp_validate) + 1; } -static ssize_t bonding_store_arp_validate(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *buf, size_t count) { int new_value; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); new_value = bond_parse_parm((char *)buf, arp_validate_tbl); if (new_value < 0) { @@ -561,7 +548,7 @@ static ssize_t bonding_store_arp_validate(struct device *d, return count; } -static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate); +static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate); /* * Show and set the arp timer interval. There are two tricky bits @@ -569,21 +556,17 @@ static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, b * MII monitoring. Second, if the ARP timer isn't running, we must * start it. */ -static ssize_t bonding_show_arp_interval(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_arp_interval(struct class_device *cd, char *buf) { - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); return sprintf(buf, "%d\n", bond->params.arp_interval) + 1; } -static ssize_t bonding_store_arp_interval(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *buf, size_t count) { int new_value, ret = count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (sscanf(buf, "%d", &new_value) != 1) { printk(KERN_ERR DRV_NAME @@ -655,17 +638,15 @@ static ssize_t bonding_store_arp_interval(struct device *d, out: return ret; } -static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval); +static CLASS_DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval); /* * Show and set the arp targets. */ -static ssize_t bonding_show_arp_targets(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf) { int i, res = 0; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) { if (bond->params.arp_targets[i]) @@ -679,13 +660,11 @@ static ssize_t bonding_show_arp_targets(struct device *d, return res; } -static ssize_t bonding_store_arp_targets(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *buf, size_t count) { u32 newtarget; int i = 0, done = 0, ret = count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); u32 *targets; targets = bond->params.arp_targets; @@ -763,28 +742,24 @@ static ssize_t bonding_store_arp_targets(struct device *d, out: return ret; } -static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets); +static CLASS_DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets); /* * Show and set the up and down delays. These must be multiples of the * MII monitoring value, and are stored internally as the multiplier. * Thus, we must translate to MS for the real world. */ -static ssize_t bonding_show_downdelay(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_downdelay(struct class_device *cd, char *buf) { - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1; } -static ssize_t bonding_store_downdelay(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf, size_t count) { int new_value, ret = count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (!(bond->params.miimon)) { printk(KERN_ERR DRV_NAME @@ -825,24 +800,20 @@ static ssize_t bonding_store_downdelay(struct device *d, out: return ret; } -static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay); +static CLASS_DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay); -static ssize_t bonding_show_updelay(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_updelay(struct class_device *cd, char *buf) { - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1; } -static ssize_t bonding_store_updelay(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, size_t count) { int new_value, ret = count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (!(bond->params.miimon)) { printk(KERN_ERR DRV_NAME @@ -883,29 +854,25 @@ static ssize_t bonding_store_updelay(struct device *d, out: return ret; } -static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay); +static CLASS_DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay); /* * Show and set the LACP interval. Interface must be down, and the mode * must be set to 802.3ad mode. */ -static ssize_t bonding_show_lacp(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_lacp(struct class_device *cd, char *buf) { - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); return sprintf(buf, "%s %d\n", bond_lacp_tbl[bond->params.lacp_fast].modename, bond->params.lacp_fast) + 1; } -static ssize_t bonding_store_lacp(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size_t count) { int new_value, ret = count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (bond->dev->flags & IFF_UP) { printk(KERN_ERR DRV_NAME @@ -939,7 +906,7 @@ static ssize_t bonding_store_lacp(struct device *d, out: return ret; } -static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp); +static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp); /* * Show and set the MII monitor interval. There are two tricky bits @@ -947,21 +914,17 @@ static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_stor * ARP monitoring. Second, if the timer isn't running, we must * start it. */ -static ssize_t bonding_show_miimon(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_miimon(struct class_device *cd, char *buf) { - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); return sprintf(buf, "%d\n", bond->params.miimon) + 1; } -static ssize_t bonding_store_miimon(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, size_t count) { int new_value, ret = count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (sscanf(buf, "%d", &new_value) != 1) { printk(KERN_ERR DRV_NAME @@ -1037,7 +1000,7 @@ static ssize_t bonding_store_miimon(struct device *d, out: return ret; } -static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon); +static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon); /* * Show and set the primary slave. The store function is much @@ -1046,12 +1009,10 @@ static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store * The bond must be a mode that supports a primary for this be * set. */ -static ssize_t bonding_show_primary(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_primary(struct class_device *cd, char *buf) { int count = 0; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (bond->primary_slave) count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1; @@ -1061,13 +1022,11 @@ static ssize_t bonding_show_primary(struct device *d, return count; } -static ssize_t bonding_store_primary(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, size_t count) { int i; struct slave *slave; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); write_lock_bh(&bond->lock); if (!USES_PRIMARY(bond->params.mode)) { @@ -1106,26 +1065,22 @@ static ssize_t bonding_store_primary(struct device *d, write_unlock_bh(&bond->lock); return count; } -static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary); +static CLASS_DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary); /* * Show and set the use_carrier flag. */ -static ssize_t bonding_show_carrier(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_carrier(struct class_device *cd, char *buf) { - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); return sprintf(buf, "%d\n", bond->params.use_carrier) + 1; } -static ssize_t bonding_store_carrier(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, size_t count) { int new_value, ret = count; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (sscanf(buf, "%d", &new_value) != 1) { @@ -1147,18 +1102,16 @@ static ssize_t bonding_store_carrier(struct device *d, out: return count; } -static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier); +static CLASS_DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier); /* * Show and set currently active_slave. */ -static ssize_t bonding_show_active_slave(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf) { struct slave *curr; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); int count; @@ -1173,15 +1126,13 @@ static ssize_t bonding_show_active_slave(struct device *d, return count; } -static ssize_t bonding_store_active_slave(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t bonding_store_active_slave(struct class_device *cd, const char *buf, size_t count) { int i; struct slave *slave; struct slave *old_active = NULL; struct slave *new_active = NULL; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); write_lock_bh(&bond->lock); if (!USES_PRIMARY(bond->params.mode)) { @@ -1243,18 +1194,16 @@ static ssize_t bonding_store_active_slave(struct device *d, return count; } -static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave); +static CLASS_DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave); /* * Show link status of the bond interface. */ -static ssize_t bonding_show_mii_status(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf) { struct slave *curr; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); read_lock(&bond->curr_slave_lock); curr = bond->curr_active_slave; @@ -1262,18 +1211,16 @@ static ssize_t bonding_show_mii_status(struct device *d, return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1; } -static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL); +static CLASS_DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL); /* * Show current 802.3ad aggregator ID. */ -static ssize_t bonding_show_ad_aggregator(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf) { int count = 0; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; @@ -1284,18 +1231,16 @@ static ssize_t bonding_show_ad_aggregator(struct device *d, return count; } -static DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL); +static CLASS_DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL); /* * Show number of active 802.3ad ports. */ -static ssize_t bonding_show_ad_num_ports(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf) { int count = 0; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; @@ -1306,18 +1251,16 @@ static ssize_t bonding_show_ad_num_ports(struct device *d, return count; } -static DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL); +static CLASS_DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL); /* * Show current 802.3ad actor key. */ -static ssize_t bonding_show_ad_actor_key(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf) { int count = 0; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; @@ -1328,18 +1271,16 @@ static ssize_t bonding_show_ad_actor_key(struct device *d, return count; } -static DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL); +static CLASS_DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL); /* * Show current 802.3ad partner key. */ -static ssize_t bonding_show_ad_partner_key(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf) { int count = 0; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; @@ -1350,18 +1291,16 @@ static ssize_t bonding_show_ad_partner_key(struct device *d, return count; } -static DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL); +static CLASS_DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL); /* * Show current 802.3ad partner mac. */ -static ssize_t bonding_show_ad_partner_mac(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf) { int count = 0; - struct bonding *bond = to_bond(d); + struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; @@ -1380,30 +1319,30 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d, return count; } -static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); +static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); static struct attribute *per_bond_attrs[] = { - &dev_attr_slaves.attr, - &dev_attr_mode.attr, - &dev_attr_arp_validate.attr, - &dev_attr_arp_interval.attr, - &dev_attr_arp_ip_target.attr, - &dev_attr_downdelay.attr, - &dev_attr_updelay.attr, - &dev_attr_lacp_rate.attr, - &dev_attr_xmit_hash_policy.attr, - &dev_attr_miimon.attr, - &dev_attr_primary.attr, - &dev_attr_use_carrier.attr, - &dev_attr_active_slave.attr, - &dev_attr_mii_status.attr, - &dev_attr_ad_aggregator.attr, - &dev_attr_ad_num_ports.attr, - &dev_attr_ad_actor_key.attr, - &dev_attr_ad_partner_key.attr, - &dev_attr_ad_partner_mac.attr, + &class_device_attr_slaves.attr, + &class_device_attr_mode.attr, + &class_device_attr_arp_validate.attr, + &class_device_attr_arp_interval.attr, + &class_device_attr_arp_ip_target.attr, + &class_device_attr_downdelay.attr, + &class_device_attr_updelay.attr, + &class_device_attr_lacp_rate.attr, + &class_device_attr_xmit_hash_policy.attr, + &class_device_attr_miimon.attr, + &class_device_attr_primary.attr, + &class_device_attr_use_carrier.attr, + &class_device_attr_active_slave.attr, + &class_device_attr_mii_status.attr, + &class_device_attr_ad_aggregator.attr, + &class_device_attr_ad_num_ports.attr, + &class_device_attr_ad_actor_key.attr, + &class_device_attr_ad_partner_key.attr, + &class_device_attr_ad_partner_mac.attr, NULL, }; @@ -1428,26 +1367,11 @@ int bond_create_sysfs(void) if (!firstbond) return -ENODEV; - netdev_class = firstbond->dev->dev.class; + netdev_class = firstbond->dev->class_dev.class; if (!netdev_class) return -ENODEV; ret = class_create_file(netdev_class, &class_attr_bonding_masters); - /* - * Permit multiple loads of the module by ignoring failures to - * create the bonding_masters sysfs file. Bonding devices - * created by second or subsequent loads of the module will - * not be listed in, or controllable by, bonding_masters, but - * will have the usual "bonding" sysfs directory. - * - * This is done to preserve backwards compatibility for - * initscripts/sysconfig, which load bonding multiple times to - * configure multiple bonding devices. - */ - if (ret == -EEXIST) { - netdev_class = NULL; - return 0; - } return ret; @@ -1471,13 +1395,13 @@ int bond_create_sysfs_entry(struct bonding *bond) struct net_device *dev = bond->dev; int err; - err = sysfs_create_group(&(dev->dev.kobj), &bonding_group); + err = sysfs_create_group(&(dev->class_dev.kobj), &bonding_group); if (err) { printk(KERN_EMERG "eek! didn't create group!\n"); } if (expected_refcount < 1) - expected_refcount = atomic_read(&bond->dev->dev.kobj.kref.refcount); + expected_refcount = atomic_read(&bond->dev->class_dev.kobj.kref.refcount); return err; } @@ -1488,6 +1412,6 @@ void bond_destroy_sysfs_entry(struct bonding *bond) { struct net_device *dev = bond->dev; - sysfs_remove_group(&(dev->dev.kobj), &bonding_group); + sysfs_remove_group(&(dev->class_dev.kobj), &bonding_group); } diff --git a/trunk/drivers/net/bonding/bonding.h b/trunk/drivers/net/bonding/bonding.h index 41aa78bf1f78..0978c9ac6d2b 100644 --- a/trunk/drivers/net/bonding/bonding.h +++ b/trunk/drivers/net/bonding/bonding.h @@ -22,8 +22,8 @@ #include "bond_3ad.h" #include "bond_alb.h" -#define DRV_VERSION "3.1.2" -#define DRV_RELDATE "January 20, 2007" +#define DRV_VERSION "3.1.1" +#define DRV_RELDATE "September 26, 2006" #define DRV_NAME "bonding" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" @@ -237,13 +237,12 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ BOND_ARP_VALIDATE_BACKUP) -static inline int slave_do_arp_validate(struct bonding *bond, - struct slave *slave) +extern inline int slave_do_arp_validate(struct bonding *bond, struct slave *slave) { return bond->params.arp_validate & (1 << slave->state); } -static inline unsigned long slave_last_rx(struct bonding *bond, +extern inline unsigned long slave_last_rx(struct bonding *bond, struct slave *slave) { if (slave_do_arp_validate(bond, slave)) diff --git a/trunk/drivers/net/chelsio/common.h b/trunk/drivers/net/chelsio/common.h index 787f2f2820fe..74758d2c7af8 100644 --- a/trunk/drivers/net/chelsio/common.h +++ b/trunk/drivers/net/chelsio/common.h @@ -324,7 +324,7 @@ struct board_info { unsigned char mdio_phybaseaddr; struct gmac *gmac; struct gphy *gphy; - struct mdio_ops *mdio_ops; + struct mdio_ops *mdio_ops; const char *desc; }; diff --git a/trunk/drivers/net/chelsio/cpl5_cmd.h b/trunk/drivers/net/chelsio/cpl5_cmd.h index e36d45b78cc7..35f565be4fd3 100644 --- a/trunk/drivers/net/chelsio/cpl5_cmd.h +++ b/trunk/drivers/net/chelsio/cpl5_cmd.h @@ -103,7 +103,7 @@ enum CPL_opcode { CPL_MIGRATE_C2T_RPL = 0xDD, CPL_ERROR = 0xD7, - /* internal: driver -> TOM */ + /* internal: driver -> TOM */ CPL_MSS_CHANGE = 0xE1 }; @@ -159,8 +159,8 @@ enum { // TX_PKT_LSO ethernet types }; union opcode_tid { - u32 opcode_tid; - u8 opcode; + u32 opcode_tid; + u8 opcode; }; #define S_OPCODE 24 @@ -234,7 +234,7 @@ struct cpl_pass_accept_req { u32 local_ip; u32 peer_ip; u32 tos_tid; - struct tcp_options tcp_options; + struct tcp_options tcp_options; u8 dst_mac[6]; u16 vlan_tag; u8 src_mac[6]; @@ -250,12 +250,12 @@ struct cpl_pass_accept_rpl { u32 peer_ip; u32 opt0h; union { - u32 opt0l; - struct { - u8 rsvd[3]; - u8 status; - }; + u32 opt0l; + struct { + u8 rsvd[3]; + u8 status; }; + }; }; struct cpl_act_open_req { diff --git a/trunk/drivers/net/chelsio/cxgb2.c b/trunk/drivers/net/chelsio/cxgb2.c index 7d0f24f69777..fd5d821f3f2a 100644 --- a/trunk/drivers/net/chelsio/cxgb2.c +++ b/trunk/drivers/net/chelsio/cxgb2.c @@ -69,14 +69,14 @@ static inline void cancel_mac_stats_update(struct adapter *ap) cancel_delayed_work(&ap->stats_update_task); } -#define MAX_CMDQ_ENTRIES 16384 -#define MAX_CMDQ1_ENTRIES 1024 -#define MAX_RX_BUFFERS 16384 -#define MAX_RX_JUMBO_BUFFERS 16384 +#define MAX_CMDQ_ENTRIES 16384 +#define MAX_CMDQ1_ENTRIES 1024 +#define MAX_RX_BUFFERS 16384 +#define MAX_RX_JUMBO_BUFFERS 16384 #define MAX_TX_BUFFERS_HIGH 16384U #define MAX_TX_BUFFERS_LOW 1536U #define MAX_TX_BUFFERS 1460U -#define MIN_FL_ENTRIES 32 +#define MIN_FL_ENTRIES 32 #define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ @@ -143,7 +143,7 @@ static void link_report(struct port_info *p) case SPEED_100: s = "100Mbps"; break; } - printk(KERN_INFO "%s: link up, %s, %s-duplex\n", + printk(KERN_INFO "%s: link up, %s, %s-duplex\n", p->dev->name, s, p->link_config.duplex == DUPLEX_FULL ? "full" : "half"); } @@ -233,7 +233,7 @@ static int cxgb_up(struct adapter *adapter) t1_sge_start(adapter->sge); t1_interrupts_enable(adapter); -out_err: + out_err: return err; } @@ -454,21 +454,51 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, const struct cmac_statistics *s; const struct sge_intr_counts *t; struct sge_port_stats ss; - unsigned int len; s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL); - len = sizeof(u64)*(&s->TxFCSErrors + 1 - &s->TxOctetsOK); - memcpy(data, &s->TxOctetsOK, len); - data += len; - - len = sizeof(u64)*(&s->RxFrameTooLongErrors + 1 - &s->RxOctetsOK); - memcpy(data, &s->RxOctetsOK, len); - data += len; + *data++ = s->TxOctetsOK; + *data++ = s->TxOctetsBad; + *data++ = s->TxUnicastFramesOK; + *data++ = s->TxMulticastFramesOK; + *data++ = s->TxBroadcastFramesOK; + *data++ = s->TxPauseFrames; + *data++ = s->TxFramesWithDeferredXmissions; + *data++ = s->TxLateCollisions; + *data++ = s->TxTotalCollisions; + *data++ = s->TxFramesAbortedDueToXSCollisions; + *data++ = s->TxUnderrun; + *data++ = s->TxLengthErrors; + *data++ = s->TxInternalMACXmitError; + *data++ = s->TxFramesWithExcessiveDeferral; + *data++ = s->TxFCSErrors; + + *data++ = s->RxOctetsOK; + *data++ = s->RxOctetsBad; + *data++ = s->RxUnicastFramesOK; + *data++ = s->RxMulticastFramesOK; + *data++ = s->RxBroadcastFramesOK; + *data++ = s->RxPauseFrames; + *data++ = s->RxFCSErrors; + *data++ = s->RxAlignErrors; + *data++ = s->RxSymbolErrors; + *data++ = s->RxDataErrors; + *data++ = s->RxSequenceErrors; + *data++ = s->RxRuntErrors; + *data++ = s->RxJabberErrors; + *data++ = s->RxInternalMACRcvError; + *data++ = s->RxInRangeLengthErrors; + *data++ = s->RxOutOfRangeLengthField; + *data++ = s->RxFrameTooLongErrors; t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss); - memcpy(data, &ss, sizeof(ss)); - data += sizeof(ss); + *data++ = ss.rx_packets; + *data++ = ss.rx_cso_good; + *data++ = ss.tx_packets; + *data++ = ss.tx_cso; + *data++ = ss.tx_tso; + *data++ = ss.vlan_xtract; + *data++ = ss.vlan_insert; t = t1_sge_get_intr_counts(adapter->sge); *data++ = t->rx_drops; @@ -719,7 +749,7 @@ static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) return -EINVAL; if (adapter->flags & FULL_INIT_DONE) - return -EBUSY; + return -EBUSY; adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending; adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending; @@ -734,7 +764,7 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) struct adapter *adapter = dev->priv; adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs; - adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce; + adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce; adapter->params.sge.sample_interval_usecs = c->rate_sample_interval; t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge); return 0; @@ -752,9 +782,9 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) static int get_eeprom_len(struct net_device *dev) { - struct adapter *adapter = dev->priv; + struct adapter *adapter = dev->priv; - return t1_is_asic(adapter) ? EEPROM_SIZE : 0; + return t1_is_asic(adapter) ? EEPROM_SIZE : 0; } #define EEPROM_MAGIC(ap) \ @@ -818,7 +848,7 @@ static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) u32 val; if (!phy->mdio_read) - return -EOPNOTSUPP; + return -EOPNOTSUPP; phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f, &val); data->val_out = val; @@ -830,7 +860,7 @@ static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) if (!capable(CAP_NET_ADMIN)) return -EPERM; if (!phy->mdio_write) - return -EOPNOTSUPP; + return -EOPNOTSUPP; phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f, data->val_in); break; @@ -849,9 +879,9 @@ static int t1_change_mtu(struct net_device *dev, int new_mtu) struct cmac *mac = adapter->port[dev->if_port].mac; if (!mac->ops->set_mtu) - return -EOPNOTSUPP; + return -EOPNOTSUPP; if (new_mtu < 68) - return -EINVAL; + return -EINVAL; if ((ret = mac->ops->set_mtu(mac, new_mtu))) return ret; dev->mtu = new_mtu; @@ -1181,9 +1211,9 @@ static int __devinit init_one(struct pci_dev *pdev, return 0; -out_release_adapter_res: + out_release_adapter_res: t1_free_sw_modules(adapter); -out_free_dev: + out_free_dev: if (adapter) { if (adapter->regs) iounmap(adapter->regs); @@ -1192,7 +1222,7 @@ static int __devinit init_one(struct pci_dev *pdev, free_netdev(adapter->port[i].dev); } pci_release_regions(pdev); -out_disable_pdev: + out_disable_pdev: pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); return err; @@ -1243,27 +1273,28 @@ static int t1_clock(struct adapter *adapter, int mode) int M_MEM_VAL; enum { - M_CORE_BITS = 9, - T_CORE_VAL = 0, - T_CORE_BITS = 2, - N_CORE_VAL = 0, - N_CORE_BITS = 2, - M_MEM_BITS = 9, - T_MEM_VAL = 0, - T_MEM_BITS = 2, - N_MEM_VAL = 0, - N_MEM_BITS = 2, - NP_LOAD = 1 << 17, - S_LOAD_MEM = 1 << 5, - S_LOAD_CORE = 1 << 6, - S_CLOCK = 1 << 3 + M_CORE_BITS = 9, + T_CORE_VAL = 0, + T_CORE_BITS = 2, + N_CORE_VAL = 0, + N_CORE_BITS = 2, + M_MEM_BITS = 9, + T_MEM_VAL = 0, + T_MEM_BITS = 2, + N_MEM_VAL = 0, + N_MEM_BITS = 2, + NP_LOAD = 1 << 17, + S_LOAD_MEM = 1 << 5, + S_LOAD_CORE = 1 << 6, + S_CLOCK = 1 << 3 }; if (!t1_is_T1B(adapter)) return -ENODEV; /* Can't re-clock this chip. */ - if (mode & 2) + if (mode & 2) { return 0; /* show current mode. */ + } if ((adapter->t1powersave & 1) == (mode & 1)) return -EALREADY; /* ASIC already running in mode. */ @@ -1355,26 +1386,26 @@ static inline void t1_sw_reset(struct pci_dev *pdev) static void __devexit remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct adapter *adapter = dev->priv; - int i; - for_each_port(adapter, i) { - if (test_bit(i, &adapter->registered_device_map)) - unregister_netdev(adapter->port[i].dev); - } + if (dev) { + int i; + struct adapter *adapter = dev->priv; - t1_free_sw_modules(adapter); - iounmap(adapter->regs); + for_each_port(adapter, i) + if (test_bit(i, &adapter->registered_device_map)) + unregister_netdev(adapter->port[i].dev); - while (--i >= 0) { - if (adapter->port[i].dev) - free_netdev(adapter->port[i].dev); - } + t1_free_sw_modules(adapter); + iounmap(adapter->regs); + while (--i >= 0) + if (adapter->port[i].dev) + free_netdev(adapter->port[i].dev); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - t1_sw_reset(pdev); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + t1_sw_reset(pdev); + } } static struct pci_driver driver = { diff --git a/trunk/drivers/net/chelsio/elmer0.h b/trunk/drivers/net/chelsio/elmer0.h index eef655c827d9..9ebecaa97d31 100644 --- a/trunk/drivers/net/chelsio/elmer0.h +++ b/trunk/drivers/net/chelsio/elmer0.h @@ -46,14 +46,14 @@ enum { }; /* ELMER0 registers */ -#define A_ELMER0_VERSION 0x100000 -#define A_ELMER0_PHY_CFG 0x100004 -#define A_ELMER0_INT_ENABLE 0x100008 -#define A_ELMER0_INT_CAUSE 0x10000c -#define A_ELMER0_GPI_CFG 0x100010 -#define A_ELMER0_GPI_STAT 0x100014 -#define A_ELMER0_GPO 0x100018 -#define A_ELMER0_PORT0_MI1_CFG 0x400000 +#define A_ELMER0_VERSION 0x100000 +#define A_ELMER0_PHY_CFG 0x100004 +#define A_ELMER0_INT_ENABLE 0x100008 +#define A_ELMER0_INT_CAUSE 0x10000c +#define A_ELMER0_GPI_CFG 0x100010 +#define A_ELMER0_GPI_STAT 0x100014 +#define A_ELMER0_GPO 0x100018 +#define A_ELMER0_PORT0_MI1_CFG 0x400000 #define S_MI1_MDI_ENABLE 0 #define V_MI1_MDI_ENABLE(x) ((x) << S_MI1_MDI_ENABLE) @@ -111,18 +111,18 @@ enum { #define V_MI1_OP_BUSY(x) ((x) << S_MI1_OP_BUSY) #define F_MI1_OP_BUSY V_MI1_OP_BUSY(1U) -#define A_ELMER0_PORT1_MI1_CFG 0x500000 -#define A_ELMER0_PORT1_MI1_ADDR 0x500004 -#define A_ELMER0_PORT1_MI1_DATA 0x500008 -#define A_ELMER0_PORT1_MI1_OP 0x50000c -#define A_ELMER0_PORT2_MI1_CFG 0x600000 -#define A_ELMER0_PORT2_MI1_ADDR 0x600004 -#define A_ELMER0_PORT2_MI1_DATA 0x600008 -#define A_ELMER0_PORT2_MI1_OP 0x60000c -#define A_ELMER0_PORT3_MI1_CFG 0x700000 -#define A_ELMER0_PORT3_MI1_ADDR 0x700004 -#define A_ELMER0_PORT3_MI1_DATA 0x700008 -#define A_ELMER0_PORT3_MI1_OP 0x70000c +#define A_ELMER0_PORT1_MI1_CFG 0x500000 +#define A_ELMER0_PORT1_MI1_ADDR 0x500004 +#define A_ELMER0_PORT1_MI1_DATA 0x500008 +#define A_ELMER0_PORT1_MI1_OP 0x50000c +#define A_ELMER0_PORT2_MI1_CFG 0x600000 +#define A_ELMER0_PORT2_MI1_ADDR 0x600004 +#define A_ELMER0_PORT2_MI1_DATA 0x600008 +#define A_ELMER0_PORT2_MI1_OP 0x60000c +#define A_ELMER0_PORT3_MI1_CFG 0x700000 +#define A_ELMER0_PORT3_MI1_ADDR 0x700004 +#define A_ELMER0_PORT3_MI1_DATA 0x700008 +#define A_ELMER0_PORT3_MI1_OP 0x70000c /* Simple bit definition for GPI and GP0 registers. */ #define ELMER0_GP_BIT0 0x0001 diff --git a/trunk/drivers/net/chelsio/espi.c b/trunk/drivers/net/chelsio/espi.c index d7c5406a6c3f..4192f0f5b3ee 100644 --- a/trunk/drivers/net/chelsio/espi.c +++ b/trunk/drivers/net/chelsio/espi.c @@ -202,9 +202,9 @@ static void espi_setup_for_pm3393(adapter_t *adapter) static void espi_setup_for_vsc7321(adapter_t *adapter) { - writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN0); - writel(0x1f401f4, adapter->regs + A_ESPI_SCH_TOKEN1); - writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN2); + writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN0); + writel(0x1f401f4, adapter->regs + A_ESPI_SCH_TOKEN1); + writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN2); writel(0xa00, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK); writel(0x1ff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK); writel(1, adapter->regs + A_ESPI_CALENDAR_LENGTH); @@ -247,10 +247,10 @@ int t1_espi_init(struct peespi *espi, int mac_type, int nports) writel(V_OUT_OF_SYNC_COUNT(4) | V_DIP2_PARITY_ERR_THRES(3) | V_DIP4_THRES(1), adapter->regs + A_ESPI_MISC_CONTROL); - writel(nports == 4 ? 0x200040 : 0x1000080, + writel(nports == 4 ? 0x200040 : 0x1000080, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2); } else - writel(0x800100, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2); + writel(0x800100, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2); if (mac_type == CHBT_MAC_PM3393) espi_setup_for_pm3393(adapter); @@ -301,8 +301,7 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val) { struct peespi *espi = adapter->espi; - if (!is_T2(adapter)) - return; + if (!is_T2(adapter)) return; spin_lock(&espi->lock); espi->misc_ctrl = (val & ~MON_MASK) | (espi->misc_ctrl & MON_MASK); @@ -341,31 +340,32 @@ u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait) * compare with t1_espi_get_mon(), it reads espiInTxSop[0 ~ 3] in * one shot, since there is no per port counter on the out side. */ -int t1_espi_get_mon_t204(adapter_t *adapter, u32 *valp, u8 wait) +int +t1_espi_get_mon_t204(adapter_t *adapter, u32 *valp, u8 wait) { - struct peespi *espi = adapter->espi; + struct peespi *espi = adapter->espi; u8 i, nport = (u8)adapter->params.nports; - if (!wait) { - if (!spin_trylock(&espi->lock)) - return -1; - } else - spin_lock(&espi->lock); + if (!wait) { + if (!spin_trylock(&espi->lock)) + return -1; + } else + spin_lock(&espi->lock); - if ((espi->misc_ctrl & MON_MASK) != F_MONITORED_DIRECTION) { + if ( (espi->misc_ctrl & MON_MASK) != F_MONITORED_DIRECTION ) { espi->misc_ctrl = (espi->misc_ctrl & ~MON_MASK) | F_MONITORED_DIRECTION; - writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); - } + writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); + } for (i = 0 ; i < nport; i++, valp++) { if (i) { writel(espi->misc_ctrl | V_MONITORED_PORT_NUM(i), adapter->regs + A_ESPI_MISC_CONTROL); } - *valp = readl(adapter->regs + A_ESPI_SCH_TOKEN3); - } + *valp = readl(adapter->regs + A_ESPI_SCH_TOKEN3); + } - writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); - spin_unlock(&espi->lock); - return 0; + writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); + spin_unlock(&espi->lock); + return 0; } diff --git a/trunk/drivers/net/chelsio/fpga_defs.h b/trunk/drivers/net/chelsio/fpga_defs.h index ccdb2bc9ae98..17a3c2ba36a3 100644 --- a/trunk/drivers/net/chelsio/fpga_defs.h +++ b/trunk/drivers/net/chelsio/fpga_defs.h @@ -98,9 +98,9 @@ #define A_MI0_DATA_INT 0xb10 /* GMAC registers */ -#define A_GMAC_MACID_LO 0x28 -#define A_GMAC_MACID_HI 0x2c -#define A_GMAC_CSR 0x30 +#define A_GMAC_MACID_LO 0x28 +#define A_GMAC_MACID_HI 0x2c +#define A_GMAC_CSR 0x30 #define S_INTERFACE 0 #define M_INTERFACE 0x3 diff --git a/trunk/drivers/net/chelsio/gmac.h b/trunk/drivers/net/chelsio/gmac.h index 006a2eb2d362..a2b8ad9b5535 100644 --- a/trunk/drivers/net/chelsio/gmac.h +++ b/trunk/drivers/net/chelsio/gmac.h @@ -42,15 +42,8 @@ #include "common.h" -enum { - MAC_STATS_UPDATE_FAST, - MAC_STATS_UPDATE_FULL -}; - -enum { - MAC_DIRECTION_RX = 1, - MAC_DIRECTION_TX = 2 -}; +enum { MAC_STATS_UPDATE_FAST, MAC_STATS_UPDATE_FULL }; +enum { MAC_DIRECTION_RX = 1, MAC_DIRECTION_TX = 2 }; struct cmac_statistics { /* Transmit */ diff --git a/trunk/drivers/net/chelsio/ixf1010.c b/trunk/drivers/net/chelsio/ixf1010.c index 10b2a9a19006..5b8f144e83d4 100644 --- a/trunk/drivers/net/chelsio/ixf1010.c +++ b/trunk/drivers/net/chelsio/ixf1010.c @@ -145,61 +145,48 @@ static void disable_port(struct cmac *mac) t1_tpi_write(mac->adapter, REG_PORT_ENABLE, val); } +#define RMON_UPDATE(mac, name, stat_name) \ + t1_tpi_read((mac)->adapter, MACREG(mac, REG_##name), &val); \ + (mac)->stats.stat_name += val; + /* * Read the current values of the RMON counters and add them to the cumulative * port statistics. The HW RMON counters are cleared by this operation. */ static void port_stats_update(struct cmac *mac) { - static struct { - unsigned int reg; - unsigned int offset; - } hw_stats[] = { - -#define HW_STAT(name, stat_name) \ - { REG_##name, \ - (&((struct cmac_statistics *)NULL)->stat_name) - (u64 *)NULL } - - /* Rx stats */ - HW_STAT(RxOctetsTotalOK, RxOctetsOK), - HW_STAT(RxOctetsBad, RxOctetsBad), - HW_STAT(RxUCPkts, RxUnicastFramesOK), - HW_STAT(RxMCPkts, RxMulticastFramesOK), - HW_STAT(RxBCPkts, RxBroadcastFramesOK), - HW_STAT(RxJumboPkts, RxJumboFramesOK), - HW_STAT(RxFCSErrors, RxFCSErrors), - HW_STAT(RxAlignErrors, RxAlignErrors), - HW_STAT(RxLongErrors, RxFrameTooLongErrors), - HW_STAT(RxVeryLongErrors, RxFrameTooLongErrors), - HW_STAT(RxPauseMacControlCounter, RxPauseFrames), - HW_STAT(RxDataErrors, RxDataErrors), - HW_STAT(RxJabberErrors, RxJabberErrors), - HW_STAT(RxRuntErrors, RxRuntErrors), - HW_STAT(RxShortErrors, RxRuntErrors), - HW_STAT(RxSequenceErrors, RxSequenceErrors), - HW_STAT(RxSymbolErrors, RxSymbolErrors), - - /* Tx stats (skip collision stats as we are full-duplex only) */ - HW_STAT(TxOctetsTotalOK, TxOctetsOK), - HW_STAT(TxOctetsBad, TxOctetsBad), - HW_STAT(TxUCPkts, TxUnicastFramesOK), - HW_STAT(TxMCPkts, TxMulticastFramesOK), - HW_STAT(TxBCPkts, TxBroadcastFramesOK), - HW_STAT(TxJumboPkts, TxJumboFramesOK), - HW_STAT(TxPauseFrames, TxPauseFrames), - HW_STAT(TxExcessiveLengthDrop, TxLengthErrors), - HW_STAT(TxUnderrun, TxUnderrun), - HW_STAT(TxCRCErrors, TxFCSErrors) - }, *p = hw_stats; - u64 *stats = (u64 *) &mac->stats; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(hw_stats); i++) { - u32 val; + u32 val; - t1_tpi_read(mac->adapter, MACREG(mac, p->reg), &val); - stats[p->offset] += val; - } + /* Rx stats */ + RMON_UPDATE(mac, RxOctetsTotalOK, RxOctetsOK); + RMON_UPDATE(mac, RxOctetsBad, RxOctetsBad); + RMON_UPDATE(mac, RxUCPkts, RxUnicastFramesOK); + RMON_UPDATE(mac, RxMCPkts, RxMulticastFramesOK); + RMON_UPDATE(mac, RxBCPkts, RxBroadcastFramesOK); + RMON_UPDATE(mac, RxJumboPkts, RxJumboFramesOK); + RMON_UPDATE(mac, RxFCSErrors, RxFCSErrors); + RMON_UPDATE(mac, RxAlignErrors, RxAlignErrors); + RMON_UPDATE(mac, RxLongErrors, RxFrameTooLongErrors); + RMON_UPDATE(mac, RxVeryLongErrors, RxFrameTooLongErrors); + RMON_UPDATE(mac, RxPauseMacControlCounter, RxPauseFrames); + RMON_UPDATE(mac, RxDataErrors, RxDataErrors); + RMON_UPDATE(mac, RxJabberErrors, RxJabberErrors); + RMON_UPDATE(mac, RxRuntErrors, RxRuntErrors); + RMON_UPDATE(mac, RxShortErrors, RxRuntErrors); + RMON_UPDATE(mac, RxSequenceErrors, RxSequenceErrors); + RMON_UPDATE(mac, RxSymbolErrors, RxSymbolErrors); + + /* Tx stats (skip collision stats as we are full-duplex only) */ + RMON_UPDATE(mac, TxOctetsTotalOK, TxOctetsOK); + RMON_UPDATE(mac, TxOctetsBad, TxOctetsBad); + RMON_UPDATE(mac, TxUCPkts, TxUnicastFramesOK); + RMON_UPDATE(mac, TxMCPkts, TxMulticastFramesOK); + RMON_UPDATE(mac, TxBCPkts, TxBroadcastFramesOK); + RMON_UPDATE(mac, TxJumboPkts, TxJumboFramesOK); + RMON_UPDATE(mac, TxPauseFrames, TxPauseFrames); + RMON_UPDATE(mac, TxExcessiveLengthDrop, TxLengthErrors); + RMON_UPDATE(mac, TxUnderrun, TxUnderrun); + RMON_UPDATE(mac, TxCRCErrors, TxFCSErrors); } /* No-op interrupt operation as this MAC does not support interrupts */ @@ -286,8 +273,7 @@ static int mac_set_rx_mode(struct cmac *mac, struct t1_rx_mode *rm) static int mac_set_mtu(struct cmac *mac, int mtu) { /* MAX_FRAME_SIZE inludes header + FCS, mtu doesn't */ - if (mtu > (MAX_FRAME_SIZE - 14 - 4)) - return -EINVAL; + if (mtu > (MAX_FRAME_SIZE - 14 - 4)) return -EINVAL; t1_tpi_write(mac->adapter, MACREG(mac, REG_MAX_FRAME_SIZE), mtu + 14 + 4); return 0; @@ -371,8 +357,8 @@ static void enable_port(struct cmac *mac) val |= (1 << index); t1_tpi_write(adapter, REG_PORT_ENABLE, val); - index <<= 2; - if (is_T2(adapter)) { + index <<= 2; + if (is_T2(adapter)) { /* T204: set the Fifo water level & threshold */ t1_tpi_write(adapter, RX_FIFO_HIGH_WATERMARK_BASE + index, 0x740); t1_tpi_write(adapter, RX_FIFO_LOW_WATERMARK_BASE + index, 0x730); @@ -403,10 +389,6 @@ static int mac_disable(struct cmac *mac, int which) return 0; } -#define RMON_UPDATE(mac, name, stat_name) \ - t1_tpi_read((mac)->adapter, MACREG(mac, REG_##name), &val); \ - (mac)->stats.stat_name += val; - /* * This function is called periodically to accumulate the current values of the * RMON counters into the port statistics. Since the counters are only 32 bits @@ -478,12 +460,10 @@ static struct cmac *ixf1010_mac_create(adapter_t *adapter, int index) struct cmac *mac; u32 val; - if (index > 9) - return NULL; + if (index > 9) return NULL; mac = kzalloc(sizeof(*mac) + sizeof(cmac_instance), GFP_KERNEL); - if (!mac) - return NULL; + if (!mac) return NULL; mac->ops = &ixf1010_ops; mac->instance = (cmac_instance *)(mac + 1); diff --git a/trunk/drivers/net/chelsio/mv88e1xxx.c b/trunk/drivers/net/chelsio/mv88e1xxx.c index 5867e3b0a887..28ac93ff7c4f 100644 --- a/trunk/drivers/net/chelsio/mv88e1xxx.c +++ b/trunk/drivers/net/chelsio/mv88e1xxx.c @@ -73,8 +73,9 @@ static int mv88e1xxx_interrupt_enable(struct cphy *cphy) t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer); elmer |= ELMER0_GP_BIT1; - if (is_T2(cphy->adapter)) - elmer |= ELMER0_GP_BIT2 | ELMER0_GP_BIT3 | ELMER0_GP_BIT4; + if (is_T2(cphy->adapter)) { + elmer |= ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4; + } t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer); } return 0; @@ -91,8 +92,9 @@ static int mv88e1xxx_interrupt_disable(struct cphy *cphy) t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer); elmer &= ~ELMER0_GP_BIT1; - if (is_T2(cphy->adapter)) + if (is_T2(cphy->adapter)) { elmer &= ~(ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4); + } t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer); } return 0; @@ -110,8 +112,9 @@ static int mv88e1xxx_interrupt_clear(struct cphy *cphy) if (t1_is_asic(cphy->adapter)) { t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer); elmer |= ELMER0_GP_BIT1; - if (is_T2(cphy->adapter)) + if (is_T2(cphy->adapter)) { elmer |= ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4; + } t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer); } return 0; @@ -297,7 +300,7 @@ static int mv88e1xxx_interrupt_handler(struct cphy *cphy) /* * Loop until cause reads zero. Need to handle bouncing interrupts. - */ + */ while (1) { u32 cause; @@ -305,16 +308,15 @@ static int mv88e1xxx_interrupt_handler(struct cphy *cphy) MV88E1XXX_INTERRUPT_STATUS_REGISTER, &cause); cause &= INTR_ENABLE_MASK; - if (!cause) - break; + if (!cause) break; if (cause & MV88E1XXX_INTR_LINK_CHNG) { (void) simple_mdio_read(cphy, MV88E1XXX_SPECIFIC_STATUS_REGISTER, &status); - if (status & MV88E1XXX_INTR_LINK_CHNG) + if (status & MV88E1XXX_INTR_LINK_CHNG) { cphy->state |= PHY_LINK_UP; - else { + } else { cphy->state &= ~PHY_LINK_UP; if (cphy->state & PHY_AUTONEG_EN) cphy->state &= ~PHY_AUTONEG_RDY; @@ -358,8 +360,7 @@ static struct cphy *mv88e1xxx_phy_create(adapter_t *adapter, int phy_addr, { struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL); - if (!cphy) - return NULL; + if (!cphy) return NULL; cphy_init(cphy, adapter, phy_addr, &mv88e1xxx_ops, mdio_ops); @@ -376,11 +377,11 @@ static struct cphy *mv88e1xxx_phy_create(adapter_t *adapter, int phy_addr, } (void) mv88e1xxx_downshift_set(cphy, 1); /* Enable downshift */ - /* LED */ + /* LED */ if (is_T2(adapter)) { (void) simple_mdio_write(cphy, MV88E1XXX_LED_CONTROL_REGISTER, 0x1); - } + } return cphy; } diff --git a/trunk/drivers/net/chelsio/my3126.c b/trunk/drivers/net/chelsio/my3126.c index 87dde3e60046..82fed1dd5005 100644 --- a/trunk/drivers/net/chelsio/my3126.c +++ b/trunk/drivers/net/chelsio/my3126.c @@ -10,25 +10,25 @@ static int my3126_reset(struct cphy *cphy, int wait) * This can be done through registers. It is not required since * a full chip reset is used. */ - return 0; + return (0); } static int my3126_interrupt_enable(struct cphy *cphy) { schedule_delayed_work(&cphy->phy_update, HZ/30); t1_tpi_read(cphy->adapter, A_ELMER0_GPO, &cphy->elmer_gpo); - return 0; + return (0); } static int my3126_interrupt_disable(struct cphy *cphy) { cancel_rearming_delayed_work(&cphy->phy_update); - return 0; + return (0); } static int my3126_interrupt_clear(struct cphy *cphy) { - return 0; + return (0); } #define OFFSET(REG_ADDR) (REG_ADDR << 2) @@ -102,7 +102,7 @@ static void my3216_poll(struct work_struct *work) static int my3126_set_loopback(struct cphy *cphy, int on) { - return 0; + return (0); } /* To check the activity LED */ @@ -146,7 +146,7 @@ static int my3126_get_link_status(struct cphy *cphy, if (fc) *fc = PAUSE_RX | PAUSE_TX; - return 0; + return (0); } static void my3126_destroy(struct cphy *cphy) @@ -177,7 +177,7 @@ static struct cphy *my3126_phy_create(adapter_t *adapter, INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll); cphy->bmsr = 0; - return cphy; + return (cphy); } /* Chip Reset */ @@ -198,7 +198,7 @@ static int my3126_phy_reset(adapter_t * adapter) val |= 0x8000; t1_tpi_write(adapter, A_ELMER0_GPO, val); udelay(100); - return 0; + return (0); } struct gphy t1_my3126_ops = { diff --git a/trunk/drivers/net/chelsio/pm3393.c b/trunk/drivers/net/chelsio/pm3393.c index 69129edeefd6..63cabeb98afe 100644 --- a/trunk/drivers/net/chelsio/pm3393.c +++ b/trunk/drivers/net/chelsio/pm3393.c @@ -446,51 +446,17 @@ static void pm3393_rmon_update(struct adapter *adapter, u32 offs, u64 *val, *val += 1ull << 40; } +#define RMON_UPDATE(mac, name, stat_name) \ + pm3393_rmon_update((mac)->adapter, OFFSET(name), \ + &(mac)->stats.stat_name, \ + (ro &((name - SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW) >> 2))) + + static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac, int flag) { - static struct { - unsigned int reg; - unsigned int offset; - } hw_stats [] = { - -#define HW_STAT(name, stat_name) \ - { name, (&((struct cmac_statistics *)NULL)->stat_name) - (u64 *)NULL } - - /* Rx stats */ - HW_STAT(RxOctetsReceivedOK, RxOctetsOK), - HW_STAT(RxUnicastFramesReceivedOK, RxUnicastFramesOK), - HW_STAT(RxMulticastFramesReceivedOK, RxMulticastFramesOK), - HW_STAT(RxBroadcastFramesReceivedOK, RxBroadcastFramesOK), - HW_STAT(RxPAUSEMACCtrlFramesReceived, RxPauseFrames), - HW_STAT(RxFrameCheckSequenceErrors, RxFCSErrors), - HW_STAT(RxFramesLostDueToInternalMACErrors, - RxInternalMACRcvError), - HW_STAT(RxSymbolErrors, RxSymbolErrors), - HW_STAT(RxInRangeLengthErrors, RxInRangeLengthErrors), - HW_STAT(RxFramesTooLongErrors , RxFrameTooLongErrors), - HW_STAT(RxJabbers, RxJabberErrors), - HW_STAT(RxFragments, RxRuntErrors), - HW_STAT(RxUndersizedFrames, RxRuntErrors), - HW_STAT(RxJumboFramesReceivedOK, RxJumboFramesOK), - HW_STAT(RxJumboOctetsReceivedOK, RxJumboOctetsOK), - - /* Tx stats */ - HW_STAT(TxOctetsTransmittedOK, TxOctetsOK), - HW_STAT(TxFramesLostDueToInternalMACTransmissionError, - TxInternalMACXmitError), - HW_STAT(TxTransmitSystemError, TxFCSErrors), - HW_STAT(TxUnicastFramesTransmittedOK, TxUnicastFramesOK), - HW_STAT(TxMulticastFramesTransmittedOK, TxMulticastFramesOK), - HW_STAT(TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK), - HW_STAT(TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames), - HW_STAT(TxJumboFramesReceivedOK, TxJumboFramesOK), - HW_STAT(TxJumboOctetsReceivedOK, TxJumboOctetsOK) - }, *p = hw_stats; - u64 ro; - u32 val0, val1, val2, val3; - u64 *stats = (u64 *) &mac->stats; - unsigned int i; + u64 ro; + u32 val0, val1, val2, val3; /* Snap the counters */ pmwrite(mac, SUNI1x10GEXP_REG_MSTAT_CONTROL, @@ -504,14 +470,35 @@ static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac, ro = ((u64)val0 & 0xffff) | (((u64)val1 & 0xffff) << 16) | (((u64)val2 & 0xffff) << 32) | (((u64)val3 & 0xffff) << 48); - for (i = 0; i < ARRAY_SIZE(hw_stats); i++) { - unsigned reg = p->reg - SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW; - - pm3393_rmon_update((mac)->adapter, OFFSET(p->reg), - stats + p->offset, ro & (reg >> 2)); - } - - + /* Rx stats */ + RMON_UPDATE(mac, RxOctetsReceivedOK, RxOctetsOK); + RMON_UPDATE(mac, RxUnicastFramesReceivedOK, RxUnicastFramesOK); + RMON_UPDATE(mac, RxMulticastFramesReceivedOK, RxMulticastFramesOK); + RMON_UPDATE(mac, RxBroadcastFramesReceivedOK, RxBroadcastFramesOK); + RMON_UPDATE(mac, RxPAUSEMACCtrlFramesReceived, RxPauseFrames); + RMON_UPDATE(mac, RxFrameCheckSequenceErrors, RxFCSErrors); + RMON_UPDATE(mac, RxFramesLostDueToInternalMACErrors, + RxInternalMACRcvError); + RMON_UPDATE(mac, RxSymbolErrors, RxSymbolErrors); + RMON_UPDATE(mac, RxInRangeLengthErrors, RxInRangeLengthErrors); + RMON_UPDATE(mac, RxFramesTooLongErrors , RxFrameTooLongErrors); + RMON_UPDATE(mac, RxJabbers, RxJabberErrors); + RMON_UPDATE(mac, RxFragments, RxRuntErrors); + RMON_UPDATE(mac, RxUndersizedFrames, RxRuntErrors); + RMON_UPDATE(mac, RxJumboFramesReceivedOK, RxJumboFramesOK); + RMON_UPDATE(mac, RxJumboOctetsReceivedOK, RxJumboOctetsOK); + + /* Tx stats */ + RMON_UPDATE(mac, TxOctetsTransmittedOK, TxOctetsOK); + RMON_UPDATE(mac, TxFramesLostDueToInternalMACTransmissionError, + TxInternalMACXmitError); + RMON_UPDATE(mac, TxTransmitSystemError, TxFCSErrors); + RMON_UPDATE(mac, TxUnicastFramesTransmittedOK, TxUnicastFramesOK); + RMON_UPDATE(mac, TxMulticastFramesTransmittedOK, TxMulticastFramesOK); + RMON_UPDATE(mac, TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK); + RMON_UPDATE(mac, TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames); + RMON_UPDATE(mac, TxJumboFramesReceivedOK, TxJumboFramesOK); + RMON_UPDATE(mac, TxJumboOctetsReceivedOK, TxJumboOctetsOK); return &mac->stats; } @@ -547,9 +534,9 @@ static int pm3393_macaddress_set(struct cmac *cmac, u8 ma[6]) /* Store local copy */ memcpy(cmac->instance->mac_addr, ma, 6); - lo = ((u32) ma[1] << 8) | (u32) ma[0]; + lo = ((u32) ma[1] << 8) | (u32) ma[0]; mid = ((u32) ma[3] << 8) | (u32) ma[2]; - hi = ((u32) ma[5] << 8) | (u32) ma[4]; + hi = ((u32) ma[5] << 8) | (u32) ma[4]; /* Disable Rx/Tx MAC before configuring it. */ if (enabled) diff --git a/trunk/drivers/net/chelsio/sge.c b/trunk/drivers/net/chelsio/sge.c index 89a682702fa9..659cb2252e44 100644 --- a/trunk/drivers/net/chelsio/sge.c +++ b/trunk/drivers/net/chelsio/sge.c @@ -71,9 +71,12 @@ #define SGE_FREEL_REFILL_THRESH 16 #define SGE_RESPQ_E_N 1024 #define SGE_INTRTIMER_NRES 1000 +#define SGE_RX_COPY_THRES 256 #define SGE_RX_SM_BUF_SIZE 1536 #define SGE_TX_DESC_MAX_PLEN 16384 +# define SGE_RX_DROP_THRES 2 + #define SGE_RESPQ_REPLENISH_THRES (SGE_RESPQ_E_N / 4) /* @@ -82,6 +85,10 @@ */ #define TX_RECLAIM_PERIOD (HZ / 4) +#ifndef NET_IP_ALIGN +# define NET_IP_ALIGN 2 +#endif + #define M_CMD_LEN 0x7fffffff #define V_CMD_LEN(v) (v) #define G_CMD_LEN(v) ((v) & M_CMD_LEN) @@ -188,7 +195,7 @@ struct cmdQ { struct cmdQ_e *entries; /* HW command descriptor Q */ struct cmdQ_ce *centries; /* SW command context descriptor Q */ dma_addr_t dma_addr; /* DMA addr HW command descriptor Q */ - spinlock_t lock; /* Lock to protect cmdQ enqueuing */ + spinlock_t lock; /* Lock to protect cmdQ enqueuing */ }; struct freelQ { @@ -234,9 +241,9 @@ struct sched_port { /* Per T204 device */ struct sched { ktime_t last_updated; /* last time quotas were computed */ - unsigned int max_avail; /* max bits to be sent to any port */ - unsigned int port; /* port index (round robin ports) */ - unsigned int num; /* num skbs in per port queues */ + unsigned int max_avail; /* max bits to be sent to any port */ + unsigned int port; /* port index (round robin ports) */ + unsigned int num; /* num skbs in per port queues */ struct sched_port p[MAX_NPORTS]; struct tasklet_struct sched_tsk;/* tasklet used to run scheduler */ }; @@ -252,10 +259,10 @@ static void restart_sched(unsigned long); * contention. */ struct sge { - struct adapter *adapter; /* adapter backpointer */ + struct adapter *adapter; /* adapter backpointer */ struct net_device *netdev; /* netdevice backpointer */ - struct freelQ freelQ[SGE_FREELQ_N]; /* buffer free lists */ - struct respQ respQ; /* response Q */ + struct freelQ freelQ[SGE_FREELQ_N]; /* buffer free lists */ + struct respQ respQ; /* response Q */ unsigned long stopped_tx_queues; /* bitmap of suspended Tx queues */ unsigned int rx_pkt_pad; /* RX padding for L2 packets */ unsigned int jumbo_fl; /* jumbo freelist Q index */ @@ -453,7 +460,7 @@ static struct sk_buff *sched_skb(struct sge *sge, struct sk_buff *skb, if (credits < MAX_SKB_FRAGS + 1) goto out; -again: + again: for (i = 0; i < MAX_NPORTS; i++) { s->port = ++s->port & (MAX_NPORTS - 1); skbq = &s->p[s->port].skbq; @@ -476,8 +483,8 @@ static struct sk_buff *sched_skb(struct sge *sge, struct sk_buff *skb, if (update-- && sched_update_avail(sge)) goto again; -out: - /* If there are more pending skbs, we use the hardware to schedule us + out: + /* If there are more pending skbs, we use the hardware to schedule us * again. */ if (s->num && !skb) { @@ -568,10 +575,11 @@ static int alloc_rx_resources(struct sge *sge, struct sge_params *p) q->size = p->freelQ_size[i]; q->dma_offset = sge->rx_pkt_pad ? 0 : NET_IP_ALIGN; size = sizeof(struct freelQ_e) * q->size; - q->entries = pci_alloc_consistent(pdev, size, &q->dma_addr); + q->entries = (struct freelQ_e *) + pci_alloc_consistent(pdev, size, &q->dma_addr); if (!q->entries) goto err_no_mem; - + memset(q->entries, 0, size); size = sizeof(struct freelQ_ce) * q->size; q->centries = kzalloc(size, GFP_KERNEL); if (!q->centries) @@ -605,10 +613,11 @@ static int alloc_rx_resources(struct sge *sge, struct sge_params *p) sge->respQ.size = SGE_RESPQ_E_N; sge->respQ.credits = 0; size = sizeof(struct respQ_e) * sge->respQ.size; - sge->respQ.entries = + sge->respQ.entries = (struct respQ_e *) pci_alloc_consistent(pdev, size, &sge->respQ.dma_addr); if (!sge->respQ.entries) goto err_no_mem; + memset(sge->respQ.entries, 0, size); return 0; err_no_mem: @@ -628,12 +637,20 @@ static void free_cmdQ_buffers(struct sge *sge, struct cmdQ *q, unsigned int n) q->in_use -= n; ce = &q->centries[cidx]; while (n--) { - if (likely(pci_unmap_len(ce, dma_len))) { - pci_unmap_single(pdev, pci_unmap_addr(ce, dma_addr), - pci_unmap_len(ce, dma_len), - PCI_DMA_TODEVICE); - if (q->sop) + if (q->sop) { + if (likely(pci_unmap_len(ce, dma_len))) { + pci_unmap_single(pdev, + pci_unmap_addr(ce, dma_addr), + pci_unmap_len(ce, dma_len), + PCI_DMA_TODEVICE); q->sop = 0; + } + } else { + if (likely(pci_unmap_len(ce, dma_len))) { + pci_unmap_page(pdev, pci_unmap_addr(ce, dma_addr), + pci_unmap_len(ce, dma_len), + PCI_DMA_TODEVICE); + } } if (ce->skb) { dev_kfree_skb_any(ce->skb); @@ -694,10 +711,11 @@ static int alloc_tx_resources(struct sge *sge, struct sge_params *p) q->stop_thres = 0; spin_lock_init(&q->lock); size = sizeof(struct cmdQ_e) * q->size; - q->entries = pci_alloc_consistent(pdev, size, &q->dma_addr); + q->entries = (struct cmdQ_e *) + pci_alloc_consistent(pdev, size, &q->dma_addr); if (!q->entries) goto err_no_mem; - + memset(q->entries, 0, size); size = sizeof(struct cmdQ_ce) * q->size; q->centries = kzalloc(size, GFP_KERNEL); if (!q->centries) @@ -752,7 +770,7 @@ void t1_set_vlan_accel(struct adapter *adapter, int on_off) static void configure_sge(struct sge *sge, struct sge_params *p) { struct adapter *ap = sge->adapter; - + writel(0, ap->regs + A_SG_CONTROL); setup_ring_params(ap, sge->cmdQ[0].dma_addr, sge->cmdQ[0].size, A_SG_CMD0BASELWR, A_SG_CMD0BASEUPR, A_SG_CMD0SIZE); @@ -832,6 +850,7 @@ static void refill_free_list(struct sge *sge, struct freelQ *q) struct freelQ_e *e = &q->entries[q->pidx]; unsigned int dma_len = q->rx_buffer_size - q->dma_offset; + while (q->credits < q->size) { struct sk_buff *skb; dma_addr_t mapping; @@ -843,8 +862,6 @@ static void refill_free_list(struct sge *sge, struct freelQ *q) skb_reserve(skb, q->dma_offset); mapping = pci_map_single(pdev, skb->data, dma_len, PCI_DMA_FROMDEVICE); - skb_reserve(skb, sge->rx_pkt_pad); - ce->skb = skb; pci_unmap_addr_set(ce, dma_addr, mapping); pci_unmap_len_set(ce, dma_len, dma_len); @@ -864,6 +881,7 @@ static void refill_free_list(struct sge *sge, struct freelQ *q) } q->credits++; } + } /* @@ -1023,10 +1041,6 @@ static void recycle_fl_buf(struct freelQ *fl, int idx) } } -static int copybreak __read_mostly = 256; -module_param(copybreak, int, 0); -MODULE_PARM_DESC(copybreak, "Receive copy threshold"); - /** * get_packet - return the next ingress packet buffer * @pdev: the PCI device that received the packet @@ -1046,42 +1060,45 @@ MODULE_PARM_DESC(copybreak, "Receive copy threshold"); * be copied but there is no memory for the copy. */ static inline struct sk_buff *get_packet(struct pci_dev *pdev, - struct freelQ *fl, unsigned int len) + struct freelQ *fl, unsigned int len, + int dma_pad, int skb_pad, + unsigned int copy_thres, + unsigned int drop_thres) { struct sk_buff *skb; - const struct freelQ_ce *ce = &fl->centries[fl->cidx]; - - if (len < copybreak) { - skb = alloc_skb(len + 2, GFP_ATOMIC); - if (!skb) - goto use_orig_buf; + struct freelQ_ce *ce = &fl->centries[fl->cidx]; - skb_reserve(skb, 2); /* align IP header */ - skb_put(skb, len); - pci_dma_sync_single_for_cpu(pdev, + if (len < copy_thres) { + skb = alloc_skb(len + skb_pad, GFP_ATOMIC); + if (likely(skb != NULL)) { + skb_reserve(skb, skb_pad); + skb_put(skb, len); + pci_dma_sync_single_for_cpu(pdev, pci_unmap_addr(ce, dma_addr), - pci_unmap_len(ce, dma_len), + pci_unmap_len(ce, dma_len), PCI_DMA_FROMDEVICE); - memcpy(skb->data, ce->skb->data, len); - pci_dma_sync_single_for_device(pdev, - pci_unmap_addr(ce, dma_addr), - pci_unmap_len(ce, dma_len), - PCI_DMA_FROMDEVICE); + memcpy(skb->data, ce->skb->data + dma_pad, len); + pci_dma_sync_single_for_device(pdev, + pci_unmap_addr(ce, dma_addr), + pci_unmap_len(ce, dma_len), + PCI_DMA_FROMDEVICE); + } else if (!drop_thres) + goto use_orig_buf; + recycle_fl_buf(fl, fl->cidx); return skb; } -use_orig_buf: - if (fl->credits < 2) { + if (fl->credits < drop_thres) { recycle_fl_buf(fl, fl->cidx); return NULL; } +use_orig_buf: pci_unmap_single(pdev, pci_unmap_addr(ce, dma_addr), pci_unmap_len(ce, dma_len), PCI_DMA_FROMDEVICE); skb = ce->skb; - prefetch(skb->data); - + skb_reserve(skb, dma_pad); skb_put(skb, len); return skb; } @@ -1120,7 +1137,6 @@ static void unexpected_offload(struct adapter *adapter, struct freelQ *fl) static inline unsigned int compute_large_page_tx_descs(struct sk_buff *skb) { unsigned int count = 0; - if (PAGE_SIZE > SGE_TX_DESC_MAX_PLEN) { unsigned int nfrags = skb_shinfo(skb)->nr_frags; unsigned int i, len = skb->len - skb->data_len; @@ -1327,7 +1343,7 @@ static void restart_sched(unsigned long arg) while ((skb = sched_skb(sge, NULL, credits)) != NULL) { unsigned int genbit, pidx, count; count = 1 + skb_shinfo(skb)->nr_frags; - count += compute_large_page_tx_descs(skb); + count += compute_large_page_tx_descs(skb); q->in_use += count; genbit = q->genbit; pidx = q->pidx; @@ -1359,25 +1375,27 @@ static void restart_sched(unsigned long arg) * * Process an ingress ethernet pakcet and deliver it to the stack. */ -static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) +static int sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) { struct sk_buff *skb; - const struct cpl_rx_pkt *p; + struct cpl_rx_pkt *p; struct adapter *adapter = sge->adapter; struct sge_port_stats *st; - skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad); + skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad, + sge->rx_pkt_pad, 2, SGE_RX_COPY_THRES, + SGE_RX_DROP_THRES); if (unlikely(!skb)) { sge->stats.rx_drops++; - return; + return 0; } - p = (const struct cpl_rx_pkt *) skb->data; + p = (struct cpl_rx_pkt *)skb->data; + skb_pull(skb, sizeof(*p)); if (p->iff >= adapter->params.nports) { kfree_skb(skb); - return; + return 0; } - __skb_pull(skb, sizeof(*p)); skb->dev = adapter->port[p->iff].dev; skb->dev->last_rx = jiffies; @@ -1409,6 +1427,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) netif_rx(skb); #endif } + return 0; } /* @@ -1429,28 +1448,29 @@ static inline int enough_free_Tx_descs(const struct cmdQ *q) static void restart_tx_queues(struct sge *sge) { struct adapter *adap = sge->adapter; - int i; - if (!enough_free_Tx_descs(&sge->cmdQ[0])) - return; + if (enough_free_Tx_descs(&sge->cmdQ[0])) { + int i; - for_each_port(adap, i) { - struct net_device *nd = adap->port[i].dev; + for_each_port(adap, i) { + struct net_device *nd = adap->port[i].dev; - if (test_and_clear_bit(nd->if_port, &sge->stopped_tx_queues) && - netif_running(nd)) { - sge->stats.cmdQ_restarted[2]++; - netif_wake_queue(nd); + if (test_and_clear_bit(nd->if_port, + &sge->stopped_tx_queues) && + netif_running(nd)) { + sge->stats.cmdQ_restarted[2]++; + netif_wake_queue(nd); + } } } } /* - * update_tx_info is called from the interrupt handler/NAPI to return cmdQ0 + * update_tx_info is called from the interrupt handler/NAPI to return cmdQ0 * information. */ -static unsigned int update_tx_info(struct adapter *adapter, - unsigned int flags, +static unsigned int update_tx_info(struct adapter *adapter, + unsigned int flags, unsigned int pr0) { struct sge *sge = adapter->sge; @@ -1490,30 +1510,29 @@ static int process_responses(struct adapter *adapter, int budget) struct sge *sge = adapter->sge; struct respQ *q = &sge->respQ; struct respQ_e *e = &q->entries[q->cidx]; - int done = 0; + int budget_left = budget; unsigned int flags = 0; unsigned int cmdq_processed[SGE_CMDQ_N] = {0, 0}; + - while (done < budget && e->GenerationBit == q->genbit) { + while (likely(budget_left && e->GenerationBit == q->genbit)) { flags |= e->Qsleeping; - + cmdq_processed[0] += e->Cmdq0CreditReturn; cmdq_processed[1] += e->Cmdq1CreditReturn; - + /* We batch updates to the TX side to avoid cacheline * ping-pong of TX state information on MP where the sender * might run on a different CPU than this function... */ - if (unlikely((flags & F_CMDQ0_ENABLE) || cmdq_processed[0] > 64)) { + if (unlikely(flags & F_CMDQ0_ENABLE || cmdq_processed[0] > 64)) { flags = update_tx_info(adapter, flags, cmdq_processed[0]); cmdq_processed[0] = 0; } - if (unlikely(cmdq_processed[1] > 16)) { sge->cmdQ[1].processed += cmdq_processed[1]; cmdq_processed[1] = 0; } - if (likely(e->DataValid)) { struct freelQ *fl = &sge->freelQ[e->FreelistQid]; @@ -1523,16 +1542,12 @@ static int process_responses(struct adapter *adapter, int budget) else sge_rx(sge, fl, e->BufferLength); - ++done; - /* * Note: this depends on each packet consuming a * single free-list buffer; cf. the BUG above. */ if (++fl->cidx == fl->size) fl->cidx = 0; - prefetch(fl->centries[fl->cidx].skb); - if (unlikely(--fl->credits < fl->size - SGE_FREEL_REFILL_THRESH)) refill_free_list(sge, fl); @@ -1551,20 +1566,14 @@ static int process_responses(struct adapter *adapter, int budget) writel(q->credits, adapter->regs + A_SG_RSPQUEUECREDIT); q->credits = 0; } + --budget_left; } - flags = update_tx_info(adapter, flags, cmdq_processed[0]); + flags = update_tx_info(adapter, flags, cmdq_processed[0]); sge->cmdQ[1].processed += cmdq_processed[1]; - return done; -} - -static inline int responses_pending(const struct adapter *adapter) -{ - const struct respQ *Q = &adapter->sge->respQ; - const struct respQ_e *e = &Q->entries[Q->cidx]; - - return (e->GenerationBit == Q->genbit); + budget -= budget_left; + return budget; } #ifdef CONFIG_CHELSIO_T1_NAPI @@ -1576,25 +1585,19 @@ static inline int responses_pending(const struct adapter *adapter) * which the caller must ensure is a valid pure response. Returns 1 if it * encounters a valid data-carrying response, 0 otherwise. */ -static int process_pure_responses(struct adapter *adapter) +static int process_pure_responses(struct adapter *adapter, struct respQ_e *e) { struct sge *sge = adapter->sge; struct respQ *q = &sge->respQ; - struct respQ_e *e = &q->entries[q->cidx]; - const struct freelQ *fl = &sge->freelQ[e->FreelistQid]; unsigned int flags = 0; unsigned int cmdq_processed[SGE_CMDQ_N] = {0, 0}; - prefetch(fl->centries[fl->cidx].skb); - if (e->DataValid) - return 1; - do { flags |= e->Qsleeping; cmdq_processed[0] += e->Cmdq0CreditReturn; cmdq_processed[1] += e->Cmdq1CreditReturn; - + e++; if (unlikely(++q->cidx == q->size)) { q->cidx = 0; @@ -1610,7 +1613,7 @@ static int process_pure_responses(struct adapter *adapter) sge->stats.pure_rsps++; } while (e->GenerationBit == q->genbit && !e->DataValid); - flags = update_tx_info(adapter, flags, cmdq_processed[0]); + flags = update_tx_info(adapter, flags, cmdq_processed[0]); sge->cmdQ[1].processed += cmdq_processed[1]; return e->GenerationBit == q->genbit; @@ -1624,20 +1627,23 @@ static int process_pure_responses(struct adapter *adapter) int t1_poll(struct net_device *dev, int *budget) { struct adapter *adapter = dev->priv; - int work_done; + int effective_budget = min(*budget, dev->quota); + int work_done = process_responses(adapter, effective_budget); - work_done = process_responses(adapter, min(*budget, dev->quota)); *budget -= work_done; dev->quota -= work_done; - if (unlikely(responses_pending(adapter))) + if (work_done >= effective_budget) return 1; - netif_rx_complete(dev); + spin_lock_irq(&adapter->async_lock); + __netif_rx_complete(dev); writel(adapter->sge->respQ.cidx, adapter->regs + A_SG_SLEEPING); + writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, + adapter->regs + A_PL_ENABLE); + spin_unlock_irq(&adapter->async_lock); return 0; - } /* @@ -1646,33 +1652,44 @@ int t1_poll(struct net_device *dev, int *budget) irqreturn_t t1_interrupt(int irq, void *data) { struct adapter *adapter = data; + struct net_device *dev = adapter->sge->netdev; struct sge *sge = adapter->sge; - int handled; - - if (likely(responses_pending(adapter))) { - struct net_device *dev = sge->netdev; + u32 cause; + int handled = 0; - writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE); + cause = readl(adapter->regs + A_PL_CAUSE); + if (cause == 0 || cause == ~0) + return IRQ_NONE; - if (__netif_rx_schedule_prep(dev)) { - if (process_pure_responses(adapter)) - __netif_rx_schedule(dev); - else { - /* no data, no NAPI needed */ - writel(sge->respQ.cidx, adapter->regs + A_SG_SLEEPING); - netif_poll_enable(dev); /* undo schedule_prep */ + spin_lock(&adapter->async_lock); + if (cause & F_PL_INTR_SGE_DATA) { + struct respQ *q = &adapter->sge->respQ; + struct respQ_e *e = &q->entries[q->cidx]; + + handled = 1; + writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE); + + if (e->GenerationBit == q->genbit && + __netif_rx_schedule_prep(dev)) { + if (e->DataValid || process_pure_responses(adapter, e)) { + /* mask off data IRQ */ + writel(adapter->slow_intr_mask, + adapter->regs + A_PL_ENABLE); + __netif_rx_schedule(sge->netdev); + goto unlock; } - } - return IRQ_HANDLED; - } + /* no data, no NAPI needed */ + netif_poll_enable(dev); - spin_lock(&adapter->async_lock); - handled = t1_slow_intr_handler(adapter); - spin_unlock(&adapter->async_lock); + } + writel(q->cidx, adapter->regs + A_SG_SLEEPING); + } else + handled = t1_slow_intr_handler(adapter); if (!handled) sge->stats.unhandled_irqs++; - +unlock: + spin_unlock(&adapter->async_lock); return IRQ_RETVAL(handled != 0); } @@ -1695,13 +1712,17 @@ irqreturn_t t1_interrupt(int irq, void *data) irqreturn_t t1_interrupt(int irq, void *cookie) { int work_done; + struct respQ_e *e; struct adapter *adapter = cookie; + struct respQ *Q = &adapter->sge->respQ; spin_lock(&adapter->async_lock); + e = &Q->entries[Q->cidx]; + prefetch(e); writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE); - if (likely(responses_pending(adapter))) + if (likely(e->GenerationBit == Q->genbit)) work_done = process_responses(adapter, -1); else work_done = t1_slow_intr_handler(adapter); @@ -1775,7 +1796,7 @@ static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, * through the scheduler. */ if (sge->tx_sched && !qid && skb->dev) { -use_sched: + use_sched: use_sched_skb = 1; /* Note that the scheduler might return a different skb than * the one passed in. @@ -1879,7 +1900,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) cpl = (struct cpl_tx_pkt *)hdr; } else { /* - * Packets shorter than ETH_HLEN can break the MAC, drop them + * Packets shorter than ETH_HLEN can break the MAC, drop them * early. Also, we may get oversized packets because some * parts of the kernel don't handle our unusual hard_header_len * right, drop those too. @@ -1963,9 +1984,9 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) * then silently discard to avoid leak. */ if (unlikely(ret != NETDEV_TX_OK && skb != orig_skb)) { - dev_kfree_skb_any(skb); + dev_kfree_skb_any(skb); ret = NETDEV_TX_OK; - } + } return ret; } @@ -2078,35 +2099,31 @@ static void espibug_workaround_t204(unsigned long data) if (adapter->open_device_map & PORT_MASK) { int i; - - if (t1_espi_get_mon_t204(adapter, &(seop[0]), 0) < 0) + if (t1_espi_get_mon_t204(adapter, &(seop[0]), 0) < 0) { return; - + } for (i = 0; i < nports; i++) { - struct sk_buff *skb = sge->espibug_skb[i]; - - if (!netif_running(adapter->port[i].dev) || - netif_queue_stopped(adapter->port[i].dev) || - !seop[i] || ((seop[i] & 0xfff) != 0) || !skb) - continue; - - if (!skb->cb[0]) { - u8 ch_mac_addr[ETH_ALEN] = { - 0x0, 0x7, 0x43, 0x0, 0x0, 0x0 - }; - - memcpy(skb->data + sizeof(struct cpl_tx_pkt), - ch_mac_addr, ETH_ALEN); - memcpy(skb->data + skb->len - 10, - ch_mac_addr, ETH_ALEN); - skb->cb[0] = 0xff; + struct sk_buff *skb = sge->espibug_skb[i]; + if ( (netif_running(adapter->port[i].dev)) && + !(netif_queue_stopped(adapter->port[i].dev)) && + (seop[i] && ((seop[i] & 0xfff) == 0)) && + skb ) { + if (!skb->cb[0]) { + u8 ch_mac_addr[ETH_ALEN] = + {0x0, 0x7, 0x43, 0x0, 0x0, 0x0}; + memcpy(skb->data + sizeof(struct cpl_tx_pkt), + ch_mac_addr, ETH_ALEN); + memcpy(skb->data + skb->len - 10, + ch_mac_addr, ETH_ALEN); + skb->cb[0] = 0xff; + } + + /* bump the reference count to avoid freeing of + * the skb once the DMA has completed. + */ + skb = skb_get(skb); + t1_sge_tx(skb, adapter, 0, adapter->port[i].dev); } - - /* bump the reference count to avoid freeing of - * the skb once the DMA has completed. - */ - skb = skb_get(skb); - t1_sge_tx(skb, adapter, 0, adapter->port[i].dev); } } mod_timer(&sge->espibug_timer, jiffies + sge->espibug_timeout); @@ -2175,8 +2192,9 @@ struct sge * __devinit t1_sge_create(struct adapter *adapter, if (adapter->params.nports > 1) { tx_sched_init(sge); sge->espibug_timer.function = espibug_workaround_t204; - } else + } else { sge->espibug_timer.function = espibug_workaround; + } sge->espibug_timer.data = (unsigned long)sge->adapter; sge->espibug_timeout = 1; @@ -2184,7 +2202,7 @@ struct sge * __devinit t1_sge_create(struct adapter *adapter, if (adapter->params.nports > 1) sge->espibug_timeout = HZ/100; } - + p->cmdQ_size[0] = SGE_CMDQ0_E_N; p->cmdQ_size[1] = SGE_CMDQ1_E_N; diff --git a/trunk/drivers/net/chelsio/subr.c b/trunk/drivers/net/chelsio/subr.c index c2522cdfab37..22ed9a383c08 100644 --- a/trunk/drivers/net/chelsio/subr.c +++ b/trunk/drivers/net/chelsio/subr.c @@ -223,13 +223,13 @@ static int fpga_slow_intr(adapter_t *adapter) t1_sge_intr_error_handler(adapter->sge); if (cause & FPGA_PCIX_INTERRUPT_GMAC) - fpga_phy_intr_handler(adapter); + fpga_phy_intr_handler(adapter); if (cause & FPGA_PCIX_INTERRUPT_TP) { - /* + /* * FPGA doesn't support MC4 interrupts and it requires * this odd layer of indirection for MC5. - */ + */ u32 tp_cause = readl(adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE); /* Clear TP interrupt */ @@ -262,7 +262,8 @@ static int mi1_wait_until_ready(adapter_t *adapter, int mi1_reg) udelay(10); } while (busy && --attempts); if (busy) - CH_ALERT("%s: MDIO operation timed out\n", adapter->name); + CH_ALERT("%s: MDIO operation timed out\n", + adapter->name); return busy; } @@ -604,23 +605,22 @@ int t1_elmer0_ext_intr_handler(adapter_t *adapter) switch (board_info(adapter)->board) { #ifdef CONFIG_CHELSIO_T1_1G - case CHBT_BOARD_CHT204: - case CHBT_BOARD_CHT204E: - case CHBT_BOARD_CHN204: - case CHBT_BOARD_CHT204V: { - int i, port_bit; + case CHBT_BOARD_CHT204: + case CHBT_BOARD_CHT204E: + case CHBT_BOARD_CHN204: + case CHBT_BOARD_CHT204V: { + int i, port_bit; for_each_port(adapter, i) { port_bit = i + 1; - if (!(cause & (1 << port_bit))) - continue; + if (!(cause & (1 << port_bit))) continue; - phy = adapter->port[i].phy; + phy = adapter->port[i].phy; phy_cause = phy->ops->interrupt_handler(phy); if (phy_cause & cphy_cause_link_change) t1_link_changed(adapter, i); } - break; - } + break; + } case CHBT_BOARD_CHT101: if (cause & ELMER0_GP_BIT1) { /* Marvell 88E1111 interrupt */ phy = adapter->port[0].phy; @@ -631,13 +631,13 @@ int t1_elmer0_ext_intr_handler(adapter_t *adapter) break; case CHBT_BOARD_7500: { int p; - /* + /* * Elmer0's interrupt cause isn't useful here because there is * only one bit that can be set for all 4 ports. This means * we are forced to check every PHY's interrupt status * register to see who initiated the interrupt. - */ - for_each_port(adapter, p) { + */ + for_each_port(adapter, p) { phy = adapter->port[p].phy; phy_cause = phy->ops->interrupt_handler(phy); if (phy_cause & cphy_cause_link_change) @@ -658,7 +658,7 @@ int t1_elmer0_ext_intr_handler(adapter_t *adapter) break; case CHBT_BOARD_8000: case CHBT_BOARD_CHT110: - CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n", + CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n", cause); if (cause & ELMER0_GP_BIT1) { /* PMC3393 INTB */ struct cmac *mac = adapter->port[0].mac; @@ -670,9 +670,9 @@ int t1_elmer0_ext_intr_handler(adapter_t *adapter) t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect); - CH_MSG(adapter, INFO, LINK, "XPAK %s\n", + CH_MSG(adapter, INFO, LINK, "XPAK %s\n", mod_detect ? "removed" : "inserted"); - } + } break; #ifdef CONFIG_CHELSIO_T1_COUGAR case CHBT_BOARD_COUGAR: @@ -688,8 +688,7 @@ int t1_elmer0_ext_intr_handler(adapter_t *adapter) for_each_port(adapter, i) { port_bit = i ? i + 1 : 0; - if (!(cause & (1 << port_bit))) - continue; + if (!(cause & (1 << port_bit))) continue; phy = adapter->port[i].phy; phy_cause = phy->ops->interrupt_handler(phy); @@ -756,7 +755,7 @@ void t1_interrupts_disable(adapter_t* adapter) /* Disable PCIX & external chip interrupts. */ if (t1_is_asic(adapter)) - writel(0, adapter->regs + A_PL_ENABLE); + writel(0, adapter->regs + A_PL_ENABLE); /* PCI-X interrupts */ pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0); @@ -831,11 +830,11 @@ int t1_slow_intr_handler(adapter_t *adapter) /* Power sequencing is a work-around for Intel's XPAKs. */ static void power_sequence_xpak(adapter_t* adapter) { - u32 mod_detect; - u32 gpo; + u32 mod_detect; + u32 gpo; - /* Check for XPAK */ - t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect); + /* Check for XPAK */ + t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect); if (!(ELMER0_GP_BIT5 & mod_detect)) { /* XPAK is present */ t1_tpi_read(adapter, A_ELMER0_GPO, &gpo); @@ -878,31 +877,31 @@ static int board_init(adapter_t *adapter, const struct board_info *bi) case CHBT_BOARD_N210: case CHBT_BOARD_CHT210: case CHBT_BOARD_COUGAR: - t1_tpi_par(adapter, 0xf); - t1_tpi_write(adapter, A_ELMER0_GPO, 0x800); + t1_tpi_par(adapter, 0xf); + t1_tpi_write(adapter, A_ELMER0_GPO, 0x800); break; case CHBT_BOARD_CHT110: - t1_tpi_par(adapter, 0xf); - t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800); + t1_tpi_par(adapter, 0xf); + t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800); - /* TBD XXX Might not need. This fixes a problem - * described in the Intel SR XPAK errata. - */ - power_sequence_xpak(adapter); + /* TBD XXX Might not need. This fixes a problem + * described in the Intel SR XPAK errata. + */ + power_sequence_xpak(adapter); break; #ifdef CONFIG_CHELSIO_T1_1G - case CHBT_BOARD_CHT204E: - /* add config space write here */ + case CHBT_BOARD_CHT204E: + /* add config space write here */ case CHBT_BOARD_CHT204: case CHBT_BOARD_CHT204V: case CHBT_BOARD_CHN204: - t1_tpi_par(adapter, 0xf); - t1_tpi_write(adapter, A_ELMER0_GPO, 0x804); - break; + t1_tpi_par(adapter, 0xf); + t1_tpi_write(adapter, A_ELMER0_GPO, 0x804); + break; case CHBT_BOARD_CHT101: case CHBT_BOARD_7500: - t1_tpi_par(adapter, 0xf); - t1_tpi_write(adapter, A_ELMER0_GPO, 0x1804); + t1_tpi_par(adapter, 0xf); + t1_tpi_write(adapter, A_ELMER0_GPO, 0x1804); break; #endif } @@ -942,7 +941,7 @@ int t1_init_hw_modules(adapter_t *adapter) goto out_err; err = 0; -out_err: + out_err: return err; } @@ -984,7 +983,7 @@ void t1_free_sw_modules(adapter_t *adapter) if (adapter->espi) t1_espi_destroy(adapter->espi); #ifdef CONFIG_CHELSIO_T1_COUGAR - if (adapter->cspi) + if (adapter->cspi) t1_cspi_destroy(adapter->cspi); #endif } @@ -1011,7 +1010,7 @@ static void __devinit init_link_config(struct link_config *lc, CH_ERR("%s: CSPI initialization failed\n", adapter->name); goto error; - } + } #endif /* diff --git a/trunk/drivers/net/chelsio/tp.c b/trunk/drivers/net/chelsio/tp.c index 6222d585e447..0ca0b6e19e43 100644 --- a/trunk/drivers/net/chelsio/tp.c +++ b/trunk/drivers/net/chelsio/tp.c @@ -17,36 +17,39 @@ struct petp { static void tp_init(adapter_t * ap, const struct tp_params *p, unsigned int tp_clk) { - u32 val; + if (t1_is_asic(ap)) { + u32 val; + + val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM | + F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET; + if (!p->pm_size) + val |= F_OFFLOAD_DISABLE; + else + val |= F_TP_IN_ESPI_CHECK_IP_CSUM | + F_TP_IN_ESPI_CHECK_TCP_CSUM; + writel(val, ap->regs + A_TP_IN_CONFIG); + writel(F_TP_OUT_CSPI_CPL | + F_TP_OUT_ESPI_ETHERNET | + F_TP_OUT_ESPI_GENERATE_IP_CSUM | + F_TP_OUT_ESPI_GENERATE_TCP_CSUM, + ap->regs + A_TP_OUT_CONFIG); + writel(V_IP_TTL(64) | + F_PATH_MTU /* IP DF bit */ | + V_5TUPLE_LOOKUP(p->use_5tuple_mode) | + V_SYN_COOKIE_PARAMETER(29), + ap->regs + A_TP_GLOBAL_CONFIG); + /* + * Enable pause frame deadlock prevention. + */ + if (is_T2(ap) && ap->params.nports > 1) { + u32 drop_ticks = DROP_MSEC * (tp_clk / 1000); + + writel(F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR | + V_DROP_TICKS_CNT(drop_ticks) | + V_NUM_PKTS_DROPPED(DROP_PKTS_CNT), + ap->regs + A_TP_TX_DROP_CONFIG); + } - if (!t1_is_asic(ap)) - return; - - val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM | - F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET; - if (!p->pm_size) - val |= F_OFFLOAD_DISABLE; - else - val |= F_TP_IN_ESPI_CHECK_IP_CSUM | F_TP_IN_ESPI_CHECK_TCP_CSUM; - writel(val, ap->regs + A_TP_IN_CONFIG); - writel(F_TP_OUT_CSPI_CPL | - F_TP_OUT_ESPI_ETHERNET | - F_TP_OUT_ESPI_GENERATE_IP_CSUM | - F_TP_OUT_ESPI_GENERATE_TCP_CSUM, ap->regs + A_TP_OUT_CONFIG); - writel(V_IP_TTL(64) | - F_PATH_MTU /* IP DF bit */ | - V_5TUPLE_LOOKUP(p->use_5tuple_mode) | - V_SYN_COOKIE_PARAMETER(29), ap->regs + A_TP_GLOBAL_CONFIG); - /* - * Enable pause frame deadlock prevention. - */ - if (is_T2(ap) && ap->params.nports > 1) { - u32 drop_ticks = DROP_MSEC * (tp_clk / 1000); - - writel(F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR | - V_DROP_TICKS_CNT(drop_ticks) | - V_NUM_PKTS_DROPPED(DROP_PKTS_CNT), - ap->regs + A_TP_TX_DROP_CONFIG); } } @@ -58,7 +61,6 @@ void t1_tp_destroy(struct petp *tp) struct petp *__devinit t1_tp_create(adapter_t * adapter, struct tp_params *p) { struct petp *tp = kzalloc(sizeof(*tp), GFP_KERNEL); - if (!tp) return NULL; diff --git a/trunk/drivers/net/chelsio/vsc7326.c b/trunk/drivers/net/chelsio/vsc7326.c index 534ffa0f616e..85dc3b1dc309 100644 --- a/trunk/drivers/net/chelsio/vsc7326.c +++ b/trunk/drivers/net/chelsio/vsc7326.c @@ -226,21 +226,22 @@ static void run_table(adapter_t *adapter, struct init_table *ib, int len) if (ib[i].addr == INITBLOCK_SLEEP) { udelay( ib[i].data ); CH_ERR("sleep %d us\n",ib[i].data); - } else + } else { vsc_write( adapter, ib[i].addr, ib[i].data ); + } } } static int bist_rd(adapter_t *adapter, int moduleid, int address) { - int data = 0; - u32 result = 0; - - if ((address != 0x0) && - (address != 0x1) && - (address != 0x2) && - (address != 0xd) && - (address != 0xe)) + int data=0; + u32 result=0; + + if( (address != 0x0) && + (address != 0x1) && + (address != 0x2) && + (address != 0xd) && + (address != 0xe)) CH_ERR("No bist address: 0x%x\n", address); data = ((0x00 << 24) | ((address & 0xff) << 16) | (0x00 << 8) | @@ -250,27 +251,27 @@ static int bist_rd(adapter_t *adapter, int moduleid, int address) udelay(10); vsc_read(adapter, REG_RAM_BIST_RESULT, &result); - if ((result & (1 << 9)) != 0x0) + if((result & (1<<9)) != 0x0) CH_ERR("Still in bist read: 0x%x\n", result); - else if ((result & (1 << 8)) != 0x0) + else if((result & (1<<8)) != 0x0) CH_ERR("bist read error: 0x%x\n", result); - return (result & 0xff); + return(result & 0xff); } static int bist_wr(adapter_t *adapter, int moduleid, int address, int value) { - int data = 0; - u32 result = 0; - - if ((address != 0x0) && - (address != 0x1) && - (address != 0x2) && - (address != 0xd) && - (address != 0xe)) + int data=0; + u32 result=0; + + if( (address != 0x0) && + (address != 0x1) && + (address != 0x2) && + (address != 0xd) && + (address != 0xe)) CH_ERR("No bist address: 0x%x\n", address); - if (value > 255) + if( value>255 ) CH_ERR("Suspicious write out of range value: 0x%x\n", value); data = ((0x01 << 24) | ((address & 0xff) << 16) | (value << 8) | @@ -280,12 +281,12 @@ static int bist_wr(adapter_t *adapter, int moduleid, int address, int value) udelay(5); vsc_read(adapter, REG_RAM_BIST_CMD, &result); - if ((result & (1 << 27)) != 0x0) + if((result & (1<<27)) != 0x0) CH_ERR("Still in bist write: 0x%x\n", result); - else if ((result & (1 << 26)) != 0x0) + else if((result & (1<<26)) != 0x0) CH_ERR("bist write error: 0x%x\n", result); - return 0; + return(0); } static int run_bist(adapter_t *adapter, int moduleid) @@ -294,7 +295,7 @@ static int run_bist(adapter_t *adapter, int moduleid) (void) bist_wr(adapter,moduleid, 0x00, 0x02); (void) bist_wr(adapter,moduleid, 0x01, 0x01); - return 0; + return(0); } static int check_bist(adapter_t *adapter, int moduleid) @@ -308,26 +309,27 @@ static int check_bist(adapter_t *adapter, int moduleid) if ((result & 3) != 0x3) CH_ERR("Result: 0x%x BIST error in ram %d, column: 0x%04x\n", result, moduleid, column); - return 0; + return(0); } static int enable_mem(adapter_t *adapter, int moduleid) { /*enable mem*/ (void) bist_wr(adapter,moduleid, 0x00, 0x00); - return 0; + return(0); } static int run_bist_all(adapter_t *adapter) { - int port = 0; - u32 val = 0; + int port=0; + u32 val=0; vsc_write(adapter, REG_MEM_BIST, 0x5); vsc_read(adapter, REG_MEM_BIST, &val); - for (port = 0; port < 12; port++) + for(port=0; port<12; port++){ vsc_write(adapter, REG_DEV_SETUP(port), 0x0); + } udelay(300); vsc_write(adapter, REG_SPI4_MISC, 0x00040409); @@ -350,13 +352,13 @@ static int run_bist_all(adapter_t *adapter) udelay(300); vsc_write(adapter, REG_SPI4_MISC, 0x60040400); udelay(300); - for (port = 0; port < 12; port++) + for(port=0; port<12; port++){ vsc_write(adapter, REG_DEV_SETUP(port), 0x1); - + } udelay(300); vsc_write(adapter, REG_MEM_BIST, 0x0); mdelay(10); - return 0; + return(0); } static int mac_intr_handler(struct cmac *mac) @@ -589,46 +591,40 @@ static void rmon_update(struct cmac *mac, unsigned int addr, u64 *stat) static void port_stats_update(struct cmac *mac) { - struct { - unsigned int reg; - unsigned int offset; - } hw_stats[] = { - -#define HW_STAT(reg, stat_name) \ - { reg, (&((struct cmac_statistics *)NULL)->stat_name) - (u64 *)NULL } - - /* Rx stats */ - HW_STAT(RxUnicast, RxUnicastFramesOK), - HW_STAT(RxMulticast, RxMulticastFramesOK), - HW_STAT(RxBroadcast, RxBroadcastFramesOK), - HW_STAT(Crc, RxFCSErrors), - HW_STAT(RxAlignment, RxAlignErrors), - HW_STAT(RxOversize, RxFrameTooLongErrors), - HW_STAT(RxPause, RxPauseFrames), - HW_STAT(RxJabbers, RxJabberErrors), - HW_STAT(RxFragments, RxRuntErrors), - HW_STAT(RxUndersize, RxRuntErrors), - HW_STAT(RxSymbolCarrier, RxSymbolErrors), - HW_STAT(RxSize1519ToMax, RxJumboFramesOK), - - /* Tx stats (skip collision stats as we are full-duplex only) */ - HW_STAT(TxUnicast, TxUnicastFramesOK), - HW_STAT(TxMulticast, TxMulticastFramesOK), - HW_STAT(TxBroadcast, TxBroadcastFramesOK), - HW_STAT(TxPause, TxPauseFrames), - HW_STAT(TxUnderrun, TxUnderrun), - HW_STAT(TxSize1519ToMax, TxJumboFramesOK), - }, *p = hw_stats; - unsigned int port = mac->instance->index; - u64 *stats = (u64 *)&mac->stats; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(hw_stats); i++) - rmon_update(mac, CRA(0x4, port, p->reg), stats + p->offset); + int port = mac->instance->index; - rmon_update(mac, REG_TX_OK_BYTES(port), &mac->stats.TxOctetsOK); + /* Rx stats */ rmon_update(mac, REG_RX_OK_BYTES(port), &mac->stats.RxOctetsOK); rmon_update(mac, REG_RX_BAD_BYTES(port), &mac->stats.RxOctetsBad); + rmon_update(mac, REG_RX_UNICAST(port), &mac->stats.RxUnicastFramesOK); + rmon_update(mac, REG_RX_MULTICAST(port), + &mac->stats.RxMulticastFramesOK); + rmon_update(mac, REG_RX_BROADCAST(port), + &mac->stats.RxBroadcastFramesOK); + rmon_update(mac, REG_CRC(port), &mac->stats.RxFCSErrors); + rmon_update(mac, REG_RX_ALIGNMENT(port), &mac->stats.RxAlignErrors); + rmon_update(mac, REG_RX_OVERSIZE(port), + &mac->stats.RxFrameTooLongErrors); + rmon_update(mac, REG_RX_PAUSE(port), &mac->stats.RxPauseFrames); + rmon_update(mac, REG_RX_JABBERS(port), &mac->stats.RxJabberErrors); + rmon_update(mac, REG_RX_FRAGMENTS(port), &mac->stats.RxRuntErrors); + rmon_update(mac, REG_RX_UNDERSIZE(port), &mac->stats.RxRuntErrors); + rmon_update(mac, REG_RX_SYMBOL_CARRIER(port), + &mac->stats.RxSymbolErrors); + rmon_update(mac, REG_RX_SIZE_1519_TO_MAX(port), + &mac->stats.RxJumboFramesOK); + + /* Tx stats (skip collision stats as we are full-duplex only) */ + rmon_update(mac, REG_TX_OK_BYTES(port), &mac->stats.TxOctetsOK); + rmon_update(mac, REG_TX_UNICAST(port), &mac->stats.TxUnicastFramesOK); + rmon_update(mac, REG_TX_MULTICAST(port), + &mac->stats.TxMulticastFramesOK); + rmon_update(mac, REG_TX_BROADCAST(port), + &mac->stats.TxBroadcastFramesOK); + rmon_update(mac, REG_TX_PAUSE(port), &mac->stats.TxPauseFrames); + rmon_update(mac, REG_TX_UNDERRUN(port), &mac->stats.TxUnderrun); + rmon_update(mac, REG_TX_SIZE_1519_TO_MAX(port), + &mac->stats.TxJumboFramesOK); } /* @@ -690,8 +686,7 @@ static struct cmac *vsc7326_mac_create(adapter_t *adapter, int index) int i; mac = kzalloc(sizeof(*mac) + sizeof(cmac_instance), GFP_KERNEL); - if (!mac) - return NULL; + if (!mac) return NULL; mac->ops = &vsc7326_ops; mac->instance = (cmac_instance *)(mac + 1); diff --git a/trunk/drivers/net/chelsio/vsc7326_reg.h b/trunk/drivers/net/chelsio/vsc7326_reg.h index 479edbcabe68..491bcf75c4fb 100644 --- a/trunk/drivers/net/chelsio/vsc7326_reg.h +++ b/trunk/drivers/net/chelsio/vsc7326_reg.h @@ -192,84 +192,73 @@ #define REG_HDX(pn) CRA(0x1,pn,0x19) /* Half-duplex config */ /* Statistics */ -/* CRA(0x4,pn,reg) */ -/* reg below */ /* pn = port number, 0-a, a = 10GbE */ +#define REG_RX_IN_BYTES(pn) CRA(0x4,pn,0x00) /* # Rx in octets */ +#define REG_RX_SYMBOL_CARRIER(pn) CRA(0x4,pn,0x01) /* Frames w/ symbol errors */ +#define REG_RX_PAUSE(pn) CRA(0x4,pn,0x02) /* # pause frames received */ +#define REG_RX_UNSUP_OPCODE(pn) CRA(0x4,pn,0x03) /* # control frames with unsupported opcode */ +#define REG_RX_OK_BYTES(pn) CRA(0x4,pn,0x04) /* # octets in good frames */ +#define REG_RX_BAD_BYTES(pn) CRA(0x4,pn,0x05) /* # octets in bad frames */ +#define REG_RX_UNICAST(pn) CRA(0x4,pn,0x06) /* # good unicast frames */ +#define REG_RX_MULTICAST(pn) CRA(0x4,pn,0x07) /* # good multicast frames */ +#define REG_RX_BROADCAST(pn) CRA(0x4,pn,0x08) /* # good broadcast frames */ +#define REG_CRC(pn) CRA(0x4,pn,0x09) /* # frames w/ bad CRC only */ +#define REG_RX_ALIGNMENT(pn) CRA(0x4,pn,0x0a) /* # frames w/ alignment err */ +#define REG_RX_UNDERSIZE(pn) CRA(0x4,pn,0x0b) /* # frames undersize */ +#define REG_RX_FRAGMENTS(pn) CRA(0x4,pn,0x0c) /* # frames undersize w/ crc err */ +#define REG_RX_IN_RANGE_LENGTH_ERROR(pn) CRA(0x4,pn,0x0d) /* # frames with length error */ +#define REG_RX_OUT_OF_RANGE_ERROR(pn) CRA(0x4,pn,0x0e) /* # frames with illegal length field */ +#define REG_RX_OVERSIZE(pn) CRA(0x4,pn,0x0f) /* # frames oversize */ +#define REG_RX_JABBERS(pn) CRA(0x4,pn,0x10) /* # frames oversize w/ crc err */ +#define REG_RX_SIZE_64(pn) CRA(0x4,pn,0x11) /* # frames 64 octets long */ +#define REG_RX_SIZE_65_TO_127(pn) CRA(0x4,pn,0x12) /* # frames 65-127 octets */ +#define REG_RX_SIZE_128_TO_255(pn) CRA(0x4,pn,0x13) /* # frames 128-255 */ +#define REG_RX_SIZE_256_TO_511(pn) CRA(0x4,pn,0x14) /* # frames 256-511 */ +#define REG_RX_SIZE_512_TO_1023(pn) CRA(0x4,pn,0x15) /* # frames 512-1023 */ +#define REG_RX_SIZE_1024_TO_1518(pn) CRA(0x4,pn,0x16) /* # frames 1024-1518 */ +#define REG_RX_SIZE_1519_TO_MAX(pn) CRA(0x4,pn,0x17) /* # frames 1519-max */ -enum { - RxInBytes = 0x00, // # Rx in octets - RxSymbolCarrier = 0x01, // Frames w/ symbol errors - RxPause = 0x02, // # pause frames received - RxUnsupOpcode = 0x03, // # control frames with unsupported opcode - RxOkBytes = 0x04, // # octets in good frames - RxBadBytes = 0x05, // # octets in bad frames - RxUnicast = 0x06, // # good unicast frames - RxMulticast = 0x07, // # good multicast frames - RxBroadcast = 0x08, // # good broadcast frames - Crc = 0x09, // # frames w/ bad CRC only - RxAlignment = 0x0a, // # frames w/ alignment err - RxUndersize = 0x0b, // # frames undersize - RxFragments = 0x0c, // # frames undersize w/ crc err - RxInRangeLengthError = 0x0d, // # frames with length error - RxOutOfRangeError = 0x0e, // # frames with illegal length field - RxOversize = 0x0f, // # frames oversize - RxJabbers = 0x10, // # frames oversize w/ crc err - RxSize64 = 0x11, // # frames 64 octets long - RxSize65To127 = 0x12, // # frames 65-127 octets - RxSize128To255 = 0x13, // # frames 128-255 - RxSize256To511 = 0x14, // # frames 256-511 - RxSize512To1023 = 0x15, // # frames 512-1023 - RxSize1024To1518 = 0x16, // # frames 1024-1518 - RxSize1519ToMax = 0x17, // # frames 1519-max +#define REG_TX_OUT_BYTES(pn) CRA(0x4,pn,0x18) /* # octets tx */ +#define REG_TX_PAUSE(pn) CRA(0x4,pn,0x19) /* # pause frames sent */ +#define REG_TX_OK_BYTES(pn) CRA(0x4,pn,0x1a) /* # octets tx OK */ +#define REG_TX_UNICAST(pn) CRA(0x4,pn,0x1b) /* # frames unicast */ +#define REG_TX_MULTICAST(pn) CRA(0x4,pn,0x1c) /* # frames multicast */ +#define REG_TX_BROADCAST(pn) CRA(0x4,pn,0x1d) /* # frames broadcast */ +#define REG_TX_MULTIPLE_COLL(pn) CRA(0x4,pn,0x1e) /* # frames tx after multiple collisions */ +#define REG_TX_LATE_COLL(pn) CRA(0x4,pn,0x1f) /* # late collisions detected */ +#define REG_TX_XCOLL(pn) CRA(0x4,pn,0x20) /* # frames lost, excessive collisions */ +#define REG_TX_DEFER(pn) CRA(0x4,pn,0x21) /* # frames deferred on first tx attempt */ +#define REG_TX_XDEFER(pn) CRA(0x4,pn,0x22) /* # frames excessively deferred */ +#define REG_TX_CSENSE(pn) CRA(0x4,pn,0x23) /* carrier sense errors at frame end */ +#define REG_TX_SIZE_64(pn) CRA(0x4,pn,0x24) /* # frames 64 octets long */ +#define REG_TX_SIZE_65_TO_127(pn) CRA(0x4,pn,0x25) /* # frames 65-127 octets */ +#define REG_TX_SIZE_128_TO_255(pn) CRA(0x4,pn,0x26) /* # frames 128-255 */ +#define REG_TX_SIZE_256_TO_511(pn) CRA(0x4,pn,0x27) /* # frames 256-511 */ +#define REG_TX_SIZE_512_TO_1023(pn) CRA(0x4,pn,0x28) /* # frames 512-1023 */ +#define REG_TX_SIZE_1024_TO_1518(pn) CRA(0x4,pn,0x29) /* # frames 1024-1518 */ +#define REG_TX_SIZE_1519_TO_MAX(pn) CRA(0x4,pn,0x2a) /* # frames 1519-max */ +#define REG_TX_SINGLE_COLL(pn) CRA(0x4,pn,0x2b) /* # frames tx after single collision */ +#define REG_TX_BACKOFF2(pn) CRA(0x4,pn,0x2c) /* # frames tx ok after 2 backoffs/collisions */ +#define REG_TX_BACKOFF3(pn) CRA(0x4,pn,0x2d) /* after 3 backoffs/collisions */ +#define REG_TX_BACKOFF4(pn) CRA(0x4,pn,0x2e) /* after 4 */ +#define REG_TX_BACKOFF5(pn) CRA(0x4,pn,0x2f) /* after 5 */ +#define REG_TX_BACKOFF6(pn) CRA(0x4,pn,0x30) /* after 6 */ +#define REG_TX_BACKOFF7(pn) CRA(0x4,pn,0x31) /* after 7 */ +#define REG_TX_BACKOFF8(pn) CRA(0x4,pn,0x32) /* after 8 */ +#define REG_TX_BACKOFF9(pn) CRA(0x4,pn,0x33) /* after 9 */ +#define REG_TX_BACKOFF10(pn) CRA(0x4,pn,0x34) /* after 10 */ +#define REG_TX_BACKOFF11(pn) CRA(0x4,pn,0x35) /* after 11 */ +#define REG_TX_BACKOFF12(pn) CRA(0x4,pn,0x36) /* after 12 */ +#define REG_TX_BACKOFF13(pn) CRA(0x4,pn,0x37) /* after 13 */ +#define REG_TX_BACKOFF14(pn) CRA(0x4,pn,0x38) /* after 14 */ +#define REG_TX_BACKOFF15(pn) CRA(0x4,pn,0x39) /* after 15 */ +#define REG_TX_UNDERRUN(pn) CRA(0x4,pn,0x3a) /* # frames dropped from underrun */ +#define REG_RX_XGMII_PROT_ERR CRA(0x4,0xa,0x3b) /* # protocol errors detected on XGMII interface */ +#define REG_RX_IPG_SHRINK(pn) CRA(0x4,pn,0x3c) /* # of IPG shrinks detected */ - TxOutBytes = 0x18, // # octets tx - TxPause = 0x19, // # pause frames sent - TxOkBytes = 0x1a, // # octets tx OK - TxUnicast = 0x1b, // # frames unicast - TxMulticast = 0x1c, // # frames multicast - TxBroadcast = 0x1d, // # frames broadcast - TxMultipleColl = 0x1e, // # frames tx after multiple collisions - TxLateColl = 0x1f, // # late collisions detected - TxXcoll = 0x20, // # frames lost, excessive collisions - TxDefer = 0x21, // # frames deferred on first tx attempt - TxXdefer = 0x22, // # frames excessively deferred - TxCsense = 0x23, // carrier sense errors at frame end - TxSize64 = 0x24, // # frames 64 octets long - TxSize65To127 = 0x25, // # frames 65-127 octets - TxSize128To255 = 0x26, // # frames 128-255 - TxSize256To511 = 0x27, // # frames 256-511 - TxSize512To1023 = 0x28, // # frames 512-1023 - TxSize1024To1518 = 0x29, // # frames 1024-1518 - TxSize1519ToMax = 0x2a, // # frames 1519-max - TxSingleColl = 0x2b, // # frames tx after single collision - TxBackoff2 = 0x2c, // # frames tx ok after 2 backoffs/collisions - TxBackoff3 = 0x2d, // after 3 backoffs/collisions - TxBackoff4 = 0x2e, // after 4 - TxBackoff5 = 0x2f, // after 5 - TxBackoff6 = 0x30, // after 6 - TxBackoff7 = 0x31, // after 7 - TxBackoff8 = 0x32, // after 8 - TxBackoff9 = 0x33, // after 9 - TxBackoff10 = 0x34, // after 10 - TxBackoff11 = 0x35, // after 11 - TxBackoff12 = 0x36, // after 12 - TxBackoff13 = 0x37, // after 13 - TxBackoff14 = 0x38, // after 14 - TxBackoff15 = 0x39, // after 15 - TxUnderrun = 0x3a, // # frames dropped from underrun - // Hole. See REG_RX_XGMII_PROT_ERR below. - RxIpgShrink = 0x3c, // # of IPG shrinks detected - // Duplicate. See REG_STAT_STICKY10G below. - StatSticky1G = 0x3e, // tri-speed sticky bits - StatInit = 0x3f // Clear all statistics -}; - -#define REG_RX_XGMII_PROT_ERR CRA(0x4,0xa,0x3b) /* # protocol errors detected on XGMII interface */ -#define REG_STAT_STICKY10G CRA(0x4,0xa,StatSticky1G) /* 10GbE sticky bits */ - -#define REG_RX_OK_BYTES(pn) CRA(0x4,pn,RxOkBytes) -#define REG_RX_BAD_BYTES(pn) CRA(0x4,pn,RxBadBytes) -#define REG_TX_OK_BYTES(pn) CRA(0x4,pn,TxOkBytes) +#define REG_STAT_STICKY1G(pn) CRA(0x4,pn,0x3e) /* tri-speed sticky bits */ +#define REG_STAT_STICKY10G CRA(0x4,0xa,0x3e) /* 10GbE sticky bits */ +#define REG_STAT_INIT(pn) CRA(0x4,pn,0x3f) /* Clear all statistics */ /* MII-Management Block registers */ /* These are for MII-M interface 0, which is the bidirectional LVTTL one. If diff --git a/trunk/drivers/net/chelsio/vsc8244.c b/trunk/drivers/net/chelsio/vsc8244.c index 251d4859c91d..c493e783d459 100644 --- a/trunk/drivers/net/chelsio/vsc8244.c +++ b/trunk/drivers/net/chelsio/vsc8244.c @@ -54,7 +54,7 @@ enum { }; #define CFG_CHG_INTR_MASK (VSC_INTR_LINK_CHG | VSC_INTR_NEG_ERR | \ - VSC_INTR_NEG_DONE) + VSC_INTR_NEG_DONE) #define INTR_MASK (CFG_CHG_INTR_MASK | VSC_INTR_TX_FIFO | VSC_INTR_RX_FIFO | \ VSC_INTR_ENABLE) @@ -94,18 +94,19 @@ static int vsc8244_intr_enable(struct cphy *cphy) { simple_mdio_write(cphy, VSC8244_INTR_ENABLE, INTR_MASK); - /* Enable interrupts through Elmer */ + /* Enable interrupts through Elmer */ if (t1_is_asic(cphy->adapter)) { u32 elmer; t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer); elmer |= ELMER0_GP_BIT1; - if (is_T2(cphy->adapter)) + if (is_T2(cphy->adapter)) { elmer |= ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4; + } t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer); } - return 0; + return 0; } static int vsc8244_intr_disable(struct cphy *cphy) @@ -117,18 +118,19 @@ static int vsc8244_intr_disable(struct cphy *cphy) t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer); elmer &= ~ELMER0_GP_BIT1; - if (is_T2(cphy->adapter)) + if (is_T2(cphy->adapter)) { elmer &= ~(ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4); + } t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer); } - return 0; + return 0; } static int vsc8244_intr_clear(struct cphy *cphy) { u32 val; - u32 elmer; + u32 elmer; /* Clear PHY interrupts by reading the register. */ simple_mdio_read(cphy, VSC8244_INTR_ENABLE, &val); @@ -136,12 +138,13 @@ static int vsc8244_intr_clear(struct cphy *cphy) if (t1_is_asic(cphy->adapter)) { t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer); elmer |= ELMER0_GP_BIT1; - if (is_T2(cphy->adapter)) + if (is_T2(cphy->adapter)) { elmer |= ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4; + } t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer); } - return 0; + return 0; } /* @@ -176,13 +179,13 @@ static int vsc8244_set_speed_duplex(struct cphy *phy, int speed, int duplex) int t1_mdio_set_bits(struct cphy *phy, int mmd, int reg, unsigned int bits) { - int ret; - unsigned int val; + int ret; + unsigned int val; - ret = mdio_read(phy, mmd, reg, &val); - if (!ret) - ret = mdio_write(phy, mmd, reg, val | bits); - return ret; + ret = mdio_read(phy, mmd, reg, &val); + if (!ret) + ret = mdio_write(phy, mmd, reg, val | bits); + return ret; } static int vsc8244_autoneg_enable(struct cphy *cphy) @@ -232,7 +235,7 @@ static int vsc8244_advertise(struct cphy *phy, unsigned int advertise_map) } static int vsc8244_get_link_status(struct cphy *cphy, int *link_ok, - int *speed, int *duplex, int *fc) + int *speed, int *duplex, int *fc) { unsigned int bmcr, status, lpa, adv; int err, sp = -1, dplx = -1, pause = 0; @@ -340,13 +343,11 @@ static struct cphy_ops vsc8244_ops = { .get_link_status = vsc8244_get_link_status }; -static struct cphy* vsc8244_phy_create(adapter_t *adapter, int phy_addr, - struct mdio_ops *mdio_ops) +static struct cphy* vsc8244_phy_create(adapter_t *adapter, int phy_addr, struct mdio_ops *mdio_ops) { struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL); - if (!cphy) - return NULL; + if (!cphy) return NULL; cphy_init(cphy, adapter, phy_addr, &vsc8244_ops, mdio_ops); diff --git a/trunk/drivers/net/cxgb3/Makefile b/trunk/drivers/net/cxgb3/Makefile deleted file mode 100644 index 343467985321..000000000000 --- a/trunk/drivers/net/cxgb3/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Chelsio T3 driver -# - -obj-$(CONFIG_CHELSIO_T3) += cxgb3.o - -cxgb3-objs := cxgb3_main.o ael1002.o vsc8211.o t3_hw.o mc5.o \ - xgmac.o sge.o l2t.o cxgb3_offload.o diff --git a/trunk/drivers/net/cxgb3/adapter.h b/trunk/drivers/net/cxgb3/adapter.h deleted file mode 100644 index 5c97a64451ce..000000000000 --- a/trunk/drivers/net/cxgb3/adapter.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* This file should not be included directly. Include common.h instead. */ - -#ifndef __T3_ADAPTER_H__ -#define __T3_ADAPTER_H__ - -#include -#include -#include -#include -#include -#include -#include "t3cdev.h" -#include -#include -#include - -typedef irqreturn_t(*intr_handler_t) (int, void *); - -struct vlan_group; - -struct port_info { - struct vlan_group *vlan_grp; - const struct port_type_info *port_type; - u8 port_id; - u8 rx_csum_offload; - u8 nqsets; - u8 first_qset; - struct cphy phy; - struct cmac mac; - struct link_config link_config; - struct net_device_stats netstats; - int activity; -}; - -enum { /* adapter flags */ - FULL_INIT_DONE = (1 << 0), - USING_MSI = (1 << 1), - USING_MSIX = (1 << 2), - QUEUES_BOUND = (1 << 3), -}; - -struct rx_desc; -struct rx_sw_desc; - -struct sge_fl { /* SGE per free-buffer list state */ - unsigned int buf_size; /* size of each Rx buffer */ - unsigned int credits; /* # of available Rx buffers */ - unsigned int size; /* capacity of free list */ - unsigned int cidx; /* consumer index */ - unsigned int pidx; /* producer index */ - unsigned int gen; /* free list generation */ - struct rx_desc *desc; /* address of HW Rx descriptor ring */ - struct rx_sw_desc *sdesc; /* address of SW Rx descriptor ring */ - dma_addr_t phys_addr; /* physical address of HW ring start */ - unsigned int cntxt_id; /* SGE context id for the free list */ - unsigned long empty; /* # of times queue ran out of buffers */ -}; - -/* - * Bundle size for grouping offload RX packets for delivery to the stack. - * Don't make this too big as we do prefetch on each packet in a bundle. - */ -# define RX_BUNDLE_SIZE 8 - -struct rsp_desc; - -struct sge_rspq { /* state for an SGE response queue */ - unsigned int credits; /* # of pending response credits */ - unsigned int size; /* capacity of response queue */ - unsigned int cidx; /* consumer index */ - unsigned int gen; /* current generation bit */ - unsigned int polling; /* is the queue serviced through NAPI? */ - unsigned int holdoff_tmr; /* interrupt holdoff timer in 100ns */ - unsigned int next_holdoff; /* holdoff time for next interrupt */ - struct rsp_desc *desc; /* address of HW response ring */ - dma_addr_t phys_addr; /* physical address of the ring */ - unsigned int cntxt_id; /* SGE context id for the response q */ - spinlock_t lock; /* guards response processing */ - struct sk_buff *rx_head; /* offload packet receive queue head */ - struct sk_buff *rx_tail; /* offload packet receive queue tail */ - - unsigned long offload_pkts; - unsigned long offload_bundles; - unsigned long eth_pkts; /* # of ethernet packets */ - unsigned long pure_rsps; /* # of pure (non-data) responses */ - unsigned long imm_data; /* responses with immediate data */ - unsigned long rx_drops; /* # of packets dropped due to no mem */ - unsigned long async_notif; /* # of asynchronous notification events */ - unsigned long empty; /* # of times queue ran out of credits */ - unsigned long nomem; /* # of responses deferred due to no mem */ - unsigned long unhandled_irqs; /* # of spurious intrs */ -}; - -struct tx_desc; -struct tx_sw_desc; - -struct sge_txq { /* state for an SGE Tx queue */ - unsigned long flags; /* HW DMA fetch status */ - unsigned int in_use; /* # of in-use Tx descriptors */ - unsigned int size; /* # of descriptors */ - unsigned int processed; /* total # of descs HW has processed */ - unsigned int cleaned; /* total # of descs SW has reclaimed */ - unsigned int stop_thres; /* SW TX queue suspend threshold */ - unsigned int cidx; /* consumer index */ - unsigned int pidx; /* producer index */ - unsigned int gen; /* current value of generation bit */ - unsigned int unacked; /* Tx descriptors used since last COMPL */ - struct tx_desc *desc; /* address of HW Tx descriptor ring */ - struct tx_sw_desc *sdesc; /* address of SW Tx descriptor ring */ - spinlock_t lock; /* guards enqueueing of new packets */ - unsigned int token; /* WR token */ - dma_addr_t phys_addr; /* physical address of the ring */ - struct sk_buff_head sendq; /* List of backpressured offload packets */ - struct tasklet_struct qresume_tsk; /* restarts the queue */ - unsigned int cntxt_id; /* SGE context id for the Tx q */ - unsigned long stops; /* # of times q has been stopped */ - unsigned long restarts; /* # of queue restarts */ -}; - -enum { /* per port SGE statistics */ - SGE_PSTAT_TSO, /* # of TSO requests */ - SGE_PSTAT_RX_CSUM_GOOD, /* # of successful RX csum offloads */ - SGE_PSTAT_TX_CSUM, /* # of TX checksum offloads */ - SGE_PSTAT_VLANEX, /* # of VLAN tag extractions */ - SGE_PSTAT_VLANINS, /* # of VLAN tag insertions */ - - SGE_PSTAT_MAX /* must be last */ -}; - -struct sge_qset { /* an SGE queue set */ - struct sge_rspq rspq; - struct sge_fl fl[SGE_RXQ_PER_SET]; - struct sge_txq txq[SGE_TXQ_PER_SET]; - struct net_device *netdev; /* associated net device */ - unsigned long txq_stopped; /* which Tx queues are stopped */ - struct timer_list tx_reclaim_timer; /* reclaims TX buffers */ - unsigned long port_stats[SGE_PSTAT_MAX]; -} ____cacheline_aligned; - -struct sge { - struct sge_qset qs[SGE_QSETS]; - spinlock_t reg_lock; /* guards non-atomic SGE registers (eg context) */ -}; - -struct adapter { - struct t3cdev tdev; - struct list_head adapter_list; - void __iomem *regs; - struct pci_dev *pdev; - unsigned long registered_device_map; - unsigned long open_device_map; - unsigned long flags; - - const char *name; - int msg_enable; - unsigned int mmio_len; - - struct adapter_params params; - unsigned int slow_intr_mask; - unsigned long irq_stats[IRQ_NUM_STATS]; - - struct { - unsigned short vec; - char desc[22]; - } msix_info[SGE_QSETS + 1]; - - /* T3 modules */ - struct sge sge; - struct mc7 pmrx; - struct mc7 pmtx; - struct mc7 cm; - struct mc5 mc5; - - struct net_device *port[MAX_NPORTS]; - unsigned int check_task_cnt; - struct delayed_work adap_check_task; - struct work_struct ext_intr_handler_task; - - /* - * Dummy netdevices are needed when using multiple receive queues with - * NAPI as each netdevice can service only one queue. - */ - struct net_device *dummy_netdev[SGE_QSETS - 1]; - - struct dentry *debugfs_root; - - struct mutex mdio_lock; - spinlock_t stats_lock; - spinlock_t work_lock; -}; - -static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr) -{ - u32 val = readl(adapter->regs + reg_addr); - - CH_DBG(adapter, MMIO, "read register 0x%x value 0x%x\n", reg_addr, val); - return val; -} - -static inline void t3_write_reg(struct adapter *adapter, u32 reg_addr, u32 val) -{ - CH_DBG(adapter, MMIO, "setting register 0x%x to 0x%x\n", reg_addr, val); - writel(val, adapter->regs + reg_addr); -} - -static inline struct port_info *adap2pinfo(struct adapter *adap, int idx) -{ - return netdev_priv(adap->port[idx]); -} - -/* - * We use the spare atalk_ptr to map a net device to its SGE queue set. - * This is a macro so it can be used as l-value. - */ -#define dev2qset(netdev) ((netdev)->atalk_ptr) - -#define OFFLOAD_DEVMAP_BIT 15 - -#define tdev2adap(d) container_of(d, struct adapter, tdev) - -static inline int offload_running(struct adapter *adapter) -{ - return test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map); -} - -int t3_offload_tx(struct t3cdev *tdev, struct sk_buff *skb); - -void t3_os_ext_intr_handler(struct adapter *adapter); -void t3_os_link_changed(struct adapter *adapter, int port_id, int link_status, - int speed, int duplex, int fc); - -void t3_sge_start(struct adapter *adap); -void t3_sge_stop(struct adapter *adap); -void t3_free_sge_resources(struct adapter *adap); -void t3_sge_err_intr_handler(struct adapter *adapter); -intr_handler_t t3_intr_handler(struct adapter *adap, int polling); -int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev); -int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb); -void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p); -int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, - int irq_vec_idx, const struct qset_params *p, - int ntxq, struct net_device *netdev); -int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, - unsigned char *data); -irqreturn_t t3_sge_intr_msix(int irq, void *cookie); - -#endif /* __T3_ADAPTER_H__ */ diff --git a/trunk/drivers/net/cxgb3/ael1002.c b/trunk/drivers/net/cxgb3/ael1002.c deleted file mode 100644 index 73a41e6a5bfc..000000000000 --- a/trunk/drivers/net/cxgb3/ael1002.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "common.h" -#include "regs.h" - -enum { - AEL100X_TX_DISABLE = 9, - AEL100X_TX_CONFIG1 = 0xc002, - AEL1002_PWR_DOWN_HI = 0xc011, - AEL1002_PWR_DOWN_LO = 0xc012, - AEL1002_XFI_EQL = 0xc015, - AEL1002_LB_EN = 0xc017, - - LASI_CTRL = 0x9002, - LASI_STAT = 0x9005 -}; - -static void ael100x_txon(struct cphy *phy) -{ - int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; - - msleep(100); - t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); - msleep(30); -} - -static int ael1002_power_down(struct cphy *phy, int enable) -{ - int err; - - err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable); - if (!err) - err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, - BMCR_PDOWN, enable ? BMCR_PDOWN : 0); - return err; -} - -static int ael1002_reset(struct cphy *phy, int wait) -{ - int err; - - if ((err = ael1002_power_down(phy, 0)) || - (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) || - (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) || - (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) || - (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) || - (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN, - 0, 1 << 5))) - return err; - return 0; -} - -static int ael1002_intr_noop(struct cphy *phy) -{ - return 0; -} - -static int ael100x_get_link_status(struct cphy *phy, int *link_ok, - int *speed, int *duplex, int *fc) -{ - if (link_ok) { - unsigned int status; - int err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &status); - - /* - * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it - * once more to get the current link state. - */ - if (!err && !(status & BMSR_LSTATUS)) - err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, - &status); - if (err) - return err; - *link_ok = !!(status & BMSR_LSTATUS); - } - if (speed) - *speed = SPEED_10000; - if (duplex) - *duplex = DUPLEX_FULL; - return 0; -} - -static struct cphy_ops ael1002_ops = { - .reset = ael1002_reset, - .intr_enable = ael1002_intr_noop, - .intr_disable = ael1002_intr_noop, - .intr_clear = ael1002_intr_noop, - .intr_handler = ael1002_intr_noop, - .get_link_status = ael100x_get_link_status, - .power_down = ael1002_power_down, -}; - -void t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops) -{ - cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops); - ael100x_txon(phy); -} - -static int ael1006_reset(struct cphy *phy, int wait) -{ - return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); -} - -static int ael1006_intr_enable(struct cphy *phy) -{ - return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1); -} - -static int ael1006_intr_disable(struct cphy *phy) -{ - return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0); -} - -static int ael1006_intr_clear(struct cphy *phy) -{ - u32 val; - - return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val); -} - -static int ael1006_intr_handler(struct cphy *phy) -{ - unsigned int status; - int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status); - - if (err) - return err; - return (status & 1) ? cphy_cause_link_change : 0; -} - -static int ael1006_power_down(struct cphy *phy, int enable) -{ - return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, - BMCR_PDOWN, enable ? BMCR_PDOWN : 0); -} - -static struct cphy_ops ael1006_ops = { - .reset = ael1006_reset, - .intr_enable = ael1006_intr_enable, - .intr_disable = ael1006_intr_disable, - .intr_clear = ael1006_intr_clear, - .intr_handler = ael1006_intr_handler, - .get_link_status = ael100x_get_link_status, - .power_down = ael1006_power_down, -}; - -void t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops) -{ - cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops); - ael100x_txon(phy); -} - -static struct cphy_ops qt2045_ops = { - .reset = ael1006_reset, - .intr_enable = ael1006_intr_enable, - .intr_disable = ael1006_intr_disable, - .intr_clear = ael1006_intr_clear, - .intr_handler = ael1006_intr_handler, - .get_link_status = ael100x_get_link_status, - .power_down = ael1006_power_down, -}; - -void t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops) -{ - unsigned int stat; - - cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops); - - /* - * Some cards where the PHY is supposed to be at address 0 actually - * have it at 1. - */ - if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) && - stat == 0xffff) - phy->addr = 1; -} - -static int xaui_direct_reset(struct cphy *phy, int wait) -{ - return 0; -} - -static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, - int *speed, int *duplex, int *fc) -{ - if (link_ok) { - unsigned int status; - - status = t3_read_reg(phy->adapter, - XGM_REG(A_XGM_SERDES_STAT0, phy->addr)); - *link_ok = !(status & F_LOWSIG0); - } - if (speed) - *speed = SPEED_10000; - if (duplex) - *duplex = DUPLEX_FULL; - return 0; -} - -static int xaui_direct_power_down(struct cphy *phy, int enable) -{ - return 0; -} - -static struct cphy_ops xaui_direct_ops = { - .reset = xaui_direct_reset, - .intr_enable = ael1002_intr_noop, - .intr_disable = ael1002_intr_noop, - .intr_clear = ael1002_intr_noop, - .intr_handler = ael1002_intr_noop, - .get_link_status = xaui_direct_get_link_status, - .power_down = xaui_direct_power_down, -}; - -void t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops) -{ - cphy_init(phy, adapter, 1, &xaui_direct_ops, mdio_ops); -} diff --git a/trunk/drivers/net/cxgb3/common.h b/trunk/drivers/net/cxgb3/common.h deleted file mode 100644 index e23deeb7d06d..000000000000 --- a/trunk/drivers/net/cxgb3/common.h +++ /dev/null @@ -1,729 +0,0 @@ -/* - * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __CHELSIO_COMMON_H -#define __CHELSIO_COMMON_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "version.h" - -#define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__) -#define CH_WARN(adap, fmt, ...) dev_warn(&adap->pdev->dev, fmt, ## __VA_ARGS__) -#define CH_ALERT(adap, fmt, ...) \ - dev_printk(KERN_ALERT, &adap->pdev->dev, fmt, ## __VA_ARGS__) - -/* - * More powerful macro that selectively prints messages based on msg_enable. - * For info and debugging messages. - */ -#define CH_MSG(adapter, level, category, fmt, ...) do { \ - if ((adapter)->msg_enable & NETIF_MSG_##category) \ - dev_printk(KERN_##level, &adapter->pdev->dev, fmt, \ - ## __VA_ARGS__); \ -} while (0) - -#ifdef DEBUG -# define CH_DBG(adapter, category, fmt, ...) \ - CH_MSG(adapter, DEBUG, category, fmt, ## __VA_ARGS__) -#else -# define CH_DBG(adapter, category, fmt, ...) -#endif - -/* Additional NETIF_MSG_* categories */ -#define NETIF_MSG_MMIO 0x8000000 - -struct t3_rx_mode { - struct net_device *dev; - struct dev_mc_list *mclist; - unsigned int idx; -}; - -static inline void init_rx_mode(struct t3_rx_mode *p, struct net_device *dev, - struct dev_mc_list *mclist) -{ - p->dev = dev; - p->mclist = mclist; - p->idx = 0; -} - -static inline u8 *t3_get_next_mcaddr(struct t3_rx_mode *rm) -{ - u8 *addr = NULL; - - if (rm->mclist && rm->idx < rm->dev->mc_count) { - addr = rm->mclist->dmi_addr; - rm->mclist = rm->mclist->next; - rm->idx++; - } - return addr; -} - -enum { - MAX_NPORTS = 2, /* max # of ports */ - MAX_FRAME_SIZE = 10240, /* max MAC frame size, including header + FCS */ - EEPROMSIZE = 8192, /* Serial EEPROM size */ - RSS_TABLE_SIZE = 64, /* size of RSS lookup and mapping tables */ - TCB_SIZE = 128, /* TCB size */ - NMTUS = 16, /* size of MTU table */ - NCCTRL_WIN = 32, /* # of congestion control windows */ -}; - -#define MAX_RX_COALESCING_LEN 16224U - -enum { - PAUSE_RX = 1 << 0, - PAUSE_TX = 1 << 1, - PAUSE_AUTONEG = 1 << 2 -}; - -enum { - SUPPORTED_OFFLOAD = 1 << 24, - SUPPORTED_IRQ = 1 << 25 -}; - -enum { /* adapter interrupt-maintained statistics */ - STAT_ULP_CH0_PBL_OOB, - STAT_ULP_CH1_PBL_OOB, - STAT_PCI_CORR_ECC, - - IRQ_NUM_STATS /* keep last */ -}; - -enum { - SGE_QSETS = 8, /* # of SGE Tx/Rx/RspQ sets */ - SGE_RXQ_PER_SET = 2, /* # of Rx queues per set */ - SGE_TXQ_PER_SET = 3 /* # of Tx queues per set */ -}; - -enum sge_context_type { /* SGE egress context types */ - SGE_CNTXT_RDMA = 0, - SGE_CNTXT_ETH = 2, - SGE_CNTXT_OFLD = 4, - SGE_CNTXT_CTRL = 5 -}; - -enum { - AN_PKT_SIZE = 32, /* async notification packet size */ - IMMED_PKT_SIZE = 48 /* packet size for immediate data */ -}; - -struct sg_ent { /* SGE scatter/gather entry */ - u32 len[2]; - u64 addr[2]; -}; - -#ifndef SGE_NUM_GENBITS -/* Must be 1 or 2 */ -# define SGE_NUM_GENBITS 2 -#endif - -#define TX_DESC_FLITS 16U -#define WR_FLITS (TX_DESC_FLITS + 1 - SGE_NUM_GENBITS) - -struct cphy; -struct adapter; - -struct mdio_ops { - int (*read)(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *val); - int (*write)(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val); -}; - -struct adapter_info { - unsigned char nports; /* # of ports */ - unsigned char phy_base_addr; /* MDIO PHY base address */ - unsigned char mdien; - unsigned char mdiinv; - unsigned int gpio_out; /* GPIO output settings */ - unsigned int gpio_intr; /* GPIO IRQ enable mask */ - unsigned long caps; /* adapter capabilities */ - const struct mdio_ops *mdio_ops; /* MDIO operations */ - const char *desc; /* product description */ -}; - -struct port_type_info { - void (*phy_prep)(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *ops); - unsigned int caps; - const char *desc; -}; - -struct mc5_stats { - unsigned long parity_err; - unsigned long active_rgn_full; - unsigned long nfa_srch_err; - unsigned long unknown_cmd; - unsigned long reqq_parity_err; - unsigned long dispq_parity_err; - unsigned long del_act_empty; -}; - -struct mc7_stats { - unsigned long corr_err; - unsigned long uncorr_err; - unsigned long parity_err; - unsigned long addr_err; -}; - -struct mac_stats { - u64 tx_octets; /* total # of octets in good frames */ - u64 tx_octets_bad; /* total # of octets in error frames */ - u64 tx_frames; /* all good frames */ - u64 tx_mcast_frames; /* good multicast frames */ - u64 tx_bcast_frames; /* good broadcast frames */ - u64 tx_pause; /* # of transmitted pause frames */ - u64 tx_deferred; /* frames with deferred transmissions */ - u64 tx_late_collisions; /* # of late collisions */ - u64 tx_total_collisions; /* # of total collisions */ - u64 tx_excess_collisions; /* frame errors from excessive collissions */ - u64 tx_underrun; /* # of Tx FIFO underruns */ - u64 tx_len_errs; /* # of Tx length errors */ - u64 tx_mac_internal_errs; /* # of internal MAC errors on Tx */ - u64 tx_excess_deferral; /* # of frames with excessive deferral */ - u64 tx_fcs_errs; /* # of frames with bad FCS */ - - u64 tx_frames_64; /* # of Tx frames in a particular range */ - u64 tx_frames_65_127; - u64 tx_frames_128_255; - u64 tx_frames_256_511; - u64 tx_frames_512_1023; - u64 tx_frames_1024_1518; - u64 tx_frames_1519_max; - - u64 rx_octets; /* total # of octets in good frames */ - u64 rx_octets_bad; /* total # of octets in error frames */ - u64 rx_frames; /* all good frames */ - u64 rx_mcast_frames; /* good multicast frames */ - u64 rx_bcast_frames; /* good broadcast frames */ - u64 rx_pause; /* # of received pause frames */ - u64 rx_fcs_errs; /* # of received frames with bad FCS */ - u64 rx_align_errs; /* alignment errors */ - u64 rx_symbol_errs; /* symbol errors */ - u64 rx_data_errs; /* data errors */ - u64 rx_sequence_errs; /* sequence errors */ - u64 rx_runt; /* # of runt frames */ - u64 rx_jabber; /* # of jabber frames */ - u64 rx_short; /* # of short frames */ - u64 rx_too_long; /* # of oversized frames */ - u64 rx_mac_internal_errs; /* # of internal MAC errors on Rx */ - - u64 rx_frames_64; /* # of Rx frames in a particular range */ - u64 rx_frames_65_127; - u64 rx_frames_128_255; - u64 rx_frames_256_511; - u64 rx_frames_512_1023; - u64 rx_frames_1024_1518; - u64 rx_frames_1519_max; - - u64 rx_cong_drops; /* # of Rx drops due to SGE congestion */ - - unsigned long tx_fifo_parity_err; - unsigned long rx_fifo_parity_err; - unsigned long tx_fifo_urun; - unsigned long rx_fifo_ovfl; - unsigned long serdes_signal_loss; - unsigned long xaui_pcs_ctc_err; - unsigned long xaui_pcs_align_change; -}; - -struct tp_mib_stats { - u32 ipInReceive_hi; - u32 ipInReceive_lo; - u32 ipInHdrErrors_hi; - u32 ipInHdrErrors_lo; - u32 ipInAddrErrors_hi; - u32 ipInAddrErrors_lo; - u32 ipInUnknownProtos_hi; - u32 ipInUnknownProtos_lo; - u32 ipInDiscards_hi; - u32 ipInDiscards_lo; - u32 ipInDelivers_hi; - u32 ipInDelivers_lo; - u32 ipOutRequests_hi; - u32 ipOutRequests_lo; - u32 ipOutDiscards_hi; - u32 ipOutDiscards_lo; - u32 ipOutNoRoutes_hi; - u32 ipOutNoRoutes_lo; - u32 ipReasmTimeout; - u32 ipReasmReqds; - u32 ipReasmOKs; - u32 ipReasmFails; - - u32 reserved[8]; - - u32 tcpActiveOpens; - u32 tcpPassiveOpens; - u32 tcpAttemptFails; - u32 tcpEstabResets; - u32 tcpOutRsts; - u32 tcpCurrEstab; - u32 tcpInSegs_hi; - u32 tcpInSegs_lo; - u32 tcpOutSegs_hi; - u32 tcpOutSegs_lo; - u32 tcpRetransSeg_hi; - u32 tcpRetransSeg_lo; - u32 tcpInErrs_hi; - u32 tcpInErrs_lo; - u32 tcpRtoMin; - u32 tcpRtoMax; -}; - -struct tp_params { - unsigned int nchan; /* # of channels */ - unsigned int pmrx_size; /* total PMRX capacity */ - unsigned int pmtx_size; /* total PMTX capacity */ - unsigned int cm_size; /* total CM capacity */ - unsigned int chan_rx_size; /* per channel Rx size */ - unsigned int chan_tx_size; /* per channel Tx size */ - unsigned int rx_pg_size; /* Rx page size */ - unsigned int tx_pg_size; /* Tx page size */ - unsigned int rx_num_pgs; /* # of Rx pages */ - unsigned int tx_num_pgs; /* # of Tx pages */ - unsigned int ntimer_qs; /* # of timer queues */ -}; - -struct qset_params { /* SGE queue set parameters */ - unsigned int polling; /* polling/interrupt service for rspq */ - unsigned int coalesce_usecs; /* irq coalescing timer */ - unsigned int rspq_size; /* # of entries in response queue */ - unsigned int fl_size; /* # of entries in regular free list */ - unsigned int jumbo_size; /* # of entries in jumbo free list */ - unsigned int txq_size[SGE_TXQ_PER_SET]; /* Tx queue sizes */ - unsigned int cong_thres; /* FL congestion threshold */ -}; - -struct sge_params { - unsigned int max_pkt_size; /* max offload pkt size */ - struct qset_params qset[SGE_QSETS]; -}; - -struct mc5_params { - unsigned int mode; /* selects MC5 width */ - unsigned int nservers; /* size of server region */ - unsigned int nfilters; /* size of filter region */ - unsigned int nroutes; /* size of routing region */ -}; - -/* Default MC5 region sizes */ -enum { - DEFAULT_NSERVERS = 512, - DEFAULT_NFILTERS = 128 -}; - -/* MC5 modes, these must be non-0 */ -enum { - MC5_MODE_144_BIT = 1, - MC5_MODE_72_BIT = 2 -}; - -struct vpd_params { - unsigned int cclk; - unsigned int mclk; - unsigned int uclk; - unsigned int mdc; - unsigned int mem_timing; - u8 eth_base[6]; - u8 port_type[MAX_NPORTS]; - unsigned short xauicfg[2]; -}; - -struct pci_params { - unsigned int vpd_cap_addr; - unsigned int pcie_cap_addr; - unsigned short speed; - unsigned char width; - unsigned char variant; -}; - -enum { - PCI_VARIANT_PCI, - PCI_VARIANT_PCIX_MODE1_PARITY, - PCI_VARIANT_PCIX_MODE1_ECC, - PCI_VARIANT_PCIX_266_MODE2, - PCI_VARIANT_PCIE -}; - -struct adapter_params { - struct sge_params sge; - struct mc5_params mc5; - struct tp_params tp; - struct vpd_params vpd; - struct pci_params pci; - - const struct adapter_info *info; - - unsigned short mtus[NMTUS]; - unsigned short a_wnd[NCCTRL_WIN]; - unsigned short b_wnd[NCCTRL_WIN]; - - unsigned int nports; /* # of ethernet ports */ - unsigned int stats_update_period; /* MAC stats accumulation period */ - unsigned int linkpoll_period; /* link poll period in 0.1s */ - unsigned int rev; /* chip revision */ -}; - -struct trace_params { - u32 sip; - u32 sip_mask; - u32 dip; - u32 dip_mask; - u16 sport; - u16 sport_mask; - u16 dport; - u16 dport_mask; - u32 vlan:12; - u32 vlan_mask:12; - u32 intf:4; - u32 intf_mask:4; - u8 proto; - u8 proto_mask; -}; - -struct link_config { - unsigned int supported; /* link capabilities */ - unsigned int advertising; /* advertised capabilities */ - unsigned short requested_speed; /* speed user has requested */ - unsigned short speed; /* actual link speed */ - unsigned char requested_duplex; /* duplex user has requested */ - unsigned char duplex; /* actual link duplex */ - unsigned char requested_fc; /* flow control user has requested */ - unsigned char fc; /* actual link flow control */ - unsigned char autoneg; /* autonegotiating? */ - unsigned int link_ok; /* link up? */ -}; - -#define SPEED_INVALID 0xffff -#define DUPLEX_INVALID 0xff - -struct mc5 { - struct adapter *adapter; - unsigned int tcam_size; - unsigned char part_type; - unsigned char parity_enabled; - unsigned char mode; - struct mc5_stats stats; -}; - -static inline unsigned int t3_mc5_size(const struct mc5 *p) -{ - return p->tcam_size; -} - -struct mc7 { - struct adapter *adapter; /* backpointer to adapter */ - unsigned int size; /* memory size in bytes */ - unsigned int width; /* MC7 interface width */ - unsigned int offset; /* register address offset for MC7 instance */ - const char *name; /* name of MC7 instance */ - struct mc7_stats stats; /* MC7 statistics */ -}; - -static inline unsigned int t3_mc7_size(const struct mc7 *p) -{ - return p->size; -} - -struct cmac { - struct adapter *adapter; - unsigned int offset; - unsigned int nucast; /* # of address filters for unicast MACs */ - struct mac_stats stats; -}; - -enum { - MAC_DIRECTION_RX = 1, - MAC_DIRECTION_TX = 2, - MAC_RXFIFO_SIZE = 32768 -}; - -/* IEEE 802.3ae specified MDIO devices */ -enum { - MDIO_DEV_PMA_PMD = 1, - MDIO_DEV_WIS = 2, - MDIO_DEV_PCS = 3, - MDIO_DEV_XGXS = 4 -}; - -/* PHY loopback direction */ -enum { - PHY_LOOPBACK_TX = 1, - PHY_LOOPBACK_RX = 2 -}; - -/* PHY interrupt types */ -enum { - cphy_cause_link_change = 1, - cphy_cause_fifo_error = 2 -}; - -/* PHY operations */ -struct cphy_ops { - void (*destroy)(struct cphy *phy); - int (*reset)(struct cphy *phy, int wait); - - int (*intr_enable)(struct cphy *phy); - int (*intr_disable)(struct cphy *phy); - int (*intr_clear)(struct cphy *phy); - int (*intr_handler)(struct cphy *phy); - - int (*autoneg_enable)(struct cphy *phy); - int (*autoneg_restart)(struct cphy *phy); - - int (*advertise)(struct cphy *phy, unsigned int advertise_map); - int (*set_loopback)(struct cphy *phy, int mmd, int dir, int enable); - int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex); - int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed, - int *duplex, int *fc); - int (*power_down)(struct cphy *phy, int enable); -}; - -/* A PHY instance */ -struct cphy { - int addr; /* PHY address */ - struct adapter *adapter; /* associated adapter */ - unsigned long fifo_errors; /* FIFO over/under-flows */ - const struct cphy_ops *ops; /* PHY operations */ - int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *val); - int (*mdio_write)(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val); -}; - -/* Convenience MDIO read/write wrappers */ -static inline int mdio_read(struct cphy *phy, int mmd, int reg, - unsigned int *valp) -{ - return phy->mdio_read(phy->adapter, phy->addr, mmd, reg, valp); -} - -static inline int mdio_write(struct cphy *phy, int mmd, int reg, - unsigned int val) -{ - return phy->mdio_write(phy->adapter, phy->addr, mmd, reg, val); -} - -/* Convenience initializer */ -static inline void cphy_init(struct cphy *phy, struct adapter *adapter, - int phy_addr, struct cphy_ops *phy_ops, - const struct mdio_ops *mdio_ops) -{ - phy->adapter = adapter; - phy->addr = phy_addr; - phy->ops = phy_ops; - if (mdio_ops) { - phy->mdio_read = mdio_ops->read; - phy->mdio_write = mdio_ops->write; - } -} - -/* Accumulate MAC statistics every 180 seconds. For 1G we multiply by 10. */ -#define MAC_STATS_ACCUM_SECS 180 - -#define XGM_REG(reg_addr, idx) \ - ((reg_addr) + (idx) * (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR)) - -struct addr_val_pair { - unsigned int reg_addr; - unsigned int val; -}; - -#include "adapter.h" - -#ifndef PCI_VENDOR_ID_CHELSIO -# define PCI_VENDOR_ID_CHELSIO 0x1425 -#endif - -#define for_each_port(adapter, iter) \ - for (iter = 0; iter < (adapter)->params.nports; ++iter) - -#define adapter_info(adap) ((adap)->params.info) - -static inline int uses_xaui(const struct adapter *adap) -{ - return adapter_info(adap)->caps & SUPPORTED_AUI; -} - -static inline int is_10G(const struct adapter *adap) -{ - return adapter_info(adap)->caps & SUPPORTED_10000baseT_Full; -} - -static inline int is_offload(const struct adapter *adap) -{ - return adapter_info(adap)->caps & SUPPORTED_OFFLOAD; -} - -static inline unsigned int core_ticks_per_usec(const struct adapter *adap) -{ - return adap->params.vpd.cclk / 1000; -} - -static inline unsigned int is_pcie(const struct adapter *adap) -{ - return adap->params.pci.variant == PCI_VARIANT_PCIE; -} - -void t3_set_reg_field(struct adapter *adap, unsigned int addr, u32 mask, - u32 val); -void t3_write_regs(struct adapter *adapter, const struct addr_val_pair *p, - int n, unsigned int offset); -int t3_wait_op_done_val(struct adapter *adapter, int reg, u32 mask, - int polarity, int attempts, int delay, u32 *valp); -static inline int t3_wait_op_done(struct adapter *adapter, int reg, u32 mask, - int polarity, int attempts, int delay) -{ - return t3_wait_op_done_val(adapter, reg, mask, polarity, attempts, - delay, NULL); -} -int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear, - unsigned int set); -int t3_phy_reset(struct cphy *phy, int mmd, int wait); -int t3_phy_advertise(struct cphy *phy, unsigned int advert); -int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex); - -void t3_intr_enable(struct adapter *adapter); -void t3_intr_disable(struct adapter *adapter); -void t3_intr_clear(struct adapter *adapter); -void t3_port_intr_enable(struct adapter *adapter, int idx); -void t3_port_intr_disable(struct adapter *adapter, int idx); -void t3_port_intr_clear(struct adapter *adapter, int idx); -int t3_slow_intr_handler(struct adapter *adapter); -int t3_phy_intr_handler(struct adapter *adapter); - -void t3_link_changed(struct adapter *adapter, int port_id); -int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc); -const struct adapter_info *t3_get_adapter_info(unsigned int board_id); -int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data); -int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data); -int t3_seeprom_wp(struct adapter *adapter, int enable); -int t3_read_flash(struct adapter *adapter, unsigned int addr, - unsigned int nwords, u32 *data, int byte_oriented); -int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size); -int t3_get_fw_version(struct adapter *adapter, u32 *vers); -int t3_check_fw_version(struct adapter *adapter); -int t3_init_hw(struct adapter *adapter, u32 fw_params); -void mac_prep(struct cmac *mac, struct adapter *adapter, int index); -void early_hw_init(struct adapter *adapter, const struct adapter_info *ai); -int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, - int reset); -void t3_led_ready(struct adapter *adapter); -void t3_fatal_err(struct adapter *adapter); -void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on); -void t3_config_rss(struct adapter *adapter, unsigned int rss_config, - const u8 * cpus, const u16 *rspq); -int t3_read_rss(struct adapter *adapter, u8 * lkup, u16 *map); -int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask); -int t3_cim_ctl_blk_read(struct adapter *adap, unsigned int addr, - unsigned int n, unsigned int *valp); -int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n, - u64 *buf); - -int t3_mac_reset(struct cmac *mac); -void t3b_pcs_reset(struct cmac *mac); -int t3_mac_enable(struct cmac *mac, int which); -int t3_mac_disable(struct cmac *mac, int which); -int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu); -int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm); -int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]); -int t3_mac_set_num_ucast(struct cmac *mac, int n); -const struct mac_stats *t3_mac_update_stats(struct cmac *mac); -int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc); - -void t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode); -int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, - unsigned int nroutes); -void t3_mc5_intr_handler(struct mc5 *mc5); -int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, unsigned int n, - u32 *buf); - -int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh); -void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size); -void t3_tp_set_offload_mode(struct adapter *adap, int enable); -void t3_tp_get_mib_stats(struct adapter *adap, struct tp_mib_stats *tps); -void t3_load_mtus(struct adapter *adap, unsigned short mtus[NMTUS], - unsigned short alpha[NCCTRL_WIN], - unsigned short beta[NCCTRL_WIN], unsigned short mtu_cap); -void t3_read_hw_mtus(struct adapter *adap, unsigned short mtus[NMTUS]); -void t3_get_cong_cntl_tab(struct adapter *adap, - unsigned short incr[NMTUS][NCCTRL_WIN]); -void t3_config_trace_filter(struct adapter *adapter, - const struct trace_params *tp, int filter_index, - int invert, int enable); -int t3_config_sched(struct adapter *adap, unsigned int kbps, int sched); - -void t3_sge_prep(struct adapter *adap, struct sge_params *p); -void t3_sge_init(struct adapter *adap, struct sge_params *p); -int t3_sge_init_ecntxt(struct adapter *adapter, unsigned int id, int gts_enable, - enum sge_context_type type, int respq, u64 base_addr, - unsigned int size, unsigned int token, int gen, - unsigned int cidx); -int t3_sge_init_flcntxt(struct adapter *adapter, unsigned int id, - int gts_enable, u64 base_addr, unsigned int size, - unsigned int esize, unsigned int cong_thres, int gen, - unsigned int cidx); -int t3_sge_init_rspcntxt(struct adapter *adapter, unsigned int id, - int irq_vec_idx, u64 base_addr, unsigned int size, - unsigned int fl_thres, int gen, unsigned int cidx); -int t3_sge_init_cqcntxt(struct adapter *adapter, unsigned int id, u64 base_addr, - unsigned int size, int rspq, int ovfl_mode, - unsigned int credits, unsigned int credit_thres); -int t3_sge_enable_ecntxt(struct adapter *adapter, unsigned int id, int enable); -int t3_sge_disable_fl(struct adapter *adapter, unsigned int id); -int t3_sge_disable_rspcntxt(struct adapter *adapter, unsigned int id); -int t3_sge_disable_cqcntxt(struct adapter *adapter, unsigned int id); -int t3_sge_read_ecntxt(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_read_fl(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_read_cq(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op, - unsigned int credits); - -void t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops); -void t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops); -void t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops); -void t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, - const struct mdio_ops *mdio_ops); -void t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops); -#endif /* __CHELSIO_COMMON_H */ diff --git a/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h b/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h deleted file mode 100644 index 2095ddacff78..000000000000 --- a/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _CXGB3_OFFLOAD_CTL_DEFS_H -#define _CXGB3_OFFLOAD_CTL_DEFS_H - -enum { - GET_MAX_OUTSTANDING_WR, - GET_TX_MAX_CHUNK, - GET_TID_RANGE, - GET_STID_RANGE, - GET_RTBL_RANGE, - GET_L2T_CAPACITY, - GET_MTUS, - GET_WR_LEN, - GET_IFF_FROM_MAC, - GET_DDP_PARAMS, - GET_PORTS, - - ULP_ISCSI_GET_PARAMS, - ULP_ISCSI_SET_PARAMS, - - RDMA_GET_PARAMS, - RDMA_CQ_OP, - RDMA_CQ_SETUP, - RDMA_CQ_DISABLE, - RDMA_CTRL_QP_SETUP, - RDMA_GET_MEM, -}; - -/* - * Structure used to describe a TID range. Valid TIDs are [base, base+num). - */ -struct tid_range { - unsigned int base; /* first TID */ - unsigned int num; /* number of TIDs in range */ -}; - -/* - * Structure used to request the size and contents of the MTU table. - */ -struct mtutab { - unsigned int size; /* # of entries in the MTU table */ - const unsigned short *mtus; /* the MTU table values */ -}; - -struct net_device; - -/* - * Structure used to request the adapter net_device owning a given MAC address. - */ -struct iff_mac { - struct net_device *dev; /* the net_device */ - const unsigned char *mac_addr; /* MAC address to lookup */ - u16 vlan_tag; -}; - -struct pci_dev; - -/* - * Structure used to request the TCP DDP parameters. - */ -struct ddp_params { - unsigned int llimit; /* TDDP region start address */ - unsigned int ulimit; /* TDDP region end address */ - unsigned int tag_mask; /* TDDP tag mask */ - struct pci_dev *pdev; -}; - -struct adap_ports { - unsigned int nports; /* number of ports on this adapter */ - struct net_device *lldevs[2]; -}; - -/* - * Structure used to return information to the iscsi layer. - */ -struct ulp_iscsi_info { - unsigned int offset; - unsigned int llimit; - unsigned int ulimit; - unsigned int tagmask; - unsigned int pgsz3; - unsigned int pgsz2; - unsigned int pgsz1; - unsigned int pgsz0; - unsigned int max_rxsz; - unsigned int max_txsz; - struct pci_dev *pdev; -}; - -/* - * Structure used to return information to the RDMA layer. - */ -struct rdma_info { - unsigned int tpt_base; /* TPT base address */ - unsigned int tpt_top; /* TPT last entry address */ - unsigned int pbl_base; /* PBL base address */ - unsigned int pbl_top; /* PBL last entry address */ - unsigned int rqt_base; /* RQT base address */ - unsigned int rqt_top; /* RQT last entry address */ - unsigned int udbell_len; /* user doorbell region length */ - unsigned long udbell_physbase; /* user doorbell physical start addr */ - void __iomem *kdb_addr; /* kernel doorbell register address */ - struct pci_dev *pdev; /* associated PCI device */ -}; - -/* - * Structure used to request an operation on an RDMA completion queue. - */ -struct rdma_cq_op { - unsigned int id; - unsigned int op; - unsigned int credits; -}; - -/* - * Structure used to setup RDMA completion queues. - */ -struct rdma_cq_setup { - unsigned int id; - unsigned long long base_addr; - unsigned int size; - unsigned int credits; - unsigned int credit_thres; - unsigned int ovfl_mode; -}; - -/* - * Structure used to setup the RDMA control egress context. - */ -struct rdma_ctrlqp_setup { - unsigned long long base_addr; - unsigned int size; -}; -#endif /* _CXGB3_OFFLOAD_CTL_DEFS_H */ diff --git a/trunk/drivers/net/cxgb3/cxgb3_defs.h b/trunk/drivers/net/cxgb3/cxgb3_defs.h deleted file mode 100644 index 16e004990c59..000000000000 --- a/trunk/drivers/net/cxgb3/cxgb3_defs.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved. - * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _CHELSIO_DEFS_H -#define _CHELSIO_DEFS_H - -#include -#include - -#include "t3cdev.h" - -#include "cxgb3_offload.h" - -#define VALIDATE_TID 1 - -void *cxgb_alloc_mem(unsigned long size); -void cxgb_free_mem(void *addr); -void cxgb_neigh_update(struct neighbour *neigh); -void cxgb_redirect(struct dst_entry *old, struct dst_entry *new); - -/* - * Map an ATID or STID to their entries in the corresponding TID tables. - */ -static inline union active_open_entry *atid2entry(const struct tid_info *t, - unsigned int atid) -{ - return &t->atid_tab[atid - t->atid_base]; -} - -static inline union listen_entry *stid2entry(const struct tid_info *t, - unsigned int stid) -{ - return &t->stid_tab[stid - t->stid_base]; -} - -/* - * Find the connection corresponding to a TID. - */ -static inline struct t3c_tid_entry *lookup_tid(const struct tid_info *t, - unsigned int tid) -{ - return tid < t->ntids ? &(t->tid_tab[tid]) : NULL; -} - -/* - * Find the connection corresponding to a server TID. - */ -static inline struct t3c_tid_entry *lookup_stid(const struct tid_info *t, - unsigned int tid) -{ - if (tid < t->stid_base || tid >= t->stid_base + t->nstids) - return NULL; - return &(stid2entry(t, tid)->t3c_tid); -} - -/* - * Find the connection corresponding to an active-open TID. - */ -static inline struct t3c_tid_entry *lookup_atid(const struct tid_info *t, - unsigned int tid) -{ - if (tid < t->atid_base || tid >= t->atid_base + t->natids) - return NULL; - return &(atid2entry(t, tid)->t3c_tid); -} - -int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n); -int attach_t3cdev(struct t3cdev *dev); -void detach_t3cdev(struct t3cdev *dev); -#endif diff --git a/trunk/drivers/net/cxgb3/cxgb3_ioctl.h b/trunk/drivers/net/cxgb3/cxgb3_ioctl.h deleted file mode 100644 index a94281861a66..000000000000 --- a/trunk/drivers/net/cxgb3/cxgb3_ioctl.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __CHIOCTL_H__ -#define __CHIOCTL_H__ - -/* - * Ioctl commands specific to this driver. - */ -enum { - CHELSIO_SETREG = 1024, - CHELSIO_GETREG, - CHELSIO_SETTPI, - CHELSIO_GETTPI, - CHELSIO_GETMTUTAB, - CHELSIO_SETMTUTAB, - CHELSIO_GETMTU, - CHELSIO_SET_PM, - CHELSIO_GET_PM, - CHELSIO_GET_TCAM, - CHELSIO_SET_TCAM, - CHELSIO_GET_TCB, - CHELSIO_GET_MEM, - CHELSIO_LOAD_FW, - CHELSIO_GET_PROTO, - CHELSIO_SET_PROTO, - CHELSIO_SET_TRACE_FILTER, - CHELSIO_SET_QSET_PARAMS, - CHELSIO_GET_QSET_PARAMS, - CHELSIO_SET_QSET_NUM, - CHELSIO_GET_QSET_NUM, - CHELSIO_SET_PKTSCHED, -}; - -struct ch_reg { - uint32_t cmd; - uint32_t addr; - uint32_t val; -}; - -struct ch_cntxt { - uint32_t cmd; - uint32_t cntxt_type; - uint32_t cntxt_id; - uint32_t data[4]; -}; - -/* context types */ -enum { CNTXT_TYPE_EGRESS, CNTXT_TYPE_FL, CNTXT_TYPE_RSP, CNTXT_TYPE_CQ }; - -struct ch_desc { - uint32_t cmd; - uint32_t queue_num; - uint32_t idx; - uint32_t size; - uint8_t data[128]; -}; - -struct ch_mem_range { - uint32_t cmd; - uint32_t mem_id; - uint32_t addr; - uint32_t len; - uint32_t version; - uint8_t buf[0]; -}; - -struct ch_qset_params { - uint32_t cmd; - uint32_t qset_idx; - int32_t txq_size[3]; - int32_t rspq_size; - int32_t fl_size[2]; - int32_t intr_lat; - int32_t polling; - int32_t cong_thres; -}; - -struct ch_pktsched_params { - uint32_t cmd; - uint8_t sched; - uint8_t idx; - uint8_t min; - uint8_t max; - uint8_t binding; -}; - -#ifndef TCB_SIZE -# define TCB_SIZE 128 -#endif - -/* TCB size in 32-bit words */ -#define TCB_WORDS (TCB_SIZE / 4) - -enum { MEM_CM, MEM_PMRX, MEM_PMTX }; /* ch_mem_range.mem_id values */ - -struct ch_mtus { - uint32_t cmd; - uint32_t nmtus; - uint16_t mtus[NMTUS]; -}; - -struct ch_pm { - uint32_t cmd; - uint32_t tx_pg_sz; - uint32_t tx_num_pg; - uint32_t rx_pg_sz; - uint32_t rx_num_pg; - uint32_t pm_total; -}; - -struct ch_tcam { - uint32_t cmd; - uint32_t tcam_size; - uint32_t nservers; - uint32_t nroutes; - uint32_t nfilters; -}; - -struct ch_tcb { - uint32_t cmd; - uint32_t tcb_index; - uint32_t tcb_data[TCB_WORDS]; -}; - -struct ch_tcam_word { - uint32_t cmd; - uint32_t addr; - uint32_t buf[3]; -}; - -struct ch_trace { - uint32_t cmd; - uint32_t sip; - uint32_t sip_mask; - uint32_t dip; - uint32_t dip_mask; - uint16_t sport; - uint16_t sport_mask; - uint16_t dport; - uint16_t dport_mask; - uint32_t vlan:12; - uint32_t vlan_mask:12; - uint32_t intf:4; - uint32_t intf_mask:4; - uint8_t proto; - uint8_t proto_mask; - uint8_t invert_match:1; - uint8_t config_tx:1; - uint8_t config_rx:1; - uint8_t trace_tx:1; - uint8_t trace_rx:1; -}; - -#define SIOCCHIOCTL SIOCDEVPRIVATE - -#endif diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c deleted file mode 100644 index dfa035a1ad45..000000000000 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ /dev/null @@ -1,2515 +0,0 @@ -/* - * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "cxgb3_ioctl.h" -#include "regs.h" -#include "cxgb3_offload.h" -#include "version.h" - -#include "cxgb3_ctl_defs.h" -#include "t3_cpl.h" -#include "firmware_exports.h" - -enum { - MAX_TXQ_ENTRIES = 16384, - MAX_CTRL_TXQ_ENTRIES = 1024, - MAX_RSPQ_ENTRIES = 16384, - MAX_RX_BUFFERS = 16384, - MAX_RX_JUMBO_BUFFERS = 16384, - MIN_TXQ_ENTRIES = 4, - MIN_CTRL_TXQ_ENTRIES = 4, - MIN_RSPQ_ENTRIES = 32, - MIN_FL_ENTRIES = 32 -}; - -#define PORT_MASK ((1 << MAX_NPORTS) - 1) - -#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ - NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ - NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) - -#define EEPROM_MAGIC 0x38E2F10C - -#define to_net_dev(class) container_of(class, struct net_device, class_dev) - -#define CH_DEVICE(devid, ssid, idx) \ - { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx } - -static const struct pci_device_id cxgb3_pci_tbl[] = { - CH_DEVICE(0x20, 1, 0), /* PE9000 */ - CH_DEVICE(0x21, 1, 1), /* T302E */ - CH_DEVICE(0x22, 1, 2), /* T310E */ - CH_DEVICE(0x23, 1, 3), /* T320X */ - CH_DEVICE(0x24, 1, 1), /* T302X */ - CH_DEVICE(0x25, 1, 3), /* T320E */ - CH_DEVICE(0x26, 1, 2), /* T310X */ - CH_DEVICE(0x30, 1, 2), /* T3B10 */ - CH_DEVICE(0x31, 1, 3), /* T3B20 */ - CH_DEVICE(0x32, 1, 1), /* T3B02 */ - {0,} -}; - -MODULE_DESCRIPTION(DRV_DESC); -MODULE_AUTHOR("Chelsio Communications"); -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_VERSION(DRV_VERSION); -MODULE_DEVICE_TABLE(pci, cxgb3_pci_tbl); - -static int dflt_msg_enable = DFLT_MSG_ENABLE; - -module_param(dflt_msg_enable, int, 0644); -MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T3 default message enable bitmap"); - -/* - * The driver uses the best interrupt scheme available on a platform in the - * order MSI-X, MSI, legacy pin interrupts. This parameter determines which - * of these schemes the driver may consider as follows: - * - * msi = 2: choose from among all three options - * msi = 1: only consider MSI and pin interrupts - * msi = 0: force pin interrupts - */ -static int msi = 2; - -module_param(msi, int, 0644); -MODULE_PARM_DESC(msi, "whether to use MSI or MSI-X"); - -/* - * The driver enables offload as a default. - * To disable it, use ofld_disable = 1. - */ - -static int ofld_disable = 0; - -module_param(ofld_disable, int, 0644); -MODULE_PARM_DESC(ofld_disable, "whether to enable offload at init time or not"); - -/* - * We have work elements that we need to cancel when an interface is taken - * down. Normally the work elements would be executed by keventd but that - * can deadlock because of linkwatch. If our close method takes the rtnl - * lock and linkwatch is ahead of our work elements in keventd, linkwatch - * will block keventd as it needs the rtnl lock, and we'll deadlock waiting - * for our work to complete. Get our own work queue to solve this. - */ -static struct workqueue_struct *cxgb3_wq; - -/** - * link_report - show link status and link speed/duplex - * @p: the port whose settings are to be reported - * - * Shows the link status, speed, and duplex of a port. - */ -static void link_report(struct net_device *dev) -{ - if (!netif_carrier_ok(dev)) - printk(KERN_INFO "%s: link down\n", dev->name); - else { - const char *s = "10Mbps"; - const struct port_info *p = netdev_priv(dev); - - switch (p->link_config.speed) { - case SPEED_10000: - s = "10Gbps"; - break; - case SPEED_1000: - s = "1000Mbps"; - break; - case SPEED_100: - s = "100Mbps"; - break; - } - - printk(KERN_INFO "%s: link up, %s, %s-duplex\n", dev->name, s, - p->link_config.duplex == DUPLEX_FULL ? "full" : "half"); - } -} - -/** - * t3_os_link_changed - handle link status changes - * @adapter: the adapter associated with the link change - * @port_id: the port index whose limk status has changed - * @link_stat: the new status of the link - * @speed: the new speed setting - * @duplex: the new duplex setting - * @pause: the new flow-control setting - * - * This is the OS-dependent handler for link status changes. The OS - * neutral handler takes care of most of the processing for these events, - * then calls this handler for any OS-specific processing. - */ -void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat, - int speed, int duplex, int pause) -{ - struct net_device *dev = adapter->port[port_id]; - - /* Skip changes from disabled ports. */ - if (!netif_running(dev)) - return; - - if (link_stat != netif_carrier_ok(dev)) { - if (link_stat) - netif_carrier_on(dev); - else - netif_carrier_off(dev); - link_report(dev); - } -} - -static void cxgb_set_rxmode(struct net_device *dev) -{ - struct t3_rx_mode rm; - struct port_info *pi = netdev_priv(dev); - - init_rx_mode(&rm, dev, dev->mc_list); - t3_mac_set_rx_mode(&pi->mac, &rm); -} - -/** - * link_start - enable a port - * @dev: the device to enable - * - * Performs the MAC and PHY actions needed to enable a port. - */ -static void link_start(struct net_device *dev) -{ - struct t3_rx_mode rm; - struct port_info *pi = netdev_priv(dev); - struct cmac *mac = &pi->mac; - - init_rx_mode(&rm, dev, dev->mc_list); - t3_mac_reset(mac); - t3_mac_set_mtu(mac, dev->mtu); - t3_mac_set_address(mac, 0, dev->dev_addr); - t3_mac_set_rx_mode(mac, &rm); - t3_link_start(&pi->phy, mac, &pi->link_config); - t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); -} - -static inline void cxgb_disable_msi(struct adapter *adapter) -{ - if (adapter->flags & USING_MSIX) { - pci_disable_msix(adapter->pdev); - adapter->flags &= ~USING_MSIX; - } else if (adapter->flags & USING_MSI) { - pci_disable_msi(adapter->pdev); - adapter->flags &= ~USING_MSI; - } -} - -/* - * Interrupt handler for asynchronous events used with MSI-X. - */ -static irqreturn_t t3_async_intr_handler(int irq, void *cookie) -{ - t3_slow_intr_handler(cookie); - return IRQ_HANDLED; -} - -/* - * Name the MSI-X interrupts. - */ -static void name_msix_vecs(struct adapter *adap) -{ - int i, j, msi_idx = 1, n = sizeof(adap->msix_info[0].desc) - 1; - - snprintf(adap->msix_info[0].desc, n, "%s", adap->name); - adap->msix_info[0].desc[n] = 0; - - for_each_port(adap, j) { - struct net_device *d = adap->port[j]; - const struct port_info *pi = netdev_priv(d); - - for (i = 0; i < pi->nqsets; i++, msi_idx++) { - snprintf(adap->msix_info[msi_idx].desc, n, - "%s (queue %d)", d->name, i); - adap->msix_info[msi_idx].desc[n] = 0; - } - } -} - -static int request_msix_data_irqs(struct adapter *adap) -{ - int i, j, err, qidx = 0; - - for_each_port(adap, i) { - int nqsets = adap2pinfo(adap, i)->nqsets; - - for (j = 0; j < nqsets; ++j) { - err = request_irq(adap->msix_info[qidx + 1].vec, - t3_intr_handler(adap, - adap->sge.qs[qidx]. - rspq.polling), 0, - adap->msix_info[qidx + 1].desc, - &adap->sge.qs[qidx]); - if (err) { - while (--qidx >= 0) - free_irq(adap->msix_info[qidx + 1].vec, - &adap->sge.qs[qidx]); - return err; - } - qidx++; - } - } - return 0; -} - -/** - * setup_rss - configure RSS - * @adap: the adapter - * - * Sets up RSS to distribute packets to multiple receive queues. We - * configure the RSS CPU lookup table to distribute to the number of HW - * receive queues, and the response queue lookup table to narrow that - * down to the response queues actually configured for each port. - * We always configure the RSS mapping for two ports since the mapping - * table has plenty of entries. - */ -static void setup_rss(struct adapter *adap) -{ - int i; - unsigned int nq0 = adap2pinfo(adap, 0)->nqsets; - unsigned int nq1 = adap->port[1] ? adap2pinfo(adap, 1)->nqsets : 1; - u8 cpus[SGE_QSETS + 1]; - u16 rspq_map[RSS_TABLE_SIZE]; - - for (i = 0; i < SGE_QSETS; ++i) - cpus[i] = i; - cpus[SGE_QSETS] = 0xff; /* terminator */ - - for (i = 0; i < RSS_TABLE_SIZE / 2; ++i) { - rspq_map[i] = i % nq0; - rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq1) + nq0; - } - - t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN | - F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | - V_RRCPLCPUSIZE(6), cpus, rspq_map); -} - -/* - * If we have multiple receive queues per port serviced by NAPI we need one - * netdevice per queue as NAPI operates on netdevices. We already have one - * netdevice, namely the one associated with the interface, so we use dummy - * ones for any additional queues. Note that these netdevices exist purely - * so that NAPI has something to work with, they do not represent network - * ports and are not registered. - */ -static int init_dummy_netdevs(struct adapter *adap) -{ - int i, j, dummy_idx = 0; - struct net_device *nd; - - for_each_port(adap, i) { - struct net_device *dev = adap->port[i]; - const struct port_info *pi = netdev_priv(dev); - - for (j = 0; j < pi->nqsets - 1; j++) { - if (!adap->dummy_netdev[dummy_idx]) { - nd = alloc_netdev(0, "", ether_setup); - if (!nd) - goto free_all; - - nd->priv = adap; - nd->weight = 64; - set_bit(__LINK_STATE_START, &nd->state); - adap->dummy_netdev[dummy_idx] = nd; - } - strcpy(adap->dummy_netdev[dummy_idx]->name, dev->name); - dummy_idx++; - } - } - return 0; - -free_all: - while (--dummy_idx >= 0) { - free_netdev(adap->dummy_netdev[dummy_idx]); - adap->dummy_netdev[dummy_idx] = NULL; - } - return -ENOMEM; -} - -/* - * Wait until all NAPI handlers are descheduled. This includes the handlers of - * both netdevices representing interfaces and the dummy ones for the extra - * queues. - */ -static void quiesce_rx(struct adapter *adap) -{ - int i; - struct net_device *dev; - - for_each_port(adap, i) { - dev = adap->port[i]; - while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) - msleep(1); - } - - for (i = 0; i < ARRAY_SIZE(adap->dummy_netdev); i++) { - dev = adap->dummy_netdev[i]; - if (dev) - while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) - msleep(1); - } -} - -/** - * setup_sge_qsets - configure SGE Tx/Rx/response queues - * @adap: the adapter - * - * Determines how many sets of SGE queues to use and initializes them. - * We support multiple queue sets per port if we have MSI-X, otherwise - * just one queue set per port. - */ -static int setup_sge_qsets(struct adapter *adap) -{ - int i, j, err, irq_idx = 0, qset_idx = 0, dummy_dev_idx = 0; - unsigned int ntxq = is_offload(adap) ? SGE_TXQ_PER_SET : 1; - - if (adap->params.rev > 0 && !(adap->flags & USING_MSI)) - irq_idx = -1; - - for_each_port(adap, i) { - struct net_device *dev = adap->port[i]; - const struct port_info *pi = netdev_priv(dev); - - for (j = 0; j < pi->nqsets; ++j, ++qset_idx) { - err = t3_sge_alloc_qset(adap, qset_idx, 1, - (adap->flags & USING_MSIX) ? qset_idx + 1 : - irq_idx, - &adap->params.sge.qset[qset_idx], ntxq, - j == 0 ? dev : - adap-> dummy_netdev[dummy_dev_idx++]); - if (err) { - t3_free_sge_resources(adap); - return err; - } - } - } - - return 0; -} - -static ssize_t attr_show(struct class_device *cd, char *buf, - ssize_t(*format) (struct adapter *, char *)) -{ - ssize_t len; - struct adapter *adap = to_net_dev(cd)->priv; - - /* Synchronize with ioctls that may shut down the device */ - rtnl_lock(); - len = (*format) (adap, buf); - rtnl_unlock(); - return len; -} - -static ssize_t attr_store(struct class_device *cd, const char *buf, size_t len, - ssize_t(*set) (struct adapter *, unsigned int), - unsigned int min_val, unsigned int max_val) -{ - char *endp; - ssize_t ret; - unsigned int val; - struct adapter *adap = to_net_dev(cd)->priv; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - val = simple_strtoul(buf, &endp, 0); - if (endp == buf || val < min_val || val > max_val) - return -EINVAL; - - rtnl_lock(); - ret = (*set) (adap, val); - if (!ret) - ret = len; - rtnl_unlock(); - return ret; -} - -#define CXGB3_SHOW(name, val_expr) \ -static ssize_t format_##name(struct adapter *adap, char *buf) \ -{ \ - return sprintf(buf, "%u\n", val_expr); \ -} \ -static ssize_t show_##name(struct class_device *cd, char *buf) \ -{ \ - return attr_show(cd, buf, format_##name); \ -} - -static ssize_t set_nfilters(struct adapter *adap, unsigned int val) -{ - if (adap->flags & FULL_INIT_DONE) - return -EBUSY; - if (val && adap->params.rev == 0) - return -EINVAL; - if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nservers) - return -EINVAL; - adap->params.mc5.nfilters = val; - return 0; -} - -static ssize_t store_nfilters(struct class_device *cd, const char *buf, - size_t len) -{ - return attr_store(cd, buf, len, set_nfilters, 0, ~0); -} - -static ssize_t set_nservers(struct adapter *adap, unsigned int val) -{ - if (adap->flags & FULL_INIT_DONE) - return -EBUSY; - if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nfilters) - return -EINVAL; - adap->params.mc5.nservers = val; - return 0; -} - -static ssize_t store_nservers(struct class_device *cd, const char *buf, - size_t len) -{ - return attr_store(cd, buf, len, set_nservers, 0, ~0); -} - -#define CXGB3_ATTR_R(name, val_expr) \ -CXGB3_SHOW(name, val_expr) \ -static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) - -#define CXGB3_ATTR_RW(name, val_expr, store_method) \ -CXGB3_SHOW(name, val_expr) \ -static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_method) - -CXGB3_ATTR_R(cam_size, t3_mc5_size(&adap->mc5)); -CXGB3_ATTR_RW(nfilters, adap->params.mc5.nfilters, store_nfilters); -CXGB3_ATTR_RW(nservers, adap->params.mc5.nservers, store_nservers); - -static struct attribute *cxgb3_attrs[] = { - &class_device_attr_cam_size.attr, - &class_device_attr_nfilters.attr, - &class_device_attr_nservers.attr, - NULL -}; - -static struct attribute_group cxgb3_attr_group = {.attrs = cxgb3_attrs }; - -static ssize_t tm_attr_show(struct class_device *cd, char *buf, int sched) -{ - ssize_t len; - unsigned int v, addr, bpt, cpt; - struct adapter *adap = to_net_dev(cd)->priv; - - addr = A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2; - rtnl_lock(); - t3_write_reg(adap, A_TP_TM_PIO_ADDR, addr); - v = t3_read_reg(adap, A_TP_TM_PIO_DATA); - if (sched & 1) - v >>= 16; - bpt = (v >> 8) & 0xff; - cpt = v & 0xff; - if (!cpt) - len = sprintf(buf, "disabled\n"); - else { - v = (adap->params.vpd.cclk * 1000) / cpt; - len = sprintf(buf, "%u Kbps\n", (v * bpt) / 125); - } - rtnl_unlock(); - return len; -} - -static ssize_t tm_attr_store(struct class_device *cd, const char *buf, - size_t len, int sched) -{ - char *endp; - ssize_t ret; - unsigned int val; - struct adapter *adap = to_net_dev(cd)->priv; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - val = simple_strtoul(buf, &endp, 0); - if (endp == buf || val > 10000000) - return -EINVAL; - - rtnl_lock(); - ret = t3_config_sched(adap, val, sched); - if (!ret) - ret = len; - rtnl_unlock(); - return ret; -} - -#define TM_ATTR(name, sched) \ -static ssize_t show_##name(struct class_device *cd, char *buf) \ -{ \ - return tm_attr_show(cd, buf, sched); \ -} \ -static ssize_t store_##name(struct class_device *cd, const char *buf, size_t len) \ -{ \ - return tm_attr_store(cd, buf, len, sched); \ -} \ -static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name) - -TM_ATTR(sched0, 0); -TM_ATTR(sched1, 1); -TM_ATTR(sched2, 2); -TM_ATTR(sched3, 3); -TM_ATTR(sched4, 4); -TM_ATTR(sched5, 5); -TM_ATTR(sched6, 6); -TM_ATTR(sched7, 7); - -static struct attribute *offload_attrs[] = { - &class_device_attr_sched0.attr, - &class_device_attr_sched1.attr, - &class_device_attr_sched2.attr, - &class_device_attr_sched3.attr, - &class_device_attr_sched4.attr, - &class_device_attr_sched5.attr, - &class_device_attr_sched6.attr, - &class_device_attr_sched7.attr, - NULL -}; - -static struct attribute_group offload_attr_group = {.attrs = offload_attrs }; - -/* - * Sends an sk_buff to an offload queue driver - * after dealing with any active network taps. - */ -static inline int offload_tx(struct t3cdev *tdev, struct sk_buff *skb) -{ - int ret; - - local_bh_disable(); - ret = t3_offload_tx(tdev, skb); - local_bh_enable(); - return ret; -} - -static int write_smt_entry(struct adapter *adapter, int idx) -{ - struct cpl_smt_write_req *req; - struct sk_buff *skb = alloc_skb(sizeof(*req), GFP_KERNEL); - - if (!skb) - return -ENOMEM; - - req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req)); - req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); - OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, idx)); - req->mtu_idx = NMTUS - 1; /* should be 0 but there's a T3 bug */ - req->iff = idx; - memset(req->src_mac1, 0, sizeof(req->src_mac1)); - memcpy(req->src_mac0, adapter->port[idx]->dev_addr, ETH_ALEN); - skb->priority = 1; - offload_tx(&adapter->tdev, skb); - return 0; -} - -static int init_smt(struct adapter *adapter) -{ - int i; - - for_each_port(adapter, i) - write_smt_entry(adapter, i); - return 0; -} - -static void init_port_mtus(struct adapter *adapter) -{ - unsigned int mtus = adapter->port[0]->mtu; - - if (adapter->port[1]) - mtus |= adapter->port[1]->mtu << 16; - t3_write_reg(adapter, A_TP_MTU_PORT_TABLE, mtus); -} - -static void send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, - int hi, int port) -{ - struct sk_buff *skb; - struct mngt_pktsched_wr *req; - - skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); - req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req)); - req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT)); - req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET; - req->sched = sched; - req->idx = qidx; - req->min = lo; - req->max = hi; - req->binding = port; - t3_mgmt_tx(adap, skb); -} - -static void bind_qsets(struct adapter *adap) -{ - int i, j; - - for_each_port(adap, i) { - const struct port_info *pi = adap2pinfo(adap, i); - - for (j = 0; j < pi->nqsets; ++j) - send_pktsched_cmd(adap, 1, pi->first_qset + j, -1, - -1, i); - } -} - -/** - * cxgb_up - enable the adapter - * @adapter: adapter being enabled - * - * Called when the first port is enabled, this function performs the - * actions necessary to make an adapter operational, such as completing - * the initialization of HW modules, and enabling interrupts. - * - * Must be called with the rtnl lock held. - */ -static int cxgb_up(struct adapter *adap) -{ - int err = 0; - - if (!(adap->flags & FULL_INIT_DONE)) { - err = t3_check_fw_version(adap); - if (err) - goto out; - - err = init_dummy_netdevs(adap); - if (err) - goto out; - - err = t3_init_hw(adap, 0); - if (err) - goto out; - - err = setup_sge_qsets(adap); - if (err) - goto out; - - setup_rss(adap); - adap->flags |= FULL_INIT_DONE; - } - - t3_intr_clear(adap); - - if (adap->flags & USING_MSIX) { - name_msix_vecs(adap); - err = request_irq(adap->msix_info[0].vec, - t3_async_intr_handler, 0, - adap->msix_info[0].desc, adap); - if (err) - goto irq_err; - - if (request_msix_data_irqs(adap)) { - free_irq(adap->msix_info[0].vec, adap); - goto irq_err; - } - } else if ((err = request_irq(adap->pdev->irq, - t3_intr_handler(adap, - adap->sge.qs[0].rspq. - polling), - (adap->flags & USING_MSI) ? 0 : SA_SHIRQ, - adap->name, adap))) - goto irq_err; - - t3_sge_start(adap); - t3_intr_enable(adap); - - if ((adap->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX) - bind_qsets(adap); - adap->flags |= QUEUES_BOUND; - -out: - return err; -irq_err: - CH_ERR(adap, "request_irq failed, err %d\n", err); - goto out; -} - -/* - * Release resources when all the ports and offloading have been stopped. - */ -static void cxgb_down(struct adapter *adapter) -{ - t3_sge_stop(adapter); - spin_lock_irq(&adapter->work_lock); /* sync with PHY intr task */ - t3_intr_disable(adapter); - spin_unlock_irq(&adapter->work_lock); - - if (adapter->flags & USING_MSIX) { - int i, n = 0; - - free_irq(adapter->msix_info[0].vec, adapter); - for_each_port(adapter, i) - n += adap2pinfo(adapter, i)->nqsets; - - for (i = 0; i < n; ++i) - free_irq(adapter->msix_info[i + 1].vec, - &adapter->sge.qs[i]); - } else - free_irq(adapter->pdev->irq, adapter); - - flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ - quiesce_rx(adapter); -} - -static void schedule_chk_task(struct adapter *adap) -{ - unsigned int timeo; - - timeo = adap->params.linkpoll_period ? - (HZ * adap->params.linkpoll_period) / 10 : - adap->params.stats_update_period * HZ; - if (timeo) - queue_delayed_work(cxgb3_wq, &adap->adap_check_task, timeo); -} - -static int offload_open(struct net_device *dev) -{ - struct adapter *adapter = dev->priv; - struct t3cdev *tdev = T3CDEV(dev); - int adap_up = adapter->open_device_map & PORT_MASK; - int err = 0; - - if (test_and_set_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) - return 0; - - if (!adap_up && (err = cxgb_up(adapter)) < 0) - return err; - - t3_tp_set_offload_mode(adapter, 1); - tdev->lldev = adapter->port[0]; - err = cxgb3_offload_activate(adapter); - if (err) - goto out; - - init_port_mtus(adapter); - t3_load_mtus(adapter, adapter->params.mtus, adapter->params.a_wnd, - adapter->params.b_wnd, - adapter->params.rev == 0 ? - adapter->port[0]->mtu : 0xffff); - init_smt(adapter); - - /* Never mind if the next step fails */ - sysfs_create_group(&tdev->lldev->class_dev.kobj, &offload_attr_group); - - /* Call back all registered clients */ - cxgb3_add_clients(tdev); - -out: - /* restore them in case the offload module has changed them */ - if (err) { - t3_tp_set_offload_mode(adapter, 0); - clear_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map); - cxgb3_set_dummy_ops(tdev); - } - return err; -} - -static int offload_close(struct t3cdev *tdev) -{ - struct adapter *adapter = tdev2adap(tdev); - - if (!test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) - return 0; - - /* Call back all registered clients */ - cxgb3_remove_clients(tdev); - - sysfs_remove_group(&tdev->lldev->class_dev.kobj, &offload_attr_group); - - tdev->lldev = NULL; - cxgb3_set_dummy_ops(tdev); - t3_tp_set_offload_mode(adapter, 0); - clear_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map); - - if (!adapter->open_device_map) - cxgb_down(adapter); - - cxgb3_offload_deactivate(adapter); - return 0; -} - -static int cxgb_open(struct net_device *dev) -{ - int err; - struct adapter *adapter = dev->priv; - struct port_info *pi = netdev_priv(dev); - int other_ports = adapter->open_device_map & PORT_MASK; - - if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) - return err; - - set_bit(pi->port_id, &adapter->open_device_map); - if (!ofld_disable) { - err = offload_open(dev); - if (err) - printk(KERN_WARNING - "Could not initialize offload capabilities\n"); - } - - link_start(dev); - t3_port_intr_enable(adapter, pi->port_id); - netif_start_queue(dev); - if (!other_ports) - schedule_chk_task(adapter); - - return 0; -} - -static int cxgb_close(struct net_device *dev) -{ - struct adapter *adapter = dev->priv; - struct port_info *p = netdev_priv(dev); - - t3_port_intr_disable(adapter, p->port_id); - netif_stop_queue(dev); - p->phy.ops->power_down(&p->phy, 1); - netif_carrier_off(dev); - t3_mac_disable(&p->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); - - spin_lock(&adapter->work_lock); /* sync with update task */ - clear_bit(p->port_id, &adapter->open_device_map); - spin_unlock(&adapter->work_lock); - - if (!(adapter->open_device_map & PORT_MASK)) - cancel_rearming_delayed_workqueue(cxgb3_wq, - &adapter->adap_check_task); - - if (!adapter->open_device_map) - cxgb_down(adapter); - - return 0; -} - -static struct net_device_stats *cxgb_get_stats(struct net_device *dev) -{ - struct adapter *adapter = dev->priv; - struct port_info *p = netdev_priv(dev); - struct net_device_stats *ns = &p->netstats; - const struct mac_stats *pstats; - - spin_lock(&adapter->stats_lock); - pstats = t3_mac_update_stats(&p->mac); - spin_unlock(&adapter->stats_lock); - - ns->tx_bytes = pstats->tx_octets; - ns->tx_packets = pstats->tx_frames; - ns->rx_bytes = pstats->rx_octets; - ns->rx_packets = pstats->rx_frames; - ns->multicast = pstats->rx_mcast_frames; - - ns->tx_errors = pstats->tx_underrun; - ns->rx_errors = pstats->rx_symbol_errs + pstats->rx_fcs_errs + - pstats->rx_too_long + pstats->rx_jabber + pstats->rx_short + - pstats->rx_fifo_ovfl; - - /* detailed rx_errors */ - ns->rx_length_errors = pstats->rx_jabber + pstats->rx_too_long; - ns->rx_over_errors = 0; - ns->rx_crc_errors = pstats->rx_fcs_errs; - ns->rx_frame_errors = pstats->rx_symbol_errs; - ns->rx_fifo_errors = pstats->rx_fifo_ovfl; - ns->rx_missed_errors = pstats->rx_cong_drops; - - /* detailed tx_errors */ - ns->tx_aborted_errors = 0; - ns->tx_carrier_errors = 0; - ns->tx_fifo_errors = pstats->tx_underrun; - ns->tx_heartbeat_errors = 0; - ns->tx_window_errors = 0; - return ns; -} - -static u32 get_msglevel(struct net_device *dev) -{ - struct adapter *adapter = dev->priv; - - return adapter->msg_enable; -} - -static void set_msglevel(struct net_device *dev, u32 val) -{ - struct adapter *adapter = dev->priv; - - adapter->msg_enable = val; -} - -static char stats_strings[][ETH_GSTRING_LEN] = { - "TxOctetsOK ", - "TxFramesOK ", - "TxMulticastFramesOK", - "TxBroadcastFramesOK", - "TxPauseFrames ", - "TxUnderrun ", - "TxExtUnderrun ", - - "TxFrames64 ", - "TxFrames65To127 ", - "TxFrames128To255 ", - "TxFrames256To511 ", - "TxFrames512To1023 ", - "TxFrames1024To1518 ", - "TxFrames1519ToMax ", - - "RxOctetsOK ", - "RxFramesOK ", - "RxMulticastFramesOK", - "RxBroadcastFramesOK", - "RxPauseFrames ", - "RxFCSErrors ", - "RxSymbolErrors ", - "RxShortErrors ", - "RxJabberErrors ", - "RxLengthErrors ", - "RxFIFOoverflow ", - - "RxFrames64 ", - "RxFrames65To127 ", - "RxFrames128To255 ", - "RxFrames256To511 ", - "RxFrames512To1023 ", - "RxFrames1024To1518 ", - "RxFrames1519ToMax ", - - "PhyFIFOErrors ", - "TSO ", - "VLANextractions ", - "VLANinsertions ", - "TxCsumOffload ", - "RxCsumGood ", - "RxDrops " -}; - -static int get_stats_count(struct net_device *dev) -{ - return ARRAY_SIZE(stats_strings); -} - -#define T3_REGMAP_SIZE (3 * 1024) - -static int get_regs_len(struct net_device *dev) -{ - return T3_REGMAP_SIZE; -} - -static int get_eeprom_len(struct net_device *dev) -{ - return EEPROMSIZE; -} - -static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - u32 fw_vers = 0; - struct adapter *adapter = dev->priv; - - t3_get_fw_version(adapter, &fw_vers); - - strcpy(info->driver, DRV_NAME); - strcpy(info->version, DRV_VERSION); - strcpy(info->bus_info, pci_name(adapter->pdev)); - if (!fw_vers) - strcpy(info->fw_version, "N/A"); - else { - snprintf(info->fw_version, sizeof(info->fw_version), - "%s %u.%u.%u", - G_FW_VERSION_TYPE(fw_vers) ? "T" : "N", - G_FW_VERSION_MAJOR(fw_vers), - G_FW_VERSION_MINOR(fw_vers), - G_FW_VERSION_MICRO(fw_vers)); - } -} - -static void get_strings(struct net_device *dev, u32 stringset, u8 * data) -{ - if (stringset == ETH_SS_STATS) - memcpy(data, stats_strings, sizeof(stats_strings)); -} - -static unsigned long collect_sge_port_stats(struct adapter *adapter, - struct port_info *p, int idx) -{ - int i; - unsigned long tot = 0; - - for (i = 0; i < p->nqsets; ++i) - tot += adapter->sge.qs[i + p->first_qset].port_stats[idx]; - return tot; -} - -static void get_stats(struct net_device *dev, struct ethtool_stats *stats, - u64 *data) -{ - struct adapter *adapter = dev->priv; - struct port_info *pi = netdev_priv(dev); - const struct mac_stats *s; - - spin_lock(&adapter->stats_lock); - s = t3_mac_update_stats(&pi->mac); - spin_unlock(&adapter->stats_lock); - - *data++ = s->tx_octets; - *data++ = s->tx_frames; - *data++ = s->tx_mcast_frames; - *data++ = s->tx_bcast_frames; - *data++ = s->tx_pause; - *data++ = s->tx_underrun; - *data++ = s->tx_fifo_urun; - - *data++ = s->tx_frames_64; - *data++ = s->tx_frames_65_127; - *data++ = s->tx_frames_128_255; - *data++ = s->tx_frames_256_511; - *data++ = s->tx_frames_512_1023; - *data++ = s->tx_frames_1024_1518; - *data++ = s->tx_frames_1519_max; - - *data++ = s->rx_octets; - *data++ = s->rx_frames; - *data++ = s->rx_mcast_frames; - *data++ = s->rx_bcast_frames; - *data++ = s->rx_pause; - *data++ = s->rx_fcs_errs; - *data++ = s->rx_symbol_errs; - *data++ = s->rx_short; - *data++ = s->rx_jabber; - *data++ = s->rx_too_long; - *data++ = s->rx_fifo_ovfl; - - *data++ = s->rx_frames_64; - *data++ = s->rx_frames_65_127; - *data++ = s->rx_frames_128_255; - *data++ = s->rx_frames_256_511; - *data++ = s->rx_frames_512_1023; - *data++ = s->rx_frames_1024_1518; - *data++ = s->rx_frames_1519_max; - - *data++ = pi->phy.fifo_errors; - - *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TSO); - *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANEX); - *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS); - *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM); - *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD); - *data++ = s->rx_cong_drops; -} - -static inline void reg_block_dump(struct adapter *ap, void *buf, - unsigned int start, unsigned int end) -{ - u32 *p = buf + start; - - for (; start <= end; start += sizeof(u32)) - *p++ = t3_read_reg(ap, start); -} - -static void get_regs(struct net_device *dev, struct ethtool_regs *regs, - void *buf) -{ - struct adapter *ap = dev->priv; - - /* - * Version scheme: - * bits 0..9: chip version - * bits 10..15: chip revision - * bit 31: set for PCIe cards - */ - regs->version = 3 | (ap->params.rev << 10) | (is_pcie(ap) << 31); - - /* - * We skip the MAC statistics registers because they are clear-on-read. - * Also reading multi-register stats would need to synchronize with the - * periodic mac stats accumulation. Hard to justify the complexity. - */ - memset(buf, 0, T3_REGMAP_SIZE); - reg_block_dump(ap, buf, 0, A_SG_RSPQ_CREDIT_RETURN); - reg_block_dump(ap, buf, A_SG_HI_DRB_HI_THRSH, A_ULPRX_PBL_ULIMIT); - reg_block_dump(ap, buf, A_ULPTX_CONFIG, A_MPS_INT_CAUSE); - reg_block_dump(ap, buf, A_CPL_SWITCH_CNTRL, A_CPL_MAP_TBL_DATA); - reg_block_dump(ap, buf, A_SMB_GLOBAL_TIME_CFG, A_XGM_SERDES_STAT3); - reg_block_dump(ap, buf, A_XGM_SERDES_STATUS0, - XGM_REG(A_XGM_SERDES_STAT3, 1)); - reg_block_dump(ap, buf, XGM_REG(A_XGM_SERDES_STATUS0, 1), - XGM_REG(A_XGM_RX_SPI4_SOP_EOP_CNT, 1)); -} - -static int restart_autoneg(struct net_device *dev) -{ - struct port_info *p = netdev_priv(dev); - - if (!netif_running(dev)) - return -EAGAIN; - if (p->link_config.autoneg != AUTONEG_ENABLE) - return -EINVAL; - p->phy.ops->autoneg_restart(&p->phy); - return 0; -} - -static int cxgb3_phys_id(struct net_device *dev, u32 data) -{ - int i; - struct adapter *adapter = dev->priv; - - if (data == 0) - data = 2; - - for (i = 0; i < data * 2; i++) { - t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, - (i & 1) ? F_GPIO0_OUT_VAL : 0); - if (msleep_interruptible(500)) - break; - } - t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, - F_GPIO0_OUT_VAL); - return 0; -} - -static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct port_info *p = netdev_priv(dev); - - cmd->supported = p->link_config.supported; - cmd->advertising = p->link_config.advertising; - - if (netif_carrier_ok(dev)) { - cmd->speed = p->link_config.speed; - cmd->duplex = p->link_config.duplex; - } else { - cmd->speed = -1; - cmd->duplex = -1; - } - - cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; - cmd->phy_address = p->phy.addr; - cmd->transceiver = XCVR_EXTERNAL; - cmd->autoneg = p->link_config.autoneg; - cmd->maxtxpkt = 0; - cmd->maxrxpkt = 0; - return 0; -} - -static int speed_duplex_to_caps(int speed, int duplex) -{ - int cap = 0; - - switch (speed) { - case SPEED_10: - if (duplex == DUPLEX_FULL) - cap = SUPPORTED_10baseT_Full; - else - cap = SUPPORTED_10baseT_Half; - break; - case SPEED_100: - if (duplex == DUPLEX_FULL) - cap = SUPPORTED_100baseT_Full; - else - cap = SUPPORTED_100baseT_Half; - break; - case SPEED_1000: - if (duplex == DUPLEX_FULL) - cap = SUPPORTED_1000baseT_Full; - else - cap = SUPPORTED_1000baseT_Half; - break; - case SPEED_10000: - if (duplex == DUPLEX_FULL) - cap = SUPPORTED_10000baseT_Full; - } - return cap; -} - -#define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ - ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \ - ADVERTISED_10000baseT_Full) - -static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct port_info *p = netdev_priv(dev); - struct link_config *lc = &p->link_config; - - if (!(lc->supported & SUPPORTED_Autoneg)) - return -EOPNOTSUPP; /* can't change speed/duplex */ - - if (cmd->autoneg == AUTONEG_DISABLE) { - int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex); - - if (!(lc->supported & cap) || cmd->speed == SPEED_1000) - return -EINVAL; - lc->requested_speed = cmd->speed; - lc->requested_duplex = cmd->duplex; - lc->advertising = 0; - } else { - cmd->advertising &= ADVERTISED_MASK; - cmd->advertising &= lc->supported; - if (!cmd->advertising) - return -EINVAL; - lc->requested_speed = SPEED_INVALID; - lc->requested_duplex = DUPLEX_INVALID; - lc->advertising = cmd->advertising | ADVERTISED_Autoneg; - } - lc->autoneg = cmd->autoneg; - if (netif_running(dev)) - t3_link_start(&p->phy, &p->mac, lc); - return 0; -} - -static void get_pauseparam(struct net_device *dev, - struct ethtool_pauseparam *epause) -{ - struct port_info *p = netdev_priv(dev); - - epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0; - epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0; - epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0; -} - -static int set_pauseparam(struct net_device *dev, - struct ethtool_pauseparam *epause) -{ - struct port_info *p = netdev_priv(dev); - struct link_config *lc = &p->link_config; - - if (epause->autoneg == AUTONEG_DISABLE) - lc->requested_fc = 0; - else if (lc->supported & SUPPORTED_Autoneg) - lc->requested_fc = PAUSE_AUTONEG; - else - return -EINVAL; - - if (epause->rx_pause) - lc->requested_fc |= PAUSE_RX; - if (epause->tx_pause) - lc->requested_fc |= PAUSE_TX; - if (lc->autoneg == AUTONEG_ENABLE) { - if (netif_running(dev)) - t3_link_start(&p->phy, &p->mac, lc); - } else { - lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); - if (netif_running(dev)) - t3_mac_set_speed_duplex_fc(&p->mac, -1, -1, lc->fc); - } - return 0; -} - -static u32 get_rx_csum(struct net_device *dev) -{ - struct port_info *p = netdev_priv(dev); - - return p->rx_csum_offload; -} - -static int set_rx_csum(struct net_device *dev, u32 data) -{ - struct port_info *p = netdev_priv(dev); - - p->rx_csum_offload = data; - return 0; -} - -static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) -{ - struct adapter *adapter = dev->priv; - - e->rx_max_pending = MAX_RX_BUFFERS; - e->rx_mini_max_pending = 0; - e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS; - e->tx_max_pending = MAX_TXQ_ENTRIES; - - e->rx_pending = adapter->params.sge.qset[0].fl_size; - e->rx_mini_pending = adapter->params.sge.qset[0].rspq_size; - e->rx_jumbo_pending = adapter->params.sge.qset[0].jumbo_size; - e->tx_pending = adapter->params.sge.qset[0].txq_size[0]; -} - -static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) -{ - int i; - struct adapter *adapter = dev->priv; - - if (e->rx_pending > MAX_RX_BUFFERS || - e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS || - e->tx_pending > MAX_TXQ_ENTRIES || - e->rx_mini_pending > MAX_RSPQ_ENTRIES || - e->rx_mini_pending < MIN_RSPQ_ENTRIES || - e->rx_pending < MIN_FL_ENTRIES || - e->rx_jumbo_pending < MIN_FL_ENTRIES || - e->tx_pending < adapter->params.nports * MIN_TXQ_ENTRIES) - return -EINVAL; - - if (adapter->flags & FULL_INIT_DONE) - return -EBUSY; - - for (i = 0; i < SGE_QSETS; ++i) { - struct qset_params *q = &adapter->params.sge.qset[i]; - - q->rspq_size = e->rx_mini_pending; - q->fl_size = e->rx_pending; - q->jumbo_size = e->rx_jumbo_pending; - q->txq_size[0] = e->tx_pending; - q->txq_size[1] = e->tx_pending; - q->txq_size[2] = e->tx_pending; - } - return 0; -} - -static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) -{ - struct adapter *adapter = dev->priv; - struct qset_params *qsp = &adapter->params.sge.qset[0]; - struct sge_qset *qs = &adapter->sge.qs[0]; - - if (c->rx_coalesce_usecs * 10 > M_NEWTIMER) - return -EINVAL; - - qsp->coalesce_usecs = c->rx_coalesce_usecs; - t3_update_qset_coalesce(qs, qsp); - return 0; -} - -static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) -{ - struct adapter *adapter = dev->priv; - struct qset_params *q = adapter->params.sge.qset; - - c->rx_coalesce_usecs = q->coalesce_usecs; - return 0; -} - -static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, - u8 * data) -{ - int i, err = 0; - struct adapter *adapter = dev->priv; - - u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - e->magic = EEPROM_MAGIC; - for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4) - err = t3_seeprom_read(adapter, i, (u32 *) & buf[i]); - - if (!err) - memcpy(data, buf + e->offset, e->len); - kfree(buf); - return err; -} - -static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, - u8 * data) -{ - u8 *buf; - int err = 0; - u32 aligned_offset, aligned_len, *p; - struct adapter *adapter = dev->priv; - - if (eeprom->magic != EEPROM_MAGIC) - return -EINVAL; - - aligned_offset = eeprom->offset & ~3; - aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3; - - if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) { - buf = kmalloc(aligned_len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - err = t3_seeprom_read(adapter, aligned_offset, (u32 *) buf); - if (!err && aligned_len > 4) - err = t3_seeprom_read(adapter, - aligned_offset + aligned_len - 4, - (u32 *) & buf[aligned_len - 4]); - if (err) - goto out; - memcpy(buf + (eeprom->offset & 3), data, eeprom->len); - } else - buf = data; - - err = t3_seeprom_wp(adapter, 0); - if (err) - goto out; - - for (p = (u32 *) buf; !err && aligned_len; aligned_len -= 4, p++) { - err = t3_seeprom_write(adapter, aligned_offset, *p); - aligned_offset += 4; - } - - if (!err) - err = t3_seeprom_wp(adapter, 1); -out: - if (buf != data) - kfree(buf); - return err; -} - -static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - wol->supported = 0; - wol->wolopts = 0; - memset(&wol->sopass, 0, sizeof(wol->sopass)); -} - -static const struct ethtool_ops cxgb_ethtool_ops = { - .get_settings = get_settings, - .set_settings = set_settings, - .get_drvinfo = get_drvinfo, - .get_msglevel = get_msglevel, - .set_msglevel = set_msglevel, - .get_ringparam = get_sge_param, - .set_ringparam = set_sge_param, - .get_coalesce = get_coalesce, - .set_coalesce = set_coalesce, - .get_eeprom_len = get_eeprom_len, - .get_eeprom = get_eeprom, - .set_eeprom = set_eeprom, - .get_pauseparam = get_pauseparam, - .set_pauseparam = set_pauseparam, - .get_rx_csum = get_rx_csum, - .set_rx_csum = set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_link = ethtool_op_get_link, - .get_strings = get_strings, - .phys_id = cxgb3_phys_id, - .nway_reset = restart_autoneg, - .get_stats_count = get_stats_count, - .get_ethtool_stats = get_stats, - .get_regs_len = get_regs_len, - .get_regs = get_regs, - .get_wol = get_wol, - .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, - .get_perm_addr = ethtool_op_get_perm_addr -}; - -static int in_range(int val, int lo, int hi) -{ - return val < 0 || (val <= hi && val >= lo); -} - -static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) -{ - int ret; - u32 cmd; - struct adapter *adapter = dev->priv; - - if (copy_from_user(&cmd, useraddr, sizeof(cmd))) - return -EFAULT; - - switch (cmd) { - case CHELSIO_SETREG:{ - struct ch_reg edata; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - if ((edata.addr & 3) != 0 - || edata.addr >= adapter->mmio_len) - return -EINVAL; - writel(edata.val, adapter->regs + edata.addr); - break; - } - case CHELSIO_GETREG:{ - struct ch_reg edata; - - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - if ((edata.addr & 3) != 0 - || edata.addr >= adapter->mmio_len) - return -EINVAL; - edata.val = readl(adapter->regs + edata.addr); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - break; - } - case CHELSIO_SET_QSET_PARAMS:{ - int i; - struct qset_params *q; - struct ch_qset_params t; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user(&t, useraddr, sizeof(t))) - return -EFAULT; - if (t.qset_idx >= SGE_QSETS) - return -EINVAL; - if (!in_range(t.intr_lat, 0, M_NEWTIMER) || - !in_range(t.cong_thres, 0, 255) || - !in_range(t.txq_size[0], MIN_TXQ_ENTRIES, - MAX_TXQ_ENTRIES) || - !in_range(t.txq_size[1], MIN_TXQ_ENTRIES, - MAX_TXQ_ENTRIES) || - !in_range(t.txq_size[2], MIN_CTRL_TXQ_ENTRIES, - MAX_CTRL_TXQ_ENTRIES) || - !in_range(t.fl_size[0], MIN_FL_ENTRIES, - MAX_RX_BUFFERS) - || !in_range(t.fl_size[1], MIN_FL_ENTRIES, - MAX_RX_JUMBO_BUFFERS) - || !in_range(t.rspq_size, MIN_RSPQ_ENTRIES, - MAX_RSPQ_ENTRIES)) - return -EINVAL; - if ((adapter->flags & FULL_INIT_DONE) && - (t.rspq_size >= 0 || t.fl_size[0] >= 0 || - t.fl_size[1] >= 0 || t.txq_size[0] >= 0 || - t.txq_size[1] >= 0 || t.txq_size[2] >= 0 || - t.polling >= 0 || t.cong_thres >= 0)) - return -EBUSY; - - q = &adapter->params.sge.qset[t.qset_idx]; - - if (t.rspq_size >= 0) - q->rspq_size = t.rspq_size; - if (t.fl_size[0] >= 0) - q->fl_size = t.fl_size[0]; - if (t.fl_size[1] >= 0) - q->jumbo_size = t.fl_size[1]; - if (t.txq_size[0] >= 0) - q->txq_size[0] = t.txq_size[0]; - if (t.txq_size[1] >= 0) - q->txq_size[1] = t.txq_size[1]; - if (t.txq_size[2] >= 0) - q->txq_size[2] = t.txq_size[2]; - if (t.cong_thres >= 0) - q->cong_thres = t.cong_thres; - if (t.intr_lat >= 0) { - struct sge_qset *qs = - &adapter->sge.qs[t.qset_idx]; - - q->coalesce_usecs = t.intr_lat; - t3_update_qset_coalesce(qs, q); - } - if (t.polling >= 0) { - if (adapter->flags & USING_MSIX) - q->polling = t.polling; - else { - /* No polling with INTx for T3A */ - if (adapter->params.rev == 0 && - !(adapter->flags & USING_MSI)) - t.polling = 0; - - for (i = 0; i < SGE_QSETS; i++) { - q = &adapter->params.sge. - qset[i]; - q->polling = t.polling; - } - } - } - break; - } - case CHELSIO_GET_QSET_PARAMS:{ - struct qset_params *q; - struct ch_qset_params t; - - if (copy_from_user(&t, useraddr, sizeof(t))) - return -EFAULT; - if (t.qset_idx >= SGE_QSETS) - return -EINVAL; - - q = &adapter->params.sge.qset[t.qset_idx]; - t.rspq_size = q->rspq_size; - t.txq_size[0] = q->txq_size[0]; - t.txq_size[1] = q->txq_size[1]; - t.txq_size[2] = q->txq_size[2]; - t.fl_size[0] = q->fl_size; - t.fl_size[1] = q->jumbo_size; - t.polling = q->polling; - t.intr_lat = q->coalesce_usecs; - t.cong_thres = q->cong_thres; - - if (copy_to_user(useraddr, &t, sizeof(t))) - return -EFAULT; - break; - } - case CHELSIO_SET_QSET_NUM:{ - struct ch_reg edata; - struct port_info *pi = netdev_priv(dev); - unsigned int i, first_qset = 0, other_qsets = 0; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (adapter->flags & FULL_INIT_DONE) - return -EBUSY; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - if (edata.val < 1 || - (edata.val > 1 && !(adapter->flags & USING_MSIX))) - return -EINVAL; - - for_each_port(adapter, i) - if (adapter->port[i] && adapter->port[i] != dev) - other_qsets += adap2pinfo(adapter, i)->nqsets; - - if (edata.val + other_qsets > SGE_QSETS) - return -EINVAL; - - pi->nqsets = edata.val; - - for_each_port(adapter, i) - if (adapter->port[i]) { - pi = adap2pinfo(adapter, i); - pi->first_qset = first_qset; - first_qset += pi->nqsets; - } - break; - } - case CHELSIO_GET_QSET_NUM:{ - struct ch_reg edata; - struct port_info *pi = netdev_priv(dev); - - edata.cmd = CHELSIO_GET_QSET_NUM; - edata.val = pi->nqsets; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - break; - } - case CHELSIO_LOAD_FW:{ - u8 *fw_data; - struct ch_mem_range t; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user(&t, useraddr, sizeof(t))) - return -EFAULT; - - fw_data = kmalloc(t.len, GFP_KERNEL); - if (!fw_data) - return -ENOMEM; - - if (copy_from_user - (fw_data, useraddr + sizeof(t), t.len)) { - kfree(fw_data); - return -EFAULT; - } - - ret = t3_load_fw(adapter, fw_data, t.len); - kfree(fw_data); - if (ret) - return ret; - break; - } - case CHELSIO_SETMTUTAB:{ - struct ch_mtus m; - int i; - - if (!is_offload(adapter)) - return -EOPNOTSUPP; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (offload_running(adapter)) - return -EBUSY; - if (copy_from_user(&m, useraddr, sizeof(m))) - return -EFAULT; - if (m.nmtus != NMTUS) - return -EINVAL; - if (m.mtus[0] < 81) /* accommodate SACK */ - return -EINVAL; - - /* MTUs must be in ascending order */ - for (i = 1; i < NMTUS; ++i) - if (m.mtus[i] < m.mtus[i - 1]) - return -EINVAL; - - memcpy(adapter->params.mtus, m.mtus, - sizeof(adapter->params.mtus)); - break; - } - case CHELSIO_GET_PM:{ - struct tp_params *p = &adapter->params.tp; - struct ch_pm m = {.cmd = CHELSIO_GET_PM }; - - if (!is_offload(adapter)) - return -EOPNOTSUPP; - m.tx_pg_sz = p->tx_pg_size; - m.tx_num_pg = p->tx_num_pgs; - m.rx_pg_sz = p->rx_pg_size; - m.rx_num_pg = p->rx_num_pgs; - m.pm_total = p->pmtx_size + p->chan_rx_size * p->nchan; - if (copy_to_user(useraddr, &m, sizeof(m))) - return -EFAULT; - break; - } - case CHELSIO_SET_PM:{ - struct ch_pm m; - struct tp_params *p = &adapter->params.tp; - - if (!is_offload(adapter)) - return -EOPNOTSUPP; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (adapter->flags & FULL_INIT_DONE) - return -EBUSY; - if (copy_from_user(&m, useraddr, sizeof(m))) - return -EFAULT; - if (!m.rx_pg_sz || (m.rx_pg_sz & (m.rx_pg_sz - 1)) || - !m.tx_pg_sz || (m.tx_pg_sz & (m.tx_pg_sz - 1))) - return -EINVAL; /* not power of 2 */ - if (!(m.rx_pg_sz & 0x14000)) - return -EINVAL; /* not 16KB or 64KB */ - if (!(m.tx_pg_sz & 0x1554000)) - return -EINVAL; - if (m.tx_num_pg == -1) - m.tx_num_pg = p->tx_num_pgs; - if (m.rx_num_pg == -1) - m.rx_num_pg = p->rx_num_pgs; - if (m.tx_num_pg % 24 || m.rx_num_pg % 24) - return -EINVAL; - if (m.rx_num_pg * m.rx_pg_sz > p->chan_rx_size || - m.tx_num_pg * m.tx_pg_sz > p->chan_tx_size) - return -EINVAL; - p->rx_pg_size = m.rx_pg_sz; - p->tx_pg_size = m.tx_pg_sz; - p->rx_num_pgs = m.rx_num_pg; - p->tx_num_pgs = m.tx_num_pg; - break; - } - case CHELSIO_GET_MEM:{ - struct ch_mem_range t; - struct mc7 *mem; - u64 buf[32]; - - if (!is_offload(adapter)) - return -EOPNOTSUPP; - if (!(adapter->flags & FULL_INIT_DONE)) - return -EIO; /* need the memory controllers */ - if (copy_from_user(&t, useraddr, sizeof(t))) - return -EFAULT; - if ((t.addr & 7) || (t.len & 7)) - return -EINVAL; - if (t.mem_id == MEM_CM) - mem = &adapter->cm; - else if (t.mem_id == MEM_PMRX) - mem = &adapter->pmrx; - else if (t.mem_id == MEM_PMTX) - mem = &adapter->pmtx; - else - return -EINVAL; - - /* - * Version scheme: - * bits 0..9: chip version - * bits 10..15: chip revision - */ - t.version = 3 | (adapter->params.rev << 10); - if (copy_to_user(useraddr, &t, sizeof(t))) - return -EFAULT; - - /* - * Read 256 bytes at a time as len can be large and we don't - * want to use huge intermediate buffers. - */ - useraddr += sizeof(t); /* advance to start of buffer */ - while (t.len) { - unsigned int chunk = - min_t(unsigned int, t.len, sizeof(buf)); - - ret = - t3_mc7_bd_read(mem, t.addr / 8, chunk / 8, - buf); - if (ret) - return ret; - if (copy_to_user(useraddr, buf, chunk)) - return -EFAULT; - useraddr += chunk; - t.addr += chunk; - t.len -= chunk; - } - break; - } - case CHELSIO_SET_TRACE_FILTER:{ - struct ch_trace t; - const struct trace_params *tp; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (!offload_running(adapter)) - return -EAGAIN; - if (copy_from_user(&t, useraddr, sizeof(t))) - return -EFAULT; - - tp = (const struct trace_params *)&t.sip; - if (t.config_tx) - t3_config_trace_filter(adapter, tp, 0, - t.invert_match, - t.trace_tx); - if (t.config_rx) - t3_config_trace_filter(adapter, tp, 1, - t.invert_match, - t.trace_rx); - break; - } - case CHELSIO_SET_PKTSCHED:{ - struct ch_pktsched_params p; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (!adapter->open_device_map) - return -EAGAIN; /* uP and SGE must be running */ - if (copy_from_user(&p, useraddr, sizeof(p))) - return -EFAULT; - send_pktsched_cmd(adapter, p.sched, p.idx, p.min, p.max, - p.binding); - break; - - } - default: - return -EOPNOTSUPP; - } - return 0; -} - -static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) -{ - int ret, mmd; - struct adapter *adapter = dev->priv; - struct port_info *pi = netdev_priv(dev); - struct mii_ioctl_data *data = if_mii(req); - - switch (cmd) { - case SIOCGMIIPHY: - data->phy_id = pi->phy.addr; - /* FALLTHRU */ - case SIOCGMIIREG:{ - u32 val; - struct cphy *phy = &pi->phy; - - if (!phy->mdio_read) - return -EOPNOTSUPP; - if (is_10G(adapter)) { - mmd = data->phy_id >> 8; - if (!mmd) - mmd = MDIO_DEV_PCS; - else if (mmd > MDIO_DEV_XGXS) - return -EINVAL; - - ret = - phy->mdio_read(adapter, data->phy_id & 0x1f, - mmd, data->reg_num, &val); - } else - ret = - phy->mdio_read(adapter, data->phy_id & 0x1f, - 0, data->reg_num & 0x1f, - &val); - if (!ret) - data->val_out = val; - break; - } - case SIOCSMIIREG:{ - struct cphy *phy = &pi->phy; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (!phy->mdio_write) - return -EOPNOTSUPP; - if (is_10G(adapter)) { - mmd = data->phy_id >> 8; - if (!mmd) - mmd = MDIO_DEV_PCS; - else if (mmd > MDIO_DEV_XGXS) - return -EINVAL; - - ret = - phy->mdio_write(adapter, - data->phy_id & 0x1f, mmd, - data->reg_num, - data->val_in); - } else - ret = - phy->mdio_write(adapter, - data->phy_id & 0x1f, 0, - data->reg_num & 0x1f, - data->val_in); - break; - } - case SIOCCHIOCTL: - return cxgb_extension_ioctl(dev, req->ifr_data); - default: - return -EOPNOTSUPP; - } - return ret; -} - -static int cxgb_change_mtu(struct net_device *dev, int new_mtu) -{ - int ret; - struct adapter *adapter = dev->priv; - struct port_info *pi = netdev_priv(dev); - - if (new_mtu < 81) /* accommodate SACK */ - return -EINVAL; - if ((ret = t3_mac_set_mtu(&pi->mac, new_mtu))) - return ret; - dev->mtu = new_mtu; - init_port_mtus(adapter); - if (adapter->params.rev == 0 && offload_running(adapter)) - t3_load_mtus(adapter, adapter->params.mtus, - adapter->params.a_wnd, adapter->params.b_wnd, - adapter->port[0]->mtu); - return 0; -} - -static int cxgb_set_mac_addr(struct net_device *dev, void *p) -{ - struct adapter *adapter = dev->priv; - struct port_info *pi = netdev_priv(dev); - struct sockaddr *addr = p; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EINVAL; - - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - t3_mac_set_address(&pi->mac, 0, dev->dev_addr); - if (offload_running(adapter)) - write_smt_entry(adapter, pi->port_id); - return 0; -} - -/** - * t3_synchronize_rx - wait for current Rx processing on a port to complete - * @adap: the adapter - * @p: the port - * - * Ensures that current Rx processing on any of the queues associated with - * the given port completes before returning. We do this by acquiring and - * releasing the locks of the response queues associated with the port. - */ -static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) -{ - int i; - - for (i = 0; i < p->nqsets; i++) { - struct sge_rspq *q = &adap->sge.qs[i + p->first_qset].rspq; - - spin_lock_irq(&q->lock); - spin_unlock_irq(&q->lock); - } -} - -static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct adapter *adapter = dev->priv; - struct port_info *pi = netdev_priv(dev); - - pi->vlan_grp = grp; - if (adapter->params.rev > 0) - t3_set_vlan_accel(adapter, 1 << pi->port_id, grp != NULL); - else { - /* single control for all ports */ - unsigned int i, have_vlans = 0; - for_each_port(adapter, i) - have_vlans |= adap2pinfo(adapter, i)->vlan_grp != NULL; - - t3_set_vlan_accel(adapter, 1, have_vlans); - } - t3_synchronize_rx(adapter, pi); -} - -static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) -{ - /* nothing */ -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void cxgb_netpoll(struct net_device *dev) -{ - struct adapter *adapter = dev->priv; - struct sge_qset *qs = dev2qset(dev); - - t3_intr_handler(adapter, qs->rspq.polling) (adapter->pdev->irq, - adapter); -} -#endif - -/* - * Periodic accumulation of MAC statistics. - */ -static void mac_stats_update(struct adapter *adapter) -{ - int i; - - for_each_port(adapter, i) { - struct net_device *dev = adapter->port[i]; - struct port_info *p = netdev_priv(dev); - - if (netif_running(dev)) { - spin_lock(&adapter->stats_lock); - t3_mac_update_stats(&p->mac); - spin_unlock(&adapter->stats_lock); - } - } -} - -static void check_link_status(struct adapter *adapter) -{ - int i; - - for_each_port(adapter, i) { - struct net_device *dev = adapter->port[i]; - struct port_info *p = netdev_priv(dev); - - if (!(p->port_type->caps & SUPPORTED_IRQ) && netif_running(dev)) - t3_link_changed(adapter, i); - } -} - -static void t3_adap_check_task(struct work_struct *work) -{ - struct adapter *adapter = container_of(work, struct adapter, - adap_check_task.work); - const struct adapter_params *p = &adapter->params; - - adapter->check_task_cnt++; - - /* Check link status for PHYs without interrupts */ - if (p->linkpoll_period) - check_link_status(adapter); - - /* Accumulate MAC stats if needed */ - if (!p->linkpoll_period || - (adapter->check_task_cnt * p->linkpoll_period) / 10 >= - p->stats_update_period) { - mac_stats_update(adapter); - adapter->check_task_cnt = 0; - } - - /* Schedule the next check update if any port is active. */ - spin_lock(&adapter->work_lock); - if (adapter->open_device_map & PORT_MASK) - schedule_chk_task(adapter); - spin_unlock(&adapter->work_lock); -} - -/* - * Processes external (PHY) interrupts in process context. - */ -static void ext_intr_task(struct work_struct *work) -{ - struct adapter *adapter = container_of(work, struct adapter, - ext_intr_handler_task); - - t3_phy_intr_handler(adapter); - - /* Now reenable external interrupts */ - spin_lock_irq(&adapter->work_lock); - if (adapter->slow_intr_mask) { - adapter->slow_intr_mask |= F_T3DBG; - t3_write_reg(adapter, A_PL_INT_CAUSE0, F_T3DBG); - t3_write_reg(adapter, A_PL_INT_ENABLE0, - adapter->slow_intr_mask); - } - spin_unlock_irq(&adapter->work_lock); -} - -/* - * Interrupt-context handler for external (PHY) interrupts. - */ -void t3_os_ext_intr_handler(struct adapter *adapter) -{ - /* - * Schedule a task to handle external interrupts as they may be slow - * and we use a mutex to protect MDIO registers. We disable PHY - * interrupts in the meantime and let the task reenable them when - * it's done. - */ - spin_lock(&adapter->work_lock); - if (adapter->slow_intr_mask) { - adapter->slow_intr_mask &= ~F_T3DBG; - t3_write_reg(adapter, A_PL_INT_ENABLE0, - adapter->slow_intr_mask); - queue_work(cxgb3_wq, &adapter->ext_intr_handler_task); - } - spin_unlock(&adapter->work_lock); -} - -void t3_fatal_err(struct adapter *adapter) -{ - unsigned int fw_status[4]; - - if (adapter->flags & FULL_INIT_DONE) { - t3_sge_stop(adapter); - t3_intr_disable(adapter); - } - CH_ALERT(adapter, "encountered fatal error, operation suspended\n"); - if (!t3_cim_ctl_blk_read(adapter, 0xa0, 4, fw_status)) - CH_ALERT(adapter, "FW status: 0x%x, 0x%x, 0x%x, 0x%x\n", - fw_status[0], fw_status[1], - fw_status[2], fw_status[3]); - -} - -static int __devinit cxgb_enable_msix(struct adapter *adap) -{ - struct msix_entry entries[SGE_QSETS + 1]; - int i, err; - - for (i = 0; i < ARRAY_SIZE(entries); ++i) - entries[i].entry = i; - - err = pci_enable_msix(adap->pdev, entries, ARRAY_SIZE(entries)); - if (!err) { - for (i = 0; i < ARRAY_SIZE(entries); ++i) - adap->msix_info[i].vec = entries[i].vector; - } else if (err > 0) - dev_info(&adap->pdev->dev, - "only %d MSI-X vectors left, not using MSI-X\n", err); - return err; -} - -static void __devinit print_port_info(struct adapter *adap, - const struct adapter_info *ai) -{ - static const char *pci_variant[] = { - "PCI", "PCI-X", "PCI-X ECC", "PCI-X 266", "PCI Express" - }; - - int i; - char buf[80]; - - if (is_pcie(adap)) - snprintf(buf, sizeof(buf), "%s x%d", - pci_variant[adap->params.pci.variant], - adap->params.pci.width); - else - snprintf(buf, sizeof(buf), "%s %dMHz/%d-bit", - pci_variant[adap->params.pci.variant], - adap->params.pci.speed, adap->params.pci.width); - - for_each_port(adap, i) { - struct net_device *dev = adap->port[i]; - const struct port_info *pi = netdev_priv(dev); - - if (!test_bit(i, &adap->registered_device_map)) - continue; - printk(KERN_INFO "%s: %s %s RNIC (rev %d) %s%s\n", - dev->name, ai->desc, pi->port_type->desc, - adap->params.rev, buf, - (adap->flags & USING_MSIX) ? " MSI-X" : - (adap->flags & USING_MSI) ? " MSI" : ""); - if (adap->name == dev->name && adap->params.vpd.mclk) - printk(KERN_INFO "%s: %uMB CM, %uMB PMTX, %uMB PMRX\n", - adap->name, t3_mc7_size(&adap->cm) >> 20, - t3_mc7_size(&adap->pmtx) >> 20, - t3_mc7_size(&adap->pmrx) >> 20); - } -} - -static int __devinit init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - static int version_printed; - - int i, err, pci_using_dac = 0; - unsigned long mmio_start, mmio_len; - const struct adapter_info *ai; - struct adapter *adapter = NULL; - struct port_info *pi; - - if (!version_printed) { - printk(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); - ++version_printed; - } - - if (!cxgb3_wq) { - cxgb3_wq = create_singlethread_workqueue(DRV_NAME); - if (!cxgb3_wq) { - printk(KERN_ERR DRV_NAME - ": cannot initialize work queue\n"); - return -ENOMEM; - } - } - - err = pci_request_regions(pdev, DRV_NAME); - if (err) { - /* Just info, some other driver may have claimed the device. */ - dev_info(&pdev->dev, "cannot obtain PCI resources\n"); - return err; - } - - err = pci_enable_device(pdev); - if (err) { - dev_err(&pdev->dev, "cannot enable PCI device\n"); - goto out_release_regions; - } - - if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { - pci_using_dac = 1; - err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); - if (err) { - dev_err(&pdev->dev, "unable to obtain 64-bit DMA for " - "coherent allocations\n"); - goto out_disable_device; - } - } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) { - dev_err(&pdev->dev, "no usable DMA configuration\n"); - goto out_disable_device; - } - - pci_set_master(pdev); - - mmio_start = pci_resource_start(pdev, 0); - mmio_len = pci_resource_len(pdev, 0); - ai = t3_get_adapter_info(ent->driver_data); - - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); - if (!adapter) { - err = -ENOMEM; - goto out_disable_device; - } - - adapter->regs = ioremap_nocache(mmio_start, mmio_len); - if (!adapter->regs) { - dev_err(&pdev->dev, "cannot map device registers\n"); - err = -ENOMEM; - goto out_free_adapter; - } - - adapter->pdev = pdev; - adapter->name = pci_name(pdev); - adapter->msg_enable = dflt_msg_enable; - adapter->mmio_len = mmio_len; - - mutex_init(&adapter->mdio_lock); - spin_lock_init(&adapter->work_lock); - spin_lock_init(&adapter->stats_lock); - - INIT_LIST_HEAD(&adapter->adapter_list); - INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); - INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); - - for (i = 0; i < ai->nports; ++i) { - struct net_device *netdev; - - netdev = alloc_etherdev(sizeof(struct port_info)); - if (!netdev) { - err = -ENOMEM; - goto out_free_dev; - } - - SET_MODULE_OWNER(netdev); - SET_NETDEV_DEV(netdev, &pdev->dev); - - adapter->port[i] = netdev; - pi = netdev_priv(netdev); - pi->rx_csum_offload = 1; - pi->nqsets = 1; - pi->first_qset = i; - pi->activity = 0; - pi->port_id = i; - netif_carrier_off(netdev); - netdev->irq = pdev->irq; - netdev->mem_start = mmio_start; - netdev->mem_end = mmio_start + mmio_len - 1; - netdev->priv = adapter; - netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; - netdev->features |= NETIF_F_LLTX; - if (pci_using_dac) - netdev->features |= NETIF_F_HIGHDMA; - - netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - netdev->vlan_rx_register = vlan_rx_register; - netdev->vlan_rx_kill_vid = vlan_rx_kill_vid; - - netdev->open = cxgb_open; - netdev->stop = cxgb_close; - netdev->hard_start_xmit = t3_eth_xmit; - netdev->get_stats = cxgb_get_stats; - netdev->set_multicast_list = cxgb_set_rxmode; - netdev->do_ioctl = cxgb_ioctl; - netdev->change_mtu = cxgb_change_mtu; - netdev->set_mac_address = cxgb_set_mac_addr; -#ifdef CONFIG_NET_POLL_CONTROLLER - netdev->poll_controller = cxgb_netpoll; -#endif - netdev->weight = 64; - - SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops); - } - - pci_set_drvdata(pdev, adapter->port[0]); - if (t3_prep_adapter(adapter, ai, 1) < 0) { - err = -ENODEV; - goto out_free_dev; - } - - /* - * The card is now ready to go. If any errors occur during device - * registration we do not fail the whole card but rather proceed only - * with the ports we manage to register successfully. However we must - * register at least one net device. - */ - for_each_port(adapter, i) { - err = register_netdev(adapter->port[i]); - if (err) - dev_warn(&pdev->dev, - "cannot register net device %s, skipping\n", - adapter->port[i]->name); - else { - /* - * Change the name we use for messages to the name of - * the first successfully registered interface. - */ - if (!adapter->registered_device_map) - adapter->name = adapter->port[i]->name; - - __set_bit(i, &adapter->registered_device_map); - } - } - if (!adapter->registered_device_map) { - dev_err(&pdev->dev, "could not register any net devices\n"); - goto out_free_dev; - } - - /* Driver's ready. Reflect it on LEDs */ - t3_led_ready(adapter); - - if (is_offload(adapter)) { - __set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map); - cxgb3_adapter_ofld(adapter); - } - - /* See what interrupts we'll be using */ - if (msi > 1 && cxgb_enable_msix(adapter) == 0) - adapter->flags |= USING_MSIX; - else if (msi > 0 && pci_enable_msi(pdev) == 0) - adapter->flags |= USING_MSI; - - err = sysfs_create_group(&adapter->port[0]->class_dev.kobj, - &cxgb3_attr_group); - - print_port_info(adapter, ai); - return 0; - -out_free_dev: - iounmap(adapter->regs); - for (i = ai->nports - 1; i >= 0; --i) - if (adapter->port[i]) - free_netdev(adapter->port[i]); - -out_free_adapter: - kfree(adapter); - -out_disable_device: - pci_disable_device(pdev); -out_release_regions: - pci_release_regions(pdev); - pci_set_drvdata(pdev, NULL); - return err; -} - -static void __devexit remove_one(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - if (dev) { - int i; - struct adapter *adapter = dev->priv; - - t3_sge_stop(adapter); - sysfs_remove_group(&adapter->port[0]->class_dev.kobj, - &cxgb3_attr_group); - - for_each_port(adapter, i) - if (test_bit(i, &adapter->registered_device_map)) - unregister_netdev(adapter->port[i]); - - if (is_offload(adapter)) { - cxgb3_adapter_unofld(adapter); - if (test_bit(OFFLOAD_DEVMAP_BIT, - &adapter->open_device_map)) - offload_close(&adapter->tdev); - } - - t3_free_sge_resources(adapter); - cxgb_disable_msi(adapter); - - for (i = 0; i < ARRAY_SIZE(adapter->dummy_netdev); i++) - if (adapter->dummy_netdev[i]) { - free_netdev(adapter->dummy_netdev[i]); - adapter->dummy_netdev[i] = NULL; - } - - for_each_port(adapter, i) - if (adapter->port[i]) - free_netdev(adapter->port[i]); - - iounmap(adapter->regs); - kfree(adapter); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - } -} - -static struct pci_driver driver = { - .name = DRV_NAME, - .id_table = cxgb3_pci_tbl, - .probe = init_one, - .remove = __devexit_p(remove_one), -}; - -static int __init cxgb3_init_module(void) -{ - int ret; - - cxgb3_offload_init(); - - ret = pci_register_driver(&driver); - return ret; -} - -static void __exit cxgb3_cleanup_module(void) -{ - pci_unregister_driver(&driver); - if (cxgb3_wq) - destroy_workqueue(cxgb3_wq); -} - -module_init(cxgb3_init_module); -module_exit(cxgb3_cleanup_module); diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.c b/trunk/drivers/net/cxgb3/cxgb3_offload.c deleted file mode 100644 index c3a02d613382..000000000000 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.c +++ /dev/null @@ -1,1222 +0,0 @@ -/* - * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved. - * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "regs.h" -#include "cxgb3_ioctl.h" -#include "cxgb3_ctl_defs.h" -#include "cxgb3_defs.h" -#include "l2t.h" -#include "firmware_exports.h" -#include "cxgb3_offload.h" - -static LIST_HEAD(client_list); -static LIST_HEAD(ofld_dev_list); -static DEFINE_MUTEX(cxgb3_db_lock); - -static DEFINE_RWLOCK(adapter_list_lock); -static LIST_HEAD(adapter_list); - -static const unsigned int MAX_ATIDS = 64 * 1024; -static const unsigned int ATID_BASE = 0x100000; - -static inline int offload_activated(struct t3cdev *tdev) -{ - const struct adapter *adapter = tdev2adap(tdev); - - return (test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)); -} - -/** - * cxgb3_register_client - register an offload client - * @client: the client - * - * Add the client to the client list, - * and call backs the client for each activated offload device - */ -void cxgb3_register_client(struct cxgb3_client *client) -{ - struct t3cdev *tdev; - - mutex_lock(&cxgb3_db_lock); - list_add_tail(&client->client_list, &client_list); - - if (client->add) { - list_for_each_entry(tdev, &ofld_dev_list, ofld_dev_list) { - if (offload_activated(tdev)) - client->add(tdev); - } - } - mutex_unlock(&cxgb3_db_lock); -} - -EXPORT_SYMBOL(cxgb3_register_client); - -/** - * cxgb3_unregister_client - unregister an offload client - * @client: the client - * - * Remove the client to the client list, - * and call backs the client for each activated offload device. - */ -void cxgb3_unregister_client(struct cxgb3_client *client) -{ - struct t3cdev *tdev; - - mutex_lock(&cxgb3_db_lock); - list_del(&client->client_list); - - if (client->remove) { - list_for_each_entry(tdev, &ofld_dev_list, ofld_dev_list) { - if (offload_activated(tdev)) - client->remove(tdev); - } - } - mutex_unlock(&cxgb3_db_lock); -} - -EXPORT_SYMBOL(cxgb3_unregister_client); - -/** - * cxgb3_add_clients - activate registered clients for an offload device - * @tdev: the offload device - * - * Call backs all registered clients once a offload device is activated - */ -void cxgb3_add_clients(struct t3cdev *tdev) -{ - struct cxgb3_client *client; - - mutex_lock(&cxgb3_db_lock); - list_for_each_entry(client, &client_list, client_list) { - if (client->add) - client->add(tdev); - } - mutex_unlock(&cxgb3_db_lock); -} - -/** - * cxgb3_remove_clients - deactivates registered clients - * for an offload device - * @tdev: the offload device - * - * Call backs all registered clients once a offload device is deactivated - */ -void cxgb3_remove_clients(struct t3cdev *tdev) -{ - struct cxgb3_client *client; - - mutex_lock(&cxgb3_db_lock); - list_for_each_entry(client, &client_list, client_list) { - if (client->remove) - client->remove(tdev); - } - mutex_unlock(&cxgb3_db_lock); -} - -static struct net_device *get_iff_from_mac(struct adapter *adapter, - const unsigned char *mac, - unsigned int vlan) -{ - int i; - - for_each_port(adapter, i) { - const struct vlan_group *grp; - struct net_device *dev = adapter->port[i]; - const struct port_info *p = netdev_priv(dev); - - if (!memcmp(dev->dev_addr, mac, ETH_ALEN)) { - if (vlan && vlan != VLAN_VID_MASK) { - grp = p->vlan_grp; - dev = grp ? grp->vlan_devices[vlan] : NULL; - } else - while (dev->master) - dev = dev->master; - return dev; - } - } - return NULL; -} - -static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req, - void *data) -{ - int ret = 0; - struct ulp_iscsi_info *uiip = data; - - switch (req) { - case ULP_ISCSI_GET_PARAMS: - uiip->pdev = adapter->pdev; - uiip->llimit = t3_read_reg(adapter, A_ULPRX_ISCSI_LLIMIT); - uiip->ulimit = t3_read_reg(adapter, A_ULPRX_ISCSI_ULIMIT); - uiip->tagmask = t3_read_reg(adapter, A_ULPRX_ISCSI_TAGMASK); - /* - * On tx, the iscsi pdu has to be <= tx page size and has to - * fit into the Tx PM FIFO. - */ - uiip->max_txsz = min(adapter->params.tp.tx_pg_size, - t3_read_reg(adapter, A_PM1_TX_CFG) >> 17); - /* on rx, the iscsi pdu has to be < rx page size and the - whole pdu + cpl headers has to fit into one sge buffer */ - uiip->max_rxsz = min_t(unsigned int, - adapter->params.tp.rx_pg_size, - (adapter->sge.qs[0].fl[1].buf_size - - sizeof(struct cpl_rx_data) * 2 - - sizeof(struct cpl_rx_data_ddp))); - break; - case ULP_ISCSI_SET_PARAMS: - t3_write_reg(adapter, A_ULPRX_ISCSI_TAGMASK, uiip->tagmask); - break; - default: - ret = -EOPNOTSUPP; - } - return ret; -} - -/* Response queue used for RDMA events. */ -#define ASYNC_NOTIF_RSPQ 0 - -static int cxgb_rdma_ctl(struct adapter *adapter, unsigned int req, void *data) -{ - int ret = 0; - - switch (req) { - case RDMA_GET_PARAMS:{ - struct rdma_info *req = data; - struct pci_dev *pdev = adapter->pdev; - - req->udbell_physbase = pci_resource_start(pdev, 2); - req->udbell_len = pci_resource_len(pdev, 2); - req->tpt_base = - t3_read_reg(adapter, A_ULPTX_TPT_LLIMIT); - req->tpt_top = t3_read_reg(adapter, A_ULPTX_TPT_ULIMIT); - req->pbl_base = - t3_read_reg(adapter, A_ULPTX_PBL_LLIMIT); - req->pbl_top = t3_read_reg(adapter, A_ULPTX_PBL_ULIMIT); - req->rqt_base = t3_read_reg(adapter, A_ULPRX_RQ_LLIMIT); - req->rqt_top = t3_read_reg(adapter, A_ULPRX_RQ_ULIMIT); - req->kdb_addr = adapter->regs + A_SG_KDOORBELL; - req->pdev = pdev; - break; - } - case RDMA_CQ_OP:{ - unsigned long flags; - struct rdma_cq_op *req = data; - - /* may be called in any context */ - spin_lock_irqsave(&adapter->sge.reg_lock, flags); - ret = t3_sge_cqcntxt_op(adapter, req->id, req->op, - req->credits); - spin_unlock_irqrestore(&adapter->sge.reg_lock, flags); - break; - } - case RDMA_GET_MEM:{ - struct ch_mem_range *t = data; - struct mc7 *mem; - - if ((t->addr & 7) || (t->len & 7)) - return -EINVAL; - if (t->mem_id == MEM_CM) - mem = &adapter->cm; - else if (t->mem_id == MEM_PMRX) - mem = &adapter->pmrx; - else if (t->mem_id == MEM_PMTX) - mem = &adapter->pmtx; - else - return -EINVAL; - - ret = - t3_mc7_bd_read(mem, t->addr / 8, t->len / 8, - (u64 *) t->buf); - if (ret) - return ret; - break; - } - case RDMA_CQ_SETUP:{ - struct rdma_cq_setup *req = data; - - spin_lock_irq(&adapter->sge.reg_lock); - ret = - t3_sge_init_cqcntxt(adapter, req->id, - req->base_addr, req->size, - ASYNC_NOTIF_RSPQ, - req->ovfl_mode, req->credits, - req->credit_thres); - spin_unlock_irq(&adapter->sge.reg_lock); - break; - } - case RDMA_CQ_DISABLE: - spin_lock_irq(&adapter->sge.reg_lock); - ret = t3_sge_disable_cqcntxt(adapter, *(unsigned int *)data); - spin_unlock_irq(&adapter->sge.reg_lock); - break; - case RDMA_CTRL_QP_SETUP:{ - struct rdma_ctrlqp_setup *req = data; - - spin_lock_irq(&adapter->sge.reg_lock); - ret = t3_sge_init_ecntxt(adapter, FW_RI_SGEEC_START, 0, - SGE_CNTXT_RDMA, - ASYNC_NOTIF_RSPQ, - req->base_addr, req->size, - FW_RI_TID_START, 1, 0); - spin_unlock_irq(&adapter->sge.reg_lock); - break; - } - default: - ret = -EOPNOTSUPP; - } - return ret; -} - -static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data) -{ - struct adapter *adapter = tdev2adap(tdev); - struct tid_range *tid; - struct mtutab *mtup; - struct iff_mac *iffmacp; - struct ddp_params *ddpp; - struct adap_ports *ports; - int i; - - switch (req) { - case GET_MAX_OUTSTANDING_WR: - *(unsigned int *)data = FW_WR_NUM; - break; - case GET_WR_LEN: - *(unsigned int *)data = WR_FLITS; - break; - case GET_TX_MAX_CHUNK: - *(unsigned int *)data = 1 << 20; /* 1MB */ - break; - case GET_TID_RANGE: - tid = data; - tid->num = t3_mc5_size(&adapter->mc5) - - adapter->params.mc5.nroutes - - adapter->params.mc5.nfilters - adapter->params.mc5.nservers; - tid->base = 0; - break; - case GET_STID_RANGE: - tid = data; - tid->num = adapter->params.mc5.nservers; - tid->base = t3_mc5_size(&adapter->mc5) - tid->num - - adapter->params.mc5.nfilters - adapter->params.mc5.nroutes; - break; - case GET_L2T_CAPACITY: - *(unsigned int *)data = 2048; - break; - case GET_MTUS: - mtup = data; - mtup->size = NMTUS; - mtup->mtus = adapter->params.mtus; - break; - case GET_IFF_FROM_MAC: - iffmacp = data; - iffmacp->dev = get_iff_from_mac(adapter, iffmacp->mac_addr, - iffmacp->vlan_tag & - VLAN_VID_MASK); - break; - case GET_DDP_PARAMS: - ddpp = data; - ddpp->llimit = t3_read_reg(adapter, A_ULPRX_TDDP_LLIMIT); - ddpp->ulimit = t3_read_reg(adapter, A_ULPRX_TDDP_ULIMIT); - ddpp->tag_mask = t3_read_reg(adapter, A_ULPRX_TDDP_TAGMASK); - break; - case GET_PORTS: - ports = data; - ports->nports = adapter->params.nports; - for_each_port(adapter, i) - ports->lldevs[i] = adapter->port[i]; - break; - case ULP_ISCSI_GET_PARAMS: - case ULP_ISCSI_SET_PARAMS: - if (!offload_running(adapter)) - return -EAGAIN; - return cxgb_ulp_iscsi_ctl(adapter, req, data); - case RDMA_GET_PARAMS: - case RDMA_CQ_OP: - case RDMA_CQ_SETUP: - case RDMA_CQ_DISABLE: - case RDMA_CTRL_QP_SETUP: - case RDMA_GET_MEM: - if (!offload_running(adapter)) - return -EAGAIN; - return cxgb_rdma_ctl(adapter, req, data); - default: - return -EOPNOTSUPP; - } - return 0; -} - -/* - * Dummy handler for Rx offload packets in case we get an offload packet before - * proper processing is setup. This complains and drops the packet as it isn't - * normal to get offload packets at this stage. - */ -static int rx_offload_blackhole(struct t3cdev *dev, struct sk_buff **skbs, - int n) -{ - CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data %u\n", - n, ntohl(*(u32 *)skbs[0]->data)); - while (n--) - dev_kfree_skb_any(skbs[n]); - return 0; -} - -static void dummy_neigh_update(struct t3cdev *dev, struct neighbour *neigh) -{ -} - -void cxgb3_set_dummy_ops(struct t3cdev *dev) -{ - dev->recv = rx_offload_blackhole; - dev->neigh_update = dummy_neigh_update; -} - -/* - * Free an active-open TID. - */ -void *cxgb3_free_atid(struct t3cdev *tdev, int atid) -{ - struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; - union active_open_entry *p = atid2entry(t, atid); - void *ctx = p->t3c_tid.ctx; - - spin_lock_bh(&t->atid_lock); - p->next = t->afree; - t->afree = p; - t->atids_in_use--; - spin_unlock_bh(&t->atid_lock); - - return ctx; -} - -EXPORT_SYMBOL(cxgb3_free_atid); - -/* - * Free a server TID and return it to the free pool. - */ -void cxgb3_free_stid(struct t3cdev *tdev, int stid) -{ - struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; - union listen_entry *p = stid2entry(t, stid); - - spin_lock_bh(&t->stid_lock); - p->next = t->sfree; - t->sfree = p; - t->stids_in_use--; - spin_unlock_bh(&t->stid_lock); -} - -EXPORT_SYMBOL(cxgb3_free_stid); - -void cxgb3_insert_tid(struct t3cdev *tdev, struct cxgb3_client *client, - void *ctx, unsigned int tid) -{ - struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; - - t->tid_tab[tid].client = client; - t->tid_tab[tid].ctx = ctx; - atomic_inc(&t->tids_in_use); -} - -EXPORT_SYMBOL(cxgb3_insert_tid); - -/* - * Populate a TID_RELEASE WR. The skb must be already propely sized. - */ -static inline void mk_tid_release(struct sk_buff *skb, unsigned int tid) -{ - struct cpl_tid_release *req; - - skb->priority = CPL_PRIORITY_SETUP; - req = (struct cpl_tid_release *)__skb_put(skb, sizeof(*req)); - req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); - OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid)); -} - -static void t3_process_tid_release_list(struct work_struct *work) -{ - struct t3c_data *td = container_of(work, struct t3c_data, - tid_release_task); - struct sk_buff *skb; - struct t3cdev *tdev = td->dev; - - - spin_lock_bh(&td->tid_release_lock); - while (td->tid_release_list) { - struct t3c_tid_entry *p = td->tid_release_list; - - td->tid_release_list = (struct t3c_tid_entry *)p->ctx; - spin_unlock_bh(&td->tid_release_lock); - - skb = alloc_skb(sizeof(struct cpl_tid_release), - GFP_KERNEL | __GFP_NOFAIL); - mk_tid_release(skb, p - td->tid_maps.tid_tab); - cxgb3_ofld_send(tdev, skb); - p->ctx = NULL; - spin_lock_bh(&td->tid_release_lock); - } - spin_unlock_bh(&td->tid_release_lock); -} - -/* use ctx as a next pointer in the tid release list */ -void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid) -{ - struct t3c_data *td = T3C_DATA(tdev); - struct t3c_tid_entry *p = &td->tid_maps.tid_tab[tid]; - - spin_lock_bh(&td->tid_release_lock); - p->ctx = (void *)td->tid_release_list; - td->tid_release_list = p; - if (!p->ctx) - schedule_work(&td->tid_release_task); - spin_unlock_bh(&td->tid_release_lock); -} - -EXPORT_SYMBOL(cxgb3_queue_tid_release); - -/* - * Remove a tid from the TID table. A client may defer processing its last - * CPL message if it is locked at the time it arrives, and while the message - * sits in the client's backlog the TID may be reused for another connection. - * To handle this we atomically switch the TID association if it still points - * to the original client context. - */ -void cxgb3_remove_tid(struct t3cdev *tdev, void *ctx, unsigned int tid) -{ - struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; - - BUG_ON(tid >= t->ntids); - if (tdev->type == T3A) - (void)cmpxchg(&t->tid_tab[tid].ctx, ctx, NULL); - else { - struct sk_buff *skb; - - skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC); - if (likely(skb)) { - mk_tid_release(skb, tid); - cxgb3_ofld_send(tdev, skb); - t->tid_tab[tid].ctx = NULL; - } else - cxgb3_queue_tid_release(tdev, tid); - } - atomic_dec(&t->tids_in_use); -} - -EXPORT_SYMBOL(cxgb3_remove_tid); - -int cxgb3_alloc_atid(struct t3cdev *tdev, struct cxgb3_client *client, - void *ctx) -{ - int atid = -1; - struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; - - spin_lock_bh(&t->atid_lock); - if (t->afree) { - union active_open_entry *p = t->afree; - - atid = (p - t->atid_tab) + t->atid_base; - t->afree = p->next; - p->t3c_tid.ctx = ctx; - p->t3c_tid.client = client; - t->atids_in_use++; - } - spin_unlock_bh(&t->atid_lock); - return atid; -} - -EXPORT_SYMBOL(cxgb3_alloc_atid); - -int cxgb3_alloc_stid(struct t3cdev *tdev, struct cxgb3_client *client, - void *ctx) -{ - int stid = -1; - struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; - - spin_lock_bh(&t->stid_lock); - if (t->sfree) { - union listen_entry *p = t->sfree; - - stid = (p - t->stid_tab) + t->stid_base; - t->sfree = p->next; - p->t3c_tid.ctx = ctx; - p->t3c_tid.client = client; - t->stids_in_use++; - } - spin_unlock_bh(&t->stid_lock); - return stid; -} - -EXPORT_SYMBOL(cxgb3_alloc_stid); - -static int do_smt_write_rpl(struct t3cdev *dev, struct sk_buff *skb) -{ - struct cpl_smt_write_rpl *rpl = cplhdr(skb); - - if (rpl->status != CPL_ERR_NONE) - printk(KERN_ERR - "Unexpected SMT_WRITE_RPL status %u for entry %u\n", - rpl->status, GET_TID(rpl)); - - return CPL_RET_BUF_DONE; -} - -static int do_l2t_write_rpl(struct t3cdev *dev, struct sk_buff *skb) -{ - struct cpl_l2t_write_rpl *rpl = cplhdr(skb); - - if (rpl->status != CPL_ERR_NONE) - printk(KERN_ERR - "Unexpected L2T_WRITE_RPL status %u for entry %u\n", - rpl->status, GET_TID(rpl)); - - return CPL_RET_BUF_DONE; -} - -static int do_act_open_rpl(struct t3cdev *dev, struct sk_buff *skb) -{ - struct cpl_act_open_rpl *rpl = cplhdr(skb); - unsigned int atid = G_TID(ntohl(rpl->atid)); - struct t3c_tid_entry *t3c_tid; - - t3c_tid = lookup_atid(&(T3C_DATA(dev))->tid_maps, atid); - if (t3c_tid->ctx && t3c_tid->client && t3c_tid->client->handlers && - t3c_tid->client->handlers[CPL_ACT_OPEN_RPL]) { - return t3c_tid->client->handlers[CPL_ACT_OPEN_RPL] (dev, skb, - t3c_tid-> - ctx); - } else { - printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", - dev->name, CPL_ACT_OPEN_RPL); - return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; - } -} - -static int do_stid_rpl(struct t3cdev *dev, struct sk_buff *skb) -{ - union opcode_tid *p = cplhdr(skb); - unsigned int stid = G_TID(ntohl(p->opcode_tid)); - struct t3c_tid_entry *t3c_tid; - - t3c_tid = lookup_stid(&(T3C_DATA(dev))->tid_maps, stid); - if (t3c_tid->ctx && t3c_tid->client->handlers && - t3c_tid->client->handlers[p->opcode]) { - return t3c_tid->client->handlers[p->opcode] (dev, skb, - t3c_tid->ctx); - } else { - printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", - dev->name, p->opcode); - return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; - } -} - -static int do_hwtid_rpl(struct t3cdev *dev, struct sk_buff *skb) -{ - union opcode_tid *p = cplhdr(skb); - unsigned int hwtid = G_TID(ntohl(p->opcode_tid)); - struct t3c_tid_entry *t3c_tid; - - t3c_tid = lookup_tid(&(T3C_DATA(dev))->tid_maps, hwtid); - if (t3c_tid->ctx && t3c_tid->client->handlers && - t3c_tid->client->handlers[p->opcode]) { - return t3c_tid->client->handlers[p->opcode] - (dev, skb, t3c_tid->ctx); - } else { - printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", - dev->name, p->opcode); - return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; - } -} - -static int do_cr(struct t3cdev *dev, struct sk_buff *skb) -{ - struct cpl_pass_accept_req *req = cplhdr(skb); - unsigned int stid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); - struct t3c_tid_entry *t3c_tid; - - t3c_tid = lookup_stid(&(T3C_DATA(dev))->tid_maps, stid); - if (t3c_tid->ctx && t3c_tid->client->handlers && - t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]) { - return t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ] - (dev, skb, t3c_tid->ctx); - } else { - printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", - dev->name, CPL_PASS_ACCEPT_REQ); - return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; - } -} - -static int do_abort_req_rss(struct t3cdev *dev, struct sk_buff *skb) -{ - union opcode_tid *p = cplhdr(skb); - unsigned int hwtid = G_TID(ntohl(p->opcode_tid)); - struct t3c_tid_entry *t3c_tid; - - t3c_tid = lookup_tid(&(T3C_DATA(dev))->tid_maps, hwtid); - if (t3c_tid->ctx && t3c_tid->client->handlers && - t3c_tid->client->handlers[p->opcode]) { - return t3c_tid->client->handlers[p->opcode] - (dev, skb, t3c_tid->ctx); - } else { - struct cpl_abort_req_rss *req = cplhdr(skb); - struct cpl_abort_rpl *rpl; - - struct sk_buff *skb = - alloc_skb(sizeof(struct cpl_abort_rpl), GFP_ATOMIC); - if (!skb) { - printk("do_abort_req_rss: couldn't get skb!\n"); - goto out; - } - skb->priority = CPL_PRIORITY_DATA; - __skb_put(skb, sizeof(struct cpl_abort_rpl)); - rpl = cplhdr(skb); - rpl->wr.wr_hi = - htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL)); - rpl->wr.wr_lo = htonl(V_WR_TID(GET_TID(req))); - OPCODE_TID(rpl) = - htonl(MK_OPCODE_TID(CPL_ABORT_RPL, GET_TID(req))); - rpl->cmd = req->status; - cxgb3_ofld_send(dev, skb); -out: - return CPL_RET_BUF_DONE; - } -} - -static int do_act_establish(struct t3cdev *dev, struct sk_buff *skb) -{ - struct cpl_act_establish *req = cplhdr(skb); - unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); - struct t3c_tid_entry *t3c_tid; - - t3c_tid = lookup_atid(&(T3C_DATA(dev))->tid_maps, atid); - if (t3c_tid->ctx && t3c_tid->client->handlers && - t3c_tid->client->handlers[CPL_ACT_ESTABLISH]) { - return t3c_tid->client->handlers[CPL_ACT_ESTABLISH] - (dev, skb, t3c_tid->ctx); - } else { - printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", - dev->name, CPL_PASS_ACCEPT_REQ); - return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; - } -} - -static int do_set_tcb_rpl(struct t3cdev *dev, struct sk_buff *skb) -{ - struct cpl_set_tcb_rpl *rpl = cplhdr(skb); - - if (rpl->status != CPL_ERR_NONE) - printk(KERN_ERR - "Unexpected SET_TCB_RPL status %u for tid %u\n", - rpl->status, GET_TID(rpl)); - return CPL_RET_BUF_DONE; -} - -static int do_trace(struct t3cdev *dev, struct sk_buff *skb) -{ - struct cpl_trace_pkt *p = cplhdr(skb); - - skb->protocol = 0xffff; - skb->dev = dev->lldev; - skb_pull(skb, sizeof(*p)); - skb->mac.raw = skb->data; - netif_receive_skb(skb); - return 0; -} - -static int do_term(struct t3cdev *dev, struct sk_buff *skb) -{ - unsigned int hwtid = ntohl(skb->priority) >> 8 & 0xfffff; - unsigned int opcode = G_OPCODE(ntohl(skb->csum)); - struct t3c_tid_entry *t3c_tid; - - t3c_tid = lookup_tid(&(T3C_DATA(dev))->tid_maps, hwtid); - if (t3c_tid->ctx && t3c_tid->client->handlers && - t3c_tid->client->handlers[opcode]) { - return t3c_tid->client->handlers[opcode] (dev, skb, - t3c_tid->ctx); - } else { - printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", - dev->name, opcode); - return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; - } -} - -static int nb_callback(struct notifier_block *self, unsigned long event, - void *ctx) -{ - switch (event) { - case (NETEVENT_NEIGH_UPDATE):{ - cxgb_neigh_update((struct neighbour *)ctx); - break; - } - case (NETEVENT_PMTU_UPDATE): - break; - case (NETEVENT_REDIRECT):{ - struct netevent_redirect *nr = ctx; - cxgb_redirect(nr->old, nr->new); - cxgb_neigh_update(nr->new->neighbour); - break; - } - default: - break; - } - return 0; -} - -static struct notifier_block nb = { - .notifier_call = nb_callback -}; - -/* - * Process a received packet with an unknown/unexpected CPL opcode. - */ -static int do_bad_cpl(struct t3cdev *dev, struct sk_buff *skb) -{ - printk(KERN_ERR "%s: received bad CPL command 0x%x\n", dev->name, - *skb->data); - return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; -} - -/* - * Handlers for each CPL opcode - */ -static cpl_handler_func cpl_handlers[NUM_CPL_CMDS]; - -/* - * Add a new handler to the CPL dispatch table. A NULL handler may be supplied - * to unregister an existing handler. - */ -void t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h) -{ - if (opcode < NUM_CPL_CMDS) - cpl_handlers[opcode] = h ? h : do_bad_cpl; - else - printk(KERN_ERR "T3C: handler registration for " - "opcode %x failed\n", opcode); -} - -EXPORT_SYMBOL(t3_register_cpl_handler); - -/* - * T3CDEV's receive method. - */ -int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n) -{ - while (n--) { - struct sk_buff *skb = *skbs++; - unsigned int opcode = G_OPCODE(ntohl(skb->csum)); - int ret = cpl_handlers[opcode] (dev, skb); - -#if VALIDATE_TID - if (ret & CPL_RET_UNKNOWN_TID) { - union opcode_tid *p = cplhdr(skb); - - printk(KERN_ERR "%s: CPL message (opcode %u) had " - "unknown TID %u\n", dev->name, opcode, - G_TID(ntohl(p->opcode_tid))); - } -#endif - if (ret & CPL_RET_BUF_DONE) - kfree_skb(skb); - } - return 0; -} - -/* - * Sends an sk_buff to a T3C driver after dealing with any active network taps. - */ -int cxgb3_ofld_send(struct t3cdev *dev, struct sk_buff *skb) -{ - int r; - - local_bh_disable(); - r = dev->send(dev, skb); - local_bh_enable(); - return r; -} - -EXPORT_SYMBOL(cxgb3_ofld_send); - -static int is_offloading(struct net_device *dev) -{ - struct adapter *adapter; - int i; - - read_lock_bh(&adapter_list_lock); - list_for_each_entry(adapter, &adapter_list, adapter_list) { - for_each_port(adapter, i) { - if (dev == adapter->port[i]) { - read_unlock_bh(&adapter_list_lock); - return 1; - } - } - } - read_unlock_bh(&adapter_list_lock); - return 0; -} - -void cxgb_neigh_update(struct neighbour *neigh) -{ - struct net_device *dev = neigh->dev; - - if (dev && (is_offloading(dev))) { - struct t3cdev *tdev = T3CDEV(dev); - - BUG_ON(!tdev); - t3_l2t_update(tdev, neigh); - } -} - -static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e) -{ - struct sk_buff *skb; - struct cpl_set_tcb_field *req; - - skb = alloc_skb(sizeof(*req), GFP_ATOMIC); - if (!skb) { - printk(KERN_ERR "%s: cannot allocate skb!\n", __FUNCTION__); - return; - } - skb->priority = CPL_PRIORITY_CONTROL; - req = (struct cpl_set_tcb_field *)skb_put(skb, sizeof(*req)); - req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); - OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid)); - req->reply = 0; - req->cpu_idx = 0; - req->word = htons(W_TCB_L2T_IX); - req->mask = cpu_to_be64(V_TCB_L2T_IX(M_TCB_L2T_IX)); - req->val = cpu_to_be64(V_TCB_L2T_IX(e->idx)); - tdev->send(tdev, skb); -} - -void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) -{ - struct net_device *olddev, *newdev; - struct tid_info *ti; - struct t3cdev *tdev; - u32 tid; - int update_tcb; - struct l2t_entry *e; - struct t3c_tid_entry *te; - - olddev = old->neighbour->dev; - newdev = new->neighbour->dev; - if (!is_offloading(olddev)) - return; - if (!is_offloading(newdev)) { - printk(KERN_WARNING "%s: Redirect to non-offload" - "device ignored.\n", __FUNCTION__); - return; - } - tdev = T3CDEV(olddev); - BUG_ON(!tdev); - if (tdev != T3CDEV(newdev)) { - printk(KERN_WARNING "%s: Redirect to different " - "offload device ignored.\n", __FUNCTION__); - return; - } - - /* Add new L2T entry */ - e = t3_l2t_get(tdev, new->neighbour, newdev); - if (!e) { - printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n", - __FUNCTION__); - return; - } - - /* Walk tid table and notify clients of dst change. */ - ti = &(T3C_DATA(tdev))->tid_maps; - for (tid = 0; tid < ti->ntids; tid++) { - te = lookup_tid(ti, tid); - BUG_ON(!te); - if (te->ctx && te->client && te->client->redirect) { - update_tcb = te->client->redirect(te->ctx, old, new, e); - if (update_tcb) { - l2t_hold(L2DATA(tdev), e); - set_l2t_ix(tdev, tid, e); - } - } - } - l2t_release(L2DATA(tdev), e); -} - -/* - * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. - * The allocated memory is cleared. - */ -void *cxgb_alloc_mem(unsigned long size) -{ - void *p = kmalloc(size, GFP_KERNEL); - - if (!p) - p = vmalloc(size); - if (p) - memset(p, 0, size); - return p; -} - -/* - * Free memory allocated through t3_alloc_mem(). - */ -void cxgb_free_mem(void *addr) -{ - unsigned long p = (unsigned long)addr; - - if (p >= VMALLOC_START && p < VMALLOC_END) - vfree(addr); - else - kfree(addr); -} - -/* - * Allocate and initialize the TID tables. Returns 0 on success. - */ -static int init_tid_tabs(struct tid_info *t, unsigned int ntids, - unsigned int natids, unsigned int nstids, - unsigned int atid_base, unsigned int stid_base) -{ - unsigned long size = ntids * sizeof(*t->tid_tab) + - natids * sizeof(*t->atid_tab) + nstids * sizeof(*t->stid_tab); - - t->tid_tab = cxgb_alloc_mem(size); - if (!t->tid_tab) - return -ENOMEM; - - t->stid_tab = (union listen_entry *)&t->tid_tab[ntids]; - t->atid_tab = (union active_open_entry *)&t->stid_tab[nstids]; - t->ntids = ntids; - t->nstids = nstids; - t->stid_base = stid_base; - t->sfree = NULL; - t->natids = natids; - t->atid_base = atid_base; - t->afree = NULL; - t->stids_in_use = t->atids_in_use = 0; - atomic_set(&t->tids_in_use, 0); - spin_lock_init(&t->stid_lock); - spin_lock_init(&t->atid_lock); - - /* - * Setup the free lists for stid_tab and atid_tab. - */ - if (nstids) { - while (--nstids) - t->stid_tab[nstids - 1].next = &t->stid_tab[nstids]; - t->sfree = t->stid_tab; - } - if (natids) { - while (--natids) - t->atid_tab[natids - 1].next = &t->atid_tab[natids]; - t->afree = t->atid_tab; - } - return 0; -} - -static void free_tid_maps(struct tid_info *t) -{ - cxgb_free_mem(t->tid_tab); -} - -static inline void add_adapter(struct adapter *adap) -{ - write_lock_bh(&adapter_list_lock); - list_add_tail(&adap->adapter_list, &adapter_list); - write_unlock_bh(&adapter_list_lock); -} - -static inline void remove_adapter(struct adapter *adap) -{ - write_lock_bh(&adapter_list_lock); - list_del(&adap->adapter_list); - write_unlock_bh(&adapter_list_lock); -} - -int cxgb3_offload_activate(struct adapter *adapter) -{ - struct t3cdev *dev = &adapter->tdev; - int natids, err; - struct t3c_data *t; - struct tid_range stid_range, tid_range; - struct mtutab mtutab; - unsigned int l2t_capacity; - - t = kcalloc(1, sizeof(*t), GFP_KERNEL); - if (!t) - return -ENOMEM; - - err = -EOPNOTSUPP; - if (dev->ctl(dev, GET_TX_MAX_CHUNK, &t->tx_max_chunk) < 0 || - dev->ctl(dev, GET_MAX_OUTSTANDING_WR, &t->max_wrs) < 0 || - dev->ctl(dev, GET_L2T_CAPACITY, &l2t_capacity) < 0 || - dev->ctl(dev, GET_MTUS, &mtutab) < 0 || - dev->ctl(dev, GET_TID_RANGE, &tid_range) < 0 || - dev->ctl(dev, GET_STID_RANGE, &stid_range) < 0) - goto out_free; - - err = -ENOMEM; - L2DATA(dev) = t3_init_l2t(l2t_capacity); - if (!L2DATA(dev)) - goto out_free; - - natids = min(tid_range.num / 2, MAX_ATIDS); - err = init_tid_tabs(&t->tid_maps, tid_range.num, natids, - stid_range.num, ATID_BASE, stid_range.base); - if (err) - goto out_free_l2t; - - t->mtus = mtutab.mtus; - t->nmtus = mtutab.size; - - INIT_WORK(&t->tid_release_task, t3_process_tid_release_list); - spin_lock_init(&t->tid_release_lock); - INIT_LIST_HEAD(&t->list_node); - t->dev = dev; - - T3C_DATA(dev) = t; - dev->recv = process_rx; - dev->neigh_update = t3_l2t_update; - - /* Register netevent handler once */ - if (list_empty(&adapter_list)) - register_netevent_notifier(&nb); - - add_adapter(adapter); - return 0; - -out_free_l2t: - t3_free_l2t(L2DATA(dev)); - L2DATA(dev) = NULL; -out_free: - kfree(t); - return err; -} - -void cxgb3_offload_deactivate(struct adapter *adapter) -{ - struct t3cdev *tdev = &adapter->tdev; - struct t3c_data *t = T3C_DATA(tdev); - - remove_adapter(adapter); - if (list_empty(&adapter_list)) - unregister_netevent_notifier(&nb); - - free_tid_maps(&t->tid_maps); - T3C_DATA(tdev) = NULL; - t3_free_l2t(L2DATA(tdev)); - L2DATA(tdev) = NULL; - kfree(t); -} - -static inline void register_tdev(struct t3cdev *tdev) -{ - static int unit; - - mutex_lock(&cxgb3_db_lock); - snprintf(tdev->name, sizeof(tdev->name), "ofld_dev%d", unit++); - list_add_tail(&tdev->ofld_dev_list, &ofld_dev_list); - mutex_unlock(&cxgb3_db_lock); -} - -static inline void unregister_tdev(struct t3cdev *tdev) -{ - mutex_lock(&cxgb3_db_lock); - list_del(&tdev->ofld_dev_list); - mutex_unlock(&cxgb3_db_lock); -} - -void __devinit cxgb3_adapter_ofld(struct adapter *adapter) -{ - struct t3cdev *tdev = &adapter->tdev; - - INIT_LIST_HEAD(&tdev->ofld_dev_list); - - cxgb3_set_dummy_ops(tdev); - tdev->send = t3_offload_tx; - tdev->ctl = cxgb_offload_ctl; - tdev->type = adapter->params.rev == 0 ? T3A : T3B; - - register_tdev(tdev); -} - -void __devexit cxgb3_adapter_unofld(struct adapter *adapter) -{ - struct t3cdev *tdev = &adapter->tdev; - - tdev->recv = NULL; - tdev->neigh_update = NULL; - - unregister_tdev(tdev); -} - -void __init cxgb3_offload_init(void) -{ - int i; - - for (i = 0; i < NUM_CPL_CMDS; ++i) - cpl_handlers[i] = do_bad_cpl; - - t3_register_cpl_handler(CPL_SMT_WRITE_RPL, do_smt_write_rpl); - t3_register_cpl_handler(CPL_L2T_WRITE_RPL, do_l2t_write_rpl); - t3_register_cpl_handler(CPL_PASS_OPEN_RPL, do_stid_rpl); - t3_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, do_stid_rpl); - t3_register_cpl_handler(CPL_PASS_ACCEPT_REQ, do_cr); - t3_register_cpl_handler(CPL_PASS_ESTABLISH, do_hwtid_rpl); - t3_register_cpl_handler(CPL_ABORT_RPL_RSS, do_hwtid_rpl); - t3_register_cpl_handler(CPL_ABORT_RPL, do_hwtid_rpl); - t3_register_cpl_handler(CPL_RX_URG_NOTIFY, do_hwtid_rpl); - t3_register_cpl_handler(CPL_RX_DATA, do_hwtid_rpl); - t3_register_cpl_handler(CPL_TX_DATA_ACK, do_hwtid_rpl); - t3_register_cpl_handler(CPL_TX_DMA_ACK, do_hwtid_rpl); - t3_register_cpl_handler(CPL_ACT_OPEN_RPL, do_act_open_rpl); - t3_register_cpl_handler(CPL_PEER_CLOSE, do_hwtid_rpl); - t3_register_cpl_handler(CPL_CLOSE_CON_RPL, do_hwtid_rpl); - t3_register_cpl_handler(CPL_ABORT_REQ_RSS, do_abort_req_rss); - t3_register_cpl_handler(CPL_ACT_ESTABLISH, do_act_establish); - t3_register_cpl_handler(CPL_SET_TCB_RPL, do_set_tcb_rpl); - t3_register_cpl_handler(CPL_RDMA_TERMINATE, do_term); - t3_register_cpl_handler(CPL_RDMA_EC_STATUS, do_hwtid_rpl); - t3_register_cpl_handler(CPL_TRACE_PKT, do_trace); - t3_register_cpl_handler(CPL_RX_DATA_DDP, do_hwtid_rpl); - t3_register_cpl_handler(CPL_RX_DDP_COMPLETE, do_hwtid_rpl); - t3_register_cpl_handler(CPL_ISCSI_HDR, do_hwtid_rpl); -} diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.h b/trunk/drivers/net/cxgb3/cxgb3_offload.h deleted file mode 100644 index 0e6beb69ba17..000000000000 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved. - * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _CXGB3_OFFLOAD_H -#define _CXGB3_OFFLOAD_H - -#include -#include - -#include "l2t.h" - -#include "t3cdev.h" -#include "t3_cpl.h" - -struct adapter; - -void cxgb3_offload_init(void); - -void cxgb3_adapter_ofld(struct adapter *adapter); -void cxgb3_adapter_unofld(struct adapter *adapter); -int cxgb3_offload_activate(struct adapter *adapter); -void cxgb3_offload_deactivate(struct adapter *adapter); - -void cxgb3_set_dummy_ops(struct t3cdev *dev); - -/* - * Client registration. Users of T3 driver must register themselves. - * The T3 driver will call the add function of every client for each T3 - * adapter activated, passing up the t3cdev ptr. Each client fills out an - * array of callback functions to process CPL messages. - */ - -void cxgb3_register_client(struct cxgb3_client *client); -void cxgb3_unregister_client(struct cxgb3_client *client); -void cxgb3_add_clients(struct t3cdev *tdev); -void cxgb3_remove_clients(struct t3cdev *tdev); - -typedef int (*cxgb3_cpl_handler_func)(struct t3cdev *dev, - struct sk_buff *skb, void *ctx); - -struct cxgb3_client { - char *name; - void (*add) (struct t3cdev *); - void (*remove) (struct t3cdev *); - cxgb3_cpl_handler_func *handlers; - int (*redirect)(void *ctx, struct dst_entry *old, - struct dst_entry *new, struct l2t_entry *l2t); - struct list_head client_list; -}; - -/* - * TID allocation services. - */ -int cxgb3_alloc_atid(struct t3cdev *dev, struct cxgb3_client *client, - void *ctx); -int cxgb3_alloc_stid(struct t3cdev *dev, struct cxgb3_client *client, - void *ctx); -void *cxgb3_free_atid(struct t3cdev *dev, int atid); -void cxgb3_free_stid(struct t3cdev *dev, int stid); -void cxgb3_insert_tid(struct t3cdev *dev, struct cxgb3_client *client, - void *ctx, unsigned int tid); -void cxgb3_queue_tid_release(struct t3cdev *dev, unsigned int tid); -void cxgb3_remove_tid(struct t3cdev *dev, void *ctx, unsigned int tid); - -struct t3c_tid_entry { - struct cxgb3_client *client; - void *ctx; -}; - -/* CPL message priority levels */ -enum { - CPL_PRIORITY_DATA = 0, /* data messages */ - CPL_PRIORITY_SETUP = 1, /* connection setup messages */ - CPL_PRIORITY_TEARDOWN = 0, /* connection teardown messages */ - CPL_PRIORITY_LISTEN = 1, /* listen start/stop messages */ - CPL_PRIORITY_ACK = 1, /* RX ACK messages */ - CPL_PRIORITY_CONTROL = 1 /* offload control messages */ -}; - -/* Flags for return value of CPL message handlers */ -enum { - CPL_RET_BUF_DONE = 1, /* buffer processing done, buffer may be freed */ - CPL_RET_BAD_MSG = 2, /* bad CPL message (e.g., unknown opcode) */ - CPL_RET_UNKNOWN_TID = 4 /* unexpected unknown TID */ -}; - -typedef int (*cpl_handler_func)(struct t3cdev *dev, struct sk_buff *skb); - -/* - * Returns a pointer to the first byte of the CPL header in an sk_buff that - * contains a CPL message. - */ -static inline void *cplhdr(struct sk_buff *skb) -{ - return skb->data; -} - -void t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h); - -union listen_entry { - struct t3c_tid_entry t3c_tid; - union listen_entry *next; -}; - -union active_open_entry { - struct t3c_tid_entry t3c_tid; - union active_open_entry *next; -}; - -/* - * Holds the size, base address, free list start, etc of the TID, server TID, - * and active-open TID tables for a offload device. - * The tables themselves are allocated dynamically. - */ -struct tid_info { - struct t3c_tid_entry *tid_tab; - unsigned int ntids; - atomic_t tids_in_use; - - union listen_entry *stid_tab; - unsigned int nstids; - unsigned int stid_base; - - union active_open_entry *atid_tab; - unsigned int natids; - unsigned int atid_base; - - /* - * The following members are accessed R/W so we put them in their own - * cache lines. - * - * XXX We could combine the atid fields above with the lock here since - * atids are use once (unlike other tids). OTOH the above fields are - * usually in cache due to tid_tab. - */ - spinlock_t atid_lock ____cacheline_aligned_in_smp; - union active_open_entry *afree; - unsigned int atids_in_use; - - spinlock_t stid_lock ____cacheline_aligned; - union listen_entry *sfree; - unsigned int stids_in_use; -}; - -struct t3c_data { - struct list_head list_node; - struct t3cdev *dev; - unsigned int tx_max_chunk; /* max payload for TX_DATA */ - unsigned int max_wrs; /* max in-flight WRs per connection */ - unsigned int nmtus; - const unsigned short *mtus; - struct tid_info tid_maps; - - struct t3c_tid_entry *tid_release_list; - spinlock_t tid_release_lock; - struct work_struct tid_release_task; -}; - -/* - * t3cdev -> t3c_data accessor - */ -#define T3C_DATA(dev) (*(struct t3c_data **)&(dev)->l4opt) - -#endif diff --git a/trunk/drivers/net/cxgb3/firmware_exports.h b/trunk/drivers/net/cxgb3/firmware_exports.h deleted file mode 100644 index 6a835f6a262a..000000000000 --- a/trunk/drivers/net/cxgb3/firmware_exports.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2004-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _FIRMWARE_EXPORTS_H_ -#define _FIRMWARE_EXPORTS_H_ - -/* WR OPCODES supported by the firmware. - */ -#define FW_WROPCODE_FORWARD 0x01 -#define FW_WROPCODE_BYPASS 0x05 - -#define FW_WROPCODE_TUNNEL_TX_PKT 0x03 - -#define FW_WROPOCDE_ULPTX_DATA_SGL 0x00 -#define FW_WROPCODE_ULPTX_MEM_READ 0x02 -#define FW_WROPCODE_ULPTX_PKT 0x04 -#define FW_WROPCODE_ULPTX_INVALIDATE 0x06 - -#define FW_WROPCODE_TUNNEL_RX_PKT 0x07 - -#define FW_WROPCODE_OFLD_GETTCB_RPL 0x08 -#define FW_WROPCODE_OFLD_CLOSE_CON 0x09 -#define FW_WROPCODE_OFLD_TP_ABORT_CON_REQ 0x0A -#define FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL 0x0F -#define FW_WROPCODE_OFLD_HOST_ABORT_CON_REQ 0x0B -#define FW_WROPCODE_OFLD_TP_ABORT_CON_RPL 0x0C -#define FW_WROPCODE_OFLD_TX_DATA 0x0D -#define FW_WROPCODE_OFLD_TX_DATA_ACK 0x0E - -#define FW_WROPCODE_RI_RDMA_INIT 0x10 -#define FW_WROPCODE_RI_RDMA_WRITE 0x11 -#define FW_WROPCODE_RI_RDMA_READ_REQ 0x12 -#define FW_WROPCODE_RI_RDMA_READ_RESP 0x13 -#define FW_WROPCODE_RI_SEND 0x14 -#define FW_WROPCODE_RI_TERMINATE 0x15 -#define FW_WROPCODE_RI_RDMA_READ 0x16 -#define FW_WROPCODE_RI_RECEIVE 0x17 -#define FW_WROPCODE_RI_BIND_MW 0x18 -#define FW_WROPCODE_RI_FASTREGISTER_MR 0x19 -#define FW_WROPCODE_RI_LOCAL_INV 0x1A -#define FW_WROPCODE_RI_MODIFY_QP 0x1B -#define FW_WROPCODE_RI_BYPASS 0x1C - -#define FW_WROPOCDE_RSVD 0x1E - -#define FW_WROPCODE_SGE_EGRESSCONTEXT_RR 0x1F - -#define FW_WROPCODE_MNGT 0x1D -#define FW_MNGTOPCODE_PKTSCHED_SET 0x00 - -/* Maximum size of a WR sent from the host, limited by the SGE. - * - * Note: WR coming from ULP or TP are only limited by CIM. - */ -#define FW_WR_SIZE 128 - -/* Maximum number of outstanding WRs sent from the host. Value must be - * programmed in the CTRL/TUNNEL/QP SGE Egress Context and used by - * offload modules to limit the number of WRs per connection. - */ -#define FW_T3_WR_NUM 16 -#define FW_N3_WR_NUM 7 - -#ifndef N3 -# define FW_WR_NUM FW_T3_WR_NUM -#else -# define FW_WR_NUM FW_N3_WR_NUM -#endif - -/* FW_TUNNEL_NUM corresponds to the number of supported TUNNEL Queues. These - * queues must start at SGE Egress Context FW_TUNNEL_SGEEC_START and must - * start at 'TID' (or 'uP Token') FW_TUNNEL_TID_START. - * - * Ingress Traffic (e.g. DMA completion credit) for TUNNEL Queue[i] is sent - * to RESP Queue[i]. - */ -#define FW_TUNNEL_NUM 8 -#define FW_TUNNEL_SGEEC_START 8 -#define FW_TUNNEL_TID_START 65544 - -/* FW_CTRL_NUM corresponds to the number of supported CTRL Queues. These queues - * must start at SGE Egress Context FW_CTRL_SGEEC_START and must start at 'TID' - * (or 'uP Token') FW_CTRL_TID_START. - * - * Ingress Traffic for CTRL Queue[i] is sent to RESP Queue[i]. - */ -#define FW_CTRL_NUM 8 -#define FW_CTRL_SGEEC_START 65528 -#define FW_CTRL_TID_START 65536 - -/* FW_OFLD_NUM corresponds to the number of supported OFFLOAD Queues. These - * queues must start at SGE Egress Context FW_OFLD_SGEEC_START. - * - * Note: the 'uP Token' in the SGE Egress Context fields is irrelevant for - * OFFLOAD Queues, as the host is responsible for providing the correct TID in - * every WR. - * - * Ingress Trafffic for OFFLOAD Queue[i] is sent to RESP Queue[i]. - */ -#define FW_OFLD_NUM 8 -#define FW_OFLD_SGEEC_START 0 - -/* - * - */ -#define FW_RI_NUM 1 -#define FW_RI_SGEEC_START 65527 -#define FW_RI_TID_START 65552 - -/* - * The RX_PKT_TID - */ -#define FW_RX_PKT_NUM 1 -#define FW_RX_PKT_TID_START 65553 - -/* FW_WRC_NUM corresponds to the number of Work Request Context that supported - * by the firmware. - */ -#define FW_WRC_NUM \ - (65536 + FW_TUNNEL_NUM + FW_CTRL_NUM + FW_RI_NUM + FW_RX_PKT_NUM) - -/* - * FW type and version. - */ -#define S_FW_VERSION_TYPE 28 -#define M_FW_VERSION_TYPE 0xF -#define V_FW_VERSION_TYPE(x) ((x) << S_FW_VERSION_TYPE) -#define G_FW_VERSION_TYPE(x) \ - (((x) >> S_FW_VERSION_TYPE) & M_FW_VERSION_TYPE) - -#define S_FW_VERSION_MAJOR 16 -#define M_FW_VERSION_MAJOR 0xFFF -#define V_FW_VERSION_MAJOR(x) ((x) << S_FW_VERSION_MAJOR) -#define G_FW_VERSION_MAJOR(x) \ - (((x) >> S_FW_VERSION_MAJOR) & M_FW_VERSION_MAJOR) - -#define S_FW_VERSION_MINOR 8 -#define M_FW_VERSION_MINOR 0xFF -#define V_FW_VERSION_MINOR(x) ((x) << S_FW_VERSION_MINOR) -#define G_FW_VERSION_MINOR(x) \ - (((x) >> S_FW_VERSION_MINOR) & M_FW_VERSION_MINOR) - -#define S_FW_VERSION_MICRO 0 -#define M_FW_VERSION_MICRO 0xFF -#define V_FW_VERSION_MICRO(x) ((x) << S_FW_VERSION_MICRO) -#define G_FW_VERSION_MICRO(x) \ - (((x) >> S_FW_VERSION_MICRO) & M_FW_VERSION_MICRO) - -#endif /* _FIRMWARE_EXPORTS_H_ */ diff --git a/trunk/drivers/net/cxgb3/l2t.c b/trunk/drivers/net/cxgb3/l2t.c deleted file mode 100644 index 3c0cb8557058..000000000000 --- a/trunk/drivers/net/cxgb3/l2t.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. - * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "t3cdev.h" -#include "cxgb3_defs.h" -#include "l2t.h" -#include "t3_cpl.h" -#include "firmware_exports.h" - -#define VLAN_NONE 0xfff - -/* - * Module locking notes: There is a RW lock protecting the L2 table as a - * whole plus a spinlock per L2T entry. Entry lookups and allocations happen - * under the protection of the table lock, individual entry changes happen - * while holding that entry's spinlock. The table lock nests outside the - * entry locks. Allocations of new entries take the table lock as writers so - * no other lookups can happen while allocating new entries. Entry updates - * take the table lock as readers so multiple entries can be updated in - * parallel. An L2T entry can be dropped by decrementing its reference count - * and therefore can happen in parallel with entry allocation but no entry - * can change state or increment its ref count during allocation as both of - * these perform lookups. - */ - -static inline unsigned int vlan_prio(const struct l2t_entry *e) -{ - return e->vlan >> 13; -} - -static inline unsigned int arp_hash(u32 key, int ifindex, - const struct l2t_data *d) -{ - return jhash_2words(key, ifindex, 0) & (d->nentries - 1); -} - -static inline void neigh_replace(struct l2t_entry *e, struct neighbour *n) -{ - neigh_hold(n); - if (e->neigh) - neigh_release(e->neigh); - e->neigh = n; -} - -/* - * Set up an L2T entry and send any packets waiting in the arp queue. The - * supplied skb is used for the CPL_L2T_WRITE_REQ. Must be called with the - * entry locked. - */ -static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb, - struct l2t_entry *e) -{ - struct cpl_l2t_write_req *req; - - if (!skb) { - skb = alloc_skb(sizeof(*req), GFP_ATOMIC); - if (!skb) - return -ENOMEM; - } - - req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); - req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); - OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, e->idx)); - req->params = htonl(V_L2T_W_IDX(e->idx) | V_L2T_W_IFF(e->smt_idx) | - V_L2T_W_VLAN(e->vlan & VLAN_VID_MASK) | - V_L2T_W_PRIO(vlan_prio(e))); - memcpy(e->dmac, e->neigh->ha, sizeof(e->dmac)); - memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac)); - skb->priority = CPL_PRIORITY_CONTROL; - cxgb3_ofld_send(dev, skb); - while (e->arpq_head) { - skb = e->arpq_head; - e->arpq_head = skb->next; - skb->next = NULL; - cxgb3_ofld_send(dev, skb); - } - e->arpq_tail = NULL; - e->state = L2T_STATE_VALID; - - return 0; -} - -/* - * Add a packet to the an L2T entry's queue of packets awaiting resolution. - * Must be called with the entry's lock held. - */ -static inline void arpq_enqueue(struct l2t_entry *e, struct sk_buff *skb) -{ - skb->next = NULL; - if (e->arpq_head) - e->arpq_tail->next = skb; - else - e->arpq_head = skb; - e->arpq_tail = skb; -} - -int t3_l2t_send_slow(struct t3cdev *dev, struct sk_buff *skb, - struct l2t_entry *e) -{ -again: - switch (e->state) { - case L2T_STATE_STALE: /* entry is stale, kick off revalidation */ - neigh_event_send(e->neigh, NULL); - spin_lock_bh(&e->lock); - if (e->state == L2T_STATE_STALE) - e->state = L2T_STATE_VALID; - spin_unlock_bh(&e->lock); - case L2T_STATE_VALID: /* fast-path, send the packet on */ - return cxgb3_ofld_send(dev, skb); - case L2T_STATE_RESOLVING: - spin_lock_bh(&e->lock); - if (e->state != L2T_STATE_RESOLVING) { - /* ARP already completed */ - spin_unlock_bh(&e->lock); - goto again; - } - arpq_enqueue(e, skb); - spin_unlock_bh(&e->lock); - - /* - * Only the first packet added to the arpq should kick off - * resolution. However, because the alloc_skb below can fail, - * we allow each packet added to the arpq to retry resolution - * as a way of recovering from transient memory exhaustion. - * A better way would be to use a work request to retry L2T - * entries when there's no memory. - */ - if (!neigh_event_send(e->neigh, NULL)) { - skb = alloc_skb(sizeof(struct cpl_l2t_write_req), - GFP_ATOMIC); - if (!skb) - break; - - spin_lock_bh(&e->lock); - if (e->arpq_head) - setup_l2e_send_pending(dev, skb, e); - else /* we lost the race */ - __kfree_skb(skb); - spin_unlock_bh(&e->lock); - } - } - return 0; -} - -EXPORT_SYMBOL(t3_l2t_send_slow); - -void t3_l2t_send_event(struct t3cdev *dev, struct l2t_entry *e) -{ -again: - switch (e->state) { - case L2T_STATE_STALE: /* entry is stale, kick off revalidation */ - neigh_event_send(e->neigh, NULL); - spin_lock_bh(&e->lock); - if (e->state == L2T_STATE_STALE) { - e->state = L2T_STATE_VALID; - } - spin_unlock_bh(&e->lock); - return; - case L2T_STATE_VALID: /* fast-path, send the packet on */ - return; - case L2T_STATE_RESOLVING: - spin_lock_bh(&e->lock); - if (e->state != L2T_STATE_RESOLVING) { - /* ARP already completed */ - spin_unlock_bh(&e->lock); - goto again; - } - spin_unlock_bh(&e->lock); - - /* - * Only the first packet added to the arpq should kick off - * resolution. However, because the alloc_skb below can fail, - * we allow each packet added to the arpq to retry resolution - * as a way of recovering from transient memory exhaustion. - * A better way would be to use a work request to retry L2T - * entries when there's no memory. - */ - neigh_event_send(e->neigh, NULL); - } - return; -} - -EXPORT_SYMBOL(t3_l2t_send_event); - -/* - * Allocate a free L2T entry. Must be called with l2t_data.lock held. - */ -static struct l2t_entry *alloc_l2e(struct l2t_data *d) -{ - struct l2t_entry *end, *e, **p; - - if (!atomic_read(&d->nfree)) - return NULL; - - /* there's definitely a free entry */ - for (e = d->rover, end = &d->l2tab[d->nentries]; e != end; ++e) - if (atomic_read(&e->refcnt) == 0) - goto found; - - for (e = &d->l2tab[1]; atomic_read(&e->refcnt); ++e) ; -found: - d->rover = e + 1; - atomic_dec(&d->nfree); - - /* - * The entry we found may be an inactive entry that is - * presently in the hash table. We need to remove it. - */ - if (e->state != L2T_STATE_UNUSED) { - int hash = arp_hash(e->addr, e->ifindex, d); - - for (p = &d->l2tab[hash].first; *p; p = &(*p)->next) - if (*p == e) { - *p = e->next; - break; - } - e->state = L2T_STATE_UNUSED; - } - return e; -} - -/* - * Called when an L2T entry has no more users. The entry is left in the hash - * table since it is likely to be reused but we also bump nfree to indicate - * that the entry can be reallocated for a different neighbor. We also drop - * the existing neighbor reference in case the neighbor is going away and is - * waiting on our reference. - * - * Because entries can be reallocated to other neighbors once their ref count - * drops to 0 we need to take the entry's lock to avoid races with a new - * incarnation. - */ -void t3_l2e_free(struct l2t_data *d, struct l2t_entry *e) -{ - spin_lock_bh(&e->lock); - if (atomic_read(&e->refcnt) == 0) { /* hasn't been recycled */ - if (e->neigh) { - neigh_release(e->neigh); - e->neigh = NULL; - } - } - spin_unlock_bh(&e->lock); - atomic_inc(&d->nfree); -} - -EXPORT_SYMBOL(t3_l2e_free); - -/* - * Update an L2T entry that was previously used for the same next hop as neigh. - * Must be called with softirqs disabled. - */ -static inline void reuse_entry(struct l2t_entry *e, struct neighbour *neigh) -{ - unsigned int nud_state; - - spin_lock(&e->lock); /* avoid race with t3_l2t_free */ - - if (neigh != e->neigh) - neigh_replace(e, neigh); - nud_state = neigh->nud_state; - if (memcmp(e->dmac, neigh->ha, sizeof(e->dmac)) || - !(nud_state & NUD_VALID)) - e->state = L2T_STATE_RESOLVING; - else if (nud_state & NUD_CONNECTED) - e->state = L2T_STATE_VALID; - else - e->state = L2T_STATE_STALE; - spin_unlock(&e->lock); -} - -struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh, - struct net_device *dev) -{ - struct l2t_entry *e; - struct l2t_data *d = L2DATA(cdev); - u32 addr = *(u32 *) neigh->primary_key; - int ifidx = neigh->dev->ifindex; - int hash = arp_hash(addr, ifidx, d); - struct port_info *p = netdev_priv(dev); - int smt_idx = p->port_id; - - write_lock_bh(&d->lock); - for (e = d->l2tab[hash].first; e; e = e->next) - if (e->addr == addr && e->ifindex == ifidx && - e->smt_idx == smt_idx) { - l2t_hold(d, e); - if (atomic_read(&e->refcnt) == 1) - reuse_entry(e, neigh); - goto done; - } - - /* Need to allocate a new entry */ - e = alloc_l2e(d); - if (e) { - spin_lock(&e->lock); /* avoid race with t3_l2t_free */ - e->next = d->l2tab[hash].first; - d->l2tab[hash].first = e; - e->state = L2T_STATE_RESOLVING; - e->addr = addr; - e->ifindex = ifidx; - e->smt_idx = smt_idx; - atomic_set(&e->refcnt, 1); - neigh_replace(e, neigh); - if (neigh->dev->priv_flags & IFF_802_1Q_VLAN) - e->vlan = VLAN_DEV_INFO(neigh->dev)->vlan_id; - else - e->vlan = VLAN_NONE; - spin_unlock(&e->lock); - } -done: - write_unlock_bh(&d->lock); - return e; -} - -EXPORT_SYMBOL(t3_l2t_get); - -/* - * Called when address resolution fails for an L2T entry to handle packets - * on the arpq head. If a packet specifies a failure handler it is invoked, - * otherwise the packets is sent to the offload device. - * - * XXX: maybe we should abandon the latter behavior and just require a failure - * handler. - */ -static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff *arpq) -{ - while (arpq) { - struct sk_buff *skb = arpq; - struct l2t_skb_cb *cb = L2T_SKB_CB(skb); - - arpq = skb->next; - skb->next = NULL; - if (cb->arp_failure_handler) - cb->arp_failure_handler(dev, skb); - else - cxgb3_ofld_send(dev, skb); - } -} - -/* - * Called when the host's ARP layer makes a change to some entry that is - * loaded into the HW L2 table. - */ -void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh) -{ - struct l2t_entry *e; - struct sk_buff *arpq = NULL; - struct l2t_data *d = L2DATA(dev); - u32 addr = *(u32 *) neigh->primary_key; - int ifidx = neigh->dev->ifindex; - int hash = arp_hash(addr, ifidx, d); - - read_lock_bh(&d->lock); - for (e = d->l2tab[hash].first; e; e = e->next) - if (e->addr == addr && e->ifindex == ifidx) { - spin_lock(&e->lock); - goto found; - } - read_unlock_bh(&d->lock); - return; - -found: - read_unlock(&d->lock); - if (atomic_read(&e->refcnt)) { - if (neigh != e->neigh) - neigh_replace(e, neigh); - - if (e->state == L2T_STATE_RESOLVING) { - if (neigh->nud_state & NUD_FAILED) { - arpq = e->arpq_head; - e->arpq_head = e->arpq_tail = NULL; - } else if (neigh_is_connected(neigh)) - setup_l2e_send_pending(dev, NULL, e); - } else { - e->state = neigh_is_connected(neigh) ? - L2T_STATE_VALID : L2T_STATE_STALE; - if (memcmp(e->dmac, neigh->ha, 6)) - setup_l2e_send_pending(dev, NULL, e); - } - } - spin_unlock_bh(&e->lock); - - if (arpq) - handle_failed_resolution(dev, arpq); -} - -struct l2t_data *t3_init_l2t(unsigned int l2t_capacity) -{ - struct l2t_data *d; - int i, size = sizeof(*d) + l2t_capacity * sizeof(struct l2t_entry); - - d = cxgb_alloc_mem(size); - if (!d) - return NULL; - - d->nentries = l2t_capacity; - d->rover = &d->l2tab[1]; /* entry 0 is not used */ - atomic_set(&d->nfree, l2t_capacity - 1); - rwlock_init(&d->lock); - - for (i = 0; i < l2t_capacity; ++i) { - d->l2tab[i].idx = i; - d->l2tab[i].state = L2T_STATE_UNUSED; - spin_lock_init(&d->l2tab[i].lock); - atomic_set(&d->l2tab[i].refcnt, 0); - } - return d; -} - -void t3_free_l2t(struct l2t_data *d) -{ - cxgb_free_mem(d); -} - diff --git a/trunk/drivers/net/cxgb3/l2t.h b/trunk/drivers/net/cxgb3/l2t.h deleted file mode 100644 index ba5d2cbd7241..000000000000 --- a/trunk/drivers/net/cxgb3/l2t.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. - * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _CHELSIO_L2T_H -#define _CHELSIO_L2T_H - -#include -#include "t3cdev.h" -#include - -enum { - L2T_STATE_VALID, /* entry is up to date */ - L2T_STATE_STALE, /* entry may be used but needs revalidation */ - L2T_STATE_RESOLVING, /* entry needs address resolution */ - L2T_STATE_UNUSED /* entry not in use */ -}; - -struct neighbour; -struct sk_buff; - -/* - * Each L2T entry plays multiple roles. First of all, it keeps state for the - * corresponding entry of the HW L2 table and maintains a queue of offload - * packets awaiting address resolution. Second, it is a node of a hash table - * chain, where the nodes of the chain are linked together through their next - * pointer. Finally, each node is a bucket of a hash table, pointing to the - * first element in its chain through its first pointer. - */ -struct l2t_entry { - u16 state; /* entry state */ - u16 idx; /* entry index */ - u32 addr; /* dest IP address */ - int ifindex; /* neighbor's net_device's ifindex */ - u16 smt_idx; /* SMT index */ - u16 vlan; /* VLAN TCI (id: bits 0-11, prio: 13-15 */ - struct neighbour *neigh; /* associated neighbour */ - struct l2t_entry *first; /* start of hash chain */ - struct l2t_entry *next; /* next l2t_entry on chain */ - struct sk_buff *arpq_head; /* queue of packets awaiting resolution */ - struct sk_buff *arpq_tail; - spinlock_t lock; - atomic_t refcnt; /* entry reference count */ - u8 dmac[6]; /* neighbour's MAC address */ -}; - -struct l2t_data { - unsigned int nentries; /* number of entries */ - struct l2t_entry *rover; /* starting point for next allocation */ - atomic_t nfree; /* number of free entries */ - rwlock_t lock; - struct l2t_entry l2tab[0]; -}; - -typedef void (*arp_failure_handler_func)(struct t3cdev * dev, - struct sk_buff * skb); - -/* - * Callback stored in an skb to handle address resolution failure. - */ -struct l2t_skb_cb { - arp_failure_handler_func arp_failure_handler; -}; - -#define L2T_SKB_CB(skb) ((struct l2t_skb_cb *)(skb)->cb) - -static inline void set_arp_failure_handler(struct sk_buff *skb, - arp_failure_handler_func hnd) -{ - L2T_SKB_CB(skb)->arp_failure_handler = hnd; -} - -/* - * Getting to the L2 data from an offload device. - */ -#define L2DATA(dev) ((dev)->l2opt) - -#define W_TCB_L2T_IX 0 -#define S_TCB_L2T_IX 7 -#define M_TCB_L2T_IX 0x7ffULL -#define V_TCB_L2T_IX(x) ((x) << S_TCB_L2T_IX) - -void t3_l2e_free(struct l2t_data *d, struct l2t_entry *e); -void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh); -struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh, - struct net_device *dev); -int t3_l2t_send_slow(struct t3cdev *dev, struct sk_buff *skb, - struct l2t_entry *e); -void t3_l2t_send_event(struct t3cdev *dev, struct l2t_entry *e); -struct l2t_data *t3_init_l2t(unsigned int l2t_capacity); -void t3_free_l2t(struct l2t_data *d); - -int cxgb3_ofld_send(struct t3cdev *dev, struct sk_buff *skb); - -static inline int l2t_send(struct t3cdev *dev, struct sk_buff *skb, - struct l2t_entry *e) -{ - if (likely(e->state == L2T_STATE_VALID)) - return cxgb3_ofld_send(dev, skb); - return t3_l2t_send_slow(dev, skb, e); -} - -static inline void l2t_release(struct l2t_data *d, struct l2t_entry *e) -{ - if (atomic_dec_and_test(&e->refcnt)) - t3_l2e_free(d, e); -} - -static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e) -{ - if (atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */ - atomic_dec(&d->nfree); -} - -#endif diff --git a/trunk/drivers/net/cxgb3/mc5.c b/trunk/drivers/net/cxgb3/mc5.c deleted file mode 100644 index 644d62ea86a6..000000000000 --- a/trunk/drivers/net/cxgb3/mc5.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "common.h" -#include "regs.h" - -enum { - IDT75P52100 = 4, - IDT75N43102 = 5 -}; - -/* DBGI command mode */ -enum { - DBGI_MODE_MBUS = 0, - DBGI_MODE_IDT52100 = 5 -}; - -/* IDT 75P52100 commands */ -#define IDT_CMD_READ 0 -#define IDT_CMD_WRITE 1 -#define IDT_CMD_SEARCH 2 -#define IDT_CMD_LEARN 3 - -/* IDT LAR register address and value for 144-bit mode (low 32 bits) */ -#define IDT_LAR_ADR0 0x180006 -#define IDT_LAR_MODE144 0xffff0000 - -/* IDT SCR and SSR addresses (low 32 bits) */ -#define IDT_SCR_ADR0 0x180000 -#define IDT_SSR0_ADR0 0x180002 -#define IDT_SSR1_ADR0 0x180004 - -/* IDT GMR base address (low 32 bits) */ -#define IDT_GMR_BASE_ADR0 0x180020 - -/* IDT data and mask array base addresses (low 32 bits) */ -#define IDT_DATARY_BASE_ADR0 0 -#define IDT_MSKARY_BASE_ADR0 0x80000 - -/* IDT 75N43102 commands */ -#define IDT4_CMD_SEARCH144 3 -#define IDT4_CMD_WRITE 4 -#define IDT4_CMD_READ 5 - -/* IDT 75N43102 SCR address (low 32 bits) */ -#define IDT4_SCR_ADR0 0x3 - -/* IDT 75N43102 GMR base addresses (low 32 bits) */ -#define IDT4_GMR_BASE0 0x10 -#define IDT4_GMR_BASE1 0x20 -#define IDT4_GMR_BASE2 0x30 - -/* IDT 75N43102 data and mask array base addresses (low 32 bits) */ -#define IDT4_DATARY_BASE_ADR0 0x1000000 -#define IDT4_MSKARY_BASE_ADR0 0x2000000 - -#define MAX_WRITE_ATTEMPTS 5 - -#define MAX_ROUTES 2048 - -/* - * Issue a command to the TCAM and wait for its completion. The address and - * any data required by the command must have been setup by the caller. - */ -static int mc5_cmd_write(struct adapter *adapter, u32 cmd) -{ - t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_CMD, cmd); - return t3_wait_op_done(adapter, A_MC5_DB_DBGI_RSP_STATUS, - F_DBGIRSPVALID, 1, MAX_WRITE_ATTEMPTS, 1); -} - -static inline void dbgi_wr_addr3(struct adapter *adapter, u32 v1, u32 v2, - u32 v3) -{ - t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, v1); - t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR1, v2); - t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR2, v3); -} - -static inline void dbgi_wr_data3(struct adapter *adapter, u32 v1, u32 v2, - u32 v3) -{ - t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA0, v1); - t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA1, v2); - t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA2, v3); -} - -static inline void dbgi_rd_rsp3(struct adapter *adapter, u32 *v1, u32 *v2, - u32 *v3) -{ - *v1 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA0); - *v2 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA1); - *v3 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA2); -} - -/* - * Write data to the TCAM register at address (0, 0, addr_lo) using the TCAM - * command cmd. The data to be written must have been set up by the caller. - * Returns -1 on failure, 0 on success. - */ -static int mc5_write(struct adapter *adapter, u32 addr_lo, u32 cmd) -{ - t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, addr_lo); - if (mc5_cmd_write(adapter, cmd) == 0) - return 0; - CH_ERR(adapter, "MC5 timeout writing to TCAM address 0x%x\n", - addr_lo); - return -1; -} - -static int init_mask_data_array(struct mc5 *mc5, u32 mask_array_base, - u32 data_array_base, u32 write_cmd, - int addr_shift) -{ - unsigned int i; - struct adapter *adap = mc5->adapter; - - /* - * We need the size of the TCAM data and mask arrays in terms of - * 72-bit entries. - */ - unsigned int size72 = mc5->tcam_size; - unsigned int server_base = t3_read_reg(adap, A_MC5_DB_SERVER_INDEX); - - if (mc5->mode == MC5_MODE_144_BIT) { - size72 *= 2; /* 1 144-bit entry is 2 72-bit entries */ - server_base *= 2; - } - - /* Clear the data array */ - dbgi_wr_data3(adap, 0, 0, 0); - for (i = 0; i < size72; i++) - if (mc5_write(adap, data_array_base + (i << addr_shift), - write_cmd)) - return -1; - - /* Initialize the mask array. */ - dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); - for (i = 0; i < size72; i++) { - if (i == server_base) /* entering server or routing region */ - t3_write_reg(adap, A_MC5_DB_DBGI_REQ_DATA0, - mc5->mode == MC5_MODE_144_BIT ? - 0xfffffff9 : 0xfffffffd); - if (mc5_write(adap, mask_array_base + (i << addr_shift), - write_cmd)) - return -1; - } - return 0; -} - -static int init_idt52100(struct mc5 *mc5) -{ - int i; - struct adapter *adap = mc5->adapter; - - t3_write_reg(adap, A_MC5_DB_RSP_LATENCY, - V_RDLAT(0x15) | V_LRNLAT(0x15) | V_SRCHLAT(0x15)); - t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 2); - - /* - * Use GMRs 14-15 for ELOOKUP, GMRs 12-13 for SYN lookups, and - * GMRs 8-9 for ACK- and AOPEN searches. - */ - t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT_CMD_WRITE); - t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT_CMD_WRITE); - t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, IDT_CMD_SEARCH); - t3_write_reg(adap, A_MC5_DB_AOPEN_LRN_CMD, IDT_CMD_LEARN); - t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT_CMD_SEARCH | 0x6000); - t3_write_reg(adap, A_MC5_DB_SYN_LRN_CMD, IDT_CMD_LEARN); - t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT_CMD_SEARCH); - t3_write_reg(adap, A_MC5_DB_ACK_LRN_CMD, IDT_CMD_LEARN); - t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT_CMD_SEARCH); - t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT_CMD_SEARCH | 0x7000); - t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT_CMD_WRITE); - t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT_CMD_READ); - - /* Set DBGI command mode for IDT TCAM. */ - t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100); - - /* Set up LAR */ - dbgi_wr_data3(adap, IDT_LAR_MODE144, 0, 0); - if (mc5_write(adap, IDT_LAR_ADR0, IDT_CMD_WRITE)) - goto err; - - /* Set up SSRs */ - dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0); - if (mc5_write(adap, IDT_SSR0_ADR0, IDT_CMD_WRITE) || - mc5_write(adap, IDT_SSR1_ADR0, IDT_CMD_WRITE)) - goto err; - - /* Set up GMRs */ - for (i = 0; i < 32; ++i) { - if (i >= 12 && i < 15) - dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff); - else if (i == 15) - dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff); - else - dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); - - if (mc5_write(adap, IDT_GMR_BASE_ADR0 + i, IDT_CMD_WRITE)) - goto err; - } - - /* Set up SCR */ - dbgi_wr_data3(adap, 1, 0, 0); - if (mc5_write(adap, IDT_SCR_ADR0, IDT_CMD_WRITE)) - goto err; - - return init_mask_data_array(mc5, IDT_MSKARY_BASE_ADR0, - IDT_DATARY_BASE_ADR0, IDT_CMD_WRITE, 0); -err: - return -EIO; -} - -static int init_idt43102(struct mc5 *mc5) -{ - int i; - struct adapter *adap = mc5->adapter; - - t3_write_reg(adap, A_MC5_DB_RSP_LATENCY, - adap->params.rev == 0 ? V_RDLAT(0xd) | V_SRCHLAT(0x11) : - V_RDLAT(0xd) | V_SRCHLAT(0x12)); - - /* - * Use GMRs 24-25 for ELOOKUP, GMRs 20-21 for SYN lookups, and no mask - * for ACK- and AOPEN searches. - */ - t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT4_CMD_WRITE); - t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT4_CMD_WRITE); - t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, - IDT4_CMD_SEARCH144 | 0x3800); - t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT4_CMD_SEARCH144); - t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT4_CMD_SEARCH144 | 0x3800); - t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x3800); - t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x800); - t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT4_CMD_WRITE); - t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT4_CMD_READ); - - t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 3); - - /* Set DBGI command mode for IDT TCAM. */ - t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100); - - /* Set up GMRs */ - dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); - for (i = 0; i < 7; ++i) - if (mc5_write(adap, IDT4_GMR_BASE0 + i, IDT4_CMD_WRITE)) - goto err; - - for (i = 0; i < 4; ++i) - if (mc5_write(adap, IDT4_GMR_BASE2 + i, IDT4_CMD_WRITE)) - goto err; - - dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff); - if (mc5_write(adap, IDT4_GMR_BASE1, IDT4_CMD_WRITE) || - mc5_write(adap, IDT4_GMR_BASE1 + 1, IDT4_CMD_WRITE) || - mc5_write(adap, IDT4_GMR_BASE1 + 4, IDT4_CMD_WRITE)) - goto err; - - dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff); - if (mc5_write(adap, IDT4_GMR_BASE1 + 5, IDT4_CMD_WRITE)) - goto err; - - /* Set up SCR */ - dbgi_wr_data3(adap, 0xf0000000, 0, 0); - if (mc5_write(adap, IDT4_SCR_ADR0, IDT4_CMD_WRITE)) - goto err; - - return init_mask_data_array(mc5, IDT4_MSKARY_BASE_ADR0, - IDT4_DATARY_BASE_ADR0, IDT4_CMD_WRITE, 1); -err: - return -EIO; -} - -/* Put MC5 in DBGI mode. */ -static inline void mc5_dbgi_mode_enable(const struct mc5 *mc5) -{ - t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG, - V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_DBGIEN); -} - -/* Put MC5 in M-Bus mode. */ -static void mc5_dbgi_mode_disable(const struct mc5 *mc5) -{ - t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG, - V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | - V_COMPEN(mc5->mode == MC5_MODE_72_BIT) | - V_PRTYEN(mc5->parity_enabled) | F_MBUSEN); -} - -/* - * Initialization that requires the OS and protocol layers to already - * be intialized goes here. - */ -int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, - unsigned int nroutes) -{ - u32 cfg; - int err; - unsigned int tcam_size = mc5->tcam_size; - struct adapter *adap = mc5->adapter; - - if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size) - return -EINVAL; - - /* Reset the TCAM */ - cfg = t3_read_reg(adap, A_MC5_DB_CONFIG) & ~F_TMMODE; - cfg |= V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_TMRST; - t3_write_reg(adap, A_MC5_DB_CONFIG, cfg); - if (t3_wait_op_done(adap, A_MC5_DB_CONFIG, F_TMRDY, 1, 500, 0)) { - CH_ERR(adap, "TCAM reset timed out\n"); - return -1; - } - - t3_write_reg(adap, A_MC5_DB_ROUTING_TABLE_INDEX, tcam_size - nroutes); - t3_write_reg(adap, A_MC5_DB_FILTER_TABLE, - tcam_size - nroutes - nfilters); - t3_write_reg(adap, A_MC5_DB_SERVER_INDEX, - tcam_size - nroutes - nfilters - nservers); - - mc5->parity_enabled = 1; - - /* All the TCAM addresses we access have only the low 32 bits non 0 */ - t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR1, 0); - t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR2, 0); - - mc5_dbgi_mode_enable(mc5); - - switch (mc5->part_type) { - case IDT75P52100: - err = init_idt52100(mc5); - break; - case IDT75N43102: - err = init_idt43102(mc5); - break; - default: - CH_ERR(adap, "Unsupported TCAM type %d\n", mc5->part_type); - err = -EINVAL; - break; - } - - mc5_dbgi_mode_disable(mc5); - return err; -} - -/* - * read_mc5_range - dump a part of the memory managed by MC5 - * @mc5: the MC5 handle - * @start: the start address for the dump - * @n: number of 72-bit words to read - * @buf: result buffer - * - * Read n 72-bit words from MC5 memory from the given start location. - */ -int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, - unsigned int n, u32 *buf) -{ - u32 read_cmd; - int err = 0; - struct adapter *adap = mc5->adapter; - - if (mc5->part_type == IDT75P52100) - read_cmd = IDT_CMD_READ; - else if (mc5->part_type == IDT75N43102) - read_cmd = IDT4_CMD_READ; - else - return -EINVAL; - - mc5_dbgi_mode_enable(mc5); - - while (n--) { - t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR0, start++); - if (mc5_cmd_write(adap, read_cmd)) { - err = -EIO; - break; - } - dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf); - buf += 3; - } - - mc5_dbgi_mode_disable(mc5); - return 0; -} - -#define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR) - -/* - * MC5 interrupt handler - */ -void t3_mc5_intr_handler(struct mc5 *mc5) -{ - struct adapter *adap = mc5->adapter; - u32 cause = t3_read_reg(adap, A_MC5_DB_INT_CAUSE); - - if ((cause & F_PARITYERR) && mc5->parity_enabled) { - CH_ALERT(adap, "MC5 parity error\n"); - mc5->stats.parity_err++; - } - - if (cause & F_REQQPARERR) { - CH_ALERT(adap, "MC5 request queue parity error\n"); - mc5->stats.reqq_parity_err++; - } - - if (cause & F_DISPQPARERR) { - CH_ALERT(adap, "MC5 dispatch queue parity error\n"); - mc5->stats.dispq_parity_err++; - } - - if (cause & F_ACTRGNFULL) - mc5->stats.active_rgn_full++; - if (cause & F_NFASRCHFAIL) - mc5->stats.nfa_srch_err++; - if (cause & F_UNKNOWNCMD) - mc5->stats.unknown_cmd++; - if (cause & F_DELACTEMPTY) - mc5->stats.del_act_empty++; - if (cause & MC5_INT_FATAL) - t3_fatal_err(adap); - - t3_write_reg(adap, A_MC5_DB_INT_CAUSE, cause); -} - -void __devinit t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode) -{ -#define K * 1024 - - static unsigned int tcam_part_size[] = { /* in K 72-bit entries */ - 64 K, 128 K, 256 K, 32 K - }; - -#undef K - - u32 cfg = t3_read_reg(adapter, A_MC5_DB_CONFIG); - - mc5->adapter = adapter; - mc5->mode = (unsigned char)mode; - mc5->part_type = (unsigned char)G_TMTYPE(cfg); - if (cfg & F_TMTYPEHI) - mc5->part_type |= 4; - - mc5->tcam_size = tcam_part_size[G_TMPARTSIZE(cfg)]; - if (mode == MC5_MODE_144_BIT) - mc5->tcam_size /= 2; -} diff --git a/trunk/drivers/net/cxgb3/regs.h b/trunk/drivers/net/cxgb3/regs.h deleted file mode 100644 index b56c5f52bcdc..000000000000 --- a/trunk/drivers/net/cxgb3/regs.h +++ /dev/null @@ -1,2195 +0,0 @@ -#define A_SG_CONTROL 0x0 - -#define S_DROPPKT 20 -#define V_DROPPKT(x) ((x) << S_DROPPKT) -#define F_DROPPKT V_DROPPKT(1U) - -#define S_EGRGENCTRL 19 -#define V_EGRGENCTRL(x) ((x) << S_EGRGENCTRL) -#define F_EGRGENCTRL V_EGRGENCTRL(1U) - -#define S_USERSPACESIZE 14 -#define M_USERSPACESIZE 0x1f -#define V_USERSPACESIZE(x) ((x) << S_USERSPACESIZE) - -#define S_HOSTPAGESIZE 11 -#define M_HOSTPAGESIZE 0x7 -#define V_HOSTPAGESIZE(x) ((x) << S_HOSTPAGESIZE) - -#define S_FLMODE 9 -#define V_FLMODE(x) ((x) << S_FLMODE) -#define F_FLMODE V_FLMODE(1U) - -#define S_PKTSHIFT 6 -#define M_PKTSHIFT 0x7 -#define V_PKTSHIFT(x) ((x) << S_PKTSHIFT) - -#define S_ONEINTMULTQ 5 -#define V_ONEINTMULTQ(x) ((x) << S_ONEINTMULTQ) -#define F_ONEINTMULTQ V_ONEINTMULTQ(1U) - -#define S_BIGENDIANINGRESS 2 -#define V_BIGENDIANINGRESS(x) ((x) << S_BIGENDIANINGRESS) -#define F_BIGENDIANINGRESS V_BIGENDIANINGRESS(1U) - -#define S_ISCSICOALESCING 1 -#define V_ISCSICOALESCING(x) ((x) << S_ISCSICOALESCING) -#define F_ISCSICOALESCING V_ISCSICOALESCING(1U) - -#define S_GLOBALENABLE 0 -#define V_GLOBALENABLE(x) ((x) << S_GLOBALENABLE) -#define F_GLOBALENABLE V_GLOBALENABLE(1U) - -#define S_AVOIDCQOVFL 24 -#define V_AVOIDCQOVFL(x) ((x) << S_AVOIDCQOVFL) -#define F_AVOIDCQOVFL V_AVOIDCQOVFL(1U) - -#define S_OPTONEINTMULTQ 23 -#define V_OPTONEINTMULTQ(x) ((x) << S_OPTONEINTMULTQ) -#define F_OPTONEINTMULTQ V_OPTONEINTMULTQ(1U) - -#define S_CQCRDTCTRL 22 -#define V_CQCRDTCTRL(x) ((x) << S_CQCRDTCTRL) -#define F_CQCRDTCTRL V_CQCRDTCTRL(1U) - -#define A_SG_KDOORBELL 0x4 - -#define S_SELEGRCNTX 31 -#define V_SELEGRCNTX(x) ((x) << S_SELEGRCNTX) -#define F_SELEGRCNTX V_SELEGRCNTX(1U) - -#define S_EGRCNTX 0 -#define M_EGRCNTX 0xffff -#define V_EGRCNTX(x) ((x) << S_EGRCNTX) - -#define A_SG_GTS 0x8 - -#define S_RSPQ 29 -#define M_RSPQ 0x7 -#define V_RSPQ(x) ((x) << S_RSPQ) -#define G_RSPQ(x) (((x) >> S_RSPQ) & M_RSPQ) - -#define S_NEWTIMER 16 -#define M_NEWTIMER 0x1fff -#define V_NEWTIMER(x) ((x) << S_NEWTIMER) - -#define S_NEWINDEX 0 -#define M_NEWINDEX 0xffff -#define V_NEWINDEX(x) ((x) << S_NEWINDEX) - -#define A_SG_CONTEXT_CMD 0xc - -#define S_CONTEXT_CMD_OPCODE 28 -#define M_CONTEXT_CMD_OPCODE 0xf -#define V_CONTEXT_CMD_OPCODE(x) ((x) << S_CONTEXT_CMD_OPCODE) - -#define S_CONTEXT_CMD_BUSY 27 -#define V_CONTEXT_CMD_BUSY(x) ((x) << S_CONTEXT_CMD_BUSY) -#define F_CONTEXT_CMD_BUSY V_CONTEXT_CMD_BUSY(1U) - -#define S_CQ_CREDIT 20 - -#define M_CQ_CREDIT 0x7f - -#define V_CQ_CREDIT(x) ((x) << S_CQ_CREDIT) - -#define G_CQ_CREDIT(x) (((x) >> S_CQ_CREDIT) & M_CQ_CREDIT) - -#define S_CQ 19 - -#define V_CQ(x) ((x) << S_CQ) -#define F_CQ V_CQ(1U) - -#define S_RESPONSEQ 18 -#define V_RESPONSEQ(x) ((x) << S_RESPONSEQ) -#define F_RESPONSEQ V_RESPONSEQ(1U) - -#define S_EGRESS 17 -#define V_EGRESS(x) ((x) << S_EGRESS) -#define F_EGRESS V_EGRESS(1U) - -#define S_FREELIST 16 -#define V_FREELIST(x) ((x) << S_FREELIST) -#define F_FREELIST V_FREELIST(1U) - -#define S_CONTEXT 0 -#define M_CONTEXT 0xffff -#define V_CONTEXT(x) ((x) << S_CONTEXT) - -#define G_CONTEXT(x) (((x) >> S_CONTEXT) & M_CONTEXT) - -#define A_SG_CONTEXT_DATA0 0x10 - -#define A_SG_CONTEXT_DATA1 0x14 - -#define A_SG_CONTEXT_DATA2 0x18 - -#define A_SG_CONTEXT_DATA3 0x1c - -#define A_SG_CONTEXT_MASK0 0x20 - -#define A_SG_CONTEXT_MASK1 0x24 - -#define A_SG_CONTEXT_MASK2 0x28 - -#define A_SG_CONTEXT_MASK3 0x2c - -#define A_SG_RSPQ_CREDIT_RETURN 0x30 - -#define S_CREDITS 0 -#define M_CREDITS 0xffff -#define V_CREDITS(x) ((x) << S_CREDITS) - -#define A_SG_DATA_INTR 0x34 - -#define S_ERRINTR 31 -#define V_ERRINTR(x) ((x) << S_ERRINTR) -#define F_ERRINTR V_ERRINTR(1U) - -#define A_SG_HI_DRB_HI_THRSH 0x38 - -#define A_SG_HI_DRB_LO_THRSH 0x3c - -#define A_SG_LO_DRB_HI_THRSH 0x40 - -#define A_SG_LO_DRB_LO_THRSH 0x44 - -#define A_SG_RSPQ_FL_STATUS 0x4c - -#define S_RSPQ0DISABLED 8 - -#define A_SG_EGR_RCQ_DRB_THRSH 0x54 - -#define S_HIRCQDRBTHRSH 16 -#define M_HIRCQDRBTHRSH 0x7ff -#define V_HIRCQDRBTHRSH(x) ((x) << S_HIRCQDRBTHRSH) - -#define S_LORCQDRBTHRSH 0 -#define M_LORCQDRBTHRSH 0x7ff -#define V_LORCQDRBTHRSH(x) ((x) << S_LORCQDRBTHRSH) - -#define A_SG_EGR_CNTX_BADDR 0x58 - -#define A_SG_INT_CAUSE 0x5c - -#define S_RSPQDISABLED 3 -#define V_RSPQDISABLED(x) ((x) << S_RSPQDISABLED) -#define F_RSPQDISABLED V_RSPQDISABLED(1U) - -#define S_RSPQCREDITOVERFOW 2 -#define V_RSPQCREDITOVERFOW(x) ((x) << S_RSPQCREDITOVERFOW) -#define F_RSPQCREDITOVERFOW V_RSPQCREDITOVERFOW(1U) - -#define A_SG_INT_ENABLE 0x60 - -#define A_SG_CMDQ_CREDIT_TH 0x64 - -#define S_TIMEOUT 8 -#define M_TIMEOUT 0xffffff -#define V_TIMEOUT(x) ((x) << S_TIMEOUT) - -#define S_THRESHOLD 0 -#define M_THRESHOLD 0xff -#define V_THRESHOLD(x) ((x) << S_THRESHOLD) - -#define A_SG_TIMER_TICK 0x68 - -#define A_SG_CQ_CONTEXT_BADDR 0x6c - -#define A_SG_OCO_BASE 0x70 - -#define S_BASE1 16 -#define M_BASE1 0xffff -#define V_BASE1(x) ((x) << S_BASE1) - -#define A_SG_DRB_PRI_THRESH 0x74 - -#define A_PCIX_INT_ENABLE 0x80 - -#define S_MSIXPARERR 22 -#define M_MSIXPARERR 0x7 - -#define V_MSIXPARERR(x) ((x) << S_MSIXPARERR) - -#define S_CFPARERR 18 -#define M_CFPARERR 0xf - -#define V_CFPARERR(x) ((x) << S_CFPARERR) - -#define S_RFPARERR 14 -#define M_RFPARERR 0xf - -#define V_RFPARERR(x) ((x) << S_RFPARERR) - -#define S_WFPARERR 12 -#define M_WFPARERR 0x3 - -#define V_WFPARERR(x) ((x) << S_WFPARERR) - -#define S_PIOPARERR 11 -#define V_PIOPARERR(x) ((x) << S_PIOPARERR) -#define F_PIOPARERR V_PIOPARERR(1U) - -#define S_DETUNCECCERR 10 -#define V_DETUNCECCERR(x) ((x) << S_DETUNCECCERR) -#define F_DETUNCECCERR V_DETUNCECCERR(1U) - -#define S_DETCORECCERR 9 -#define V_DETCORECCERR(x) ((x) << S_DETCORECCERR) -#define F_DETCORECCERR V_DETCORECCERR(1U) - -#define S_RCVSPLCMPERR 8 -#define V_RCVSPLCMPERR(x) ((x) << S_RCVSPLCMPERR) -#define F_RCVSPLCMPERR V_RCVSPLCMPERR(1U) - -#define S_UNXSPLCMP 7 -#define V_UNXSPLCMP(x) ((x) << S_UNXSPLCMP) -#define F_UNXSPLCMP V_UNXSPLCMP(1U) - -#define S_SPLCMPDIS 6 -#define V_SPLCMPDIS(x) ((x) << S_SPLCMPDIS) -#define F_SPLCMPDIS V_SPLCMPDIS(1U) - -#define S_DETPARERR 5 -#define V_DETPARERR(x) ((x) << S_DETPARERR) -#define F_DETPARERR V_DETPARERR(1U) - -#define S_SIGSYSERR 4 -#define V_SIGSYSERR(x) ((x) << S_SIGSYSERR) -#define F_SIGSYSERR V_SIGSYSERR(1U) - -#define S_RCVMSTABT 3 -#define V_RCVMSTABT(x) ((x) << S_RCVMSTABT) -#define F_RCVMSTABT V_RCVMSTABT(1U) - -#define S_RCVTARABT 2 -#define V_RCVTARABT(x) ((x) << S_RCVTARABT) -#define F_RCVTARABT V_RCVTARABT(1U) - -#define S_SIGTARABT 1 -#define V_SIGTARABT(x) ((x) << S_SIGTARABT) -#define F_SIGTARABT V_SIGTARABT(1U) - -#define S_MSTDETPARERR 0 -#define V_MSTDETPARERR(x) ((x) << S_MSTDETPARERR) -#define F_MSTDETPARERR V_MSTDETPARERR(1U) - -#define A_PCIX_INT_CAUSE 0x84 - -#define A_PCIX_CFG 0x88 - -#define S_CLIDECEN 18 -#define V_CLIDECEN(x) ((x) << S_CLIDECEN) -#define F_CLIDECEN V_CLIDECEN(1U) - -#define A_PCIX_MODE 0x8c - -#define S_PCLKRANGE 6 -#define M_PCLKRANGE 0x3 -#define V_PCLKRANGE(x) ((x) << S_PCLKRANGE) -#define G_PCLKRANGE(x) (((x) >> S_PCLKRANGE) & M_PCLKRANGE) - -#define S_PCIXINITPAT 2 -#define M_PCIXINITPAT 0xf -#define V_PCIXINITPAT(x) ((x) << S_PCIXINITPAT) -#define G_PCIXINITPAT(x) (((x) >> S_PCIXINITPAT) & M_PCIXINITPAT) - -#define S_64BIT 0 -#define V_64BIT(x) ((x) << S_64BIT) -#define F_64BIT V_64BIT(1U) - -#define A_PCIE_INT_ENABLE 0x80 - -#define S_BISTERR 15 -#define M_BISTERR 0xff - -#define V_BISTERR(x) ((x) << S_BISTERR) - -#define S_PCIE_MSIXPARERR 12 -#define M_PCIE_MSIXPARERR 0x7 - -#define V_PCIE_MSIXPARERR(x) ((x) << S_PCIE_MSIXPARERR) - -#define S_PCIE_CFPARERR 11 -#define V_PCIE_CFPARERR(x) ((x) << S_PCIE_CFPARERR) -#define F_PCIE_CFPARERR V_PCIE_CFPARERR(1U) - -#define S_PCIE_RFPARERR 10 -#define V_PCIE_RFPARERR(x) ((x) << S_PCIE_RFPARERR) -#define F_PCIE_RFPARERR V_PCIE_RFPARERR(1U) - -#define S_PCIE_WFPARERR 9 -#define V_PCIE_WFPARERR(x) ((x) << S_PCIE_WFPARERR) -#define F_PCIE_WFPARERR V_PCIE_WFPARERR(1U) - -#define S_PCIE_PIOPARERR 8 -#define V_PCIE_PIOPARERR(x) ((x) << S_PCIE_PIOPARERR) -#define F_PCIE_PIOPARERR V_PCIE_PIOPARERR(1U) - -#define S_UNXSPLCPLERRC 7 -#define V_UNXSPLCPLERRC(x) ((x) << S_UNXSPLCPLERRC) -#define F_UNXSPLCPLERRC V_UNXSPLCPLERRC(1U) - -#define S_UNXSPLCPLERRR 6 -#define V_UNXSPLCPLERRR(x) ((x) << S_UNXSPLCPLERRR) -#define F_UNXSPLCPLERRR V_UNXSPLCPLERRR(1U) - -#define S_PEXERR 0 -#define V_PEXERR(x) ((x) << S_PEXERR) -#define F_PEXERR V_PEXERR(1U) - -#define A_PCIE_INT_CAUSE 0x84 - -#define A_PCIE_CFG 0x88 - -#define S_PCIE_CLIDECEN 16 -#define V_PCIE_CLIDECEN(x) ((x) << S_PCIE_CLIDECEN) -#define F_PCIE_CLIDECEN V_PCIE_CLIDECEN(1U) - -#define S_CRSTWRMMODE 0 -#define V_CRSTWRMMODE(x) ((x) << S_CRSTWRMMODE) -#define F_CRSTWRMMODE V_CRSTWRMMODE(1U) - -#define A_PCIE_MODE 0x8c - -#define S_NUMFSTTRNSEQRX 10 -#define M_NUMFSTTRNSEQRX 0xff -#define V_NUMFSTTRNSEQRX(x) ((x) << S_NUMFSTTRNSEQRX) -#define G_NUMFSTTRNSEQRX(x) (((x) >> S_NUMFSTTRNSEQRX) & M_NUMFSTTRNSEQRX) - -#define A_PCIE_PEX_CTRL0 0x98 - -#define S_NUMFSTTRNSEQ 22 -#define M_NUMFSTTRNSEQ 0xff -#define V_NUMFSTTRNSEQ(x) ((x) << S_NUMFSTTRNSEQ) -#define G_NUMFSTTRNSEQ(x) (((x) >> S_NUMFSTTRNSEQ) & M_NUMFSTTRNSEQ) - -#define S_REPLAYLMT 2 -#define M_REPLAYLMT 0xfffff - -#define V_REPLAYLMT(x) ((x) << S_REPLAYLMT) - -#define A_PCIE_PEX_CTRL1 0x9c - -#define S_T3A_ACKLAT 0 -#define M_T3A_ACKLAT 0x7ff - -#define V_T3A_ACKLAT(x) ((x) << S_T3A_ACKLAT) - -#define S_ACKLAT 0 -#define M_ACKLAT 0x1fff - -#define V_ACKLAT(x) ((x) << S_ACKLAT) - -#define A_PCIE_PEX_ERR 0xa4 - -#define A_T3DBG_GPIO_EN 0xd0 - -#define S_GPIO11_OEN 27 -#define V_GPIO11_OEN(x) ((x) << S_GPIO11_OEN) -#define F_GPIO11_OEN V_GPIO11_OEN(1U) - -#define S_GPIO10_OEN 26 -#define V_GPIO10_OEN(x) ((x) << S_GPIO10_OEN) -#define F_GPIO10_OEN V_GPIO10_OEN(1U) - -#define S_GPIO7_OEN 23 -#define V_GPIO7_OEN(x) ((x) << S_GPIO7_OEN) -#define F_GPIO7_OEN V_GPIO7_OEN(1U) - -#define S_GPIO6_OEN 22 -#define V_GPIO6_OEN(x) ((x) << S_GPIO6_OEN) -#define F_GPIO6_OEN V_GPIO6_OEN(1U) - -#define S_GPIO5_OEN 21 -#define V_GPIO5_OEN(x) ((x) << S_GPIO5_OEN) -#define F_GPIO5_OEN V_GPIO5_OEN(1U) - -#define S_GPIO4_OEN 20 -#define V_GPIO4_OEN(x) ((x) << S_GPIO4_OEN) -#define F_GPIO4_OEN V_GPIO4_OEN(1U) - -#define S_GPIO2_OEN 18 -#define V_GPIO2_OEN(x) ((x) << S_GPIO2_OEN) -#define F_GPIO2_OEN V_GPIO2_OEN(1U) - -#define S_GPIO1_OEN 17 -#define V_GPIO1_OEN(x) ((x) << S_GPIO1_OEN) -#define F_GPIO1_OEN V_GPIO1_OEN(1U) - -#define S_GPIO0_OEN 16 -#define V_GPIO0_OEN(x) ((x) << S_GPIO0_OEN) -#define F_GPIO0_OEN V_GPIO0_OEN(1U) - -#define S_GPIO10_OUT_VAL 10 -#define V_GPIO10_OUT_VAL(x) ((x) << S_GPIO10_OUT_VAL) -#define F_GPIO10_OUT_VAL V_GPIO10_OUT_VAL(1U) - -#define S_GPIO7_OUT_VAL 7 -#define V_GPIO7_OUT_VAL(x) ((x) << S_GPIO7_OUT_VAL) -#define F_GPIO7_OUT_VAL V_GPIO7_OUT_VAL(1U) - -#define S_GPIO6_OUT_VAL 6 -#define V_GPIO6_OUT_VAL(x) ((x) << S_GPIO6_OUT_VAL) -#define F_GPIO6_OUT_VAL V_GPIO6_OUT_VAL(1U) - -#define S_GPIO5_OUT_VAL 5 -#define V_GPIO5_OUT_VAL(x) ((x) << S_GPIO5_OUT_VAL) -#define F_GPIO5_OUT_VAL V_GPIO5_OUT_VAL(1U) - -#define S_GPIO4_OUT_VAL 4 -#define V_GPIO4_OUT_VAL(x) ((x) << S_GPIO4_OUT_VAL) -#define F_GPIO4_OUT_VAL V_GPIO4_OUT_VAL(1U) - -#define S_GPIO2_OUT_VAL 2 -#define V_GPIO2_OUT_VAL(x) ((x) << S_GPIO2_OUT_VAL) -#define F_GPIO2_OUT_VAL V_GPIO2_OUT_VAL(1U) - -#define S_GPIO1_OUT_VAL 1 -#define V_GPIO1_OUT_VAL(x) ((x) << S_GPIO1_OUT_VAL) -#define F_GPIO1_OUT_VAL V_GPIO1_OUT_VAL(1U) - -#define S_GPIO0_OUT_VAL 0 -#define V_GPIO0_OUT_VAL(x) ((x) << S_GPIO0_OUT_VAL) -#define F_GPIO0_OUT_VAL V_GPIO0_OUT_VAL(1U) - -#define A_T3DBG_INT_ENABLE 0xd8 - -#define S_GPIO11 11 -#define V_GPIO11(x) ((x) << S_GPIO11) -#define F_GPIO11 V_GPIO11(1U) - -#define S_GPIO10 10 -#define V_GPIO10(x) ((x) << S_GPIO10) -#define F_GPIO10 V_GPIO10(1U) - -#define S_GPIO7 7 -#define V_GPIO7(x) ((x) << S_GPIO7) -#define F_GPIO7 V_GPIO7(1U) - -#define S_GPIO6 6 -#define V_GPIO6(x) ((x) << S_GPIO6) -#define F_GPIO6 V_GPIO6(1U) - -#define S_GPIO5 5 -#define V_GPIO5(x) ((x) << S_GPIO5) -#define F_GPIO5 V_GPIO5(1U) - -#define S_GPIO4 4 -#define V_GPIO4(x) ((x) << S_GPIO4) -#define F_GPIO4 V_GPIO4(1U) - -#define S_GPIO3 3 -#define V_GPIO3(x) ((x) << S_GPIO3) -#define F_GPIO3 V_GPIO3(1U) - -#define S_GPIO2 2 -#define V_GPIO2(x) ((x) << S_GPIO2) -#define F_GPIO2 V_GPIO2(1U) - -#define S_GPIO1 1 -#define V_GPIO1(x) ((x) << S_GPIO1) -#define F_GPIO1 V_GPIO1(1U) - -#define S_GPIO0 0 -#define V_GPIO0(x) ((x) << S_GPIO0) -#define F_GPIO0 V_GPIO0(1U) - -#define A_T3DBG_INT_CAUSE 0xdc - -#define A_T3DBG_GPIO_ACT_LOW 0xf0 - -#define MC7_PMRX_BASE_ADDR 0x100 - -#define A_MC7_CFG 0x100 - -#define S_IFEN 13 -#define V_IFEN(x) ((x) << S_IFEN) -#define F_IFEN V_IFEN(1U) - -#define S_TERM150 11 -#define V_TERM150(x) ((x) << S_TERM150) -#define F_TERM150 V_TERM150(1U) - -#define S_SLOW 10 -#define V_SLOW(x) ((x) << S_SLOW) -#define F_SLOW V_SLOW(1U) - -#define S_WIDTH 8 -#define M_WIDTH 0x3 -#define V_WIDTH(x) ((x) << S_WIDTH) -#define G_WIDTH(x) (((x) >> S_WIDTH) & M_WIDTH) - -#define S_BKS 6 -#define V_BKS(x) ((x) << S_BKS) -#define F_BKS V_BKS(1U) - -#define S_ORG 5 -#define V_ORG(x) ((x) << S_ORG) -#define F_ORG V_ORG(1U) - -#define S_DEN 2 -#define M_DEN 0x7 -#define V_DEN(x) ((x) << S_DEN) -#define G_DEN(x) (((x) >> S_DEN) & M_DEN) - -#define S_RDY 1 -#define V_RDY(x) ((x) << S_RDY) -#define F_RDY V_RDY(1U) - -#define S_CLKEN 0 -#define V_CLKEN(x) ((x) << S_CLKEN) -#define F_CLKEN V_CLKEN(1U) - -#define A_MC7_MODE 0x104 - -#define S_BUSY 31 -#define V_BUSY(x) ((x) << S_BUSY) -#define F_BUSY V_BUSY(1U) - -#define S_BUSY 31 -#define V_BUSY(x) ((x) << S_BUSY) -#define F_BUSY V_BUSY(1U) - -#define A_MC7_EXT_MODE1 0x108 - -#define A_MC7_EXT_MODE2 0x10c - -#define A_MC7_EXT_MODE3 0x110 - -#define A_MC7_PRE 0x114 - -#define A_MC7_REF 0x118 - -#define S_PREREFDIV 1 -#define M_PREREFDIV 0x3fff -#define V_PREREFDIV(x) ((x) << S_PREREFDIV) - -#define S_PERREFEN 0 -#define V_PERREFEN(x) ((x) << S_PERREFEN) -#define F_PERREFEN V_PERREFEN(1U) - -#define A_MC7_DLL 0x11c - -#define S_DLLENB 1 -#define V_DLLENB(x) ((x) << S_DLLENB) -#define F_DLLENB V_DLLENB(1U) - -#define S_DLLRST 0 -#define V_DLLRST(x) ((x) << S_DLLRST) -#define F_DLLRST V_DLLRST(1U) - -#define A_MC7_PARM 0x120 - -#define S_ACTTOPREDLY 26 -#define M_ACTTOPREDLY 0xf -#define V_ACTTOPREDLY(x) ((x) << S_ACTTOPREDLY) - -#define S_ACTTORDWRDLY 23 -#define M_ACTTORDWRDLY 0x7 -#define V_ACTTORDWRDLY(x) ((x) << S_ACTTORDWRDLY) - -#define S_PRECYC 20 -#define M_PRECYC 0x7 -#define V_PRECYC(x) ((x) << S_PRECYC) - -#define S_REFCYC 13 -#define M_REFCYC 0x7f -#define V_REFCYC(x) ((x) << S_REFCYC) - -#define S_BKCYC 8 -#define M_BKCYC 0x1f -#define V_BKCYC(x) ((x) << S_BKCYC) - -#define S_WRTORDDLY 4 -#define M_WRTORDDLY 0xf -#define V_WRTORDDLY(x) ((x) << S_WRTORDDLY) - -#define S_RDTOWRDLY 0 -#define M_RDTOWRDLY 0xf -#define V_RDTOWRDLY(x) ((x) << S_RDTOWRDLY) - -#define A_MC7_CAL 0x128 - -#define S_BUSY 31 -#define V_BUSY(x) ((x) << S_BUSY) -#define F_BUSY V_BUSY(1U) - -#define S_BUSY 31 -#define V_BUSY(x) ((x) << S_BUSY) -#define F_BUSY V_BUSY(1U) - -#define S_CAL_FAULT 30 -#define V_CAL_FAULT(x) ((x) << S_CAL_FAULT) -#define F_CAL_FAULT V_CAL_FAULT(1U) - -#define S_SGL_CAL_EN 20 -#define V_SGL_CAL_EN(x) ((x) << S_SGL_CAL_EN) -#define F_SGL_CAL_EN V_SGL_CAL_EN(1U) - -#define A_MC7_ERR_ADDR 0x12c - -#define A_MC7_ECC 0x130 - -#define S_ECCCHKEN 1 -#define V_ECCCHKEN(x) ((x) << S_ECCCHKEN) -#define F_ECCCHKEN V_ECCCHKEN(1U) - -#define S_ECCGENEN 0 -#define V_ECCGENEN(x) ((x) << S_ECCGENEN) -#define F_ECCGENEN V_ECCGENEN(1U) - -#define A_MC7_CE_ADDR 0x134 - -#define A_MC7_CE_DATA0 0x138 - -#define A_MC7_CE_DATA1 0x13c - -#define A_MC7_CE_DATA2 0x140 - -#define S_DATA 0 -#define M_DATA 0xff - -#define G_DATA(x) (((x) >> S_DATA) & M_DATA) - -#define A_MC7_UE_ADDR 0x144 - -#define A_MC7_UE_DATA0 0x148 - -#define A_MC7_UE_DATA1 0x14c - -#define A_MC7_UE_DATA2 0x150 - -#define A_MC7_BD_ADDR 0x154 - -#define S_ADDR 3 - -#define M_ADDR 0x1fffffff - -#define A_MC7_BD_DATA0 0x158 - -#define A_MC7_BD_DATA1 0x15c - -#define A_MC7_BD_OP 0x164 - -#define S_OP 0 - -#define V_OP(x) ((x) << S_OP) -#define F_OP V_OP(1U) - -#define F_OP V_OP(1U) -#define A_SF_OP 0x6dc - -#define A_MC7_BIST_ADDR_BEG 0x168 - -#define A_MC7_BIST_ADDR_END 0x16c - -#define A_MC7_BIST_DATA 0x170 - -#define A_MC7_BIST_OP 0x174 - -#define S_CONT 3 -#define V_CONT(x) ((x) << S_CONT) -#define F_CONT V_CONT(1U) - -#define F_CONT V_CONT(1U) - -#define A_MC7_INT_ENABLE 0x178 - -#define S_AE 17 -#define V_AE(x) ((x) << S_AE) -#define F_AE V_AE(1U) - -#define S_PE 2 -#define M_PE 0x7fff - -#define V_PE(x) ((x) << S_PE) - -#define G_PE(x) (((x) >> S_PE) & M_PE) - -#define S_UE 1 -#define V_UE(x) ((x) << S_UE) -#define F_UE V_UE(1U) - -#define S_CE 0 -#define V_CE(x) ((x) << S_CE) -#define F_CE V_CE(1U) - -#define A_MC7_INT_CAUSE 0x17c - -#define MC7_PMTX_BASE_ADDR 0x180 - -#define MC7_CM_BASE_ADDR 0x200 - -#define A_CIM_BOOT_CFG 0x280 - -#define S_BOOTADDR 2 -#define M_BOOTADDR 0x3fffffff -#define V_BOOTADDR(x) ((x) << S_BOOTADDR) - -#define A_CIM_SDRAM_BASE_ADDR 0x28c - -#define A_CIM_SDRAM_ADDR_SIZE 0x290 - -#define A_CIM_HOST_INT_ENABLE 0x298 - -#define A_CIM_HOST_INT_CAUSE 0x29c - -#define S_BLKWRPLINT 12 -#define V_BLKWRPLINT(x) ((x) << S_BLKWRPLINT) -#define F_BLKWRPLINT V_BLKWRPLINT(1U) - -#define S_BLKRDPLINT 11 -#define V_BLKRDPLINT(x) ((x) << S_BLKRDPLINT) -#define F_BLKRDPLINT V_BLKRDPLINT(1U) - -#define S_BLKWRCTLINT 10 -#define V_BLKWRCTLINT(x) ((x) << S_BLKWRCTLINT) -#define F_BLKWRCTLINT V_BLKWRCTLINT(1U) - -#define S_BLKRDCTLINT 9 -#define V_BLKRDCTLINT(x) ((x) << S_BLKRDCTLINT) -#define F_BLKRDCTLINT V_BLKRDCTLINT(1U) - -#define S_BLKWRFLASHINT 8 -#define V_BLKWRFLASHINT(x) ((x) << S_BLKWRFLASHINT) -#define F_BLKWRFLASHINT V_BLKWRFLASHINT(1U) - -#define S_BLKRDFLASHINT 7 -#define V_BLKRDFLASHINT(x) ((x) << S_BLKRDFLASHINT) -#define F_BLKRDFLASHINT V_BLKRDFLASHINT(1U) - -#define S_SGLWRFLASHINT 6 -#define V_SGLWRFLASHINT(x) ((x) << S_SGLWRFLASHINT) -#define F_SGLWRFLASHINT V_SGLWRFLASHINT(1U) - -#define S_WRBLKFLASHINT 5 -#define V_WRBLKFLASHINT(x) ((x) << S_WRBLKFLASHINT) -#define F_WRBLKFLASHINT V_WRBLKFLASHINT(1U) - -#define S_BLKWRBOOTINT 4 -#define V_BLKWRBOOTINT(x) ((x) << S_BLKWRBOOTINT) -#define F_BLKWRBOOTINT V_BLKWRBOOTINT(1U) - -#define S_FLASHRANGEINT 2 -#define V_FLASHRANGEINT(x) ((x) << S_FLASHRANGEINT) -#define F_FLASHRANGEINT V_FLASHRANGEINT(1U) - -#define S_SDRAMRANGEINT 1 -#define V_SDRAMRANGEINT(x) ((x) << S_SDRAMRANGEINT) -#define F_SDRAMRANGEINT V_SDRAMRANGEINT(1U) - -#define S_RSVDSPACEINT 0 -#define V_RSVDSPACEINT(x) ((x) << S_RSVDSPACEINT) -#define F_RSVDSPACEINT V_RSVDSPACEINT(1U) - -#define A_CIM_HOST_ACC_CTRL 0x2b0 - -#define S_HOSTBUSY 17 -#define V_HOSTBUSY(x) ((x) << S_HOSTBUSY) -#define F_HOSTBUSY V_HOSTBUSY(1U) - -#define A_CIM_HOST_ACC_DATA 0x2b4 - -#define A_TP_IN_CONFIG 0x300 - -#define S_NICMODE 14 -#define V_NICMODE(x) ((x) << S_NICMODE) -#define F_NICMODE V_NICMODE(1U) - -#define F_NICMODE V_NICMODE(1U) - -#define S_IPV6ENABLE 15 -#define V_IPV6ENABLE(x) ((x) << S_IPV6ENABLE) -#define F_IPV6ENABLE V_IPV6ENABLE(1U) - -#define A_TP_OUT_CONFIG 0x304 - -#define S_VLANEXTRACTIONENABLE 12 - -#define A_TP_GLOBAL_CONFIG 0x308 - -#define S_TXPACINGENABLE 24 -#define V_TXPACINGENABLE(x) ((x) << S_TXPACINGENABLE) -#define F_TXPACINGENABLE V_TXPACINGENABLE(1U) - -#define S_PATHMTU 15 -#define V_PATHMTU(x) ((x) << S_PATHMTU) -#define F_PATHMTU V_PATHMTU(1U) - -#define S_IPCHECKSUMOFFLOAD 13 -#define V_IPCHECKSUMOFFLOAD(x) ((x) << S_IPCHECKSUMOFFLOAD) -#define F_IPCHECKSUMOFFLOAD V_IPCHECKSUMOFFLOAD(1U) - -#define S_UDPCHECKSUMOFFLOAD 12 -#define V_UDPCHECKSUMOFFLOAD(x) ((x) << S_UDPCHECKSUMOFFLOAD) -#define F_UDPCHECKSUMOFFLOAD V_UDPCHECKSUMOFFLOAD(1U) - -#define S_TCPCHECKSUMOFFLOAD 11 -#define V_TCPCHECKSUMOFFLOAD(x) ((x) << S_TCPCHECKSUMOFFLOAD) -#define F_TCPCHECKSUMOFFLOAD V_TCPCHECKSUMOFFLOAD(1U) - -#define S_IPTTL 0 -#define M_IPTTL 0xff -#define V_IPTTL(x) ((x) << S_IPTTL) - -#define A_TP_CMM_MM_BASE 0x314 - -#define A_TP_CMM_TIMER_BASE 0x318 - -#define S_CMTIMERMAXNUM 28 -#define M_CMTIMERMAXNUM 0x3 -#define V_CMTIMERMAXNUM(x) ((x) << S_CMTIMERMAXNUM) - -#define A_TP_PMM_SIZE 0x31c - -#define A_TP_PMM_TX_BASE 0x320 - -#define A_TP_PMM_RX_BASE 0x328 - -#define A_TP_PMM_RX_PAGE_SIZE 0x32c - -#define A_TP_PMM_RX_MAX_PAGE 0x330 - -#define A_TP_PMM_TX_PAGE_SIZE 0x334 - -#define A_TP_PMM_TX_MAX_PAGE 0x338 - -#define A_TP_TCP_OPTIONS 0x340 - -#define S_MTUDEFAULT 16 -#define M_MTUDEFAULT 0xffff -#define V_MTUDEFAULT(x) ((x) << S_MTUDEFAULT) - -#define S_MTUENABLE 10 -#define V_MTUENABLE(x) ((x) << S_MTUENABLE) -#define F_MTUENABLE V_MTUENABLE(1U) - -#define S_SACKRX 8 -#define V_SACKRX(x) ((x) << S_SACKRX) -#define F_SACKRX V_SACKRX(1U) - -#define S_SACKMODE 4 - -#define M_SACKMODE 0x3 - -#define V_SACKMODE(x) ((x) << S_SACKMODE) - -#define S_WINDOWSCALEMODE 2 -#define M_WINDOWSCALEMODE 0x3 -#define V_WINDOWSCALEMODE(x) ((x) << S_WINDOWSCALEMODE) - -#define S_TIMESTAMPSMODE 0 - -#define M_TIMESTAMPSMODE 0x3 - -#define V_TIMESTAMPSMODE(x) ((x) << S_TIMESTAMPSMODE) - -#define A_TP_DACK_CONFIG 0x344 - -#define S_AUTOSTATE3 30 -#define M_AUTOSTATE3 0x3 -#define V_AUTOSTATE3(x) ((x) << S_AUTOSTATE3) - -#define S_AUTOSTATE2 28 -#define M_AUTOSTATE2 0x3 -#define V_AUTOSTATE2(x) ((x) << S_AUTOSTATE2) - -#define S_AUTOSTATE1 26 -#define M_AUTOSTATE1 0x3 -#define V_AUTOSTATE1(x) ((x) << S_AUTOSTATE1) - -#define S_BYTETHRESHOLD 5 -#define M_BYTETHRESHOLD 0xfffff -#define V_BYTETHRESHOLD(x) ((x) << S_BYTETHRESHOLD) - -#define S_MSSTHRESHOLD 3 -#define M_MSSTHRESHOLD 0x3 -#define V_MSSTHRESHOLD(x) ((x) << S_MSSTHRESHOLD) - -#define S_AUTOCAREFUL 2 -#define V_AUTOCAREFUL(x) ((x) << S_AUTOCAREFUL) -#define F_AUTOCAREFUL V_AUTOCAREFUL(1U) - -#define S_AUTOENABLE 1 -#define V_AUTOENABLE(x) ((x) << S_AUTOENABLE) -#define F_AUTOENABLE V_AUTOENABLE(1U) - -#define S_DACK_MODE 0 -#define V_DACK_MODE(x) ((x) << S_DACK_MODE) -#define F_DACK_MODE V_DACK_MODE(1U) - -#define A_TP_PC_CONFIG 0x348 - -#define S_TXTOSQUEUEMAPMODE 26 -#define V_TXTOSQUEUEMAPMODE(x) ((x) << S_TXTOSQUEUEMAPMODE) -#define F_TXTOSQUEUEMAPMODE V_TXTOSQUEUEMAPMODE(1U) - -#define S_ENABLEEPCMDAFULL 23 -#define V_ENABLEEPCMDAFULL(x) ((x) << S_ENABLEEPCMDAFULL) -#define F_ENABLEEPCMDAFULL V_ENABLEEPCMDAFULL(1U) - -#define S_MODULATEUNIONMODE 22 -#define V_MODULATEUNIONMODE(x) ((x) << S_MODULATEUNIONMODE) -#define F_MODULATEUNIONMODE V_MODULATEUNIONMODE(1U) - -#define S_TXDEFERENABLE 20 -#define V_TXDEFERENABLE(x) ((x) << S_TXDEFERENABLE) -#define F_TXDEFERENABLE V_TXDEFERENABLE(1U) - -#define S_RXCONGESTIONMODE 19 -#define V_RXCONGESTIONMODE(x) ((x) << S_RXCONGESTIONMODE) -#define F_RXCONGESTIONMODE V_RXCONGESTIONMODE(1U) - -#define S_HEARBEATDACK 16 -#define V_HEARBEATDACK(x) ((x) << S_HEARBEATDACK) -#define F_HEARBEATDACK V_HEARBEATDACK(1U) - -#define S_TXCONGESTIONMODE 15 -#define V_TXCONGESTIONMODE(x) ((x) << S_TXCONGESTIONMODE) -#define F_TXCONGESTIONMODE V_TXCONGESTIONMODE(1U) - -#define S_ENABLEOCSPIFULL 30 -#define V_ENABLEOCSPIFULL(x) ((x) << S_ENABLEOCSPIFULL) -#define F_ENABLEOCSPIFULL V_ENABLEOCSPIFULL(1U) - -#define S_LOCKTID 28 -#define V_LOCKTID(x) ((x) << S_LOCKTID) -#define F_LOCKTID V_LOCKTID(1U) - -#define A_TP_PC_CONFIG2 0x34c - -#define S_CHDRAFULL 4 -#define V_CHDRAFULL(x) ((x) << S_CHDRAFULL) -#define F_CHDRAFULL V_CHDRAFULL(1U) - -#define A_TP_TCP_BACKOFF_REG0 0x350 - -#define A_TP_TCP_BACKOFF_REG1 0x354 - -#define A_TP_TCP_BACKOFF_REG2 0x358 - -#define A_TP_TCP_BACKOFF_REG3 0x35c - -#define A_TP_PARA_REG2 0x368 - -#define S_MAXRXDATA 16 -#define M_MAXRXDATA 0xffff -#define V_MAXRXDATA(x) ((x) << S_MAXRXDATA) - -#define S_RXCOALESCESIZE 0 -#define M_RXCOALESCESIZE 0xffff -#define V_RXCOALESCESIZE(x) ((x) << S_RXCOALESCESIZE) - -#define A_TP_PARA_REG3 0x36c - -#define S_TXDATAACKIDX 16 -#define M_TXDATAACKIDX 0xf - -#define V_TXDATAACKIDX(x) ((x) << S_TXDATAACKIDX) - -#define S_TXPACEAUTOSTRICT 10 -#define V_TXPACEAUTOSTRICT(x) ((x) << S_TXPACEAUTOSTRICT) -#define F_TXPACEAUTOSTRICT V_TXPACEAUTOSTRICT(1U) - -#define S_TXPACEFIXED 9 -#define V_TXPACEFIXED(x) ((x) << S_TXPACEFIXED) -#define F_TXPACEFIXED V_TXPACEFIXED(1U) - -#define S_TXPACEAUTO 8 -#define V_TXPACEAUTO(x) ((x) << S_TXPACEAUTO) -#define F_TXPACEAUTO V_TXPACEAUTO(1U) - -#define S_RXCOALESCEENABLE 1 -#define V_RXCOALESCEENABLE(x) ((x) << S_RXCOALESCEENABLE) -#define F_RXCOALESCEENABLE V_RXCOALESCEENABLE(1U) - -#define S_RXCOALESCEPSHEN 0 -#define V_RXCOALESCEPSHEN(x) ((x) << S_RXCOALESCEPSHEN) -#define F_RXCOALESCEPSHEN V_RXCOALESCEPSHEN(1U) - -#define A_TP_PARA_REG4 0x370 - -#define A_TP_PARA_REG6 0x378 - -#define S_T3A_ENABLEESND 13 -#define V_T3A_ENABLEESND(x) ((x) << S_T3A_ENABLEESND) -#define F_T3A_ENABLEESND V_T3A_ENABLEESND(1U) - -#define S_ENABLEESND 11 -#define V_ENABLEESND(x) ((x) << S_ENABLEESND) -#define F_ENABLEESND V_ENABLEESND(1U) - -#define A_TP_PARA_REG7 0x37c - -#define S_PMMAXXFERLEN1 16 -#define M_PMMAXXFERLEN1 0xffff -#define V_PMMAXXFERLEN1(x) ((x) << S_PMMAXXFERLEN1) - -#define S_PMMAXXFERLEN0 0 -#define M_PMMAXXFERLEN0 0xffff -#define V_PMMAXXFERLEN0(x) ((x) << S_PMMAXXFERLEN0) - -#define A_TP_TIMER_RESOLUTION 0x390 - -#define S_TIMERRESOLUTION 16 -#define M_TIMERRESOLUTION 0xff -#define V_TIMERRESOLUTION(x) ((x) << S_TIMERRESOLUTION) - -#define S_TIMESTAMPRESOLUTION 8 -#define M_TIMESTAMPRESOLUTION 0xff -#define V_TIMESTAMPRESOLUTION(x) ((x) << S_TIMESTAMPRESOLUTION) - -#define S_DELAYEDACKRESOLUTION 0 -#define M_DELAYEDACKRESOLUTION 0xff -#define V_DELAYEDACKRESOLUTION(x) ((x) << S_DELAYEDACKRESOLUTION) - -#define A_TP_MSL 0x394 - -#define A_TP_RXT_MIN 0x398 - -#define A_TP_RXT_MAX 0x39c - -#define A_TP_PERS_MIN 0x3a0 - -#define A_TP_PERS_MAX 0x3a4 - -#define A_TP_KEEP_IDLE 0x3a8 - -#define A_TP_KEEP_INTVL 0x3ac - -#define A_TP_INIT_SRTT 0x3b0 - -#define A_TP_DACK_TIMER 0x3b4 - -#define A_TP_FINWAIT2_TIMER 0x3b8 - -#define A_TP_SHIFT_CNT 0x3c0 - -#define S_SYNSHIFTMAX 24 - -#define M_SYNSHIFTMAX 0xff - -#define V_SYNSHIFTMAX(x) ((x) << S_SYNSHIFTMAX) - -#define S_RXTSHIFTMAXR1 20 - -#define M_RXTSHIFTMAXR1 0xf - -#define V_RXTSHIFTMAXR1(x) ((x) << S_RXTSHIFTMAXR1) - -#define S_RXTSHIFTMAXR2 16 - -#define M_RXTSHIFTMAXR2 0xf - -#define V_RXTSHIFTMAXR2(x) ((x) << S_RXTSHIFTMAXR2) - -#define S_PERSHIFTBACKOFFMAX 12 -#define M_PERSHIFTBACKOFFMAX 0xf -#define V_PERSHIFTBACKOFFMAX(x) ((x) << S_PERSHIFTBACKOFFMAX) - -#define S_PERSHIFTMAX 8 -#define M_PERSHIFTMAX 0xf -#define V_PERSHIFTMAX(x) ((x) << S_PERSHIFTMAX) - -#define S_KEEPALIVEMAX 0 - -#define M_KEEPALIVEMAX 0xff - -#define V_KEEPALIVEMAX(x) ((x) << S_KEEPALIVEMAX) - -#define A_TP_MTU_PORT_TABLE 0x3d0 - -#define A_TP_CCTRL_TABLE 0x3dc - -#define A_TP_MTU_TABLE 0x3e4 - -#define A_TP_RSS_MAP_TABLE 0x3e8 - -#define A_TP_RSS_LKP_TABLE 0x3ec - -#define A_TP_RSS_CONFIG 0x3f0 - -#define S_TNL4TUPEN 29 -#define V_TNL4TUPEN(x) ((x) << S_TNL4TUPEN) -#define F_TNL4TUPEN V_TNL4TUPEN(1U) - -#define S_TNL2TUPEN 28 -#define V_TNL2TUPEN(x) ((x) << S_TNL2TUPEN) -#define F_TNL2TUPEN V_TNL2TUPEN(1U) - -#define S_TNLPRTEN 26 -#define V_TNLPRTEN(x) ((x) << S_TNLPRTEN) -#define F_TNLPRTEN V_TNLPRTEN(1U) - -#define S_TNLMAPEN 25 -#define V_TNLMAPEN(x) ((x) << S_TNLMAPEN) -#define F_TNLMAPEN V_TNLMAPEN(1U) - -#define S_TNLLKPEN 24 -#define V_TNLLKPEN(x) ((x) << S_TNLLKPEN) -#define F_TNLLKPEN V_TNLLKPEN(1U) - -#define S_RRCPLCPUSIZE 4 -#define M_RRCPLCPUSIZE 0x7 -#define V_RRCPLCPUSIZE(x) ((x) << S_RRCPLCPUSIZE) - -#define S_RQFEEDBACKENABLE 3 -#define V_RQFEEDBACKENABLE(x) ((x) << S_RQFEEDBACKENABLE) -#define F_RQFEEDBACKENABLE V_RQFEEDBACKENABLE(1U) - -#define S_DISABLE 0 - -#define A_TP_TM_PIO_ADDR 0x418 - -#define A_TP_TM_PIO_DATA 0x41c - -#define A_TP_TX_MOD_QUE_TABLE 0x420 - -#define A_TP_TX_RESOURCE_LIMIT 0x424 - -#define A_TP_TX_MOD_QUEUE_REQ_MAP 0x428 - -#define S_TX_MOD_QUEUE_REQ_MAP 0 -#define M_TX_MOD_QUEUE_REQ_MAP 0xff -#define V_TX_MOD_QUEUE_REQ_MAP(x) ((x) << S_TX_MOD_QUEUE_REQ_MAP) - -#define A_TP_TX_MOD_QUEUE_WEIGHT1 0x42c - -#define A_TP_TX_MOD_QUEUE_WEIGHT0 0x430 - -#define A_TP_MOD_CHANNEL_WEIGHT 0x434 - -#define A_TP_PIO_ADDR 0x440 - -#define A_TP_PIO_DATA 0x444 - -#define A_TP_RESET 0x44c - -#define S_FLSTINITENABLE 1 -#define V_FLSTINITENABLE(x) ((x) << S_FLSTINITENABLE) -#define F_FLSTINITENABLE V_FLSTINITENABLE(1U) - -#define S_TPRESET 0 -#define V_TPRESET(x) ((x) << S_TPRESET) -#define F_TPRESET V_TPRESET(1U) - -#define A_TP_CMM_MM_RX_FLST_BASE 0x460 - -#define A_TP_CMM_MM_TX_FLST_BASE 0x464 - -#define A_TP_CMM_MM_PS_FLST_BASE 0x468 - -#define A_TP_MIB_INDEX 0x450 - -#define A_TP_MIB_RDATA 0x454 - -#define A_TP_CMM_MM_MAX_PSTRUCT 0x46c - -#define A_TP_INT_ENABLE 0x470 - -#define A_TP_INT_CAUSE 0x474 - -#define A_TP_TX_MOD_Q1_Q0_RATE_LIMIT 0x8 - -#define A_TP_TX_DROP_CFG_CH0 0x12b - -#define A_TP_TX_DROP_MODE 0x12f - -#define A_TP_EGRESS_CONFIG 0x145 - -#define S_REWRITEFORCETOSIZE 0 -#define V_REWRITEFORCETOSIZE(x) ((x) << S_REWRITEFORCETOSIZE) -#define F_REWRITEFORCETOSIZE V_REWRITEFORCETOSIZE(1U) - -#define A_TP_TX_TRC_KEY0 0x20 - -#define A_TP_RX_TRC_KEY0 0x120 - -#define A_ULPRX_CTL 0x500 - -#define S_ROUND_ROBIN 4 -#define V_ROUND_ROBIN(x) ((x) << S_ROUND_ROBIN) -#define F_ROUND_ROBIN V_ROUND_ROBIN(1U) - -#define A_ULPRX_INT_ENABLE 0x504 - -#define S_PARERR 0 -#define V_PARERR(x) ((x) << S_PARERR) -#define F_PARERR V_PARERR(1U) - -#define A_ULPRX_INT_CAUSE 0x508 - -#define A_ULPRX_ISCSI_LLIMIT 0x50c - -#define A_ULPRX_ISCSI_ULIMIT 0x510 - -#define A_ULPRX_ISCSI_TAGMASK 0x514 - -#define A_ULPRX_TDDP_LLIMIT 0x51c - -#define A_ULPRX_TDDP_ULIMIT 0x520 - -#define A_ULPRX_STAG_LLIMIT 0x52c - -#define A_ULPRX_STAG_ULIMIT 0x530 - -#define A_ULPRX_RQ_LLIMIT 0x534 -#define A_ULPRX_RQ_LLIMIT 0x534 - -#define A_ULPRX_RQ_ULIMIT 0x538 -#define A_ULPRX_RQ_ULIMIT 0x538 - -#define A_ULPRX_PBL_LLIMIT 0x53c - -#define A_ULPRX_PBL_ULIMIT 0x540 -#define A_ULPRX_PBL_ULIMIT 0x540 - -#define A_ULPRX_TDDP_TAGMASK 0x524 - -#define A_ULPRX_RQ_LLIMIT 0x534 -#define A_ULPRX_RQ_LLIMIT 0x534 - -#define A_ULPRX_RQ_ULIMIT 0x538 -#define A_ULPRX_RQ_ULIMIT 0x538 - -#define A_ULPRX_PBL_ULIMIT 0x540 -#define A_ULPRX_PBL_ULIMIT 0x540 - -#define A_ULPTX_CONFIG 0x580 - -#define S_CFG_RR_ARB 0 -#define V_CFG_RR_ARB(x) ((x) << S_CFG_RR_ARB) -#define F_CFG_RR_ARB V_CFG_RR_ARB(1U) - -#define A_ULPTX_INT_ENABLE 0x584 - -#define S_PBL_BOUND_ERR_CH1 1 -#define V_PBL_BOUND_ERR_CH1(x) ((x) << S_PBL_BOUND_ERR_CH1) -#define F_PBL_BOUND_ERR_CH1 V_PBL_BOUND_ERR_CH1(1U) - -#define S_PBL_BOUND_ERR_CH0 0 -#define V_PBL_BOUND_ERR_CH0(x) ((x) << S_PBL_BOUND_ERR_CH0) -#define F_PBL_BOUND_ERR_CH0 V_PBL_BOUND_ERR_CH0(1U) - -#define A_ULPTX_INT_CAUSE 0x588 - -#define A_ULPTX_TPT_LLIMIT 0x58c - -#define A_ULPTX_TPT_ULIMIT 0x590 - -#define A_ULPTX_PBL_LLIMIT 0x594 - -#define A_ULPTX_PBL_ULIMIT 0x598 - -#define A_ULPTX_DMA_WEIGHT 0x5ac - -#define S_D1_WEIGHT 16 -#define M_D1_WEIGHT 0xffff -#define V_D1_WEIGHT(x) ((x) << S_D1_WEIGHT) - -#define S_D0_WEIGHT 0 -#define M_D0_WEIGHT 0xffff -#define V_D0_WEIGHT(x) ((x) << S_D0_WEIGHT) - -#define A_PM1_RX_CFG 0x5c0 - -#define A_PM1_RX_INT_ENABLE 0x5d8 - -#define S_ZERO_E_CMD_ERROR 18 -#define V_ZERO_E_CMD_ERROR(x) ((x) << S_ZERO_E_CMD_ERROR) -#define F_ZERO_E_CMD_ERROR V_ZERO_E_CMD_ERROR(1U) - -#define S_IESPI0_FIFO2X_RX_FRAMING_ERROR 17 -#define V_IESPI0_FIFO2X_RX_FRAMING_ERROR(x) ((x) << S_IESPI0_FIFO2X_RX_FRAMING_ERROR) -#define F_IESPI0_FIFO2X_RX_FRAMING_ERROR V_IESPI0_FIFO2X_RX_FRAMING_ERROR(1U) - -#define S_IESPI1_FIFO2X_RX_FRAMING_ERROR 16 -#define V_IESPI1_FIFO2X_RX_FRAMING_ERROR(x) ((x) << S_IESPI1_FIFO2X_RX_FRAMING_ERROR) -#define F_IESPI1_FIFO2X_RX_FRAMING_ERROR V_IESPI1_FIFO2X_RX_FRAMING_ERROR(1U) - -#define S_IESPI0_RX_FRAMING_ERROR 15 -#define V_IESPI0_RX_FRAMING_ERROR(x) ((x) << S_IESPI0_RX_FRAMING_ERROR) -#define F_IESPI0_RX_FRAMING_ERROR V_IESPI0_RX_FRAMING_ERROR(1U) - -#define S_IESPI1_RX_FRAMING_ERROR 14 -#define V_IESPI1_RX_FRAMING_ERROR(x) ((x) << S_IESPI1_RX_FRAMING_ERROR) -#define F_IESPI1_RX_FRAMING_ERROR V_IESPI1_RX_FRAMING_ERROR(1U) - -#define S_IESPI0_TX_FRAMING_ERROR 13 -#define V_IESPI0_TX_FRAMING_ERROR(x) ((x) << S_IESPI0_TX_FRAMING_ERROR) -#define F_IESPI0_TX_FRAMING_ERROR V_IESPI0_TX_FRAMING_ERROR(1U) - -#define S_IESPI1_TX_FRAMING_ERROR 12 -#define V_IESPI1_TX_FRAMING_ERROR(x) ((x) << S_IESPI1_TX_FRAMING_ERROR) -#define F_IESPI1_TX_FRAMING_ERROR V_IESPI1_TX_FRAMING_ERROR(1U) - -#define S_OCSPI0_RX_FRAMING_ERROR 11 -#define V_OCSPI0_RX_FRAMING_ERROR(x) ((x) << S_OCSPI0_RX_FRAMING_ERROR) -#define F_OCSPI0_RX_FRAMING_ERROR V_OCSPI0_RX_FRAMING_ERROR(1U) - -#define S_OCSPI1_RX_FRAMING_ERROR 10 -#define V_OCSPI1_RX_FRAMING_ERROR(x) ((x) << S_OCSPI1_RX_FRAMING_ERROR) -#define F_OCSPI1_RX_FRAMING_ERROR V_OCSPI1_RX_FRAMING_ERROR(1U) - -#define S_OCSPI0_TX_FRAMING_ERROR 9 -#define V_OCSPI0_TX_FRAMING_ERROR(x) ((x) << S_OCSPI0_TX_FRAMING_ERROR) -#define F_OCSPI0_TX_FRAMING_ERROR V_OCSPI0_TX_FRAMING_ERROR(1U) - -#define S_OCSPI1_TX_FRAMING_ERROR 8 -#define V_OCSPI1_TX_FRAMING_ERROR(x) ((x) << S_OCSPI1_TX_FRAMING_ERROR) -#define F_OCSPI1_TX_FRAMING_ERROR V_OCSPI1_TX_FRAMING_ERROR(1U) - -#define S_OCSPI0_OFIFO2X_TX_FRAMING_ERROR 7 -#define V_OCSPI0_OFIFO2X_TX_FRAMING_ERROR(x) ((x) << S_OCSPI0_OFIFO2X_TX_FRAMING_ERROR) -#define F_OCSPI0_OFIFO2X_TX_FRAMING_ERROR V_OCSPI0_OFIFO2X_TX_FRAMING_ERROR(1U) - -#define S_OCSPI1_OFIFO2X_TX_FRAMING_ERROR 6 -#define V_OCSPI1_OFIFO2X_TX_FRAMING_ERROR(x) ((x) << S_OCSPI1_OFIFO2X_TX_FRAMING_ERROR) -#define F_OCSPI1_OFIFO2X_TX_FRAMING_ERROR V_OCSPI1_OFIFO2X_TX_FRAMING_ERROR(1U) - -#define S_IESPI_PAR_ERROR 3 -#define M_IESPI_PAR_ERROR 0x7 - -#define V_IESPI_PAR_ERROR(x) ((x) << S_IESPI_PAR_ERROR) - -#define S_OCSPI_PAR_ERROR 0 -#define M_OCSPI_PAR_ERROR 0x7 - -#define V_OCSPI_PAR_ERROR(x) ((x) << S_OCSPI_PAR_ERROR) - -#define A_PM1_RX_INT_CAUSE 0x5dc - -#define A_PM1_TX_CFG 0x5e0 - -#define A_PM1_TX_INT_ENABLE 0x5f8 - -#define S_ZERO_C_CMD_ERROR 18 -#define V_ZERO_C_CMD_ERROR(x) ((x) << S_ZERO_C_CMD_ERROR) -#define F_ZERO_C_CMD_ERROR V_ZERO_C_CMD_ERROR(1U) - -#define S_ICSPI0_FIFO2X_RX_FRAMING_ERROR 17 -#define V_ICSPI0_FIFO2X_RX_FRAMING_ERROR(x) ((x) << S_ICSPI0_FIFO2X_RX_FRAMING_ERROR) -#define F_ICSPI0_FIFO2X_RX_FRAMING_ERROR V_ICSPI0_FIFO2X_RX_FRAMING_ERROR(1U) - -#define S_ICSPI1_FIFO2X_RX_FRAMING_ERROR 16 -#define V_ICSPI1_FIFO2X_RX_FRAMING_ERROR(x) ((x) << S_ICSPI1_FIFO2X_RX_FRAMING_ERROR) -#define F_ICSPI1_FIFO2X_RX_FRAMING_ERROR V_ICSPI1_FIFO2X_RX_FRAMING_ERROR(1U) - -#define S_ICSPI0_RX_FRAMING_ERROR 15 -#define V_ICSPI0_RX_FRAMING_ERROR(x) ((x) << S_ICSPI0_RX_FRAMING_ERROR) -#define F_ICSPI0_RX_FRAMING_ERROR V_ICSPI0_RX_FRAMING_ERROR(1U) - -#define S_ICSPI1_RX_FRAMING_ERROR 14 -#define V_ICSPI1_RX_FRAMING_ERROR(x) ((x) << S_ICSPI1_RX_FRAMING_ERROR) -#define F_ICSPI1_RX_FRAMING_ERROR V_ICSPI1_RX_FRAMING_ERROR(1U) - -#define S_ICSPI0_TX_FRAMING_ERROR 13 -#define V_ICSPI0_TX_FRAMING_ERROR(x) ((x) << S_ICSPI0_TX_FRAMING_ERROR) -#define F_ICSPI0_TX_FRAMING_ERROR V_ICSPI0_TX_FRAMING_ERROR(1U) - -#define S_ICSPI1_TX_FRAMING_ERROR 12 -#define V_ICSPI1_TX_FRAMING_ERROR(x) ((x) << S_ICSPI1_TX_FRAMING_ERROR) -#define F_ICSPI1_TX_FRAMING_ERROR V_ICSPI1_TX_FRAMING_ERROR(1U) - -#define S_OESPI0_RX_FRAMING_ERROR 11 -#define V_OESPI0_RX_FRAMING_ERROR(x) ((x) << S_OESPI0_RX_FRAMING_ERROR) -#define F_OESPI0_RX_FRAMING_ERROR V_OESPI0_RX_FRAMING_ERROR(1U) - -#define S_OESPI1_RX_FRAMING_ERROR 10 -#define V_OESPI1_RX_FRAMING_ERROR(x) ((x) << S_OESPI1_RX_FRAMING_ERROR) -#define F_OESPI1_RX_FRAMING_ERROR V_OESPI1_RX_FRAMING_ERROR(1U) - -#define S_OESPI0_TX_FRAMING_ERROR 9 -#define V_OESPI0_TX_FRAMING_ERROR(x) ((x) << S_OESPI0_TX_FRAMING_ERROR) -#define F_OESPI0_TX_FRAMING_ERROR V_OESPI0_TX_FRAMING_ERROR(1U) - -#define S_OESPI1_TX_FRAMING_ERROR 8 -#define V_OESPI1_TX_FRAMING_ERROR(x) ((x) << S_OESPI1_TX_FRAMING_ERROR) -#define F_OESPI1_TX_FRAMING_ERROR V_OESPI1_TX_FRAMING_ERROR(1U) - -#define S_OESPI0_OFIFO2X_TX_FRAMING_ERROR 7 -#define V_OESPI0_OFIFO2X_TX_FRAMING_ERROR(x) ((x) << S_OESPI0_OFIFO2X_TX_FRAMING_ERROR) -#define F_OESPI0_OFIFO2X_TX_FRAMING_ERROR V_OESPI0_OFIFO2X_TX_FRAMING_ERROR(1U) - -#define S_OESPI1_OFIFO2X_TX_FRAMING_ERROR 6 -#define V_OESPI1_OFIFO2X_TX_FRAMING_ERROR(x) ((x) << S_OESPI1_OFIFO2X_TX_FRAMING_ERROR) -#define F_OESPI1_OFIFO2X_TX_FRAMING_ERROR V_OESPI1_OFIFO2X_TX_FRAMING_ERROR(1U) - -#define S_ICSPI_PAR_ERROR 3 -#define M_ICSPI_PAR_ERROR 0x7 - -#define V_ICSPI_PAR_ERROR(x) ((x) << S_ICSPI_PAR_ERROR) - -#define S_OESPI_PAR_ERROR 0 -#define M_OESPI_PAR_ERROR 0x7 - -#define V_OESPI_PAR_ERROR(x) ((x) << S_OESPI_PAR_ERROR) - -#define A_PM1_TX_INT_CAUSE 0x5fc - -#define A_MPS_CFG 0x600 - -#define S_TPRXPORTEN 4 -#define V_TPRXPORTEN(x) ((x) << S_TPRXPORTEN) -#define F_TPRXPORTEN V_TPRXPORTEN(1U) - -#define S_TPTXPORT1EN 3 -#define V_TPTXPORT1EN(x) ((x) << S_TPTXPORT1EN) -#define F_TPTXPORT1EN V_TPTXPORT1EN(1U) - -#define S_TPTXPORT0EN 2 -#define V_TPTXPORT0EN(x) ((x) << S_TPTXPORT0EN) -#define F_TPTXPORT0EN V_TPTXPORT0EN(1U) - -#define S_PORT1ACTIVE 1 -#define V_PORT1ACTIVE(x) ((x) << S_PORT1ACTIVE) -#define F_PORT1ACTIVE V_PORT1ACTIVE(1U) - -#define S_PORT0ACTIVE 0 -#define V_PORT0ACTIVE(x) ((x) << S_PORT0ACTIVE) -#define F_PORT0ACTIVE V_PORT0ACTIVE(1U) - -#define S_ENFORCEPKT 11 -#define V_ENFORCEPKT(x) ((x) << S_ENFORCEPKT) -#define F_ENFORCEPKT V_ENFORCEPKT(1U) - -#define A_MPS_INT_ENABLE 0x61c - -#define S_MCAPARERRENB 6 -#define M_MCAPARERRENB 0x7 - -#define V_MCAPARERRENB(x) ((x) << S_MCAPARERRENB) - -#define S_RXTPPARERRENB 4 -#define M_RXTPPARERRENB 0x3 - -#define V_RXTPPARERRENB(x) ((x) << S_RXTPPARERRENB) - -#define S_TX1TPPARERRENB 2 -#define M_TX1TPPARERRENB 0x3 - -#define V_TX1TPPARERRENB(x) ((x) << S_TX1TPPARERRENB) - -#define S_TX0TPPARERRENB 0 -#define M_TX0TPPARERRENB 0x3 - -#define V_TX0TPPARERRENB(x) ((x) << S_TX0TPPARERRENB) - -#define A_MPS_INT_CAUSE 0x620 - -#define S_MCAPARERR 6 -#define M_MCAPARERR 0x7 - -#define V_MCAPARERR(x) ((x) << S_MCAPARERR) - -#define S_RXTPPARERR 4 -#define M_RXTPPARERR 0x3 - -#define V_RXTPPARERR(x) ((x) << S_RXTPPARERR) - -#define S_TX1TPPARERR 2 -#define M_TX1TPPARERR 0x3 - -#define V_TX1TPPARERR(x) ((x) << S_TX1TPPARERR) - -#define S_TX0TPPARERR 0 -#define M_TX0TPPARERR 0x3 - -#define V_TX0TPPARERR(x) ((x) << S_TX0TPPARERR) - -#define A_CPL_SWITCH_CNTRL 0x640 - -#define A_CPL_INTR_ENABLE 0x650 - -#define S_CIM_OVFL_ERROR 4 -#define V_CIM_OVFL_ERROR(x) ((x) << S_CIM_OVFL_ERROR) -#define F_CIM_OVFL_ERROR V_CIM_OVFL_ERROR(1U) - -#define S_TP_FRAMING_ERROR 3 -#define V_TP_FRAMING_ERROR(x) ((x) << S_TP_FRAMING_ERROR) -#define F_TP_FRAMING_ERROR V_TP_FRAMING_ERROR(1U) - -#define S_SGE_FRAMING_ERROR 2 -#define V_SGE_FRAMING_ERROR(x) ((x) << S_SGE_FRAMING_ERROR) -#define F_SGE_FRAMING_ERROR V_SGE_FRAMING_ERROR(1U) - -#define S_CIM_FRAMING_ERROR 1 -#define V_CIM_FRAMING_ERROR(x) ((x) << S_CIM_FRAMING_ERROR) -#define F_CIM_FRAMING_ERROR V_CIM_FRAMING_ERROR(1U) - -#define S_ZERO_SWITCH_ERROR 0 -#define V_ZERO_SWITCH_ERROR(x) ((x) << S_ZERO_SWITCH_ERROR) -#define F_ZERO_SWITCH_ERROR V_ZERO_SWITCH_ERROR(1U) - -#define A_CPL_INTR_CAUSE 0x654 - -#define A_CPL_MAP_TBL_DATA 0x65c - -#define A_SMB_GLOBAL_TIME_CFG 0x660 - -#define A_I2C_CFG 0x6a0 - -#define S_I2C_CLKDIV 0 -#define M_I2C_CLKDIV 0xfff -#define V_I2C_CLKDIV(x) ((x) << S_I2C_CLKDIV) - -#define A_MI1_CFG 0x6b0 - -#define S_CLKDIV 5 -#define M_CLKDIV 0xff -#define V_CLKDIV(x) ((x) << S_CLKDIV) - -#define S_ST 3 - -#define M_ST 0x3 - -#define V_ST(x) ((x) << S_ST) - -#define G_ST(x) (((x) >> S_ST) & M_ST) - -#define S_PREEN 2 -#define V_PREEN(x) ((x) << S_PREEN) -#define F_PREEN V_PREEN(1U) - -#define S_MDIINV 1 -#define V_MDIINV(x) ((x) << S_MDIINV) -#define F_MDIINV V_MDIINV(1U) - -#define S_MDIEN 0 -#define V_MDIEN(x) ((x) << S_MDIEN) -#define F_MDIEN V_MDIEN(1U) - -#define A_MI1_ADDR 0x6b4 - -#define S_PHYADDR 5 -#define M_PHYADDR 0x1f -#define V_PHYADDR(x) ((x) << S_PHYADDR) - -#define S_REGADDR 0 -#define M_REGADDR 0x1f -#define V_REGADDR(x) ((x) << S_REGADDR) - -#define A_MI1_DATA 0x6b8 - -#define A_MI1_OP 0x6bc - -#define S_MDI_OP 0 -#define M_MDI_OP 0x3 -#define V_MDI_OP(x) ((x) << S_MDI_OP) - -#define A_SF_DATA 0x6d8 - -#define A_SF_OP 0x6dc - -#define S_BYTECNT 1 -#define M_BYTECNT 0x3 -#define V_BYTECNT(x) ((x) << S_BYTECNT) - -#define A_PL_INT_ENABLE0 0x6e0 - -#define S_T3DBG 23 -#define V_T3DBG(x) ((x) << S_T3DBG) -#define F_T3DBG V_T3DBG(1U) - -#define S_XGMAC0_1 20 -#define V_XGMAC0_1(x) ((x) << S_XGMAC0_1) -#define F_XGMAC0_1 V_XGMAC0_1(1U) - -#define S_XGMAC0_0 19 -#define V_XGMAC0_0(x) ((x) << S_XGMAC0_0) -#define F_XGMAC0_0 V_XGMAC0_0(1U) - -#define S_MC5A 18 -#define V_MC5A(x) ((x) << S_MC5A) -#define F_MC5A V_MC5A(1U) - -#define S_CPL_SWITCH 12 -#define V_CPL_SWITCH(x) ((x) << S_CPL_SWITCH) -#define F_CPL_SWITCH V_CPL_SWITCH(1U) - -#define S_MPS0 11 -#define V_MPS0(x) ((x) << S_MPS0) -#define F_MPS0 V_MPS0(1U) - -#define S_PM1_TX 10 -#define V_PM1_TX(x) ((x) << S_PM1_TX) -#define F_PM1_TX V_PM1_TX(1U) - -#define S_PM1_RX 9 -#define V_PM1_RX(x) ((x) << S_PM1_RX) -#define F_PM1_RX V_PM1_RX(1U) - -#define S_ULP2_TX 8 -#define V_ULP2_TX(x) ((x) << S_ULP2_TX) -#define F_ULP2_TX V_ULP2_TX(1U) - -#define S_ULP2_RX 7 -#define V_ULP2_RX(x) ((x) << S_ULP2_RX) -#define F_ULP2_RX V_ULP2_RX(1U) - -#define S_TP1 6 -#define V_TP1(x) ((x) << S_TP1) -#define F_TP1 V_TP1(1U) - -#define S_CIM 5 -#define V_CIM(x) ((x) << S_CIM) -#define F_CIM V_CIM(1U) - -#define S_MC7_CM 4 -#define V_MC7_CM(x) ((x) << S_MC7_CM) -#define F_MC7_CM V_MC7_CM(1U) - -#define S_MC7_PMTX 3 -#define V_MC7_PMTX(x) ((x) << S_MC7_PMTX) -#define F_MC7_PMTX V_MC7_PMTX(1U) - -#define S_MC7_PMRX 2 -#define V_MC7_PMRX(x) ((x) << S_MC7_PMRX) -#define F_MC7_PMRX V_MC7_PMRX(1U) - -#define S_PCIM0 1 -#define V_PCIM0(x) ((x) << S_PCIM0) -#define F_PCIM0 V_PCIM0(1U) - -#define S_SGE3 0 -#define V_SGE3(x) ((x) << S_SGE3) -#define F_SGE3 V_SGE3(1U) - -#define A_PL_INT_CAUSE0 0x6e4 - -#define A_PL_RST 0x6f0 - -#define S_CRSTWRM 1 -#define V_CRSTWRM(x) ((x) << S_CRSTWRM) -#define F_CRSTWRM V_CRSTWRM(1U) - -#define A_PL_REV 0x6f4 - -#define A_PL_CLI 0x6f8 - -#define A_MC5_DB_CONFIG 0x704 - -#define S_TMTYPEHI 30 -#define V_TMTYPEHI(x) ((x) << S_TMTYPEHI) -#define F_TMTYPEHI V_TMTYPEHI(1U) - -#define S_TMPARTSIZE 28 -#define M_TMPARTSIZE 0x3 -#define V_TMPARTSIZE(x) ((x) << S_TMPARTSIZE) -#define G_TMPARTSIZE(x) (((x) >> S_TMPARTSIZE) & M_TMPARTSIZE) - -#define S_TMTYPE 26 -#define M_TMTYPE 0x3 -#define V_TMTYPE(x) ((x) << S_TMTYPE) -#define G_TMTYPE(x) (((x) >> S_TMTYPE) & M_TMTYPE) - -#define S_COMPEN 17 -#define V_COMPEN(x) ((x) << S_COMPEN) -#define F_COMPEN V_COMPEN(1U) - -#define S_PRTYEN 6 -#define V_PRTYEN(x) ((x) << S_PRTYEN) -#define F_PRTYEN V_PRTYEN(1U) - -#define S_MBUSEN 5 -#define V_MBUSEN(x) ((x) << S_MBUSEN) -#define F_MBUSEN V_MBUSEN(1U) - -#define S_DBGIEN 4 -#define V_DBGIEN(x) ((x) << S_DBGIEN) -#define F_DBGIEN V_DBGIEN(1U) - -#define S_TMRDY 2 -#define V_TMRDY(x) ((x) << S_TMRDY) -#define F_TMRDY V_TMRDY(1U) - -#define S_TMRST 1 -#define V_TMRST(x) ((x) << S_TMRST) -#define F_TMRST V_TMRST(1U) - -#define S_TMMODE 0 -#define V_TMMODE(x) ((x) << S_TMMODE) -#define F_TMMODE V_TMMODE(1U) - -#define F_TMMODE V_TMMODE(1U) - -#define A_MC5_DB_ROUTING_TABLE_INDEX 0x70c - -#define A_MC5_DB_FILTER_TABLE 0x710 - -#define A_MC5_DB_SERVER_INDEX 0x714 - -#define A_MC5_DB_RSP_LATENCY 0x720 - -#define S_RDLAT 16 -#define M_RDLAT 0x1f -#define V_RDLAT(x) ((x) << S_RDLAT) - -#define S_LRNLAT 8 -#define M_LRNLAT 0x1f -#define V_LRNLAT(x) ((x) << S_LRNLAT) - -#define S_SRCHLAT 0 -#define M_SRCHLAT 0x1f -#define V_SRCHLAT(x) ((x) << S_SRCHLAT) - -#define A_MC5_DB_PART_ID_INDEX 0x72c - -#define A_MC5_DB_INT_ENABLE 0x740 - -#define S_DELACTEMPTY 18 -#define V_DELACTEMPTY(x) ((x) << S_DELACTEMPTY) -#define F_DELACTEMPTY V_DELACTEMPTY(1U) - -#define S_DISPQPARERR 17 -#define V_DISPQPARERR(x) ((x) << S_DISPQPARERR) -#define F_DISPQPARERR V_DISPQPARERR(1U) - -#define S_REQQPARERR 16 -#define V_REQQPARERR(x) ((x) << S_REQQPARERR) -#define F_REQQPARERR V_REQQPARERR(1U) - -#define S_UNKNOWNCMD 15 -#define V_UNKNOWNCMD(x) ((x) << S_UNKNOWNCMD) -#define F_UNKNOWNCMD V_UNKNOWNCMD(1U) - -#define S_NFASRCHFAIL 8 -#define V_NFASRCHFAIL(x) ((x) << S_NFASRCHFAIL) -#define F_NFASRCHFAIL V_NFASRCHFAIL(1U) - -#define S_ACTRGNFULL 7 -#define V_ACTRGNFULL(x) ((x) << S_ACTRGNFULL) -#define F_ACTRGNFULL V_ACTRGNFULL(1U) - -#define S_PARITYERR 6 -#define V_PARITYERR(x) ((x) << S_PARITYERR) -#define F_PARITYERR V_PARITYERR(1U) - -#define A_MC5_DB_INT_CAUSE 0x744 - -#define A_MC5_DB_DBGI_CONFIG 0x774 - -#define A_MC5_DB_DBGI_REQ_CMD 0x778 - -#define A_MC5_DB_DBGI_REQ_ADDR0 0x77c - -#define A_MC5_DB_DBGI_REQ_ADDR1 0x780 - -#define A_MC5_DB_DBGI_REQ_ADDR2 0x784 - -#define A_MC5_DB_DBGI_REQ_DATA0 0x788 - -#define A_MC5_DB_DBGI_REQ_DATA1 0x78c - -#define A_MC5_DB_DBGI_REQ_DATA2 0x790 - -#define A_MC5_DB_DBGI_RSP_STATUS 0x7b0 - -#define S_DBGIRSPVALID 0 -#define V_DBGIRSPVALID(x) ((x) << S_DBGIRSPVALID) -#define F_DBGIRSPVALID V_DBGIRSPVALID(1U) - -#define A_MC5_DB_DBGI_RSP_DATA0 0x7b4 - -#define A_MC5_DB_DBGI_RSP_DATA1 0x7b8 - -#define A_MC5_DB_DBGI_RSP_DATA2 0x7bc - -#define A_MC5_DB_POPEN_DATA_WR_CMD 0x7cc - -#define A_MC5_DB_POPEN_MASK_WR_CMD 0x7d0 - -#define A_MC5_DB_AOPEN_SRCH_CMD 0x7d4 - -#define A_MC5_DB_AOPEN_LRN_CMD 0x7d8 - -#define A_MC5_DB_SYN_SRCH_CMD 0x7dc - -#define A_MC5_DB_SYN_LRN_CMD 0x7e0 - -#define A_MC5_DB_ACK_SRCH_CMD 0x7e4 - -#define A_MC5_DB_ACK_LRN_CMD 0x7e8 - -#define A_MC5_DB_ILOOKUP_CMD 0x7ec - -#define A_MC5_DB_ELOOKUP_CMD 0x7f0 - -#define A_MC5_DB_DATA_WRITE_CMD 0x7f4 - -#define A_MC5_DB_DATA_READ_CMD 0x7f8 - -#define XGMAC0_0_BASE_ADDR 0x800 - -#define A_XGM_TX_CTRL 0x800 - -#define S_TXEN 0 -#define V_TXEN(x) ((x) << S_TXEN) -#define F_TXEN V_TXEN(1U) - -#define A_XGM_TX_CFG 0x804 - -#define S_TXPAUSEEN 0 -#define V_TXPAUSEEN(x) ((x) << S_TXPAUSEEN) -#define F_TXPAUSEEN V_TXPAUSEEN(1U) - -#define A_XGM_RX_CTRL 0x80c - -#define S_RXEN 0 -#define V_RXEN(x) ((x) << S_RXEN) -#define F_RXEN V_RXEN(1U) - -#define A_XGM_RX_CFG 0x810 - -#define S_DISPAUSEFRAMES 9 -#define V_DISPAUSEFRAMES(x) ((x) << S_DISPAUSEFRAMES) -#define F_DISPAUSEFRAMES V_DISPAUSEFRAMES(1U) - -#define S_EN1536BFRAMES 8 -#define V_EN1536BFRAMES(x) ((x) << S_EN1536BFRAMES) -#define F_EN1536BFRAMES V_EN1536BFRAMES(1U) - -#define S_ENJUMBO 7 -#define V_ENJUMBO(x) ((x) << S_ENJUMBO) -#define F_ENJUMBO V_ENJUMBO(1U) - -#define S_RMFCS 6 -#define V_RMFCS(x) ((x) << S_RMFCS) -#define F_RMFCS V_RMFCS(1U) - -#define S_ENHASHMCAST 2 -#define V_ENHASHMCAST(x) ((x) << S_ENHASHMCAST) -#define F_ENHASHMCAST V_ENHASHMCAST(1U) - -#define S_COPYALLFRAMES 0 -#define V_COPYALLFRAMES(x) ((x) << S_COPYALLFRAMES) -#define F_COPYALLFRAMES V_COPYALLFRAMES(1U) - -#define A_XGM_RX_HASH_LOW 0x814 - -#define A_XGM_RX_HASH_HIGH 0x818 - -#define A_XGM_RX_EXACT_MATCH_LOW_1 0x81c - -#define A_XGM_RX_EXACT_MATCH_HIGH_1 0x820 - -#define A_XGM_RX_EXACT_MATCH_LOW_2 0x824 - -#define A_XGM_RX_EXACT_MATCH_LOW_3 0x82c - -#define A_XGM_RX_EXACT_MATCH_LOW_4 0x834 - -#define A_XGM_RX_EXACT_MATCH_LOW_5 0x83c - -#define A_XGM_RX_EXACT_MATCH_LOW_6 0x844 - -#define A_XGM_RX_EXACT_MATCH_LOW_7 0x84c - -#define A_XGM_RX_EXACT_MATCH_LOW_8 0x854 - -#define A_XGM_STAT_CTRL 0x880 - -#define S_CLRSTATS 2 -#define V_CLRSTATS(x) ((x) << S_CLRSTATS) -#define F_CLRSTATS V_CLRSTATS(1U) - -#define A_XGM_RXFIFO_CFG 0x884 - -#define S_RXFIFOPAUSEHWM 17 -#define M_RXFIFOPAUSEHWM 0xfff - -#define V_RXFIFOPAUSEHWM(x) ((x) << S_RXFIFOPAUSEHWM) - -#define G_RXFIFOPAUSEHWM(x) (((x) >> S_RXFIFOPAUSEHWM) & M_RXFIFOPAUSEHWM) - -#define S_RXFIFOPAUSELWM 5 -#define M_RXFIFOPAUSELWM 0xfff - -#define V_RXFIFOPAUSELWM(x) ((x) << S_RXFIFOPAUSELWM) - -#define G_RXFIFOPAUSELWM(x) (((x) >> S_RXFIFOPAUSELWM) & M_RXFIFOPAUSELWM) - -#define S_RXSTRFRWRD 1 -#define V_RXSTRFRWRD(x) ((x) << S_RXSTRFRWRD) -#define F_RXSTRFRWRD V_RXSTRFRWRD(1U) - -#define S_DISERRFRAMES 0 -#define V_DISERRFRAMES(x) ((x) << S_DISERRFRAMES) -#define F_DISERRFRAMES V_DISERRFRAMES(1U) - -#define A_XGM_TXFIFO_CFG 0x888 - -#define S_TXFIFOTHRESH 4 -#define M_TXFIFOTHRESH 0x1ff - -#define V_TXFIFOTHRESH(x) ((x) << S_TXFIFOTHRESH) - -#define A_XGM_SERDES_CTRL 0x890 -#define A_XGM_SERDES_CTRL0 0x8e0 - -#define S_SERDESRESET_ 24 -#define V_SERDESRESET_(x) ((x) << S_SERDESRESET_) -#define F_SERDESRESET_ V_SERDESRESET_(1U) - -#define S_RXENABLE 4 -#define V_RXENABLE(x) ((x) << S_RXENABLE) -#define F_RXENABLE V_RXENABLE(1U) - -#define S_TXENABLE 3 -#define V_TXENABLE(x) ((x) << S_TXENABLE) -#define F_TXENABLE V_TXENABLE(1U) - -#define A_XGM_PAUSE_TIMER 0x890 - -#define A_XGM_RGMII_IMP 0x89c - -#define S_XGM_IMPSETUPDATE 6 -#define V_XGM_IMPSETUPDATE(x) ((x) << S_XGM_IMPSETUPDATE) -#define F_XGM_IMPSETUPDATE V_XGM_IMPSETUPDATE(1U) - -#define S_RGMIIIMPPD 3 -#define M_RGMIIIMPPD 0x7 -#define V_RGMIIIMPPD(x) ((x) << S_RGMIIIMPPD) - -#define S_RGMIIIMPPU 0 -#define M_RGMIIIMPPU 0x7 -#define V_RGMIIIMPPU(x) ((x) << S_RGMIIIMPPU) - -#define S_CALRESET 8 -#define V_CALRESET(x) ((x) << S_CALRESET) -#define F_CALRESET V_CALRESET(1U) - -#define S_CALUPDATE 7 -#define V_CALUPDATE(x) ((x) << S_CALUPDATE) -#define F_CALUPDATE V_CALUPDATE(1U) - -#define A_XGM_XAUI_IMP 0x8a0 - -#define S_CALBUSY 31 -#define V_CALBUSY(x) ((x) << S_CALBUSY) -#define F_CALBUSY V_CALBUSY(1U) - -#define S_XGM_CALFAULT 29 -#define V_XGM_CALFAULT(x) ((x) << S_XGM_CALFAULT) -#define F_XGM_CALFAULT V_XGM_CALFAULT(1U) - -#define S_CALIMP 24 -#define M_CALIMP 0x1f -#define V_CALIMP(x) ((x) << S_CALIMP) -#define G_CALIMP(x) (((x) >> S_CALIMP) & M_CALIMP) - -#define S_XAUIIMP 0 -#define M_XAUIIMP 0x7 -#define V_XAUIIMP(x) ((x) << S_XAUIIMP) - -#define A_XGM_RX_MAX_PKT_SIZE 0x8a8 -#define A_XGM_RX_MAX_PKT_SIZE_ERR_CNT 0x9a4 - -#define A_XGM_RESET_CTRL 0x8ac - -#define S_XG2G_RESET_ 3 -#define V_XG2G_RESET_(x) ((x) << S_XG2G_RESET_) -#define F_XG2G_RESET_ V_XG2G_RESET_(1U) - -#define S_RGMII_RESET_ 2 -#define V_RGMII_RESET_(x) ((x) << S_RGMII_RESET_) -#define F_RGMII_RESET_ V_RGMII_RESET_(1U) - -#define S_PCS_RESET_ 1 -#define V_PCS_RESET_(x) ((x) << S_PCS_RESET_) -#define F_PCS_RESET_ V_PCS_RESET_(1U) - -#define S_MAC_RESET_ 0 -#define V_MAC_RESET_(x) ((x) << S_MAC_RESET_) -#define F_MAC_RESET_ V_MAC_RESET_(1U) - -#define A_XGM_PORT_CFG 0x8b8 - -#define S_CLKDIVRESET_ 3 -#define V_CLKDIVRESET_(x) ((x) << S_CLKDIVRESET_) -#define F_CLKDIVRESET_ V_CLKDIVRESET_(1U) - -#define S_PORTSPEED 1 -#define M_PORTSPEED 0x3 - -#define V_PORTSPEED(x) ((x) << S_PORTSPEED) - -#define S_ENRGMII 0 -#define V_ENRGMII(x) ((x) << S_ENRGMII) -#define F_ENRGMII V_ENRGMII(1U) - -#define A_XGM_INT_ENABLE 0x8d4 - -#define S_TXFIFO_PRTY_ERR 17 -#define M_TXFIFO_PRTY_ERR 0x7 - -#define V_TXFIFO_PRTY_ERR(x) ((x) << S_TXFIFO_PRTY_ERR) - -#define S_RXFIFO_PRTY_ERR 14 -#define M_RXFIFO_PRTY_ERR 0x7 - -#define V_RXFIFO_PRTY_ERR(x) ((x) << S_RXFIFO_PRTY_ERR) - -#define S_TXFIFO_UNDERRUN 13 -#define V_TXFIFO_UNDERRUN(x) ((x) << S_TXFIFO_UNDERRUN) -#define F_TXFIFO_UNDERRUN V_TXFIFO_UNDERRUN(1U) - -#define S_RXFIFO_OVERFLOW 12 -#define V_RXFIFO_OVERFLOW(x) ((x) << S_RXFIFO_OVERFLOW) -#define F_RXFIFO_OVERFLOW V_RXFIFO_OVERFLOW(1U) - -#define S_SERDES_LOS 4 -#define M_SERDES_LOS 0xf - -#define V_SERDES_LOS(x) ((x) << S_SERDES_LOS) - -#define S_XAUIPCSCTCERR 3 -#define V_XAUIPCSCTCERR(x) ((x) << S_XAUIPCSCTCERR) -#define F_XAUIPCSCTCERR V_XAUIPCSCTCERR(1U) - -#define S_XAUIPCSALIGNCHANGE 2 -#define V_XAUIPCSALIGNCHANGE(x) ((x) << S_XAUIPCSALIGNCHANGE) -#define F_XAUIPCSALIGNCHANGE V_XAUIPCSALIGNCHANGE(1U) - -#define A_XGM_INT_CAUSE 0x8d8 - -#define A_XGM_XAUI_ACT_CTRL 0x8dc - -#define S_TXACTENABLE 1 -#define V_TXACTENABLE(x) ((x) << S_TXACTENABLE) -#define F_TXACTENABLE V_TXACTENABLE(1U) - -#define A_XGM_SERDES_CTRL0 0x8e0 - -#define S_RESET3 23 -#define V_RESET3(x) ((x) << S_RESET3) -#define F_RESET3 V_RESET3(1U) - -#define S_RESET2 22 -#define V_RESET2(x) ((x) << S_RESET2) -#define F_RESET2 V_RESET2(1U) - -#define S_RESET1 21 -#define V_RESET1(x) ((x) << S_RESET1) -#define F_RESET1 V_RESET1(1U) - -#define S_RESET0 20 -#define V_RESET0(x) ((x) << S_RESET0) -#define F_RESET0 V_RESET0(1U) - -#define S_PWRDN3 19 -#define V_PWRDN3(x) ((x) << S_PWRDN3) -#define F_PWRDN3 V_PWRDN3(1U) - -#define S_PWRDN2 18 -#define V_PWRDN2(x) ((x) << S_PWRDN2) -#define F_PWRDN2 V_PWRDN2(1U) - -#define S_PWRDN1 17 -#define V_PWRDN1(x) ((x) << S_PWRDN1) -#define F_PWRDN1 V_PWRDN1(1U) - -#define S_PWRDN0 16 -#define V_PWRDN0(x) ((x) << S_PWRDN0) -#define F_PWRDN0 V_PWRDN0(1U) - -#define S_RESETPLL23 15 -#define V_RESETPLL23(x) ((x) << S_RESETPLL23) -#define F_RESETPLL23 V_RESETPLL23(1U) - -#define S_RESETPLL01 14 -#define V_RESETPLL01(x) ((x) << S_RESETPLL01) -#define F_RESETPLL01 V_RESETPLL01(1U) - -#define A_XGM_SERDES_STAT0 0x8f0 - -#define S_LOWSIG0 0 -#define V_LOWSIG0(x) ((x) << S_LOWSIG0) -#define F_LOWSIG0 V_LOWSIG0(1U) - -#define A_XGM_SERDES_STAT3 0x8fc - -#define A_XGM_STAT_TX_BYTE_LOW 0x900 - -#define A_XGM_STAT_TX_BYTE_HIGH 0x904 - -#define A_XGM_STAT_TX_FRAME_LOW 0x908 - -#define A_XGM_STAT_TX_FRAME_HIGH 0x90c - -#define A_XGM_STAT_TX_BCAST 0x910 - -#define A_XGM_STAT_TX_MCAST 0x914 - -#define A_XGM_STAT_TX_PAUSE 0x918 - -#define A_XGM_STAT_TX_64B_FRAMES 0x91c - -#define A_XGM_STAT_TX_65_127B_FRAMES 0x920 - -#define A_XGM_STAT_TX_128_255B_FRAMES 0x924 - -#define A_XGM_STAT_TX_256_511B_FRAMES 0x928 - -#define A_XGM_STAT_TX_512_1023B_FRAMES 0x92c - -#define A_XGM_STAT_TX_1024_1518B_FRAMES 0x930 - -#define A_XGM_STAT_TX_1519_MAXB_FRAMES 0x934 - -#define A_XGM_STAT_TX_ERR_FRAMES 0x938 - -#define A_XGM_STAT_RX_BYTES_LOW 0x93c - -#define A_XGM_STAT_RX_BYTES_HIGH 0x940 - -#define A_XGM_STAT_RX_FRAMES_LOW 0x944 - -#define A_XGM_STAT_RX_FRAMES_HIGH 0x948 - -#define A_XGM_STAT_RX_BCAST_FRAMES 0x94c - -#define A_XGM_STAT_RX_MCAST_FRAMES 0x950 - -#define A_XGM_STAT_RX_PAUSE_FRAMES 0x954 - -#define A_XGM_STAT_RX_64B_FRAMES 0x958 - -#define A_XGM_STAT_RX_65_127B_FRAMES 0x95c - -#define A_XGM_STAT_RX_128_255B_FRAMES 0x960 - -#define A_XGM_STAT_RX_256_511B_FRAMES 0x964 - -#define A_XGM_STAT_RX_512_1023B_FRAMES 0x968 - -#define A_XGM_STAT_RX_1024_1518B_FRAMES 0x96c - -#define A_XGM_STAT_RX_1519_MAXB_FRAMES 0x970 - -#define A_XGM_STAT_RX_SHORT_FRAMES 0x974 - -#define A_XGM_STAT_RX_OVERSIZE_FRAMES 0x978 - -#define A_XGM_STAT_RX_JABBER_FRAMES 0x97c - -#define A_XGM_STAT_RX_CRC_ERR_FRAMES 0x980 - -#define A_XGM_STAT_RX_LENGTH_ERR_FRAMES 0x984 - -#define A_XGM_STAT_RX_SYM_CODE_ERR_FRAMES 0x988 - -#define A_XGM_SERDES_STATUS0 0x98c - -#define A_XGM_SERDES_STATUS1 0x990 - -#define S_CMULOCK 31 -#define V_CMULOCK(x) ((x) << S_CMULOCK) -#define F_CMULOCK V_CMULOCK(1U) - -#define A_XGM_RX_MAX_PKT_SIZE_ERR_CNT 0x9a4 - -#define A_XGM_RX_SPI4_SOP_EOP_CNT 0x9ac - -#define XGMAC0_1_BASE_ADDR 0xa00 diff --git a/trunk/drivers/net/cxgb3/sge.c b/trunk/drivers/net/cxgb3/sge.c deleted file mode 100644 index 3f2cf8a07c61..000000000000 --- a/trunk/drivers/net/cxgb3/sge.c +++ /dev/null @@ -1,2681 +0,0 @@ -/* - * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "regs.h" -#include "sge_defs.h" -#include "t3_cpl.h" -#include "firmware_exports.h" - -#define USE_GTS 0 - -#define SGE_RX_SM_BUF_SIZE 1536 -#define SGE_RX_COPY_THRES 256 - -# define SGE_RX_DROP_THRES 16 - -/* - * Period of the Tx buffer reclaim timer. This timer does not need to run - * frequently as Tx buffers are usually reclaimed by new Tx packets. - */ -#define TX_RECLAIM_PERIOD (HZ / 4) - -/* WR size in bytes */ -#define WR_LEN (WR_FLITS * 8) - -/* - * Types of Tx queues in each queue set. Order here matters, do not change. - */ -enum { TXQ_ETH, TXQ_OFLD, TXQ_CTRL }; - -/* Values for sge_txq.flags */ -enum { - TXQ_RUNNING = 1 << 0, /* fetch engine is running */ - TXQ_LAST_PKT_DB = 1 << 1, /* last packet rang the doorbell */ -}; - -struct tx_desc { - u64 flit[TX_DESC_FLITS]; -}; - -struct rx_desc { - __be32 addr_lo; - __be32 len_gen; - __be32 gen2; - __be32 addr_hi; -}; - -struct tx_sw_desc { /* SW state per Tx descriptor */ - struct sk_buff *skb; -}; - -struct rx_sw_desc { /* SW state per Rx descriptor */ - struct sk_buff *skb; - DECLARE_PCI_UNMAP_ADDR(dma_addr); -}; - -struct rsp_desc { /* response queue descriptor */ - struct rss_header rss_hdr; - __be32 flags; - __be32 len_cq; - u8 imm_data[47]; - u8 intr_gen; -}; - -struct unmap_info { /* packet unmapping info, overlays skb->cb */ - int sflit; /* start flit of first SGL entry in Tx descriptor */ - u16 fragidx; /* first page fragment in current Tx descriptor */ - u16 addr_idx; /* buffer index of first SGL entry in descriptor */ - u32 len; /* mapped length of skb main body */ -}; - -/* - * Maps a number of flits to the number of Tx descriptors that can hold them. - * The formula is - * - * desc = 1 + (flits - 2) / (WR_FLITS - 1). - * - * HW allows up to 4 descriptors to be combined into a WR. - */ -static u8 flit_desc_map[] = { - 0, -#if SGE_NUM_GENBITS == 1 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 -#elif SGE_NUM_GENBITS == 2 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -#else -# error "SGE_NUM_GENBITS must be 1 or 2" -#endif -}; - -static inline struct sge_qset *fl_to_qset(const struct sge_fl *q, int qidx) -{ - return container_of(q, struct sge_qset, fl[qidx]); -} - -static inline struct sge_qset *rspq_to_qset(const struct sge_rspq *q) -{ - return container_of(q, struct sge_qset, rspq); -} - -static inline struct sge_qset *txq_to_qset(const struct sge_txq *q, int qidx) -{ - return container_of(q, struct sge_qset, txq[qidx]); -} - -/** - * refill_rspq - replenish an SGE response queue - * @adapter: the adapter - * @q: the response queue to replenish - * @credits: how many new responses to make available - * - * Replenishes a response queue by making the supplied number of responses - * available to HW. - */ -static inline void refill_rspq(struct adapter *adapter, - const struct sge_rspq *q, unsigned int credits) -{ - t3_write_reg(adapter, A_SG_RSPQ_CREDIT_RETURN, - V_RSPQ(q->cntxt_id) | V_CREDITS(credits)); -} - -/** - * need_skb_unmap - does the platform need unmapping of sk_buffs? - * - * Returns true if the platfrom needs sk_buff unmapping. The compiler - * optimizes away unecessary code if this returns true. - */ -static inline int need_skb_unmap(void) -{ - /* - * This structure is used to tell if the platfrom needs buffer - * unmapping by checking if DECLARE_PCI_UNMAP_ADDR defines anything. - */ - struct dummy { - DECLARE_PCI_UNMAP_ADDR(addr); - }; - - return sizeof(struct dummy) != 0; -} - -/** - * unmap_skb - unmap a packet main body and its page fragments - * @skb: the packet - * @q: the Tx queue containing Tx descriptors for the packet - * @cidx: index of Tx descriptor - * @pdev: the PCI device - * - * Unmap the main body of an sk_buff and its page fragments, if any. - * Because of the fairly complicated structure of our SGLs and the desire - * to conserve space for metadata, we keep the information necessary to - * unmap an sk_buff partly in the sk_buff itself (in its cb), and partly - * in the Tx descriptors (the physical addresses of the various data - * buffers). The send functions initialize the state in skb->cb so we - * can unmap the buffers held in the first Tx descriptor here, and we - * have enough information at this point to update the state for the next - * Tx descriptor. - */ -static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q, - unsigned int cidx, struct pci_dev *pdev) -{ - const struct sg_ent *sgp; - struct unmap_info *ui = (struct unmap_info *)skb->cb; - int nfrags, frag_idx, curflit, j = ui->addr_idx; - - sgp = (struct sg_ent *)&q->desc[cidx].flit[ui->sflit]; - - if (ui->len) { - pci_unmap_single(pdev, be64_to_cpu(sgp->addr[0]), ui->len, - PCI_DMA_TODEVICE); - ui->len = 0; /* so we know for next descriptor for this skb */ - j = 1; - } - - frag_idx = ui->fragidx; - curflit = ui->sflit + 1 + j; - nfrags = skb_shinfo(skb)->nr_frags; - - while (frag_idx < nfrags && curflit < WR_FLITS) { - pci_unmap_page(pdev, be64_to_cpu(sgp->addr[j]), - skb_shinfo(skb)->frags[frag_idx].size, - PCI_DMA_TODEVICE); - j ^= 1; - if (j == 0) { - sgp++; - curflit++; - } - curflit++; - frag_idx++; - } - - if (frag_idx < nfrags) { /* SGL continues into next Tx descriptor */ - ui->fragidx = frag_idx; - ui->addr_idx = j; - ui->sflit = curflit - WR_FLITS - j; /* sflit can be -1 */ - } -} - -/** - * free_tx_desc - reclaims Tx descriptors and their buffers - * @adapter: the adapter - * @q: the Tx queue to reclaim descriptors from - * @n: the number of descriptors to reclaim - * - * Reclaims Tx descriptors from an SGE Tx queue and frees the associated - * Tx buffers. Called with the Tx queue lock held. - */ -static void free_tx_desc(struct adapter *adapter, struct sge_txq *q, - unsigned int n) -{ - struct tx_sw_desc *d; - struct pci_dev *pdev = adapter->pdev; - unsigned int cidx = q->cidx; - - d = &q->sdesc[cidx]; - while (n--) { - if (d->skb) { /* an SGL is present */ - if (need_skb_unmap()) - unmap_skb(d->skb, q, cidx, pdev); - if (d->skb->priority == cidx) - kfree_skb(d->skb); - } - ++d; - if (++cidx == q->size) { - cidx = 0; - d = q->sdesc; - } - } - q->cidx = cidx; -} - -/** - * reclaim_completed_tx - reclaims completed Tx descriptors - * @adapter: the adapter - * @q: the Tx queue to reclaim completed descriptors from - * - * Reclaims Tx descriptors that the SGE has indicated it has processed, - * and frees the associated buffers if possible. Called with the Tx - * queue's lock held. - */ -static inline void reclaim_completed_tx(struct adapter *adapter, - struct sge_txq *q) -{ - unsigned int reclaim = q->processed - q->cleaned; - - if (reclaim) { - free_tx_desc(adapter, q, reclaim); - q->cleaned += reclaim; - q->in_use -= reclaim; - } -} - -/** - * should_restart_tx - are there enough resources to restart a Tx queue? - * @q: the Tx queue - * - * Checks if there are enough descriptors to restart a suspended Tx queue. - */ -static inline int should_restart_tx(const struct sge_txq *q) -{ - unsigned int r = q->processed - q->cleaned; - - return q->in_use - r < (q->size >> 1); -} - -/** - * free_rx_bufs - free the Rx buffers on an SGE free list - * @pdev: the PCI device associated with the adapter - * @rxq: the SGE free list to clean up - * - * Release the buffers on an SGE free-buffer Rx queue. HW fetching from - * this queue should be stopped before calling this function. - */ -static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q) -{ - unsigned int cidx = q->cidx; - - while (q->credits--) { - struct rx_sw_desc *d = &q->sdesc[cidx]; - - pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr), - q->buf_size, PCI_DMA_FROMDEVICE); - kfree_skb(d->skb); - d->skb = NULL; - if (++cidx == q->size) - cidx = 0; - } -} - -/** - * add_one_rx_buf - add a packet buffer to a free-buffer list - * @skb: the buffer to add - * @len: the buffer length - * @d: the HW Rx descriptor to write - * @sd: the SW Rx descriptor to write - * @gen: the generation bit value - * @pdev: the PCI device associated with the adapter - * - * Add a buffer of the given length to the supplied HW and SW Rx - * descriptors. - */ -static inline void add_one_rx_buf(struct sk_buff *skb, unsigned int len, - struct rx_desc *d, struct rx_sw_desc *sd, - unsigned int gen, struct pci_dev *pdev) -{ - dma_addr_t mapping; - - sd->skb = skb; - mapping = pci_map_single(pdev, skb->data, len, PCI_DMA_FROMDEVICE); - pci_unmap_addr_set(sd, dma_addr, mapping); - - d->addr_lo = cpu_to_be32(mapping); - d->addr_hi = cpu_to_be32((u64) mapping >> 32); - wmb(); - d->len_gen = cpu_to_be32(V_FLD_GEN1(gen)); - d->gen2 = cpu_to_be32(V_FLD_GEN2(gen)); -} - -/** - * refill_fl - refill an SGE free-buffer list - * @adapter: the adapter - * @q: the free-list to refill - * @n: the number of new buffers to allocate - * @gfp: the gfp flags for allocating new buffers - * - * (Re)populate an SGE free-buffer list with up to @n new packet buffers, - * allocated with the supplied gfp flags. The caller must assure that - * @n does not exceed the queue's capacity. - */ -static void refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp) -{ - struct rx_sw_desc *sd = &q->sdesc[q->pidx]; - struct rx_desc *d = &q->desc[q->pidx]; - - while (n--) { - struct sk_buff *skb = alloc_skb(q->buf_size, gfp); - - if (!skb) - break; - - add_one_rx_buf(skb, q->buf_size, d, sd, q->gen, adap->pdev); - d++; - sd++; - if (++q->pidx == q->size) { - q->pidx = 0; - q->gen ^= 1; - sd = q->sdesc; - d = q->desc; - } - q->credits++; - } - - t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id)); -} - -static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl) -{ - refill_fl(adap, fl, min(16U, fl->size - fl->credits), GFP_ATOMIC); -} - -/** - * recycle_rx_buf - recycle a receive buffer - * @adapter: the adapter - * @q: the SGE free list - * @idx: index of buffer to recycle - * - * Recycles the specified buffer on the given free list by adding it at - * the next available slot on the list. - */ -static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q, - unsigned int idx) -{ - struct rx_desc *from = &q->desc[idx]; - struct rx_desc *to = &q->desc[q->pidx]; - - q->sdesc[q->pidx] = q->sdesc[idx]; - to->addr_lo = from->addr_lo; /* already big endian */ - to->addr_hi = from->addr_hi; /* likewise */ - wmb(); - to->len_gen = cpu_to_be32(V_FLD_GEN1(q->gen)); - to->gen2 = cpu_to_be32(V_FLD_GEN2(q->gen)); - q->credits++; - - if (++q->pidx == q->size) { - q->pidx = 0; - q->gen ^= 1; - } - t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id)); -} - -/** - * alloc_ring - allocate resources for an SGE descriptor ring - * @pdev: the PCI device - * @nelem: the number of descriptors - * @elem_size: the size of each descriptor - * @sw_size: the size of the SW state associated with each ring element - * @phys: the physical address of the allocated ring - * @metadata: address of the array holding the SW state for the ring - * - * Allocates resources for an SGE descriptor ring, such as Tx queues, - * free buffer lists, or response queues. Each SGE ring requires - * space for its HW descriptors plus, optionally, space for the SW state - * associated with each HW entry (the metadata). The function returns - * three values: the virtual address for the HW ring (the return value - * of the function), the physical address of the HW ring, and the address - * of the SW ring. - */ -static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size, - size_t sw_size, dma_addr_t *phys, void *metadata) -{ - size_t len = nelem * elem_size; - void *s = NULL; - void *p = dma_alloc_coherent(&pdev->dev, len, phys, GFP_KERNEL); - - if (!p) - return NULL; - if (sw_size) { - s = kcalloc(nelem, sw_size, GFP_KERNEL); - - if (!s) { - dma_free_coherent(&pdev->dev, len, p, *phys); - return NULL; - } - } - if (metadata) - *(void **)metadata = s; - memset(p, 0, len); - return p; -} - -/** - * free_qset - free the resources of an SGE queue set - * @adapter: the adapter owning the queue set - * @q: the queue set - * - * Release the HW and SW resources associated with an SGE queue set, such - * as HW contexts, packet buffers, and descriptor rings. Traffic to the - * queue set must be quiesced prior to calling this. - */ -void t3_free_qset(struct adapter *adapter, struct sge_qset *q) -{ - int i; - struct pci_dev *pdev = adapter->pdev; - - if (q->tx_reclaim_timer.function) - del_timer_sync(&q->tx_reclaim_timer); - - for (i = 0; i < SGE_RXQ_PER_SET; ++i) - if (q->fl[i].desc) { - spin_lock(&adapter->sge.reg_lock); - t3_sge_disable_fl(adapter, q->fl[i].cntxt_id); - spin_unlock(&adapter->sge.reg_lock); - free_rx_bufs(pdev, &q->fl[i]); - kfree(q->fl[i].sdesc); - dma_free_coherent(&pdev->dev, - q->fl[i].size * - sizeof(struct rx_desc), q->fl[i].desc, - q->fl[i].phys_addr); - } - - for (i = 0; i < SGE_TXQ_PER_SET; ++i) - if (q->txq[i].desc) { - spin_lock(&adapter->sge.reg_lock); - t3_sge_enable_ecntxt(adapter, q->txq[i].cntxt_id, 0); - spin_unlock(&adapter->sge.reg_lock); - if (q->txq[i].sdesc) { - free_tx_desc(adapter, &q->txq[i], - q->txq[i].in_use); - kfree(q->txq[i].sdesc); - } - dma_free_coherent(&pdev->dev, - q->txq[i].size * - sizeof(struct tx_desc), - q->txq[i].desc, q->txq[i].phys_addr); - __skb_queue_purge(&q->txq[i].sendq); - } - - if (q->rspq.desc) { - spin_lock(&adapter->sge.reg_lock); - t3_sge_disable_rspcntxt(adapter, q->rspq.cntxt_id); - spin_unlock(&adapter->sge.reg_lock); - dma_free_coherent(&pdev->dev, - q->rspq.size * sizeof(struct rsp_desc), - q->rspq.desc, q->rspq.phys_addr); - } - - if (q->netdev) - q->netdev->atalk_ptr = NULL; - - memset(q, 0, sizeof(*q)); -} - -/** - * init_qset_cntxt - initialize an SGE queue set context info - * @qs: the queue set - * @id: the queue set id - * - * Initializes the TIDs and context ids for the queues of a queue set. - */ -static void init_qset_cntxt(struct sge_qset *qs, unsigned int id) -{ - qs->rspq.cntxt_id = id; - qs->fl[0].cntxt_id = 2 * id; - qs->fl[1].cntxt_id = 2 * id + 1; - qs->txq[TXQ_ETH].cntxt_id = FW_TUNNEL_SGEEC_START + id; - qs->txq[TXQ_ETH].token = FW_TUNNEL_TID_START + id; - qs->txq[TXQ_OFLD].cntxt_id = FW_OFLD_SGEEC_START + id; - qs->txq[TXQ_CTRL].cntxt_id = FW_CTRL_SGEEC_START + id; - qs->txq[TXQ_CTRL].token = FW_CTRL_TID_START + id; -} - -/** - * sgl_len - calculates the size of an SGL of the given capacity - * @n: the number of SGL entries - * - * Calculates the number of flits needed for a scatter/gather list that - * can hold the given number of entries. - */ -static inline unsigned int sgl_len(unsigned int n) -{ - /* alternatively: 3 * (n / 2) + 2 * (n & 1) */ - return (3 * n) / 2 + (n & 1); -} - -/** - * flits_to_desc - returns the num of Tx descriptors for the given flits - * @n: the number of flits - * - * Calculates the number of Tx descriptors needed for the supplied number - * of flits. - */ -static inline unsigned int flits_to_desc(unsigned int n) -{ - BUG_ON(n >= ARRAY_SIZE(flit_desc_map)); - return flit_desc_map[n]; -} - -/** - * get_packet - return the next ingress packet buffer from a free list - * @adap: the adapter that received the packet - * @fl: the SGE free list holding the packet - * @len: the packet length including any SGE padding - * @drop_thres: # of remaining buffers before we start dropping packets - * - * Get the next packet from a free list and complete setup of the - * sk_buff. If the packet is small we make a copy and recycle the - * original buffer, otherwise we use the original buffer itself. If a - * positive drop threshold is supplied packets are dropped and their - * buffers recycled if (a) the number of remaining buffers is under the - * threshold and the packet is too big to copy, or (b) the packet should - * be copied but there is no memory for the copy. - */ -static struct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl, - unsigned int len, unsigned int drop_thres) -{ - struct sk_buff *skb = NULL; - struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; - - prefetch(sd->skb->data); - - if (len <= SGE_RX_COPY_THRES) { - skb = alloc_skb(len, GFP_ATOMIC); - if (likely(skb != NULL)) { - __skb_put(skb, len); - pci_dma_sync_single_for_cpu(adap->pdev, - pci_unmap_addr(sd, - dma_addr), - len, PCI_DMA_FROMDEVICE); - memcpy(skb->data, sd->skb->data, len); - pci_dma_sync_single_for_device(adap->pdev, - pci_unmap_addr(sd, - dma_addr), - len, PCI_DMA_FROMDEVICE); - } else if (!drop_thres) - goto use_orig_buf; - recycle: - recycle_rx_buf(adap, fl, fl->cidx); - return skb; - } - - if (unlikely(fl->credits < drop_thres)) - goto recycle; - - use_orig_buf: - pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr), - fl->buf_size, PCI_DMA_FROMDEVICE); - skb = sd->skb; - skb_put(skb, len); - __refill_fl(adap, fl); - return skb; -} - -/** - * get_imm_packet - return the next ingress packet buffer from a response - * @resp: the response descriptor containing the packet data - * - * Return a packet containing the immediate data of the given response. - */ -static inline struct sk_buff *get_imm_packet(const struct rsp_desc *resp) -{ - struct sk_buff *skb = alloc_skb(IMMED_PKT_SIZE, GFP_ATOMIC); - - if (skb) { - __skb_put(skb, IMMED_PKT_SIZE); - memcpy(skb->data, resp->imm_data, IMMED_PKT_SIZE); - } - return skb; -} - -/** - * calc_tx_descs - calculate the number of Tx descriptors for a packet - * @skb: the packet - * - * Returns the number of Tx descriptors needed for the given Ethernet - * packet. Ethernet packets require addition of WR and CPL headers. - */ -static inline unsigned int calc_tx_descs(const struct sk_buff *skb) -{ - unsigned int flits; - - if (skb->len <= WR_LEN - sizeof(struct cpl_tx_pkt)) - return 1; - - flits = sgl_len(skb_shinfo(skb)->nr_frags + 1) + 2; - if (skb_shinfo(skb)->gso_size) - flits++; - return flits_to_desc(flits); -} - -/** - * make_sgl - populate a scatter/gather list for a packet - * @skb: the packet - * @sgp: the SGL to populate - * @start: start address of skb main body data to include in the SGL - * @len: length of skb main body data to include in the SGL - * @pdev: the PCI device - * - * Generates a scatter/gather list for the buffers that make up a packet - * and returns the SGL size in 8-byte words. The caller must size the SGL - * appropriately. - */ -static inline unsigned int make_sgl(const struct sk_buff *skb, - struct sg_ent *sgp, unsigned char *start, - unsigned int len, struct pci_dev *pdev) -{ - dma_addr_t mapping; - unsigned int i, j = 0, nfrags; - - if (len) { - mapping = pci_map_single(pdev, start, len, PCI_DMA_TODEVICE); - sgp->len[0] = cpu_to_be32(len); - sgp->addr[0] = cpu_to_be64(mapping); - j = 1; - } - - nfrags = skb_shinfo(skb)->nr_frags; - for (i = 0; i < nfrags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - mapping = pci_map_page(pdev, frag->page, frag->page_offset, - frag->size, PCI_DMA_TODEVICE); - sgp->len[j] = cpu_to_be32(frag->size); - sgp->addr[j] = cpu_to_be64(mapping); - j ^= 1; - if (j == 0) - ++sgp; - } - if (j) - sgp->len[j] = 0; - return ((nfrags + (len != 0)) * 3) / 2 + j; -} - -/** - * check_ring_tx_db - check and potentially ring a Tx queue's doorbell - * @adap: the adapter - * @q: the Tx queue - * - * Ring the doorbel if a Tx queue is asleep. There is a natural race, - * where the HW is going to sleep just after we checked, however, - * then the interrupt handler will detect the outstanding TX packet - * and ring the doorbell for us. - * - * When GTS is disabled we unconditionally ring the doorbell. - */ -static inline void check_ring_tx_db(struct adapter *adap, struct sge_txq *q) -{ -#if USE_GTS - clear_bit(TXQ_LAST_PKT_DB, &q->flags); - if (test_and_set_bit(TXQ_RUNNING, &q->flags) == 0) { - set_bit(TXQ_LAST_PKT_DB, &q->flags); - t3_write_reg(adap, A_SG_KDOORBELL, - F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); - } -#else - wmb(); /* write descriptors before telling HW */ - t3_write_reg(adap, A_SG_KDOORBELL, - F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); -#endif -} - -static inline void wr_gen2(struct tx_desc *d, unsigned int gen) -{ -#if SGE_NUM_GENBITS == 2 - d->flit[TX_DESC_FLITS - 1] = cpu_to_be64(gen); -#endif -} - -/** - * write_wr_hdr_sgl - write a WR header and, optionally, SGL - * @ndesc: number of Tx descriptors spanned by the SGL - * @skb: the packet corresponding to the WR - * @d: first Tx descriptor to be written - * @pidx: index of above descriptors - * @q: the SGE Tx queue - * @sgl: the SGL - * @flits: number of flits to the start of the SGL in the first descriptor - * @sgl_flits: the SGL size in flits - * @gen: the Tx descriptor generation - * @wr_hi: top 32 bits of WR header based on WR type (big endian) - * @wr_lo: low 32 bits of WR header based on WR type (big endian) - * - * Write a work request header and an associated SGL. If the SGL is - * small enough to fit into one Tx descriptor it has already been written - * and we just need to write the WR header. Otherwise we distribute the - * SGL across the number of descriptors it spans. - */ -static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb, - struct tx_desc *d, unsigned int pidx, - const struct sge_txq *q, - const struct sg_ent *sgl, - unsigned int flits, unsigned int sgl_flits, - unsigned int gen, unsigned int wr_hi, - unsigned int wr_lo) -{ - struct work_request_hdr *wrp = (struct work_request_hdr *)d; - struct tx_sw_desc *sd = &q->sdesc[pidx]; - - sd->skb = skb; - if (need_skb_unmap()) { - struct unmap_info *ui = (struct unmap_info *)skb->cb; - - ui->fragidx = 0; - ui->addr_idx = 0; - ui->sflit = flits; - } - - if (likely(ndesc == 1)) { - skb->priority = pidx; - wrp->wr_hi = htonl(F_WR_SOP | F_WR_EOP | V_WR_DATATYPE(1) | - V_WR_SGLSFLT(flits)) | wr_hi; - wmb(); - wrp->wr_lo = htonl(V_WR_LEN(flits + sgl_flits) | - V_WR_GEN(gen)) | wr_lo; - wr_gen2(d, gen); - } else { - unsigned int ogen = gen; - const u64 *fp = (const u64 *)sgl; - struct work_request_hdr *wp = wrp; - - wrp->wr_hi = htonl(F_WR_SOP | V_WR_DATATYPE(1) | - V_WR_SGLSFLT(flits)) | wr_hi; - - while (sgl_flits) { - unsigned int avail = WR_FLITS - flits; - - if (avail > sgl_flits) - avail = sgl_flits; - memcpy(&d->flit[flits], fp, avail * sizeof(*fp)); - sgl_flits -= avail; - ndesc--; - if (!sgl_flits) - break; - - fp += avail; - d++; - sd++; - if (++pidx == q->size) { - pidx = 0; - gen ^= 1; - d = q->desc; - sd = q->sdesc; - } - - sd->skb = skb; - wrp = (struct work_request_hdr *)d; - wrp->wr_hi = htonl(V_WR_DATATYPE(1) | - V_WR_SGLSFLT(1)) | wr_hi; - wrp->wr_lo = htonl(V_WR_LEN(min(WR_FLITS, - sgl_flits + 1)) | - V_WR_GEN(gen)) | wr_lo; - wr_gen2(d, gen); - flits = 1; - } - skb->priority = pidx; - wrp->wr_hi |= htonl(F_WR_EOP); - wmb(); - wp->wr_lo = htonl(V_WR_LEN(WR_FLITS) | V_WR_GEN(ogen)) | wr_lo; - wr_gen2((struct tx_desc *)wp, ogen); - WARN_ON(ndesc != 0); - } -} - -/** - * write_tx_pkt_wr - write a TX_PKT work request - * @adap: the adapter - * @skb: the packet to send - * @pi: the egress interface - * @pidx: index of the first Tx descriptor to write - * @gen: the generation value to use - * @q: the Tx queue - * @ndesc: number of descriptors the packet will occupy - * @compl: the value of the COMPL bit to use - * - * Generate a TX_PKT work request to send the supplied packet. - */ -static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb, - const struct port_info *pi, - unsigned int pidx, unsigned int gen, - struct sge_txq *q, unsigned int ndesc, - unsigned int compl) -{ - unsigned int flits, sgl_flits, cntrl, tso_info; - struct sg_ent *sgp, sgl[MAX_SKB_FRAGS / 2 + 1]; - struct tx_desc *d = &q->desc[pidx]; - struct cpl_tx_pkt *cpl = (struct cpl_tx_pkt *)d; - - cpl->len = htonl(skb->len | 0x80000000); - cntrl = V_TXPKT_INTF(pi->port_id); - - if (vlan_tx_tag_present(skb) && pi->vlan_grp) - cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(vlan_tx_tag_get(skb)); - - tso_info = V_LSO_MSS(skb_shinfo(skb)->gso_size); - if (tso_info) { - int eth_type; - struct cpl_tx_pkt_lso *hdr = (struct cpl_tx_pkt_lso *)cpl; - - d->flit[2] = 0; - cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT_LSO); - hdr->cntrl = htonl(cntrl); - eth_type = skb->nh.raw - skb->data == ETH_HLEN ? - CPL_ETH_II : CPL_ETH_II_VLAN; - tso_info |= V_LSO_ETH_TYPE(eth_type) | - V_LSO_IPHDR_WORDS(skb->nh.iph->ihl) | - V_LSO_TCPHDR_WORDS(skb->h.th->doff); - hdr->lso_info = htonl(tso_info); - flits = 3; - } else { - cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT); - cntrl |= F_TXPKT_IPCSUM_DIS; /* SW calculates IP csum */ - cntrl |= V_TXPKT_L4CSUM_DIS(skb->ip_summed != CHECKSUM_PARTIAL); - cpl->cntrl = htonl(cntrl); - - if (skb->len <= WR_LEN - sizeof(*cpl)) { - q->sdesc[pidx].skb = NULL; - if (!skb->data_len) - memcpy(&d->flit[2], skb->data, skb->len); - else - skb_copy_bits(skb, 0, &d->flit[2], skb->len); - - flits = (skb->len + 7) / 8 + 2; - cpl->wr.wr_hi = htonl(V_WR_BCNTLFLT(skb->len & 7) | - V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) - | F_WR_SOP | F_WR_EOP | compl); - wmb(); - cpl->wr.wr_lo = htonl(V_WR_LEN(flits) | V_WR_GEN(gen) | - V_WR_TID(q->token)); - wr_gen2(d, gen); - kfree_skb(skb); - return; - } - - flits = 2; - } - - sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl; - sgl_flits = make_sgl(skb, sgp, skb->data, skb_headlen(skb), adap->pdev); - if (need_skb_unmap()) - ((struct unmap_info *)skb->cb)->len = skb_headlen(skb); - - write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits, gen, - htonl(V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) | compl), - htonl(V_WR_TID(q->token))); -} - -/** - * eth_xmit - add a packet to the Ethernet Tx queue - * @skb: the packet - * @dev: the egress net device - * - * Add a packet to an SGE Tx queue. Runs with softirqs disabled. - */ -int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) -{ - unsigned int ndesc, pidx, credits, gen, compl; - const struct port_info *pi = netdev_priv(dev); - struct adapter *adap = dev->priv; - struct sge_qset *qs = dev2qset(dev); - struct sge_txq *q = &qs->txq[TXQ_ETH]; - - /* - * The chip min packet length is 9 octets but play safe and reject - * anything shorter than an Ethernet header. - */ - if (unlikely(skb->len < ETH_HLEN)) { - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } - - spin_lock(&q->lock); - reclaim_completed_tx(adap, q); - - credits = q->size - q->in_use; - ndesc = calc_tx_descs(skb); - - if (unlikely(credits < ndesc)) { - if (!netif_queue_stopped(dev)) { - netif_stop_queue(dev); - set_bit(TXQ_ETH, &qs->txq_stopped); - q->stops++; - dev_err(&adap->pdev->dev, - "%s: Tx ring %u full while queue awake!\n", - dev->name, q->cntxt_id & 7); - } - spin_unlock(&q->lock); - return NETDEV_TX_BUSY; - } - - q->in_use += ndesc; - if (unlikely(credits - ndesc < q->stop_thres)) { - q->stops++; - netif_stop_queue(dev); - set_bit(TXQ_ETH, &qs->txq_stopped); -#if !USE_GTS - if (should_restart_tx(q) && - test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) { - q->restarts++; - netif_wake_queue(dev); - } -#endif - } - - gen = q->gen; - q->unacked += ndesc; - compl = (q->unacked & 8) << (S_WR_COMPL - 3); - q->unacked &= 7; - pidx = q->pidx; - q->pidx += ndesc; - if (q->pidx >= q->size) { - q->pidx -= q->size; - q->gen ^= 1; - } - - /* update port statistics */ - if (skb->ip_summed == CHECKSUM_COMPLETE) - qs->port_stats[SGE_PSTAT_TX_CSUM]++; - if (skb_shinfo(skb)->gso_size) - qs->port_stats[SGE_PSTAT_TSO]++; - if (vlan_tx_tag_present(skb) && pi->vlan_grp) - qs->port_stats[SGE_PSTAT_VLANINS]++; - - dev->trans_start = jiffies; - spin_unlock(&q->lock); - - /* - * We do not use Tx completion interrupts to free DMAd Tx packets. - * This is good for performamce but means that we rely on new Tx - * packets arriving to run the destructors of completed packets, - * which open up space in their sockets' send queues. Sometimes - * we do not get such new packets causing Tx to stall. A single - * UDP transmitter is a good example of this situation. We have - * a clean up timer that periodically reclaims completed packets - * but it doesn't run often enough (nor do we want it to) to prevent - * lengthy stalls. A solution to this problem is to run the - * destructor early, after the packet is queued but before it's DMAd. - * A cons is that we lie to socket memory accounting, but the amount - * of extra memory is reasonable (limited by the number of Tx - * descriptors), the packets do actually get freed quickly by new - * packets almost always, and for protocols like TCP that wait for - * acks to really free up the data the extra memory is even less. - * On the positive side we run the destructors on the sending CPU - * rather than on a potentially different completing CPU, usually a - * good thing. We also run them without holding our Tx queue lock, - * unlike what reclaim_completed_tx() would otherwise do. - * - * Run the destructor before telling the DMA engine about the packet - * to make sure it doesn't complete and get freed prematurely. - */ - if (likely(!skb_shared(skb))) - skb_orphan(skb); - - write_tx_pkt_wr(adap, skb, pi, pidx, gen, q, ndesc, compl); - check_ring_tx_db(adap, q); - return NETDEV_TX_OK; -} - -/** - * write_imm - write a packet into a Tx descriptor as immediate data - * @d: the Tx descriptor to write - * @skb: the packet - * @len: the length of packet data to write as immediate data - * @gen: the generation bit value to write - * - * Writes a packet as immediate data into a Tx descriptor. The packet - * contains a work request at its beginning. We must write the packet - * carefully so the SGE doesn't read accidentally before it's written in - * its entirety. - */ -static inline void write_imm(struct tx_desc *d, struct sk_buff *skb, - unsigned int len, unsigned int gen) -{ - struct work_request_hdr *from = (struct work_request_hdr *)skb->data; - struct work_request_hdr *to = (struct work_request_hdr *)d; - - memcpy(&to[1], &from[1], len - sizeof(*from)); - to->wr_hi = from->wr_hi | htonl(F_WR_SOP | F_WR_EOP | - V_WR_BCNTLFLT(len & 7)); - wmb(); - to->wr_lo = from->wr_lo | htonl(V_WR_GEN(gen) | - V_WR_LEN((len + 7) / 8)); - wr_gen2(d, gen); - kfree_skb(skb); -} - -/** - * check_desc_avail - check descriptor availability on a send queue - * @adap: the adapter - * @q: the send queue - * @skb: the packet needing the descriptors - * @ndesc: the number of Tx descriptors needed - * @qid: the Tx queue number in its queue set (TXQ_OFLD or TXQ_CTRL) - * - * Checks if the requested number of Tx descriptors is available on an - * SGE send queue. If the queue is already suspended or not enough - * descriptors are available the packet is queued for later transmission. - * Must be called with the Tx queue locked. - * - * Returns 0 if enough descriptors are available, 1 if there aren't - * enough descriptors and the packet has been queued, and 2 if the caller - * needs to retry because there weren't enough descriptors at the - * beginning of the call but some freed up in the mean time. - */ -static inline int check_desc_avail(struct adapter *adap, struct sge_txq *q, - struct sk_buff *skb, unsigned int ndesc, - unsigned int qid) -{ - if (unlikely(!skb_queue_empty(&q->sendq))) { - addq_exit:__skb_queue_tail(&q->sendq, skb); - return 1; - } - if (unlikely(q->size - q->in_use < ndesc)) { - struct sge_qset *qs = txq_to_qset(q, qid); - - set_bit(qid, &qs->txq_stopped); - smp_mb__after_clear_bit(); - - if (should_restart_tx(q) && - test_and_clear_bit(qid, &qs->txq_stopped)) - return 2; - - q->stops++; - goto addq_exit; - } - return 0; -} - -/** - * reclaim_completed_tx_imm - reclaim completed control-queue Tx descs - * @q: the SGE control Tx queue - * - * This is a variant of reclaim_completed_tx() that is used for Tx queues - * that send only immediate data (presently just the control queues) and - * thus do not have any sk_buffs to release. - */ -static inline void reclaim_completed_tx_imm(struct sge_txq *q) -{ - unsigned int reclaim = q->processed - q->cleaned; - - q->in_use -= reclaim; - q->cleaned += reclaim; -} - -static inline int immediate(const struct sk_buff *skb) -{ - return skb->len <= WR_LEN && !skb->data_len; -} - -/** - * ctrl_xmit - send a packet through an SGE control Tx queue - * @adap: the adapter - * @q: the control queue - * @skb: the packet - * - * Send a packet through an SGE control Tx queue. Packets sent through - * a control queue must fit entirely as immediate data in a single Tx - * descriptor and have no page fragments. - */ -static int ctrl_xmit(struct adapter *adap, struct sge_txq *q, - struct sk_buff *skb) -{ - int ret; - struct work_request_hdr *wrp = (struct work_request_hdr *)skb->data; - - if (unlikely(!immediate(skb))) { - WARN_ON(1); - dev_kfree_skb(skb); - return NET_XMIT_SUCCESS; - } - - wrp->wr_hi |= htonl(F_WR_SOP | F_WR_EOP); - wrp->wr_lo = htonl(V_WR_TID(q->token)); - - spin_lock(&q->lock); - again:reclaim_completed_tx_imm(q); - - ret = check_desc_avail(adap, q, skb, 1, TXQ_CTRL); - if (unlikely(ret)) { - if (ret == 1) { - spin_unlock(&q->lock); - return NET_XMIT_CN; - } - goto again; - } - - write_imm(&q->desc[q->pidx], skb, skb->len, q->gen); - - q->in_use++; - if (++q->pidx >= q->size) { - q->pidx = 0; - q->gen ^= 1; - } - spin_unlock(&q->lock); - wmb(); - t3_write_reg(adap, A_SG_KDOORBELL, - F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); - return NET_XMIT_SUCCESS; -} - -/** - * restart_ctrlq - restart a suspended control queue - * @qs: the queue set cotaining the control queue - * - * Resumes transmission on a suspended Tx control queue. - */ -static void restart_ctrlq(unsigned long data) -{ - struct sk_buff *skb; - struct sge_qset *qs = (struct sge_qset *)data; - struct sge_txq *q = &qs->txq[TXQ_CTRL]; - struct adapter *adap = qs->netdev->priv; - - spin_lock(&q->lock); - again:reclaim_completed_tx_imm(q); - - while (q->in_use < q->size && (skb = __skb_dequeue(&q->sendq)) != NULL) { - - write_imm(&q->desc[q->pidx], skb, skb->len, q->gen); - - if (++q->pidx >= q->size) { - q->pidx = 0; - q->gen ^= 1; - } - q->in_use++; - } - - if (!skb_queue_empty(&q->sendq)) { - set_bit(TXQ_CTRL, &qs->txq_stopped); - smp_mb__after_clear_bit(); - - if (should_restart_tx(q) && - test_and_clear_bit(TXQ_CTRL, &qs->txq_stopped)) - goto again; - q->stops++; - } - - spin_unlock(&q->lock); - t3_write_reg(adap, A_SG_KDOORBELL, - F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); -} - -/* - * Send a management message through control queue 0 - */ -int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb) -{ - return ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb); -} - -/** - * write_ofld_wr - write an offload work request - * @adap: the adapter - * @skb: the packet to send - * @q: the Tx queue - * @pidx: index of the first Tx descriptor to write - * @gen: the generation value to use - * @ndesc: number of descriptors the packet will occupy - * - * Write an offload work request to send the supplied packet. The packet - * data already carry the work request with most fields populated. - */ -static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb, - struct sge_txq *q, unsigned int pidx, - unsigned int gen, unsigned int ndesc) -{ - unsigned int sgl_flits, flits; - struct work_request_hdr *from; - struct sg_ent *sgp, sgl[MAX_SKB_FRAGS / 2 + 1]; - struct tx_desc *d = &q->desc[pidx]; - - if (immediate(skb)) { - q->sdesc[pidx].skb = NULL; - write_imm(d, skb, skb->len, gen); - return; - } - - /* Only TX_DATA builds SGLs */ - - from = (struct work_request_hdr *)skb->data; - memcpy(&d->flit[1], &from[1], skb->h.raw - skb->data - sizeof(*from)); - - flits = (skb->h.raw - skb->data) / 8; - sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl; - sgl_flits = make_sgl(skb, sgp, skb->h.raw, skb->tail - skb->h.raw, - adap->pdev); - if (need_skb_unmap()) - ((struct unmap_info *)skb->cb)->len = skb->tail - skb->h.raw; - - write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits, - gen, from->wr_hi, from->wr_lo); -} - -/** - * calc_tx_descs_ofld - calculate # of Tx descriptors for an offload packet - * @skb: the packet - * - * Returns the number of Tx descriptors needed for the given offload - * packet. These packets are already fully constructed. - */ -static inline unsigned int calc_tx_descs_ofld(const struct sk_buff *skb) -{ - unsigned int flits, cnt = skb_shinfo(skb)->nr_frags; - - if (skb->len <= WR_LEN && cnt == 0) - return 1; /* packet fits as immediate data */ - - flits = (skb->h.raw - skb->data) / 8; /* headers */ - if (skb->tail != skb->h.raw) - cnt++; - return flits_to_desc(flits + sgl_len(cnt)); -} - -/** - * ofld_xmit - send a packet through an offload queue - * @adap: the adapter - * @q: the Tx offload queue - * @skb: the packet - * - * Send an offload packet through an SGE offload queue. - */ -static int ofld_xmit(struct adapter *adap, struct sge_txq *q, - struct sk_buff *skb) -{ - int ret; - unsigned int ndesc = calc_tx_descs_ofld(skb), pidx, gen; - - spin_lock(&q->lock); - again:reclaim_completed_tx(adap, q); - - ret = check_desc_avail(adap, q, skb, ndesc, TXQ_OFLD); - if (unlikely(ret)) { - if (ret == 1) { - skb->priority = ndesc; /* save for restart */ - spin_unlock(&q->lock); - return NET_XMIT_CN; - } - goto again; - } - - gen = q->gen; - q->in_use += ndesc; - pidx = q->pidx; - q->pidx += ndesc; - if (q->pidx >= q->size) { - q->pidx -= q->size; - q->gen ^= 1; - } - spin_unlock(&q->lock); - - write_ofld_wr(adap, skb, q, pidx, gen, ndesc); - check_ring_tx_db(adap, q); - return NET_XMIT_SUCCESS; -} - -/** - * restart_offloadq - restart a suspended offload queue - * @qs: the queue set cotaining the offload queue - * - * Resumes transmission on a suspended Tx offload queue. - */ -static void restart_offloadq(unsigned long data) -{ - struct sk_buff *skb; - struct sge_qset *qs = (struct sge_qset *)data; - struct sge_txq *q = &qs->txq[TXQ_OFLD]; - struct adapter *adap = qs->netdev->priv; - - spin_lock(&q->lock); - again:reclaim_completed_tx(adap, q); - - while ((skb = skb_peek(&q->sendq)) != NULL) { - unsigned int gen, pidx; - unsigned int ndesc = skb->priority; - - if (unlikely(q->size - q->in_use < ndesc)) { - set_bit(TXQ_OFLD, &qs->txq_stopped); - smp_mb__after_clear_bit(); - - if (should_restart_tx(q) && - test_and_clear_bit(TXQ_OFLD, &qs->txq_stopped)) - goto again; - q->stops++; - break; - } - - gen = q->gen; - q->in_use += ndesc; - pidx = q->pidx; - q->pidx += ndesc; - if (q->pidx >= q->size) { - q->pidx -= q->size; - q->gen ^= 1; - } - __skb_unlink(skb, &q->sendq); - spin_unlock(&q->lock); - - write_ofld_wr(adap, skb, q, pidx, gen, ndesc); - spin_lock(&q->lock); - } - spin_unlock(&q->lock); - -#if USE_GTS - set_bit(TXQ_RUNNING, &q->flags); - set_bit(TXQ_LAST_PKT_DB, &q->flags); -#endif - t3_write_reg(adap, A_SG_KDOORBELL, - F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); -} - -/** - * queue_set - return the queue set a packet should use - * @skb: the packet - * - * Maps a packet to the SGE queue set it should use. The desired queue - * set is carried in bits 1-3 in the packet's priority. - */ -static inline int queue_set(const struct sk_buff *skb) -{ - return skb->priority >> 1; -} - -/** - * is_ctrl_pkt - return whether an offload packet is a control packet - * @skb: the packet - * - * Determines whether an offload packet should use an OFLD or a CTRL - * Tx queue. This is indicated by bit 0 in the packet's priority. - */ -static inline int is_ctrl_pkt(const struct sk_buff *skb) -{ - return skb->priority & 1; -} - -/** - * t3_offload_tx - send an offload packet - * @tdev: the offload device to send to - * @skb: the packet - * - * Sends an offload packet. We use the packet priority to select the - * appropriate Tx queue as follows: bit 0 indicates whether the packet - * should be sent as regular or control, bits 1-3 select the queue set. - */ -int t3_offload_tx(struct t3cdev *tdev, struct sk_buff *skb) -{ - struct adapter *adap = tdev2adap(tdev); - struct sge_qset *qs = &adap->sge.qs[queue_set(skb)]; - - if (unlikely(is_ctrl_pkt(skb))) - return ctrl_xmit(adap, &qs->txq[TXQ_CTRL], skb); - - return ofld_xmit(adap, &qs->txq[TXQ_OFLD], skb); -} - -/** - * offload_enqueue - add an offload packet to an SGE offload receive queue - * @q: the SGE response queue - * @skb: the packet - * - * Add a new offload packet to an SGE response queue's offload packet - * queue. If the packet is the first on the queue it schedules the RX - * softirq to process the queue. - */ -static inline void offload_enqueue(struct sge_rspq *q, struct sk_buff *skb) -{ - skb->next = skb->prev = NULL; - if (q->rx_tail) - q->rx_tail->next = skb; - else { - struct sge_qset *qs = rspq_to_qset(q); - - if (__netif_rx_schedule_prep(qs->netdev)) - __netif_rx_schedule(qs->netdev); - q->rx_head = skb; - } - q->rx_tail = skb; -} - -/** - * deliver_partial_bundle - deliver a (partial) bundle of Rx offload pkts - * @tdev: the offload device that will be receiving the packets - * @q: the SGE response queue that assembled the bundle - * @skbs: the partial bundle - * @n: the number of packets in the bundle - * - * Delivers a (partial) bundle of Rx offload packets to an offload device. - */ -static inline void deliver_partial_bundle(struct t3cdev *tdev, - struct sge_rspq *q, - struct sk_buff *skbs[], int n) -{ - if (n) { - q->offload_bundles++; - tdev->recv(tdev, skbs, n); - } -} - -/** - * ofld_poll - NAPI handler for offload packets in interrupt mode - * @dev: the network device doing the polling - * @budget: polling budget - * - * The NAPI handler for offload packets when a response queue is serviced - * by the hard interrupt handler, i.e., when it's operating in non-polling - * mode. Creates small packet batches and sends them through the offload - * receive handler. Batches need to be of modest size as we do prefetches - * on the packets in each. - */ -static int ofld_poll(struct net_device *dev, int *budget) -{ - struct adapter *adapter = dev->priv; - struct sge_qset *qs = dev2qset(dev); - struct sge_rspq *q = &qs->rspq; - int work_done, limit = min(*budget, dev->quota), avail = limit; - - while (avail) { - struct sk_buff *head, *tail, *skbs[RX_BUNDLE_SIZE]; - int ngathered; - - spin_lock_irq(&q->lock); - head = q->rx_head; - if (!head) { - work_done = limit - avail; - *budget -= work_done; - dev->quota -= work_done; - __netif_rx_complete(dev); - spin_unlock_irq(&q->lock); - return 0; - } - - tail = q->rx_tail; - q->rx_head = q->rx_tail = NULL; - spin_unlock_irq(&q->lock); - - for (ngathered = 0; avail && head; avail--) { - prefetch(head->data); - skbs[ngathered] = head; - head = head->next; - skbs[ngathered]->next = NULL; - if (++ngathered == RX_BUNDLE_SIZE) { - q->offload_bundles++; - adapter->tdev.recv(&adapter->tdev, skbs, - ngathered); - ngathered = 0; - } - } - if (head) { /* splice remaining packets back onto Rx queue */ - spin_lock_irq(&q->lock); - tail->next = q->rx_head; - if (!q->rx_head) - q->rx_tail = tail; - q->rx_head = head; - spin_unlock_irq(&q->lock); - } - deliver_partial_bundle(&adapter->tdev, q, skbs, ngathered); - } - work_done = limit - avail; - *budget -= work_done; - dev->quota -= work_done; - return 1; -} - -/** - * rx_offload - process a received offload packet - * @tdev: the offload device receiving the packet - * @rq: the response queue that received the packet - * @skb: the packet - * @rx_gather: a gather list of packets if we are building a bundle - * @gather_idx: index of the next available slot in the bundle - * - * Process an ingress offload pakcet and add it to the offload ingress - * queue. Returns the index of the next available slot in the bundle. - */ -static inline int rx_offload(struct t3cdev *tdev, struct sge_rspq *rq, - struct sk_buff *skb, struct sk_buff *rx_gather[], - unsigned int gather_idx) -{ - rq->offload_pkts++; - skb->mac.raw = skb->nh.raw = skb->h.raw = skb->data; - - if (rq->polling) { - rx_gather[gather_idx++] = skb; - if (gather_idx == RX_BUNDLE_SIZE) { - tdev->recv(tdev, rx_gather, RX_BUNDLE_SIZE); - gather_idx = 0; - rq->offload_bundles++; - } - } else - offload_enqueue(rq, skb); - - return gather_idx; -} - -/** - * restart_tx - check whether to restart suspended Tx queues - * @qs: the queue set to resume - * - * Restarts suspended Tx queues of an SGE queue set if they have enough - * free resources to resume operation. - */ -static void restart_tx(struct sge_qset *qs) -{ - if (test_bit(TXQ_ETH, &qs->txq_stopped) && - should_restart_tx(&qs->txq[TXQ_ETH]) && - test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) { - qs->txq[TXQ_ETH].restarts++; - if (netif_running(qs->netdev)) - netif_wake_queue(qs->netdev); - } - - if (test_bit(TXQ_OFLD, &qs->txq_stopped) && - should_restart_tx(&qs->txq[TXQ_OFLD]) && - test_and_clear_bit(TXQ_OFLD, &qs->txq_stopped)) { - qs->txq[TXQ_OFLD].restarts++; - tasklet_schedule(&qs->txq[TXQ_OFLD].qresume_tsk); - } - if (test_bit(TXQ_CTRL, &qs->txq_stopped) && - should_restart_tx(&qs->txq[TXQ_CTRL]) && - test_and_clear_bit(TXQ_CTRL, &qs->txq_stopped)) { - qs->txq[TXQ_CTRL].restarts++; - tasklet_schedule(&qs->txq[TXQ_CTRL].qresume_tsk); - } -} - -/** - * rx_eth - process an ingress ethernet packet - * @adap: the adapter - * @rq: the response queue that received the packet - * @skb: the packet - * @pad: amount of padding at the start of the buffer - * - * Process an ingress ethernet pakcet and deliver it to the stack. - * The padding is 2 if the packet was delivered in an Rx buffer and 0 - * if it was immediate data in a response. - */ -static void rx_eth(struct adapter *adap, struct sge_rspq *rq, - struct sk_buff *skb, int pad) -{ - struct cpl_rx_pkt *p = (struct cpl_rx_pkt *)(skb->data + pad); - struct port_info *pi; - - rq->eth_pkts++; - skb_pull(skb, sizeof(*p) + pad); - skb->dev = adap->port[p->iff]; - skb->dev->last_rx = jiffies; - skb->protocol = eth_type_trans(skb, skb->dev); - pi = netdev_priv(skb->dev); - if (pi->rx_csum_offload && p->csum_valid && p->csum == 0xffff && - !p->fragment) { - rspq_to_qset(rq)->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else - skb->ip_summed = CHECKSUM_NONE; - - if (unlikely(p->vlan_valid)) { - struct vlan_group *grp = pi->vlan_grp; - - rspq_to_qset(rq)->port_stats[SGE_PSTAT_VLANEX]++; - if (likely(grp)) - __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan), - rq->polling); - else - dev_kfree_skb_any(skb); - } else if (rq->polling) - netif_receive_skb(skb); - else - netif_rx(skb); -} - -/** - * handle_rsp_cntrl_info - handles control information in a response - * @qs: the queue set corresponding to the response - * @flags: the response control flags - * - * Handles the control information of an SGE response, such as GTS - * indications and completion credits for the queue set's Tx queues. - * HW coalesces credits, we don't do any extra SW coalescing. - */ -static inline void handle_rsp_cntrl_info(struct sge_qset *qs, u32 flags) -{ - unsigned int credits; - -#if USE_GTS - if (flags & F_RSPD_TXQ0_GTS) - clear_bit(TXQ_RUNNING, &qs->txq[TXQ_ETH].flags); -#endif - - credits = G_RSPD_TXQ0_CR(flags); - if (credits) - qs->txq[TXQ_ETH].processed += credits; - - credits = G_RSPD_TXQ2_CR(flags); - if (credits) - qs->txq[TXQ_CTRL].processed += credits; - -# if USE_GTS - if (flags & F_RSPD_TXQ1_GTS) - clear_bit(TXQ_RUNNING, &qs->txq[TXQ_OFLD].flags); -# endif - credits = G_RSPD_TXQ1_CR(flags); - if (credits) - qs->txq[TXQ_OFLD].processed += credits; -} - -/** - * check_ring_db - check if we need to ring any doorbells - * @adapter: the adapter - * @qs: the queue set whose Tx queues are to be examined - * @sleeping: indicates which Tx queue sent GTS - * - * Checks if some of a queue set's Tx queues need to ring their doorbells - * to resume transmission after idling while they still have unprocessed - * descriptors. - */ -static void check_ring_db(struct adapter *adap, struct sge_qset *qs, - unsigned int sleeping) -{ - if (sleeping & F_RSPD_TXQ0_GTS) { - struct sge_txq *txq = &qs->txq[TXQ_ETH]; - - if (txq->cleaned + txq->in_use != txq->processed && - !test_and_set_bit(TXQ_LAST_PKT_DB, &txq->flags)) { - set_bit(TXQ_RUNNING, &txq->flags); - t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX | - V_EGRCNTX(txq->cntxt_id)); - } - } - - if (sleeping & F_RSPD_TXQ1_GTS) { - struct sge_txq *txq = &qs->txq[TXQ_OFLD]; - - if (txq->cleaned + txq->in_use != txq->processed && - !test_and_set_bit(TXQ_LAST_PKT_DB, &txq->flags)) { - set_bit(TXQ_RUNNING, &txq->flags); - t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX | - V_EGRCNTX(txq->cntxt_id)); - } - } -} - -/** - * is_new_response - check if a response is newly written - * @r: the response descriptor - * @q: the response queue - * - * Returns true if a response descriptor contains a yet unprocessed - * response. - */ -static inline int is_new_response(const struct rsp_desc *r, - const struct sge_rspq *q) -{ - return (r->intr_gen & F_RSPD_GEN2) == q->gen; -} - -#define RSPD_GTS_MASK (F_RSPD_TXQ0_GTS | F_RSPD_TXQ1_GTS) -#define RSPD_CTRL_MASK (RSPD_GTS_MASK | \ - V_RSPD_TXQ0_CR(M_RSPD_TXQ0_CR) | \ - V_RSPD_TXQ1_CR(M_RSPD_TXQ1_CR) | \ - V_RSPD_TXQ2_CR(M_RSPD_TXQ2_CR)) - -/* How long to delay the next interrupt in case of memory shortage, in 0.1us. */ -#define NOMEM_INTR_DELAY 2500 - -/** - * process_responses - process responses from an SGE response queue - * @adap: the adapter - * @qs: the queue set to which the response queue belongs - * @budget: how many responses can be processed in this round - * - * Process responses from an SGE response queue up to the supplied budget. - * Responses include received packets as well as credits and other events - * for the queues that belong to the response queue's queue set. - * A negative budget is effectively unlimited. - * - * Additionally choose the interrupt holdoff time for the next interrupt - * on this queue. If the system is under memory shortage use a fairly - * long delay to help recovery. - */ -static int process_responses(struct adapter *adap, struct sge_qset *qs, - int budget) -{ - struct sge_rspq *q = &qs->rspq; - struct rsp_desc *r = &q->desc[q->cidx]; - int budget_left = budget; - unsigned int sleeping = 0; - struct sk_buff *offload_skbs[RX_BUNDLE_SIZE]; - int ngathered = 0; - - q->next_holdoff = q->holdoff_tmr; - - while (likely(budget_left && is_new_response(r, q))) { - int eth, ethpad = 0; - struct sk_buff *skb = NULL; - u32 len, flags = ntohl(r->flags); - u32 rss_hi = *(const u32 *)r, rss_lo = r->rss_hdr.rss_hash_val; - - eth = r->rss_hdr.opcode == CPL_RX_PKT; - - if (unlikely(flags & F_RSPD_ASYNC_NOTIF)) { - skb = alloc_skb(AN_PKT_SIZE, GFP_ATOMIC); - if (!skb) - goto no_mem; - - memcpy(__skb_put(skb, AN_PKT_SIZE), r, AN_PKT_SIZE); - skb->data[0] = CPL_ASYNC_NOTIF; - rss_hi = htonl(CPL_ASYNC_NOTIF << 24); - q->async_notif++; - } else if (flags & F_RSPD_IMM_DATA_VALID) { - skb = get_imm_packet(r); - if (unlikely(!skb)) { - no_mem: - q->next_holdoff = NOMEM_INTR_DELAY; - q->nomem++; - /* consume one credit since we tried */ - budget_left--; - break; - } - q->imm_data++; - } else if ((len = ntohl(r->len_cq)) != 0) { - struct sge_fl *fl; - - fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0]; - fl->credits--; - skb = get_packet(adap, fl, G_RSPD_LEN(len), - eth ? SGE_RX_DROP_THRES : 0); - if (!skb) - q->rx_drops++; - else if (r->rss_hdr.opcode == CPL_TRACE_PKT) - __skb_pull(skb, 2); - ethpad = 2; - if (++fl->cidx == fl->size) - fl->cidx = 0; - } else - q->pure_rsps++; - - if (flags & RSPD_CTRL_MASK) { - sleeping |= flags & RSPD_GTS_MASK; - handle_rsp_cntrl_info(qs, flags); - } - - r++; - if (unlikely(++q->cidx == q->size)) { - q->cidx = 0; - q->gen ^= 1; - r = q->desc; - } - prefetch(r); - - if (++q->credits >= (q->size / 4)) { - refill_rspq(adap, q, q->credits); - q->credits = 0; - } - - if (likely(skb != NULL)) { - if (eth) - rx_eth(adap, q, skb, ethpad); - else { - /* Preserve the RSS info in csum & priority */ - skb->csum = rss_hi; - skb->priority = rss_lo; - ngathered = rx_offload(&adap->tdev, q, skb, - offload_skbs, ngathered); - } - } - - --budget_left; - } - - deliver_partial_bundle(&adap->tdev, q, offload_skbs, ngathered); - if (sleeping) - check_ring_db(adap, qs, sleeping); - - smp_mb(); /* commit Tx queue .processed updates */ - if (unlikely(qs->txq_stopped != 0)) - restart_tx(qs); - - budget -= budget_left; - return budget; -} - -static inline int is_pure_response(const struct rsp_desc *r) -{ - u32 n = ntohl(r->flags) & (F_RSPD_ASYNC_NOTIF | F_RSPD_IMM_DATA_VALID); - - return (n | r->len_cq) == 0; -} - -/** - * napi_rx_handler - the NAPI handler for Rx processing - * @dev: the net device - * @budget: how many packets we can process in this round - * - * Handler for new data events when using NAPI. - */ -static int napi_rx_handler(struct net_device *dev, int *budget) -{ - struct adapter *adap = dev->priv; - struct sge_qset *qs = dev2qset(dev); - int effective_budget = min(*budget, dev->quota); - - int work_done = process_responses(adap, qs, effective_budget); - *budget -= work_done; - dev->quota -= work_done; - - if (work_done >= effective_budget) - return 1; - - netif_rx_complete(dev); - - /* - * Because we don't atomically flush the following write it is - * possible that in very rare cases it can reach the device in a way - * that races with a new response being written plus an error interrupt - * causing the NAPI interrupt handler below to return unhandled status - * to the OS. To protect against this would require flushing the write - * and doing both the write and the flush with interrupts off. Way too - * expensive and unjustifiable given the rarity of the race. - * - * The race cannot happen at all with MSI-X. - */ - t3_write_reg(adap, A_SG_GTS, V_RSPQ(qs->rspq.cntxt_id) | - V_NEWTIMER(qs->rspq.next_holdoff) | - V_NEWINDEX(qs->rspq.cidx)); - return 0; -} - -/* - * Returns true if the device is already scheduled for polling. - */ -static inline int napi_is_scheduled(struct net_device *dev) -{ - return test_bit(__LINK_STATE_RX_SCHED, &dev->state); -} - -/** - * process_pure_responses - process pure responses from a response queue - * @adap: the adapter - * @qs: the queue set owning the response queue - * @r: the first pure response to process - * - * A simpler version of process_responses() that handles only pure (i.e., - * non data-carrying) responses. Such respones are too light-weight to - * justify calling a softirq under NAPI, so we handle them specially in - * the interrupt handler. The function is called with a pointer to a - * response, which the caller must ensure is a valid pure response. - * - * Returns 1 if it encounters a valid data-carrying response, 0 otherwise. - */ -static int process_pure_responses(struct adapter *adap, struct sge_qset *qs, - struct rsp_desc *r) -{ - struct sge_rspq *q = &qs->rspq; - unsigned int sleeping = 0; - - do { - u32 flags = ntohl(r->flags); - - r++; - if (unlikely(++q->cidx == q->size)) { - q->cidx = 0; - q->gen ^= 1; - r = q->desc; - } - prefetch(r); - - if (flags & RSPD_CTRL_MASK) { - sleeping |= flags & RSPD_GTS_MASK; - handle_rsp_cntrl_info(qs, flags); - } - - q->pure_rsps++; - if (++q->credits >= (q->size / 4)) { - refill_rspq(adap, q, q->credits); - q->credits = 0; - } - } while (is_new_response(r, q) && is_pure_response(r)); - - if (sleeping) - check_ring_db(adap, qs, sleeping); - - smp_mb(); /* commit Tx queue .processed updates */ - if (unlikely(qs->txq_stopped != 0)) - restart_tx(qs); - - return is_new_response(r, q); -} - -/** - * handle_responses - decide what to do with new responses in NAPI mode - * @adap: the adapter - * @q: the response queue - * - * This is used by the NAPI interrupt handlers to decide what to do with - * new SGE responses. If there are no new responses it returns -1. If - * there are new responses and they are pure (i.e., non-data carrying) - * it handles them straight in hard interrupt context as they are very - * cheap and don't deliver any packets. Finally, if there are any data - * signaling responses it schedules the NAPI handler. Returns 1 if it - * schedules NAPI, 0 if all new responses were pure. - * - * The caller must ascertain NAPI is not already running. - */ -static inline int handle_responses(struct adapter *adap, struct sge_rspq *q) -{ - struct sge_qset *qs = rspq_to_qset(q); - struct rsp_desc *r = &q->desc[q->cidx]; - - if (!is_new_response(r, q)) - return -1; - if (is_pure_response(r) && process_pure_responses(adap, qs, r) == 0) { - t3_write_reg(adap, A_SG_GTS, V_RSPQ(q->cntxt_id) | - V_NEWTIMER(q->holdoff_tmr) | V_NEWINDEX(q->cidx)); - return 0; - } - if (likely(__netif_rx_schedule_prep(qs->netdev))) - __netif_rx_schedule(qs->netdev); - return 1; -} - -/* - * The MSI-X interrupt handler for an SGE response queue for the non-NAPI case - * (i.e., response queue serviced in hard interrupt). - */ -irqreturn_t t3_sge_intr_msix(int irq, void *cookie) -{ - struct sge_qset *qs = cookie; - struct adapter *adap = qs->netdev->priv; - struct sge_rspq *q = &qs->rspq; - - spin_lock(&q->lock); - if (process_responses(adap, qs, -1) == 0) - q->unhandled_irqs++; - t3_write_reg(adap, A_SG_GTS, V_RSPQ(q->cntxt_id) | - V_NEWTIMER(q->next_holdoff) | V_NEWINDEX(q->cidx)); - spin_unlock(&q->lock); - return IRQ_HANDLED; -} - -/* - * The MSI-X interrupt handler for an SGE response queue for the NAPI case - * (i.e., response queue serviced by NAPI polling). - */ -irqreturn_t t3_sge_intr_msix_napi(int irq, void *cookie) -{ - struct sge_qset *qs = cookie; - struct adapter *adap = qs->netdev->priv; - struct sge_rspq *q = &qs->rspq; - - spin_lock(&q->lock); - BUG_ON(napi_is_scheduled(qs->netdev)); - - if (handle_responses(adap, q) < 0) - q->unhandled_irqs++; - spin_unlock(&q->lock); - return IRQ_HANDLED; -} - -/* - * The non-NAPI MSI interrupt handler. This needs to handle data events from - * SGE response queues as well as error and other async events as they all use - * the same MSI vector. We use one SGE response queue per port in this mode - * and protect all response queues with queue 0's lock. - */ -static irqreturn_t t3_intr_msi(int irq, void *cookie) -{ - int new_packets = 0; - struct adapter *adap = cookie; - struct sge_rspq *q = &adap->sge.qs[0].rspq; - - spin_lock(&q->lock); - - if (process_responses(adap, &adap->sge.qs[0], -1)) { - t3_write_reg(adap, A_SG_GTS, V_RSPQ(q->cntxt_id) | - V_NEWTIMER(q->next_holdoff) | V_NEWINDEX(q->cidx)); - new_packets = 1; - } - - if (adap->params.nports == 2 && - process_responses(adap, &adap->sge.qs[1], -1)) { - struct sge_rspq *q1 = &adap->sge.qs[1].rspq; - - t3_write_reg(adap, A_SG_GTS, V_RSPQ(q1->cntxt_id) | - V_NEWTIMER(q1->next_holdoff) | - V_NEWINDEX(q1->cidx)); - new_packets = 1; - } - - if (!new_packets && t3_slow_intr_handler(adap) == 0) - q->unhandled_irqs++; - - spin_unlock(&q->lock); - return IRQ_HANDLED; -} - -static int rspq_check_napi(struct net_device *dev, struct sge_rspq *q) -{ - if (!napi_is_scheduled(dev) && is_new_response(&q->desc[q->cidx], q)) { - if (likely(__netif_rx_schedule_prep(dev))) - __netif_rx_schedule(dev); - return 1; - } - return 0; -} - -/* - * The MSI interrupt handler for the NAPI case (i.e., response queues serviced - * by NAPI polling). Handles data events from SGE response queues as well as - * error and other async events as they all use the same MSI vector. We use - * one SGE response queue per port in this mode and protect all response - * queues with queue 0's lock. - */ -irqreturn_t t3_intr_msi_napi(int irq, void *cookie) -{ - int new_packets; - struct adapter *adap = cookie; - struct sge_rspq *q = &adap->sge.qs[0].rspq; - - spin_lock(&q->lock); - - new_packets = rspq_check_napi(adap->sge.qs[0].netdev, q); - if (adap->params.nports == 2) - new_packets += rspq_check_napi(adap->sge.qs[1].netdev, - &adap->sge.qs[1].rspq); - if (!new_packets && t3_slow_intr_handler(adap) == 0) - q->unhandled_irqs++; - - spin_unlock(&q->lock); - return IRQ_HANDLED; -} - -/* - * A helper function that processes responses and issues GTS. - */ -static inline int process_responses_gts(struct adapter *adap, - struct sge_rspq *rq) -{ - int work; - - work = process_responses(adap, rspq_to_qset(rq), -1); - t3_write_reg(adap, A_SG_GTS, V_RSPQ(rq->cntxt_id) | - V_NEWTIMER(rq->next_holdoff) | V_NEWINDEX(rq->cidx)); - return work; -} - -/* - * The legacy INTx interrupt handler. This needs to handle data events from - * SGE response queues as well as error and other async events as they all use - * the same interrupt pin. We use one SGE response queue per port in this mode - * and protect all response queues with queue 0's lock. - */ -static irqreturn_t t3_intr(int irq, void *cookie) -{ - int work_done, w0, w1; - struct adapter *adap = cookie; - struct sge_rspq *q0 = &adap->sge.qs[0].rspq; - struct sge_rspq *q1 = &adap->sge.qs[1].rspq; - - spin_lock(&q0->lock); - - w0 = is_new_response(&q0->desc[q0->cidx], q0); - w1 = adap->params.nports == 2 && - is_new_response(&q1->desc[q1->cidx], q1); - - if (likely(w0 | w1)) { - t3_write_reg(adap, A_PL_CLI, 0); - t3_read_reg(adap, A_PL_CLI); /* flush */ - - if (likely(w0)) - process_responses_gts(adap, q0); - - if (w1) - process_responses_gts(adap, q1); - - work_done = w0 | w1; - } else - work_done = t3_slow_intr_handler(adap); - - spin_unlock(&q0->lock); - return IRQ_RETVAL(work_done != 0); -} - -/* - * Interrupt handler for legacy INTx interrupts for T3B-based cards. - * Handles data events from SGE response queues as well as error and other - * async events as they all use the same interrupt pin. We use one SGE - * response queue per port in this mode and protect all response queues with - * queue 0's lock. - */ -static irqreturn_t t3b_intr(int irq, void *cookie) -{ - u32 map; - struct adapter *adap = cookie; - struct sge_rspq *q0 = &adap->sge.qs[0].rspq; - - t3_write_reg(adap, A_PL_CLI, 0); - map = t3_read_reg(adap, A_SG_DATA_INTR); - - if (unlikely(!map)) /* shared interrupt, most likely */ - return IRQ_NONE; - - spin_lock(&q0->lock); - - if (unlikely(map & F_ERRINTR)) - t3_slow_intr_handler(adap); - - if (likely(map & 1)) - process_responses_gts(adap, q0); - - if (map & 2) - process_responses_gts(adap, &adap->sge.qs[1].rspq); - - spin_unlock(&q0->lock); - return IRQ_HANDLED; -} - -/* - * NAPI interrupt handler for legacy INTx interrupts for T3B-based cards. - * Handles data events from SGE response queues as well as error and other - * async events as they all use the same interrupt pin. We use one SGE - * response queue per port in this mode and protect all response queues with - * queue 0's lock. - */ -static irqreturn_t t3b_intr_napi(int irq, void *cookie) -{ - u32 map; - struct net_device *dev; - struct adapter *adap = cookie; - struct sge_rspq *q0 = &adap->sge.qs[0].rspq; - - t3_write_reg(adap, A_PL_CLI, 0); - map = t3_read_reg(adap, A_SG_DATA_INTR); - - if (unlikely(!map)) /* shared interrupt, most likely */ - return IRQ_NONE; - - spin_lock(&q0->lock); - - if (unlikely(map & F_ERRINTR)) - t3_slow_intr_handler(adap); - - if (likely(map & 1)) { - dev = adap->sge.qs[0].netdev; - - if (likely(__netif_rx_schedule_prep(dev))) - __netif_rx_schedule(dev); - } - if (map & 2) { - dev = adap->sge.qs[1].netdev; - - if (likely(__netif_rx_schedule_prep(dev))) - __netif_rx_schedule(dev); - } - - spin_unlock(&q0->lock); - return IRQ_HANDLED; -} - -/** - * t3_intr_handler - select the top-level interrupt handler - * @adap: the adapter - * @polling: whether using NAPI to service response queues - * - * Selects the top-level interrupt handler based on the type of interrupts - * (MSI-X, MSI, or legacy) and whether NAPI will be used to service the - * response queues. - */ -intr_handler_t t3_intr_handler(struct adapter *adap, int polling) -{ - if (adap->flags & USING_MSIX) - return polling ? t3_sge_intr_msix_napi : t3_sge_intr_msix; - if (adap->flags & USING_MSI) - return polling ? t3_intr_msi_napi : t3_intr_msi; - if (adap->params.rev > 0) - return polling ? t3b_intr_napi : t3b_intr; - return t3_intr; -} - -/** - * t3_sge_err_intr_handler - SGE async event interrupt handler - * @adapter: the adapter - * - * Interrupt handler for SGE asynchronous (non-data) events. - */ -void t3_sge_err_intr_handler(struct adapter *adapter) -{ - unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE); - - if (status & F_RSPQCREDITOVERFOW) - CH_ALERT(adapter, "SGE response queue credit overflow\n"); - - if (status & F_RSPQDISABLED) { - v = t3_read_reg(adapter, A_SG_RSPQ_FL_STATUS); - - CH_ALERT(adapter, - "packet delivered to disabled response queue " - "(0x%x)\n", (v >> S_RSPQ0DISABLED) & 0xff); - } - - t3_write_reg(adapter, A_SG_INT_CAUSE, status); - if (status & (F_RSPQCREDITOVERFOW | F_RSPQDISABLED)) - t3_fatal_err(adapter); -} - -/** - * sge_timer_cb - perform periodic maintenance of an SGE qset - * @data: the SGE queue set to maintain - * - * Runs periodically from a timer to perform maintenance of an SGE queue - * set. It performs two tasks: - * - * a) Cleans up any completed Tx descriptors that may still be pending. - * Normal descriptor cleanup happens when new packets are added to a Tx - * queue so this timer is relatively infrequent and does any cleanup only - * if the Tx queue has not seen any new packets in a while. We make a - * best effort attempt to reclaim descriptors, in that we don't wait - * around if we cannot get a queue's lock (which most likely is because - * someone else is queueing new packets and so will also handle the clean - * up). Since control queues use immediate data exclusively we don't - * bother cleaning them up here. - * - * b) Replenishes Rx queues that have run out due to memory shortage. - * Normally new Rx buffers are added when existing ones are consumed but - * when out of memory a queue can become empty. We try to add only a few - * buffers here, the queue will be replenished fully as these new buffers - * are used up if memory shortage has subsided. - */ -static void sge_timer_cb(unsigned long data) -{ - spinlock_t *lock; - struct sge_qset *qs = (struct sge_qset *)data; - struct adapter *adap = qs->netdev->priv; - - if (spin_trylock(&qs->txq[TXQ_ETH].lock)) { - reclaim_completed_tx(adap, &qs->txq[TXQ_ETH]); - spin_unlock(&qs->txq[TXQ_ETH].lock); - } - if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) { - reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD]); - spin_unlock(&qs->txq[TXQ_OFLD].lock); - } - lock = (adap->flags & USING_MSIX) ? &qs->rspq.lock : - &adap->sge.qs[0].rspq.lock; - if (spin_trylock_irq(lock)) { - if (!napi_is_scheduled(qs->netdev)) { - if (qs->fl[0].credits < qs->fl[0].size) - __refill_fl(adap, &qs->fl[0]); - if (qs->fl[1].credits < qs->fl[1].size) - __refill_fl(adap, &qs->fl[1]); - } - spin_unlock_irq(lock); - } - mod_timer(&qs->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD); -} - -/** - * t3_update_qset_coalesce - update coalescing settings for a queue set - * @qs: the SGE queue set - * @p: new queue set parameters - * - * Update the coalescing settings for an SGE queue set. Nothing is done - * if the queue set is not initialized yet. - */ -void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p) -{ - if (!qs->netdev) - return; - - qs->rspq.holdoff_tmr = max(p->coalesce_usecs * 10, 1U);/* can't be 0 */ - qs->rspq.polling = p->polling; - qs->netdev->poll = p->polling ? napi_rx_handler : ofld_poll; -} - -/** - * t3_sge_alloc_qset - initialize an SGE queue set - * @adapter: the adapter - * @id: the queue set id - * @nports: how many Ethernet ports will be using this queue set - * @irq_vec_idx: the IRQ vector index for response queue interrupts - * @p: configuration parameters for this queue set - * @ntxq: number of Tx queues for the queue set - * @netdev: net device associated with this queue set - * - * Allocate resources and initialize an SGE queue set. A queue set - * comprises a response queue, two Rx free-buffer queues, and up to 3 - * Tx queues. The Tx queues are assigned roles in the order Ethernet - * queue, offload queue, and control queue. - */ -int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, - int irq_vec_idx, const struct qset_params *p, - int ntxq, struct net_device *netdev) -{ - int i, ret = -ENOMEM; - struct sge_qset *q = &adapter->sge.qs[id]; - - init_qset_cntxt(q, id); - init_timer(&q->tx_reclaim_timer); - q->tx_reclaim_timer.data = (unsigned long)q; - q->tx_reclaim_timer.function = sge_timer_cb; - - q->fl[0].desc = alloc_ring(adapter->pdev, p->fl_size, - sizeof(struct rx_desc), - sizeof(struct rx_sw_desc), - &q->fl[0].phys_addr, &q->fl[0].sdesc); - if (!q->fl[0].desc) - goto err; - - q->fl[1].desc = alloc_ring(adapter->pdev, p->jumbo_size, - sizeof(struct rx_desc), - sizeof(struct rx_sw_desc), - &q->fl[1].phys_addr, &q->fl[1].sdesc); - if (!q->fl[1].desc) - goto err; - - q->rspq.desc = alloc_ring(adapter->pdev, p->rspq_size, - sizeof(struct rsp_desc), 0, - &q->rspq.phys_addr, NULL); - if (!q->rspq.desc) - goto err; - - for (i = 0; i < ntxq; ++i) { - /* - * The control queue always uses immediate data so does not - * need to keep track of any sk_buffs. - */ - size_t sz = i == TXQ_CTRL ? 0 : sizeof(struct tx_sw_desc); - - q->txq[i].desc = alloc_ring(adapter->pdev, p->txq_size[i], - sizeof(struct tx_desc), sz, - &q->txq[i].phys_addr, - &q->txq[i].sdesc); - if (!q->txq[i].desc) - goto err; - - q->txq[i].gen = 1; - q->txq[i].size = p->txq_size[i]; - spin_lock_init(&q->txq[i].lock); - skb_queue_head_init(&q->txq[i].sendq); - } - - tasklet_init(&q->txq[TXQ_OFLD].qresume_tsk, restart_offloadq, - (unsigned long)q); - tasklet_init(&q->txq[TXQ_CTRL].qresume_tsk, restart_ctrlq, - (unsigned long)q); - - q->fl[0].gen = q->fl[1].gen = 1; - q->fl[0].size = p->fl_size; - q->fl[1].size = p->jumbo_size; - - q->rspq.gen = 1; - q->rspq.size = p->rspq_size; - spin_lock_init(&q->rspq.lock); - - q->txq[TXQ_ETH].stop_thres = nports * - flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3); - - if (ntxq == 1) { - q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + 2 + - sizeof(struct cpl_rx_pkt); - q->fl[1].buf_size = MAX_FRAME_SIZE + 2 + - sizeof(struct cpl_rx_pkt); - } else { - q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + - sizeof(struct cpl_rx_data); - q->fl[1].buf_size = (16 * 1024) - - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - } - - spin_lock(&adapter->sge.reg_lock); - - /* FL threshold comparison uses < */ - ret = t3_sge_init_rspcntxt(adapter, q->rspq.cntxt_id, irq_vec_idx, - q->rspq.phys_addr, q->rspq.size, - q->fl[0].buf_size, 1, 0); - if (ret) - goto err_unlock; - - for (i = 0; i < SGE_RXQ_PER_SET; ++i) { - ret = t3_sge_init_flcntxt(adapter, q->fl[i].cntxt_id, 0, - q->fl[i].phys_addr, q->fl[i].size, - q->fl[i].buf_size, p->cong_thres, 1, - 0); - if (ret) - goto err_unlock; - } - - ret = t3_sge_init_ecntxt(adapter, q->txq[TXQ_ETH].cntxt_id, USE_GTS, - SGE_CNTXT_ETH, id, q->txq[TXQ_ETH].phys_addr, - q->txq[TXQ_ETH].size, q->txq[TXQ_ETH].token, - 1, 0); - if (ret) - goto err_unlock; - - if (ntxq > 1) { - ret = t3_sge_init_ecntxt(adapter, q->txq[TXQ_OFLD].cntxt_id, - USE_GTS, SGE_CNTXT_OFLD, id, - q->txq[TXQ_OFLD].phys_addr, - q->txq[TXQ_OFLD].size, 0, 1, 0); - if (ret) - goto err_unlock; - } - - if (ntxq > 2) { - ret = t3_sge_init_ecntxt(adapter, q->txq[TXQ_CTRL].cntxt_id, 0, - SGE_CNTXT_CTRL, id, - q->txq[TXQ_CTRL].phys_addr, - q->txq[TXQ_CTRL].size, - q->txq[TXQ_CTRL].token, 1, 0); - if (ret) - goto err_unlock; - } - - spin_unlock(&adapter->sge.reg_lock); - q->netdev = netdev; - t3_update_qset_coalesce(q, p); - - /* - * We use atalk_ptr as a backpointer to a qset. In case a device is - * associated with multiple queue sets only the first one sets - * atalk_ptr. - */ - if (netdev->atalk_ptr == NULL) - netdev->atalk_ptr = q; - - refill_fl(adapter, &q->fl[0], q->fl[0].size, GFP_KERNEL); - refill_fl(adapter, &q->fl[1], q->fl[1].size, GFP_KERNEL); - refill_rspq(adapter, &q->rspq, q->rspq.size - 1); - - t3_write_reg(adapter, A_SG_GTS, V_RSPQ(q->rspq.cntxt_id) | - V_NEWTIMER(q->rspq.holdoff_tmr)); - - mod_timer(&q->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD); - return 0; - - err_unlock: - spin_unlock(&adapter->sge.reg_lock); - err: - t3_free_qset(adapter, q); - return ret; -} - -/** - * t3_free_sge_resources - free SGE resources - * @adap: the adapter - * - * Frees resources used by the SGE queue sets. - */ -void t3_free_sge_resources(struct adapter *adap) -{ - int i; - - for (i = 0; i < SGE_QSETS; ++i) - t3_free_qset(adap, &adap->sge.qs[i]); -} - -/** - * t3_sge_start - enable SGE - * @adap: the adapter - * - * Enables the SGE for DMAs. This is the last step in starting packet - * transfers. - */ -void t3_sge_start(struct adapter *adap) -{ - t3_set_reg_field(adap, A_SG_CONTROL, F_GLOBALENABLE, F_GLOBALENABLE); -} - -/** - * t3_sge_stop - disable SGE operation - * @adap: the adapter - * - * Disables the DMA engine. This can be called in emeregencies (e.g., - * from error interrupts) or from normal process context. In the latter - * case it also disables any pending queue restart tasklets. Note that - * if it is called in interrupt context it cannot disable the restart - * tasklets as it cannot wait, however the tasklets will have no effect - * since the doorbells are disabled and the driver will call this again - * later from process context, at which time the tasklets will be stopped - * if they are still running. - */ -void t3_sge_stop(struct adapter *adap) -{ - t3_set_reg_field(adap, A_SG_CONTROL, F_GLOBALENABLE, 0); - if (!in_interrupt()) { - int i; - - for (i = 0; i < SGE_QSETS; ++i) { - struct sge_qset *qs = &adap->sge.qs[i]; - - tasklet_kill(&qs->txq[TXQ_OFLD].qresume_tsk); - tasklet_kill(&qs->txq[TXQ_CTRL].qresume_tsk); - } - } -} - -/** - * t3_sge_init - initialize SGE - * @adap: the adapter - * @p: the SGE parameters - * - * Performs SGE initialization needed every time after a chip reset. - * We do not initialize any of the queue sets here, instead the driver - * top-level must request those individually. We also do not enable DMA - * here, that should be done after the queues have been set up. - */ -void t3_sge_init(struct adapter *adap, struct sge_params *p) -{ - unsigned int ctrl, ups = ffs(pci_resource_len(adap->pdev, 2) >> 12); - - ctrl = F_DROPPKT | V_PKTSHIFT(2) | F_FLMODE | F_AVOIDCQOVFL | - F_CQCRDTCTRL | - V_HOSTPAGESIZE(PAGE_SHIFT - 11) | F_BIGENDIANINGRESS | - V_USERSPACESIZE(ups ? ups - 1 : 0) | F_ISCSICOALESCING; -#if SGE_NUM_GENBITS == 1 - ctrl |= F_EGRGENCTRL; -#endif - if (adap->params.rev > 0) { - if (!(adap->flags & (USING_MSIX | USING_MSI))) - ctrl |= F_ONEINTMULTQ | F_OPTONEINTMULTQ; - ctrl |= F_CQCRDTCTRL | F_AVOIDCQOVFL; - } - t3_write_reg(adap, A_SG_CONTROL, ctrl); - t3_write_reg(adap, A_SG_EGR_RCQ_DRB_THRSH, V_HIRCQDRBTHRSH(512) | - V_LORCQDRBTHRSH(512)); - t3_write_reg(adap, A_SG_TIMER_TICK, core_ticks_per_usec(adap) / 10); - t3_write_reg(adap, A_SG_CMDQ_CREDIT_TH, V_THRESHOLD(32) | - V_TIMEOUT(200 * core_ticks_per_usec(adap))); - t3_write_reg(adap, A_SG_HI_DRB_HI_THRSH, 1000); - t3_write_reg(adap, A_SG_HI_DRB_LO_THRSH, 256); - t3_write_reg(adap, A_SG_LO_DRB_HI_THRSH, 1000); - t3_write_reg(adap, A_SG_LO_DRB_LO_THRSH, 256); - t3_write_reg(adap, A_SG_OCO_BASE, V_BASE1(0xfff)); - t3_write_reg(adap, A_SG_DRB_PRI_THRESH, 63 * 1024); -} - -/** - * t3_sge_prep - one-time SGE initialization - * @adap: the associated adapter - * @p: SGE parameters - * - * Performs one-time initialization of SGE SW state. Includes determining - * defaults for the assorted SGE parameters, which admins can change until - * they are used to initialize the SGE. - */ -void __devinit t3_sge_prep(struct adapter *adap, struct sge_params *p) -{ - int i; - - p->max_pkt_size = (16 * 1024) - sizeof(struct cpl_rx_data) - - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - - for (i = 0; i < SGE_QSETS; ++i) { - struct qset_params *q = p->qset + i; - - q->polling = adap->params.rev > 0; - q->coalesce_usecs = 5; - q->rspq_size = 1024; - q->fl_size = 4096; - q->jumbo_size = 512; - q->txq_size[TXQ_ETH] = 1024; - q->txq_size[TXQ_OFLD] = 1024; - q->txq_size[TXQ_CTRL] = 256; - q->cong_thres = 0; - } - - spin_lock_init(&adap->sge.reg_lock); -} - -/** - * t3_get_desc - dump an SGE descriptor for debugging purposes - * @qs: the queue set - * @qnum: identifies the specific queue (0..2: Tx, 3:response, 4..5: Rx) - * @idx: the descriptor index in the queue - * @data: where to dump the descriptor contents - * - * Dumps the contents of a HW descriptor of an SGE queue. Returns the - * size of the descriptor. - */ -int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, - unsigned char *data) -{ - if (qnum >= 6) - return -EINVAL; - - if (qnum < 3) { - if (!qs->txq[qnum].desc || idx >= qs->txq[qnum].size) - return -EINVAL; - memcpy(data, &qs->txq[qnum].desc[idx], sizeof(struct tx_desc)); - return sizeof(struct tx_desc); - } - - if (qnum == 3) { - if (!qs->rspq.desc || idx >= qs->rspq.size) - return -EINVAL; - memcpy(data, &qs->rspq.desc[idx], sizeof(struct rsp_desc)); - return sizeof(struct rsp_desc); - } - - qnum -= 4; - if (!qs->fl[qnum].desc || idx >= qs->fl[qnum].size) - return -EINVAL; - memcpy(data, &qs->fl[qnum].desc[idx], sizeof(struct rx_desc)); - return sizeof(struct rx_desc); -} diff --git a/trunk/drivers/net/cxgb3/sge_defs.h b/trunk/drivers/net/cxgb3/sge_defs.h deleted file mode 100644 index 514869e26a76..000000000000 --- a/trunk/drivers/net/cxgb3/sge_defs.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * This file is automatically generated --- any changes will be lost. - */ - -#ifndef _SGE_DEFS_H -#define _SGE_DEFS_H - -#define S_EC_CREDITS 0 -#define M_EC_CREDITS 0x7FFF -#define V_EC_CREDITS(x) ((x) << S_EC_CREDITS) -#define G_EC_CREDITS(x) (((x) >> S_EC_CREDITS) & M_EC_CREDITS) - -#define S_EC_GTS 15 -#define V_EC_GTS(x) ((x) << S_EC_GTS) -#define F_EC_GTS V_EC_GTS(1U) - -#define S_EC_INDEX 16 -#define M_EC_INDEX 0xFFFF -#define V_EC_INDEX(x) ((x) << S_EC_INDEX) -#define G_EC_INDEX(x) (((x) >> S_EC_INDEX) & M_EC_INDEX) - -#define S_EC_SIZE 0 -#define M_EC_SIZE 0xFFFF -#define V_EC_SIZE(x) ((x) << S_EC_SIZE) -#define G_EC_SIZE(x) (((x) >> S_EC_SIZE) & M_EC_SIZE) - -#define S_EC_BASE_LO 16 -#define M_EC_BASE_LO 0xFFFF -#define V_EC_BASE_LO(x) ((x) << S_EC_BASE_LO) -#define G_EC_BASE_LO(x) (((x) >> S_EC_BASE_LO) & M_EC_BASE_LO) - -#define S_EC_BASE_HI 0 -#define M_EC_BASE_HI 0xF -#define V_EC_BASE_HI(x) ((x) << S_EC_BASE_HI) -#define G_EC_BASE_HI(x) (((x) >> S_EC_BASE_HI) & M_EC_BASE_HI) - -#define S_EC_RESPQ 4 -#define M_EC_RESPQ 0x7 -#define V_EC_RESPQ(x) ((x) << S_EC_RESPQ) -#define G_EC_RESPQ(x) (((x) >> S_EC_RESPQ) & M_EC_RESPQ) - -#define S_EC_TYPE 7 -#define M_EC_TYPE 0x7 -#define V_EC_TYPE(x) ((x) << S_EC_TYPE) -#define G_EC_TYPE(x) (((x) >> S_EC_TYPE) & M_EC_TYPE) - -#define S_EC_GEN 10 -#define V_EC_GEN(x) ((x) << S_EC_GEN) -#define F_EC_GEN V_EC_GEN(1U) - -#define S_EC_UP_TOKEN 11 -#define M_EC_UP_TOKEN 0xFFFFF -#define V_EC_UP_TOKEN(x) ((x) << S_EC_UP_TOKEN) -#define G_EC_UP_TOKEN(x) (((x) >> S_EC_UP_TOKEN) & M_EC_UP_TOKEN) - -#define S_EC_VALID 31 -#define V_EC_VALID(x) ((x) << S_EC_VALID) -#define F_EC_VALID V_EC_VALID(1U) - -#define S_RQ_MSI_VEC 20 -#define M_RQ_MSI_VEC 0x3F -#define V_RQ_MSI_VEC(x) ((x) << S_RQ_MSI_VEC) -#define G_RQ_MSI_VEC(x) (((x) >> S_RQ_MSI_VEC) & M_RQ_MSI_VEC) - -#define S_RQ_INTR_EN 26 -#define V_RQ_INTR_EN(x) ((x) << S_RQ_INTR_EN) -#define F_RQ_INTR_EN V_RQ_INTR_EN(1U) - -#define S_RQ_GEN 28 -#define V_RQ_GEN(x) ((x) << S_RQ_GEN) -#define F_RQ_GEN V_RQ_GEN(1U) - -#define S_CQ_INDEX 0 -#define M_CQ_INDEX 0xFFFF -#define V_CQ_INDEX(x) ((x) << S_CQ_INDEX) -#define G_CQ_INDEX(x) (((x) >> S_CQ_INDEX) & M_CQ_INDEX) - -#define S_CQ_SIZE 16 -#define M_CQ_SIZE 0xFFFF -#define V_CQ_SIZE(x) ((x) << S_CQ_SIZE) -#define G_CQ_SIZE(x) (((x) >> S_CQ_SIZE) & M_CQ_SIZE) - -#define S_CQ_BASE_HI 0 -#define M_CQ_BASE_HI 0xFFFFF -#define V_CQ_BASE_HI(x) ((x) << S_CQ_BASE_HI) -#define G_CQ_BASE_HI(x) (((x) >> S_CQ_BASE_HI) & M_CQ_BASE_HI) - -#define S_CQ_RSPQ 20 -#define M_CQ_RSPQ 0x3F -#define V_CQ_RSPQ(x) ((x) << S_CQ_RSPQ) -#define G_CQ_RSPQ(x) (((x) >> S_CQ_RSPQ) & M_CQ_RSPQ) - -#define S_CQ_ASYNC_NOTIF 26 -#define V_CQ_ASYNC_NOTIF(x) ((x) << S_CQ_ASYNC_NOTIF) -#define F_CQ_ASYNC_NOTIF V_CQ_ASYNC_NOTIF(1U) - -#define S_CQ_ARMED 27 -#define V_CQ_ARMED(x) ((x) << S_CQ_ARMED) -#define F_CQ_ARMED V_CQ_ARMED(1U) - -#define S_CQ_ASYNC_NOTIF_SOL 28 -#define V_CQ_ASYNC_NOTIF_SOL(x) ((x) << S_CQ_ASYNC_NOTIF_SOL) -#define F_CQ_ASYNC_NOTIF_SOL V_CQ_ASYNC_NOTIF_SOL(1U) - -#define S_CQ_GEN 29 -#define V_CQ_GEN(x) ((x) << S_CQ_GEN) -#define F_CQ_GEN V_CQ_GEN(1U) - -#define S_CQ_OVERFLOW_MODE 31 -#define V_CQ_OVERFLOW_MODE(x) ((x) << S_CQ_OVERFLOW_MODE) -#define F_CQ_OVERFLOW_MODE V_CQ_OVERFLOW_MODE(1U) - -#define S_CQ_CREDITS 0 -#define M_CQ_CREDITS 0xFFFF -#define V_CQ_CREDITS(x) ((x) << S_CQ_CREDITS) -#define G_CQ_CREDITS(x) (((x) >> S_CQ_CREDITS) & M_CQ_CREDITS) - -#define S_CQ_CREDIT_THRES 16 -#define M_CQ_CREDIT_THRES 0x1FFF -#define V_CQ_CREDIT_THRES(x) ((x) << S_CQ_CREDIT_THRES) -#define G_CQ_CREDIT_THRES(x) (((x) >> S_CQ_CREDIT_THRES) & M_CQ_CREDIT_THRES) - -#define S_FL_BASE_HI 0 -#define M_FL_BASE_HI 0xFFFFF -#define V_FL_BASE_HI(x) ((x) << S_FL_BASE_HI) -#define G_FL_BASE_HI(x) (((x) >> S_FL_BASE_HI) & M_FL_BASE_HI) - -#define S_FL_INDEX_LO 20 -#define M_FL_INDEX_LO 0xFFF -#define V_FL_INDEX_LO(x) ((x) << S_FL_INDEX_LO) -#define G_FL_INDEX_LO(x) (((x) >> S_FL_INDEX_LO) & M_FL_INDEX_LO) - -#define S_FL_INDEX_HI 0 -#define M_FL_INDEX_HI 0xF -#define V_FL_INDEX_HI(x) ((x) << S_FL_INDEX_HI) -#define G_FL_INDEX_HI(x) (((x) >> S_FL_INDEX_HI) & M_FL_INDEX_HI) - -#define S_FL_SIZE 4 -#define M_FL_SIZE 0xFFFF -#define V_FL_SIZE(x) ((x) << S_FL_SIZE) -#define G_FL_SIZE(x) (((x) >> S_FL_SIZE) & M_FL_SIZE) - -#define S_FL_GEN 20 -#define V_FL_GEN(x) ((x) << S_FL_GEN) -#define F_FL_GEN V_FL_GEN(1U) - -#define S_FL_ENTRY_SIZE_LO 21 -#define M_FL_ENTRY_SIZE_LO 0x7FF -#define V_FL_ENTRY_SIZE_LO(x) ((x) << S_FL_ENTRY_SIZE_LO) -#define G_FL_ENTRY_SIZE_LO(x) (((x) >> S_FL_ENTRY_SIZE_LO) & M_FL_ENTRY_SIZE_LO) - -#define S_FL_ENTRY_SIZE_HI 0 -#define M_FL_ENTRY_SIZE_HI 0x1FFFFF -#define V_FL_ENTRY_SIZE_HI(x) ((x) << S_FL_ENTRY_SIZE_HI) -#define G_FL_ENTRY_SIZE_HI(x) (((x) >> S_FL_ENTRY_SIZE_HI) & M_FL_ENTRY_SIZE_HI) - -#define S_FL_CONG_THRES 21 -#define M_FL_CONG_THRES 0x3FF -#define V_FL_CONG_THRES(x) ((x) << S_FL_CONG_THRES) -#define G_FL_CONG_THRES(x) (((x) >> S_FL_CONG_THRES) & M_FL_CONG_THRES) - -#define S_FL_GTS 31 -#define V_FL_GTS(x) ((x) << S_FL_GTS) -#define F_FL_GTS V_FL_GTS(1U) - -#define S_FLD_GEN1 31 -#define V_FLD_GEN1(x) ((x) << S_FLD_GEN1) -#define F_FLD_GEN1 V_FLD_GEN1(1U) - -#define S_FLD_GEN2 0 -#define V_FLD_GEN2(x) ((x) << S_FLD_GEN2) -#define F_FLD_GEN2 V_FLD_GEN2(1U) - -#define S_RSPD_TXQ1_CR 0 -#define M_RSPD_TXQ1_CR 0x7F -#define V_RSPD_TXQ1_CR(x) ((x) << S_RSPD_TXQ1_CR) -#define G_RSPD_TXQ1_CR(x) (((x) >> S_RSPD_TXQ1_CR) & M_RSPD_TXQ1_CR) - -#define S_RSPD_TXQ1_GTS 7 -#define V_RSPD_TXQ1_GTS(x) ((x) << S_RSPD_TXQ1_GTS) -#define F_RSPD_TXQ1_GTS V_RSPD_TXQ1_GTS(1U) - -#define S_RSPD_TXQ2_CR 8 -#define M_RSPD_TXQ2_CR 0x7F -#define V_RSPD_TXQ2_CR(x) ((x) << S_RSPD_TXQ2_CR) -#define G_RSPD_TXQ2_CR(x) (((x) >> S_RSPD_TXQ2_CR) & M_RSPD_TXQ2_CR) - -#define S_RSPD_TXQ2_GTS 15 -#define V_RSPD_TXQ2_GTS(x) ((x) << S_RSPD_TXQ2_GTS) -#define F_RSPD_TXQ2_GTS V_RSPD_TXQ2_GTS(1U) - -#define S_RSPD_TXQ0_CR 16 -#define M_RSPD_TXQ0_CR 0x7F -#define V_RSPD_TXQ0_CR(x) ((x) << S_RSPD_TXQ0_CR) -#define G_RSPD_TXQ0_CR(x) (((x) >> S_RSPD_TXQ0_CR) & M_RSPD_TXQ0_CR) - -#define S_RSPD_TXQ0_GTS 23 -#define V_RSPD_TXQ0_GTS(x) ((x) << S_RSPD_TXQ0_GTS) -#define F_RSPD_TXQ0_GTS V_RSPD_TXQ0_GTS(1U) - -#define S_RSPD_EOP 24 -#define V_RSPD_EOP(x) ((x) << S_RSPD_EOP) -#define F_RSPD_EOP V_RSPD_EOP(1U) - -#define S_RSPD_SOP 25 -#define V_RSPD_SOP(x) ((x) << S_RSPD_SOP) -#define F_RSPD_SOP V_RSPD_SOP(1U) - -#define S_RSPD_ASYNC_NOTIF 26 -#define V_RSPD_ASYNC_NOTIF(x) ((x) << S_RSPD_ASYNC_NOTIF) -#define F_RSPD_ASYNC_NOTIF V_RSPD_ASYNC_NOTIF(1U) - -#define S_RSPD_FL0_GTS 27 -#define V_RSPD_FL0_GTS(x) ((x) << S_RSPD_FL0_GTS) -#define F_RSPD_FL0_GTS V_RSPD_FL0_GTS(1U) - -#define S_RSPD_FL1_GTS 28 -#define V_RSPD_FL1_GTS(x) ((x) << S_RSPD_FL1_GTS) -#define F_RSPD_FL1_GTS V_RSPD_FL1_GTS(1U) - -#define S_RSPD_IMM_DATA_VALID 29 -#define V_RSPD_IMM_DATA_VALID(x) ((x) << S_RSPD_IMM_DATA_VALID) -#define F_RSPD_IMM_DATA_VALID V_RSPD_IMM_DATA_VALID(1U) - -#define S_RSPD_OFFLOAD 30 -#define V_RSPD_OFFLOAD(x) ((x) << S_RSPD_OFFLOAD) -#define F_RSPD_OFFLOAD V_RSPD_OFFLOAD(1U) - -#define S_RSPD_GEN1 31 -#define V_RSPD_GEN1(x) ((x) << S_RSPD_GEN1) -#define F_RSPD_GEN1 V_RSPD_GEN1(1U) - -#define S_RSPD_LEN 0 -#define M_RSPD_LEN 0x7FFFFFFF -#define V_RSPD_LEN(x) ((x) << S_RSPD_LEN) -#define G_RSPD_LEN(x) (((x) >> S_RSPD_LEN) & M_RSPD_LEN) - -#define S_RSPD_FLQ 31 -#define V_RSPD_FLQ(x) ((x) << S_RSPD_FLQ) -#define F_RSPD_FLQ V_RSPD_FLQ(1U) - -#define S_RSPD_GEN2 0 -#define V_RSPD_GEN2(x) ((x) << S_RSPD_GEN2) -#define F_RSPD_GEN2 V_RSPD_GEN2(1U) - -#define S_RSPD_INR_VEC 1 -#define M_RSPD_INR_VEC 0x7F -#define V_RSPD_INR_VEC(x) ((x) << S_RSPD_INR_VEC) -#define G_RSPD_INR_VEC(x) (((x) >> S_RSPD_INR_VEC) & M_RSPD_INR_VEC) - -#endif /* _SGE_DEFS_H */ diff --git a/trunk/drivers/net/cxgb3/t3_cpl.h b/trunk/drivers/net/cxgb3/t3_cpl.h deleted file mode 100644 index b7a1a310dfd4..000000000000 --- a/trunk/drivers/net/cxgb3/t3_cpl.h +++ /dev/null @@ -1,1444 +0,0 @@ -/* - * Copyright (c) 2004-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef T3_CPL_H -#define T3_CPL_H - -#if !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD) -# include -#endif - -enum CPL_opcode { - CPL_PASS_OPEN_REQ = 0x1, - CPL_PASS_ACCEPT_RPL = 0x2, - CPL_ACT_OPEN_REQ = 0x3, - CPL_SET_TCB = 0x4, - CPL_SET_TCB_FIELD = 0x5, - CPL_GET_TCB = 0x6, - CPL_PCMD = 0x7, - CPL_CLOSE_CON_REQ = 0x8, - CPL_CLOSE_LISTSRV_REQ = 0x9, - CPL_ABORT_REQ = 0xA, - CPL_ABORT_RPL = 0xB, - CPL_TX_DATA = 0xC, - CPL_RX_DATA_ACK = 0xD, - CPL_TX_PKT = 0xE, - CPL_RTE_DELETE_REQ = 0xF, - CPL_RTE_WRITE_REQ = 0x10, - CPL_RTE_READ_REQ = 0x11, - CPL_L2T_WRITE_REQ = 0x12, - CPL_L2T_READ_REQ = 0x13, - CPL_SMT_WRITE_REQ = 0x14, - CPL_SMT_READ_REQ = 0x15, - CPL_TX_PKT_LSO = 0x16, - CPL_PCMD_READ = 0x17, - CPL_BARRIER = 0x18, - CPL_TID_RELEASE = 0x1A, - - CPL_CLOSE_LISTSRV_RPL = 0x20, - CPL_ERROR = 0x21, - CPL_GET_TCB_RPL = 0x22, - CPL_L2T_WRITE_RPL = 0x23, - CPL_PCMD_READ_RPL = 0x24, - CPL_PCMD_RPL = 0x25, - CPL_PEER_CLOSE = 0x26, - CPL_RTE_DELETE_RPL = 0x27, - CPL_RTE_WRITE_RPL = 0x28, - CPL_RX_DDP_COMPLETE = 0x29, - CPL_RX_PHYS_ADDR = 0x2A, - CPL_RX_PKT = 0x2B, - CPL_RX_URG_NOTIFY = 0x2C, - CPL_SET_TCB_RPL = 0x2D, - CPL_SMT_WRITE_RPL = 0x2E, - CPL_TX_DATA_ACK = 0x2F, - - CPL_ABORT_REQ_RSS = 0x30, - CPL_ABORT_RPL_RSS = 0x31, - CPL_CLOSE_CON_RPL = 0x32, - CPL_ISCSI_HDR = 0x33, - CPL_L2T_READ_RPL = 0x34, - CPL_RDMA_CQE = 0x35, - CPL_RDMA_CQE_READ_RSP = 0x36, - CPL_RDMA_CQE_ERR = 0x37, - CPL_RTE_READ_RPL = 0x38, - CPL_RX_DATA = 0x39, - - CPL_ACT_OPEN_RPL = 0x40, - CPL_PASS_OPEN_RPL = 0x41, - CPL_RX_DATA_DDP = 0x42, - CPL_SMT_READ_RPL = 0x43, - - CPL_ACT_ESTABLISH = 0x50, - CPL_PASS_ESTABLISH = 0x51, - - CPL_PASS_ACCEPT_REQ = 0x70, - - CPL_ASYNC_NOTIF = 0x80, /* fake opcode for async notifications */ - - CPL_TX_DMA_ACK = 0xA0, - CPL_RDMA_READ_REQ = 0xA1, - CPL_RDMA_TERMINATE = 0xA2, - CPL_TRACE_PKT = 0xA3, - CPL_RDMA_EC_STATUS = 0xA5, - - NUM_CPL_CMDS /* must be last and previous entries must be sorted */ -}; - -enum CPL_error { - CPL_ERR_NONE = 0, - CPL_ERR_TCAM_PARITY = 1, - CPL_ERR_TCAM_FULL = 3, - CPL_ERR_CONN_RESET = 20, - CPL_ERR_CONN_EXIST = 22, - CPL_ERR_ARP_MISS = 23, - CPL_ERR_BAD_SYN = 24, - CPL_ERR_CONN_TIMEDOUT = 30, - CPL_ERR_XMIT_TIMEDOUT = 31, - CPL_ERR_PERSIST_TIMEDOUT = 32, - CPL_ERR_FINWAIT2_TIMEDOUT = 33, - CPL_ERR_KEEPALIVE_TIMEDOUT = 34, - CPL_ERR_RTX_NEG_ADVICE = 35, - CPL_ERR_PERSIST_NEG_ADVICE = 36, - CPL_ERR_ABORT_FAILED = 42, - CPL_ERR_GENERAL = 99 -}; - -enum { - CPL_CONN_POLICY_AUTO = 0, - CPL_CONN_POLICY_ASK = 1, - CPL_CONN_POLICY_DENY = 3 -}; - -enum { - ULP_MODE_NONE = 0, - ULP_MODE_ISCSI = 2, - ULP_MODE_RDMA = 4, - ULP_MODE_TCPDDP = 5 -}; - -enum { - ULP_CRC_HEADER = 1 << 0, - ULP_CRC_DATA = 1 << 1 -}; - -enum { - CPL_PASS_OPEN_ACCEPT, - CPL_PASS_OPEN_REJECT -}; - -enum { - CPL_ABORT_SEND_RST = 0, - CPL_ABORT_NO_RST, - CPL_ABORT_POST_CLOSE_REQ = 2 -}; - -enum { /* TX_PKT_LSO ethernet types */ - CPL_ETH_II, - CPL_ETH_II_VLAN, - CPL_ETH_802_3, - CPL_ETH_802_3_VLAN -}; - -enum { /* TCP congestion control algorithms */ - CONG_ALG_RENO, - CONG_ALG_TAHOE, - CONG_ALG_NEWRENO, - CONG_ALG_HIGHSPEED -}; - -union opcode_tid { - __be32 opcode_tid; - __u8 opcode; -}; - -#define S_OPCODE 24 -#define V_OPCODE(x) ((x) << S_OPCODE) -#define G_OPCODE(x) (((x) >> S_OPCODE) & 0xFF) -#define G_TID(x) ((x) & 0xFFFFFF) - -/* tid is assumed to be 24-bits */ -#define MK_OPCODE_TID(opcode, tid) (V_OPCODE(opcode) | (tid)) - -#define OPCODE_TID(cmd) ((cmd)->ot.opcode_tid) - -/* extract the TID from a CPL command */ -#define GET_TID(cmd) (G_TID(ntohl(OPCODE_TID(cmd)))) - -struct tcp_options { - __be16 mss; - __u8 wsf; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8:5; - __u8 ecn:1; - __u8 sack:1; - __u8 tstamp:1; -#else - __u8 tstamp:1; - __u8 sack:1; - __u8 ecn:1; - __u8:5; -#endif -}; - -struct rss_header { - __u8 opcode; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 cpu_idx:6; - __u8 hash_type:2; -#else - __u8 hash_type:2; - __u8 cpu_idx:6; -#endif - __be16 cq_idx; - __be32 rss_hash_val; -}; - -#ifndef CHELSIO_FW -struct work_request_hdr { - __be32 wr_hi; - __be32 wr_lo; -}; - -/* wr_hi fields */ -#define S_WR_SGE_CREDITS 0 -#define M_WR_SGE_CREDITS 0xFF -#define V_WR_SGE_CREDITS(x) ((x) << S_WR_SGE_CREDITS) -#define G_WR_SGE_CREDITS(x) (((x) >> S_WR_SGE_CREDITS) & M_WR_SGE_CREDITS) - -#define S_WR_SGLSFLT 8 -#define M_WR_SGLSFLT 0xFF -#define V_WR_SGLSFLT(x) ((x) << S_WR_SGLSFLT) -#define G_WR_SGLSFLT(x) (((x) >> S_WR_SGLSFLT) & M_WR_SGLSFLT) - -#define S_WR_BCNTLFLT 16 -#define M_WR_BCNTLFLT 0xF -#define V_WR_BCNTLFLT(x) ((x) << S_WR_BCNTLFLT) -#define G_WR_BCNTLFLT(x) (((x) >> S_WR_BCNTLFLT) & M_WR_BCNTLFLT) - -#define S_WR_DATATYPE 20 -#define V_WR_DATATYPE(x) ((x) << S_WR_DATATYPE) -#define F_WR_DATATYPE V_WR_DATATYPE(1U) - -#define S_WR_COMPL 21 -#define V_WR_COMPL(x) ((x) << S_WR_COMPL) -#define F_WR_COMPL V_WR_COMPL(1U) - -#define S_WR_EOP 22 -#define V_WR_EOP(x) ((x) << S_WR_EOP) -#define F_WR_EOP V_WR_EOP(1U) - -#define S_WR_SOP 23 -#define V_WR_SOP(x) ((x) << S_WR_SOP) -#define F_WR_SOP V_WR_SOP(1U) - -#define S_WR_OP 24 -#define M_WR_OP 0xFF -#define V_WR_OP(x) ((x) << S_WR_OP) -#define G_WR_OP(x) (((x) >> S_WR_OP) & M_WR_OP) - -/* wr_lo fields */ -#define S_WR_LEN 0 -#define M_WR_LEN 0xFF -#define V_WR_LEN(x) ((x) << S_WR_LEN) -#define G_WR_LEN(x) (((x) >> S_WR_LEN) & M_WR_LEN) - -#define S_WR_TID 8 -#define M_WR_TID 0xFFFFF -#define V_WR_TID(x) ((x) << S_WR_TID) -#define G_WR_TID(x) (((x) >> S_WR_TID) & M_WR_TID) - -#define S_WR_CR_FLUSH 30 -#define V_WR_CR_FLUSH(x) ((x) << S_WR_CR_FLUSH) -#define F_WR_CR_FLUSH V_WR_CR_FLUSH(1U) - -#define S_WR_GEN 31 -#define V_WR_GEN(x) ((x) << S_WR_GEN) -#define F_WR_GEN V_WR_GEN(1U) - -# define WR_HDR struct work_request_hdr wr -# define RSS_HDR -#else -# define WR_HDR -# define RSS_HDR struct rss_header rss_hdr; -#endif - -/* option 0 lower-half fields */ -#define S_CPL_STATUS 0 -#define M_CPL_STATUS 0xFF -#define V_CPL_STATUS(x) ((x) << S_CPL_STATUS) -#define G_CPL_STATUS(x) (((x) >> S_CPL_STATUS) & M_CPL_STATUS) - -#define S_INJECT_TIMER 6 -#define V_INJECT_TIMER(x) ((x) << S_INJECT_TIMER) -#define F_INJECT_TIMER V_INJECT_TIMER(1U) - -#define S_NO_OFFLOAD 7 -#define V_NO_OFFLOAD(x) ((x) << S_NO_OFFLOAD) -#define F_NO_OFFLOAD V_NO_OFFLOAD(1U) - -#define S_ULP_MODE 8 -#define M_ULP_MODE 0xF -#define V_ULP_MODE(x) ((x) << S_ULP_MODE) -#define G_ULP_MODE(x) (((x) >> S_ULP_MODE) & M_ULP_MODE) - -#define S_RCV_BUFSIZ 12 -#define M_RCV_BUFSIZ 0x3FFF -#define V_RCV_BUFSIZ(x) ((x) << S_RCV_BUFSIZ) -#define G_RCV_BUFSIZ(x) (((x) >> S_RCV_BUFSIZ) & M_RCV_BUFSIZ) - -#define S_TOS 26 -#define M_TOS 0x3F -#define V_TOS(x) ((x) << S_TOS) -#define G_TOS(x) (((x) >> S_TOS) & M_TOS) - -/* option 0 upper-half fields */ -#define S_DELACK 0 -#define V_DELACK(x) ((x) << S_DELACK) -#define F_DELACK V_DELACK(1U) - -#define S_NO_CONG 1 -#define V_NO_CONG(x) ((x) << S_NO_CONG) -#define F_NO_CONG V_NO_CONG(1U) - -#define S_SRC_MAC_SEL 2 -#define M_SRC_MAC_SEL 0x3 -#define V_SRC_MAC_SEL(x) ((x) << S_SRC_MAC_SEL) -#define G_SRC_MAC_SEL(x) (((x) >> S_SRC_MAC_SEL) & M_SRC_MAC_SEL) - -#define S_L2T_IDX 4 -#define M_L2T_IDX 0x7FF -#define V_L2T_IDX(x) ((x) << S_L2T_IDX) -#define G_L2T_IDX(x) (((x) >> S_L2T_IDX) & M_L2T_IDX) - -#define S_TX_CHANNEL 15 -#define V_TX_CHANNEL(x) ((x) << S_TX_CHANNEL) -#define F_TX_CHANNEL V_TX_CHANNEL(1U) - -#define S_TCAM_BYPASS 16 -#define V_TCAM_BYPASS(x) ((x) << S_TCAM_BYPASS) -#define F_TCAM_BYPASS V_TCAM_BYPASS(1U) - -#define S_NAGLE 17 -#define V_NAGLE(x) ((x) << S_NAGLE) -#define F_NAGLE V_NAGLE(1U) - -#define S_WND_SCALE 18 -#define M_WND_SCALE 0xF -#define V_WND_SCALE(x) ((x) << S_WND_SCALE) -#define G_WND_SCALE(x) (((x) >> S_WND_SCALE) & M_WND_SCALE) - -#define S_KEEP_ALIVE 22 -#define V_KEEP_ALIVE(x) ((x) << S_KEEP_ALIVE) -#define F_KEEP_ALIVE V_KEEP_ALIVE(1U) - -#define S_MAX_RETRANS 23 -#define M_MAX_RETRANS 0xF -#define V_MAX_RETRANS(x) ((x) << S_MAX_RETRANS) -#define G_MAX_RETRANS(x) (((x) >> S_MAX_RETRANS) & M_MAX_RETRANS) - -#define S_MAX_RETRANS_OVERRIDE 27 -#define V_MAX_RETRANS_OVERRIDE(x) ((x) << S_MAX_RETRANS_OVERRIDE) -#define F_MAX_RETRANS_OVERRIDE V_MAX_RETRANS_OVERRIDE(1U) - -#define S_MSS_IDX 28 -#define M_MSS_IDX 0xF -#define V_MSS_IDX(x) ((x) << S_MSS_IDX) -#define G_MSS_IDX(x) (((x) >> S_MSS_IDX) & M_MSS_IDX) - -/* option 1 fields */ -#define S_RSS_ENABLE 0 -#define V_RSS_ENABLE(x) ((x) << S_RSS_ENABLE) -#define F_RSS_ENABLE V_RSS_ENABLE(1U) - -#define S_RSS_MASK_LEN 1 -#define M_RSS_MASK_LEN 0x7 -#define V_RSS_MASK_LEN(x) ((x) << S_RSS_MASK_LEN) -#define G_RSS_MASK_LEN(x) (((x) >> S_RSS_MASK_LEN) & M_RSS_MASK_LEN) - -#define S_CPU_IDX 4 -#define M_CPU_IDX 0x3F -#define V_CPU_IDX(x) ((x) << S_CPU_IDX) -#define G_CPU_IDX(x) (((x) >> S_CPU_IDX) & M_CPU_IDX) - -#define S_MAC_MATCH_VALID 18 -#define V_MAC_MATCH_VALID(x) ((x) << S_MAC_MATCH_VALID) -#define F_MAC_MATCH_VALID V_MAC_MATCH_VALID(1U) - -#define S_CONN_POLICY 19 -#define M_CONN_POLICY 0x3 -#define V_CONN_POLICY(x) ((x) << S_CONN_POLICY) -#define G_CONN_POLICY(x) (((x) >> S_CONN_POLICY) & M_CONN_POLICY) - -#define S_SYN_DEFENSE 21 -#define V_SYN_DEFENSE(x) ((x) << S_SYN_DEFENSE) -#define F_SYN_DEFENSE V_SYN_DEFENSE(1U) - -#define S_VLAN_PRI 22 -#define M_VLAN_PRI 0x3 -#define V_VLAN_PRI(x) ((x) << S_VLAN_PRI) -#define G_VLAN_PRI(x) (((x) >> S_VLAN_PRI) & M_VLAN_PRI) - -#define S_VLAN_PRI_VALID 24 -#define V_VLAN_PRI_VALID(x) ((x) << S_VLAN_PRI_VALID) -#define F_VLAN_PRI_VALID V_VLAN_PRI_VALID(1U) - -#define S_PKT_TYPE 25 -#define M_PKT_TYPE 0x3 -#define V_PKT_TYPE(x) ((x) << S_PKT_TYPE) -#define G_PKT_TYPE(x) (((x) >> S_PKT_TYPE) & M_PKT_TYPE) - -#define S_MAC_MATCH 27 -#define M_MAC_MATCH 0x1F -#define V_MAC_MATCH(x) ((x) << S_MAC_MATCH) -#define G_MAC_MATCH(x) (((x) >> S_MAC_MATCH) & M_MAC_MATCH) - -/* option 2 fields */ -#define S_CPU_INDEX 0 -#define M_CPU_INDEX 0x7F -#define V_CPU_INDEX(x) ((x) << S_CPU_INDEX) -#define G_CPU_INDEX(x) (((x) >> S_CPU_INDEX) & M_CPU_INDEX) - -#define S_CPU_INDEX_VALID 7 -#define V_CPU_INDEX_VALID(x) ((x) << S_CPU_INDEX_VALID) -#define F_CPU_INDEX_VALID V_CPU_INDEX_VALID(1U) - -#define S_RX_COALESCE 8 -#define M_RX_COALESCE 0x3 -#define V_RX_COALESCE(x) ((x) << S_RX_COALESCE) -#define G_RX_COALESCE(x) (((x) >> S_RX_COALESCE) & M_RX_COALESCE) - -#define S_RX_COALESCE_VALID 10 -#define V_RX_COALESCE_VALID(x) ((x) << S_RX_COALESCE_VALID) -#define F_RX_COALESCE_VALID V_RX_COALESCE_VALID(1U) - -#define S_CONG_CONTROL_FLAVOR 11 -#define M_CONG_CONTROL_FLAVOR 0x3 -#define V_CONG_CONTROL_FLAVOR(x) ((x) << S_CONG_CONTROL_FLAVOR) -#define G_CONG_CONTROL_FLAVOR(x) (((x) >> S_CONG_CONTROL_FLAVOR) & M_CONG_CONTROL_FLAVOR) - -#define S_PACING_FLAVOR 13 -#define M_PACING_FLAVOR 0x3 -#define V_PACING_FLAVOR(x) ((x) << S_PACING_FLAVOR) -#define G_PACING_FLAVOR(x) (((x) >> S_PACING_FLAVOR) & M_PACING_FLAVOR) - -#define S_FLAVORS_VALID 15 -#define V_FLAVORS_VALID(x) ((x) << S_FLAVORS_VALID) -#define F_FLAVORS_VALID V_FLAVORS_VALID(1U) - -#define S_RX_FC_DISABLE 16 -#define V_RX_FC_DISABLE(x) ((x) << S_RX_FC_DISABLE) -#define F_RX_FC_DISABLE V_RX_FC_DISABLE(1U) - -#define S_RX_FC_VALID 17 -#define V_RX_FC_VALID(x) ((x) << S_RX_FC_VALID) -#define F_RX_FC_VALID V_RX_FC_VALID(1U) - -struct cpl_pass_open_req { - WR_HDR; - union opcode_tid ot; - __be16 local_port; - __be16 peer_port; - __be32 local_ip; - __be32 peer_ip; - __be32 opt0h; - __be32 opt0l; - __be32 peer_netmask; - __be32 opt1; -}; - -struct cpl_pass_open_rpl { - RSS_HDR union opcode_tid ot; - __be16 local_port; - __be16 peer_port; - __be32 local_ip; - __be32 peer_ip; - __u8 resvd[7]; - __u8 status; -}; - -struct cpl_pass_establish { - RSS_HDR union opcode_tid ot; - __be16 local_port; - __be16 peer_port; - __be32 local_ip; - __be32 peer_ip; - __be32 tos_tid; - __be16 l2t_idx; - __be16 tcp_opt; - __be32 snd_isn; - __be32 rcv_isn; -}; - -/* cpl_pass_establish.tos_tid fields */ -#define S_PASS_OPEN_TID 0 -#define M_PASS_OPEN_TID 0xFFFFFF -#define V_PASS_OPEN_TID(x) ((x) << S_PASS_OPEN_TID) -#define G_PASS_OPEN_TID(x) (((x) >> S_PASS_OPEN_TID) & M_PASS_OPEN_TID) - -#define S_PASS_OPEN_TOS 24 -#define M_PASS_OPEN_TOS 0xFF -#define V_PASS_OPEN_TOS(x) ((x) << S_PASS_OPEN_TOS) -#define G_PASS_OPEN_TOS(x) (((x) >> S_PASS_OPEN_TOS) & M_PASS_OPEN_TOS) - -/* cpl_pass_establish.l2t_idx fields */ -#define S_L2T_IDX16 5 -#define M_L2T_IDX16 0x7FF -#define V_L2T_IDX16(x) ((x) << S_L2T_IDX16) -#define G_L2T_IDX16(x) (((x) >> S_L2T_IDX16) & M_L2T_IDX16) - -/* cpl_pass_establish.tcp_opt fields (also applies act_open_establish) */ -#define G_TCPOPT_WSCALE_OK(x) (((x) >> 5) & 1) -#define G_TCPOPT_SACK(x) (((x) >> 6) & 1) -#define G_TCPOPT_TSTAMP(x) (((x) >> 7) & 1) -#define G_TCPOPT_SND_WSCALE(x) (((x) >> 8) & 0xf) -#define G_TCPOPT_MSS(x) (((x) >> 12) & 0xf) - -struct cpl_pass_accept_req { - RSS_HDR union opcode_tid ot; - __be16 local_port; - __be16 peer_port; - __be32 local_ip; - __be32 peer_ip; - __be32 tos_tid; - struct tcp_options tcp_options; - __u8 dst_mac[6]; - __be16 vlan_tag; - __u8 src_mac[6]; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8:3; - __u8 addr_idx:3; - __u8 port_idx:1; - __u8 exact_match:1; -#else - __u8 exact_match:1; - __u8 port_idx:1; - __u8 addr_idx:3; - __u8:3; -#endif - __u8 rsvd; - __be32 rcv_isn; - __be32 rsvd2; -}; - -struct cpl_pass_accept_rpl { - WR_HDR; - union opcode_tid ot; - __be32 opt2; - __be32 rsvd; - __be32 peer_ip; - __be32 opt0h; - __be32 opt0l_status; -}; - -struct cpl_act_open_req { - WR_HDR; - union opcode_tid ot; - __be16 local_port; - __be16 peer_port; - __be32 local_ip; - __be32 peer_ip; - __be32 opt0h; - __be32 opt0l; - __be32 params; - __be32 opt2; -}; - -/* cpl_act_open_req.params fields */ -#define S_AOPEN_VLAN_PRI 9 -#define M_AOPEN_VLAN_PRI 0x3 -#define V_AOPEN_VLAN_PRI(x) ((x) << S_AOPEN_VLAN_PRI) -#define G_AOPEN_VLAN_PRI(x) (((x) >> S_AOPEN_VLAN_PRI) & M_AOPEN_VLAN_PRI) - -#define S_AOPEN_VLAN_PRI_VALID 11 -#define V_AOPEN_VLAN_PRI_VALID(x) ((x) << S_AOPEN_VLAN_PRI_VALID) -#define F_AOPEN_VLAN_PRI_VALID V_AOPEN_VLAN_PRI_VALID(1U) - -#define S_AOPEN_PKT_TYPE 12 -#define M_AOPEN_PKT_TYPE 0x3 -#define V_AOPEN_PKT_TYPE(x) ((x) << S_AOPEN_PKT_TYPE) -#define G_AOPEN_PKT_TYPE(x) (((x) >> S_AOPEN_PKT_TYPE) & M_AOPEN_PKT_TYPE) - -#define S_AOPEN_MAC_MATCH 14 -#define M_AOPEN_MAC_MATCH 0x1F -#define V_AOPEN_MAC_MATCH(x) ((x) << S_AOPEN_MAC_MATCH) -#define G_AOPEN_MAC_MATCH(x) (((x) >> S_AOPEN_MAC_MATCH) & M_AOPEN_MAC_MATCH) - -#define S_AOPEN_MAC_MATCH_VALID 19 -#define V_AOPEN_MAC_MATCH_VALID(x) ((x) << S_AOPEN_MAC_MATCH_VALID) -#define F_AOPEN_MAC_MATCH_VALID V_AOPEN_MAC_MATCH_VALID(1U) - -#define S_AOPEN_IFF_VLAN 20 -#define M_AOPEN_IFF_VLAN 0xFFF -#define V_AOPEN_IFF_VLAN(x) ((x) << S_AOPEN_IFF_VLAN) -#define G_AOPEN_IFF_VLAN(x) (((x) >> S_AOPEN_IFF_VLAN) & M_AOPEN_IFF_VLAN) - -struct cpl_act_open_rpl { - RSS_HDR union opcode_tid ot; - __be16 local_port; - __be16 peer_port; - __be32 local_ip; - __be32 peer_ip; - __be32 atid; - __u8 rsvd[3]; - __u8 status; -}; - -struct cpl_act_establish { - RSS_HDR union opcode_tid ot; - __be16 local_port; - __be16 peer_port; - __be32 local_ip; - __be32 peer_ip; - __be32 tos_tid; - __be16 l2t_idx; - __be16 tcp_opt; - __be32 snd_isn; - __be32 rcv_isn; -}; - -struct cpl_get_tcb { - WR_HDR; - union opcode_tid ot; - __be16 cpuno; - __be16 rsvd; -}; - -struct cpl_get_tcb_rpl { - RSS_HDR union opcode_tid ot; - __u8 rsvd; - __u8 status; - __be16 len; -}; - -struct cpl_set_tcb { - WR_HDR; - union opcode_tid ot; - __u8 reply; - __u8 cpu_idx; - __be16 len; -}; - -/* cpl_set_tcb.reply fields */ -#define S_NO_REPLY 7 -#define V_NO_REPLY(x) ((x) << S_NO_REPLY) -#define F_NO_REPLY V_NO_REPLY(1U) - -struct cpl_set_tcb_field { - WR_HDR; - union opcode_tid ot; - __u8 reply; - __u8 cpu_idx; - __be16 word; - __be64 mask; - __be64 val; -}; - -struct cpl_set_tcb_rpl { - RSS_HDR union opcode_tid ot; - __u8 rsvd[3]; - __u8 status; -}; - -struct cpl_pcmd { - WR_HDR; - union opcode_tid ot; - __u8 rsvd[3]; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 src:1; - __u8 bundle:1; - __u8 channel:1; - __u8:5; -#else - __u8:5; - __u8 channel:1; - __u8 bundle:1; - __u8 src:1; -#endif - __be32 pcmd_parm[2]; -}; - -struct cpl_pcmd_reply { - RSS_HDR union opcode_tid ot; - __u8 status; - __u8 rsvd; - __be16 len; -}; - -struct cpl_close_con_req { - WR_HDR; - union opcode_tid ot; - __be32 rsvd; -}; - -struct cpl_close_con_rpl { - RSS_HDR union opcode_tid ot; - __u8 rsvd[3]; - __u8 status; - __be32 snd_nxt; - __be32 rcv_nxt; -}; - -struct cpl_close_listserv_req { - WR_HDR; - union opcode_tid ot; - __u8 rsvd0; - __u8 cpu_idx; - __be16 rsvd1; -}; - -struct cpl_close_listserv_rpl { - RSS_HDR union opcode_tid ot; - __u8 rsvd[3]; - __u8 status; -}; - -struct cpl_abort_req_rss { - RSS_HDR union opcode_tid ot; - __be32 rsvd0; - __u8 rsvd1; - __u8 status; - __u8 rsvd2[6]; -}; - -struct cpl_abort_req { - WR_HDR; - union opcode_tid ot; - __be32 rsvd0; - __u8 rsvd1; - __u8 cmd; - __u8 rsvd2[6]; -}; - -struct cpl_abort_rpl_rss { - RSS_HDR union opcode_tid ot; - __be32 rsvd0; - __u8 rsvd1; - __u8 status; - __u8 rsvd2[6]; -}; - -struct cpl_abort_rpl { - WR_HDR; - union opcode_tid ot; - __be32 rsvd0; - __u8 rsvd1; - __u8 cmd; - __u8 rsvd2[6]; -}; - -struct cpl_peer_close { - RSS_HDR union opcode_tid ot; - __be32 rcv_nxt; -}; - -struct tx_data_wr { - __be32 wr_hi; - __be32 wr_lo; - __be32 len; - __be32 flags; - __be32 sndseq; - __be32 param; -}; - -/* tx_data_wr.param fields */ -#define S_TX_PORT 0 -#define M_TX_PORT 0x7 -#define V_TX_PORT(x) ((x) << S_TX_PORT) -#define G_TX_PORT(x) (((x) >> S_TX_PORT) & M_TX_PORT) - -#define S_TX_MSS 4 -#define M_TX_MSS 0xF -#define V_TX_MSS(x) ((x) << S_TX_MSS) -#define G_TX_MSS(x) (((x) >> S_TX_MSS) & M_TX_MSS) - -#define S_TX_QOS 8 -#define M_TX_QOS 0xFF -#define V_TX_QOS(x) ((x) << S_TX_QOS) -#define G_TX_QOS(x) (((x) >> S_TX_QOS) & M_TX_QOS) - -#define S_TX_SNDBUF 16 -#define M_TX_SNDBUF 0xFFFF -#define V_TX_SNDBUF(x) ((x) << S_TX_SNDBUF) -#define G_TX_SNDBUF(x) (((x) >> S_TX_SNDBUF) & M_TX_SNDBUF) - -struct cpl_tx_data { - union opcode_tid ot; - __be32 len; - __be32 rsvd; - __be16 urg; - __be16 flags; -}; - -/* cpl_tx_data.flags fields */ -#define S_TX_ULP_SUBMODE 6 -#define M_TX_ULP_SUBMODE 0xF -#define V_TX_ULP_SUBMODE(x) ((x) << S_TX_ULP_SUBMODE) -#define G_TX_ULP_SUBMODE(x) (((x) >> S_TX_ULP_SUBMODE) & M_TX_ULP_SUBMODE) - -#define S_TX_ULP_MODE 10 -#define M_TX_ULP_MODE 0xF -#define V_TX_ULP_MODE(x) ((x) << S_TX_ULP_MODE) -#define G_TX_ULP_MODE(x) (((x) >> S_TX_ULP_MODE) & M_TX_ULP_MODE) - -#define S_TX_SHOVE 14 -#define V_TX_SHOVE(x) ((x) << S_TX_SHOVE) -#define F_TX_SHOVE V_TX_SHOVE(1U) - -#define S_TX_MORE 15 -#define V_TX_MORE(x) ((x) << S_TX_MORE) -#define F_TX_MORE V_TX_MORE(1U) - -/* additional tx_data_wr.flags fields */ -#define S_TX_CPU_IDX 0 -#define M_TX_CPU_IDX 0x3F -#define V_TX_CPU_IDX(x) ((x) << S_TX_CPU_IDX) -#define G_TX_CPU_IDX(x) (((x) >> S_TX_CPU_IDX) & M_TX_CPU_IDX) - -#define S_TX_URG 16 -#define V_TX_URG(x) ((x) << S_TX_URG) -#define F_TX_URG V_TX_URG(1U) - -#define S_TX_CLOSE 17 -#define V_TX_CLOSE(x) ((x) << S_TX_CLOSE) -#define F_TX_CLOSE V_TX_CLOSE(1U) - -#define S_TX_INIT 18 -#define V_TX_INIT(x) ((x) << S_TX_INIT) -#define F_TX_INIT V_TX_INIT(1U) - -#define S_TX_IMM_ACK 19 -#define V_TX_IMM_ACK(x) ((x) << S_TX_IMM_ACK) -#define F_TX_IMM_ACK V_TX_IMM_ACK(1U) - -#define S_TX_IMM_DMA 20 -#define V_TX_IMM_DMA(x) ((x) << S_TX_IMM_DMA) -#define F_TX_IMM_DMA V_TX_IMM_DMA(1U) - -struct cpl_tx_data_ack { - RSS_HDR union opcode_tid ot; - __be32 ack_seq; -}; - -struct cpl_wr_ack { - RSS_HDR union opcode_tid ot; - __be16 credits; - __be16 rsvd; - __be32 snd_nxt; - __be32 snd_una; -}; - -struct cpl_rdma_ec_status { - RSS_HDR union opcode_tid ot; - __u8 rsvd[3]; - __u8 status; -}; - -struct mngt_pktsched_wr { - __be32 wr_hi; - __be32 wr_lo; - __u8 mngt_opcode; - __u8 rsvd[7]; - __u8 sched; - __u8 idx; - __u8 min; - __u8 max; - __u8 binding; - __u8 rsvd1[3]; -}; - -struct cpl_iscsi_hdr { - RSS_HDR union opcode_tid ot; - __be16 pdu_len_ddp; - __be16 len; - __be32 seq; - __be16 urg; - __u8 rsvd; - __u8 status; -}; - -/* cpl_iscsi_hdr.pdu_len_ddp fields */ -#define S_ISCSI_PDU_LEN 0 -#define M_ISCSI_PDU_LEN 0x7FFF -#define V_ISCSI_PDU_LEN(x) ((x) << S_ISCSI_PDU_LEN) -#define G_ISCSI_PDU_LEN(x) (((x) >> S_ISCSI_PDU_LEN) & M_ISCSI_PDU_LEN) - -#define S_ISCSI_DDP 15 -#define V_ISCSI_DDP(x) ((x) << S_ISCSI_DDP) -#define F_ISCSI_DDP V_ISCSI_DDP(1U) - -struct cpl_rx_data { - RSS_HDR union opcode_tid ot; - __be16 rsvd; - __be16 len; - __be32 seq; - __be16 urg; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 dack_mode:2; - __u8 psh:1; - __u8 heartbeat:1; - __u8:4; -#else - __u8:4; - __u8 heartbeat:1; - __u8 psh:1; - __u8 dack_mode:2; -#endif - __u8 status; -}; - -struct cpl_rx_data_ack { - WR_HDR; - union opcode_tid ot; - __be32 credit_dack; -}; - -/* cpl_rx_data_ack.ack_seq fields */ -#define S_RX_CREDITS 0 -#define M_RX_CREDITS 0x7FFFFFF -#define V_RX_CREDITS(x) ((x) << S_RX_CREDITS) -#define G_RX_CREDITS(x) (((x) >> S_RX_CREDITS) & M_RX_CREDITS) - -#define S_RX_MODULATE 27 -#define V_RX_MODULATE(x) ((x) << S_RX_MODULATE) -#define F_RX_MODULATE V_RX_MODULATE(1U) - -#define S_RX_FORCE_ACK 28 -#define V_RX_FORCE_ACK(x) ((x) << S_RX_FORCE_ACK) -#define F_RX_FORCE_ACK V_RX_FORCE_ACK(1U) - -#define S_RX_DACK_MODE 29 -#define M_RX_DACK_MODE 0x3 -#define V_RX_DACK_MODE(x) ((x) << S_RX_DACK_MODE) -#define G_RX_DACK_MODE(x) (((x) >> S_RX_DACK_MODE) & M_RX_DACK_MODE) - -#define S_RX_DACK_CHANGE 31 -#define V_RX_DACK_CHANGE(x) ((x) << S_RX_DACK_CHANGE) -#define F_RX_DACK_CHANGE V_RX_DACK_CHANGE(1U) - -struct cpl_rx_urg_notify { - RSS_HDR union opcode_tid ot; - __be32 seq; -}; - -struct cpl_rx_ddp_complete { - RSS_HDR union opcode_tid ot; - __be32 ddp_report; -}; - -struct cpl_rx_data_ddp { - RSS_HDR union opcode_tid ot; - __be16 urg; - __be16 len; - __be32 seq; - union { - __be32 nxt_seq; - __be32 ddp_report; - }; - __be32 ulp_crc; - __be32 ddpvld_status; -}; - -/* cpl_rx_data_ddp.ddpvld_status fields */ -#define S_DDP_STATUS 0 -#define M_DDP_STATUS 0xFF -#define V_DDP_STATUS(x) ((x) << S_DDP_STATUS) -#define G_DDP_STATUS(x) (((x) >> S_DDP_STATUS) & M_DDP_STATUS) - -#define S_DDP_VALID 15 -#define M_DDP_VALID 0x1FFFF -#define V_DDP_VALID(x) ((x) << S_DDP_VALID) -#define G_DDP_VALID(x) (((x) >> S_DDP_VALID) & M_DDP_VALID) - -#define S_DDP_PPOD_MISMATCH 15 -#define V_DDP_PPOD_MISMATCH(x) ((x) << S_DDP_PPOD_MISMATCH) -#define F_DDP_PPOD_MISMATCH V_DDP_PPOD_MISMATCH(1U) - -#define S_DDP_PDU 16 -#define V_DDP_PDU(x) ((x) << S_DDP_PDU) -#define F_DDP_PDU V_DDP_PDU(1U) - -#define S_DDP_LLIMIT_ERR 17 -#define V_DDP_LLIMIT_ERR(x) ((x) << S_DDP_LLIMIT_ERR) -#define F_DDP_LLIMIT_ERR V_DDP_LLIMIT_ERR(1U) - -#define S_DDP_PPOD_PARITY_ERR 18 -#define V_DDP_PPOD_PARITY_ERR(x) ((x) << S_DDP_PPOD_PARITY_ERR) -#define F_DDP_PPOD_PARITY_ERR V_DDP_PPOD_PARITY_ERR(1U) - -#define S_DDP_PADDING_ERR 19 -#define V_DDP_PADDING_ERR(x) ((x) << S_DDP_PADDING_ERR) -#define F_DDP_PADDING_ERR V_DDP_PADDING_ERR(1U) - -#define S_DDP_HDRCRC_ERR 20 -#define V_DDP_HDRCRC_ERR(x) ((x) << S_DDP_HDRCRC_ERR) -#define F_DDP_HDRCRC_ERR V_DDP_HDRCRC_ERR(1U) - -#define S_DDP_DATACRC_ERR 21 -#define V_DDP_DATACRC_ERR(x) ((x) << S_DDP_DATACRC_ERR) -#define F_DDP_DATACRC_ERR V_DDP_DATACRC_ERR(1U) - -#define S_DDP_INVALID_TAG 22 -#define V_DDP_INVALID_TAG(x) ((x) << S_DDP_INVALID_TAG) -#define F_DDP_INVALID_TAG V_DDP_INVALID_TAG(1U) - -#define S_DDP_ULIMIT_ERR 23 -#define V_DDP_ULIMIT_ERR(x) ((x) << S_DDP_ULIMIT_ERR) -#define F_DDP_ULIMIT_ERR V_DDP_ULIMIT_ERR(1U) - -#define S_DDP_OFFSET_ERR 24 -#define V_DDP_OFFSET_ERR(x) ((x) << S_DDP_OFFSET_ERR) -#define F_DDP_OFFSET_ERR V_DDP_OFFSET_ERR(1U) - -#define S_DDP_COLOR_ERR 25 -#define V_DDP_COLOR_ERR(x) ((x) << S_DDP_COLOR_ERR) -#define F_DDP_COLOR_ERR V_DDP_COLOR_ERR(1U) - -#define S_DDP_TID_MISMATCH 26 -#define V_DDP_TID_MISMATCH(x) ((x) << S_DDP_TID_MISMATCH) -#define F_DDP_TID_MISMATCH V_DDP_TID_MISMATCH(1U) - -#define S_DDP_INVALID_PPOD 27 -#define V_DDP_INVALID_PPOD(x) ((x) << S_DDP_INVALID_PPOD) -#define F_DDP_INVALID_PPOD V_DDP_INVALID_PPOD(1U) - -#define S_DDP_ULP_MODE 28 -#define M_DDP_ULP_MODE 0xF -#define V_DDP_ULP_MODE(x) ((x) << S_DDP_ULP_MODE) -#define G_DDP_ULP_MODE(x) (((x) >> S_DDP_ULP_MODE) & M_DDP_ULP_MODE) - -/* cpl_rx_data_ddp.ddp_report fields */ -#define S_DDP_OFFSET 0 -#define M_DDP_OFFSET 0x3FFFFF -#define V_DDP_OFFSET(x) ((x) << S_DDP_OFFSET) -#define G_DDP_OFFSET(x) (((x) >> S_DDP_OFFSET) & M_DDP_OFFSET) - -#define S_DDP_URG 24 -#define V_DDP_URG(x) ((x) << S_DDP_URG) -#define F_DDP_URG V_DDP_URG(1U) - -#define S_DDP_PSH 25 -#define V_DDP_PSH(x) ((x) << S_DDP_PSH) -#define F_DDP_PSH V_DDP_PSH(1U) - -#define S_DDP_BUF_COMPLETE 26 -#define V_DDP_BUF_COMPLETE(x) ((x) << S_DDP_BUF_COMPLETE) -#define F_DDP_BUF_COMPLETE V_DDP_BUF_COMPLETE(1U) - -#define S_DDP_BUF_TIMED_OUT 27 -#define V_DDP_BUF_TIMED_OUT(x) ((x) << S_DDP_BUF_TIMED_OUT) -#define F_DDP_BUF_TIMED_OUT V_DDP_BUF_TIMED_OUT(1U) - -#define S_DDP_BUF_IDX 28 -#define V_DDP_BUF_IDX(x) ((x) << S_DDP_BUF_IDX) -#define F_DDP_BUF_IDX V_DDP_BUF_IDX(1U) - -struct cpl_tx_pkt { - WR_HDR; - __be32 cntrl; - __be32 len; -}; - -struct cpl_tx_pkt_lso { - WR_HDR; - __be32 cntrl; - __be32 len; - - __be32 rsvd; - __be32 lso_info; -}; - -/* cpl_tx_pkt*.cntrl fields */ -#define S_TXPKT_VLAN 0 -#define M_TXPKT_VLAN 0xFFFF -#define V_TXPKT_VLAN(x) ((x) << S_TXPKT_VLAN) -#define G_TXPKT_VLAN(x) (((x) >> S_TXPKT_VLAN) & M_TXPKT_VLAN) - -#define S_TXPKT_INTF 16 -#define M_TXPKT_INTF 0xF -#define V_TXPKT_INTF(x) ((x) << S_TXPKT_INTF) -#define G_TXPKT_INTF(x) (((x) >> S_TXPKT_INTF) & M_TXPKT_INTF) - -#define S_TXPKT_IPCSUM_DIS 20 -#define V_TXPKT_IPCSUM_DIS(x) ((x) << S_TXPKT_IPCSUM_DIS) -#define F_TXPKT_IPCSUM_DIS V_TXPKT_IPCSUM_DIS(1U) - -#define S_TXPKT_L4CSUM_DIS 21 -#define V_TXPKT_L4CSUM_DIS(x) ((x) << S_TXPKT_L4CSUM_DIS) -#define F_TXPKT_L4CSUM_DIS V_TXPKT_L4CSUM_DIS(1U) - -#define S_TXPKT_VLAN_VLD 22 -#define V_TXPKT_VLAN_VLD(x) ((x) << S_TXPKT_VLAN_VLD) -#define F_TXPKT_VLAN_VLD V_TXPKT_VLAN_VLD(1U) - -#define S_TXPKT_LOOPBACK 23 -#define V_TXPKT_LOOPBACK(x) ((x) << S_TXPKT_LOOPBACK) -#define F_TXPKT_LOOPBACK V_TXPKT_LOOPBACK(1U) - -#define S_TXPKT_OPCODE 24 -#define M_TXPKT_OPCODE 0xFF -#define V_TXPKT_OPCODE(x) ((x) << S_TXPKT_OPCODE) -#define G_TXPKT_OPCODE(x) (((x) >> S_TXPKT_OPCODE) & M_TXPKT_OPCODE) - -/* cpl_tx_pkt_lso.lso_info fields */ -#define S_LSO_MSS 0 -#define M_LSO_MSS 0x3FFF -#define V_LSO_MSS(x) ((x) << S_LSO_MSS) -#define G_LSO_MSS(x) (((x) >> S_LSO_MSS) & M_LSO_MSS) - -#define S_LSO_ETH_TYPE 14 -#define M_LSO_ETH_TYPE 0x3 -#define V_LSO_ETH_TYPE(x) ((x) << S_LSO_ETH_TYPE) -#define G_LSO_ETH_TYPE(x) (((x) >> S_LSO_ETH_TYPE) & M_LSO_ETH_TYPE) - -#define S_LSO_TCPHDR_WORDS 16 -#define M_LSO_TCPHDR_WORDS 0xF -#define V_LSO_TCPHDR_WORDS(x) ((x) << S_LSO_TCPHDR_WORDS) -#define G_LSO_TCPHDR_WORDS(x) (((x) >> S_LSO_TCPHDR_WORDS) & M_LSO_TCPHDR_WORDS) - -#define S_LSO_IPHDR_WORDS 20 -#define M_LSO_IPHDR_WORDS 0xF -#define V_LSO_IPHDR_WORDS(x) ((x) << S_LSO_IPHDR_WORDS) -#define G_LSO_IPHDR_WORDS(x) (((x) >> S_LSO_IPHDR_WORDS) & M_LSO_IPHDR_WORDS) - -#define S_LSO_IPV6 24 -#define V_LSO_IPV6(x) ((x) << S_LSO_IPV6) -#define F_LSO_IPV6 V_LSO_IPV6(1U) - -struct cpl_trace_pkt { -#ifdef CHELSIO_FW - __u8 rss_opcode; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 err:1; - __u8:7; -#else - __u8:7; - __u8 err:1; -#endif - __u8 rsvd0; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 qid:4; - __u8:4; -#else - __u8:4; - __u8 qid:4; -#endif - __be32 tstamp; -#endif /* CHELSIO_FW */ - - __u8 opcode; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 iff:4; - __u8:4; -#else - __u8:4; - __u8 iff:4; -#endif - __u8 rsvd[4]; - __be16 len; -}; - -struct cpl_rx_pkt { - RSS_HDR __u8 opcode; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 iff:4; - __u8 csum_valid:1; - __u8 ipmi_pkt:1; - __u8 vlan_valid:1; - __u8 fragment:1; -#else - __u8 fragment:1; - __u8 vlan_valid:1; - __u8 ipmi_pkt:1; - __u8 csum_valid:1; - __u8 iff:4; -#endif - __be16 csum; - __be16 vlan; - __be16 len; -}; - -struct cpl_l2t_write_req { - WR_HDR; - union opcode_tid ot; - __be32 params; - __u8 rsvd[2]; - __u8 dst_mac[6]; -}; - -/* cpl_l2t_write_req.params fields */ -#define S_L2T_W_IDX 0 -#define M_L2T_W_IDX 0x7FF -#define V_L2T_W_IDX(x) ((x) << S_L2T_W_IDX) -#define G_L2T_W_IDX(x) (((x) >> S_L2T_W_IDX) & M_L2T_W_IDX) - -#define S_L2T_W_VLAN 11 -#define M_L2T_W_VLAN 0xFFF -#define V_L2T_W_VLAN(x) ((x) << S_L2T_W_VLAN) -#define G_L2T_W_VLAN(x) (((x) >> S_L2T_W_VLAN) & M_L2T_W_VLAN) - -#define S_L2T_W_IFF 23 -#define M_L2T_W_IFF 0xF -#define V_L2T_W_IFF(x) ((x) << S_L2T_W_IFF) -#define G_L2T_W_IFF(x) (((x) >> S_L2T_W_IFF) & M_L2T_W_IFF) - -#define S_L2T_W_PRIO 27 -#define M_L2T_W_PRIO 0x7 -#define V_L2T_W_PRIO(x) ((x) << S_L2T_W_PRIO) -#define G_L2T_W_PRIO(x) (((x) >> S_L2T_W_PRIO) & M_L2T_W_PRIO) - -struct cpl_l2t_write_rpl { - RSS_HDR union opcode_tid ot; - __u8 status; - __u8 rsvd[3]; -}; - -struct cpl_l2t_read_req { - WR_HDR; - union opcode_tid ot; - __be16 rsvd; - __be16 l2t_idx; -}; - -struct cpl_l2t_read_rpl { - RSS_HDR union opcode_tid ot; - __be32 params; - __u8 rsvd[2]; - __u8 dst_mac[6]; -}; - -/* cpl_l2t_read_rpl.params fields */ -#define S_L2T_R_PRIO 0 -#define M_L2T_R_PRIO 0x7 -#define V_L2T_R_PRIO(x) ((x) << S_L2T_R_PRIO) -#define G_L2T_R_PRIO(x) (((x) >> S_L2T_R_PRIO) & M_L2T_R_PRIO) - -#define S_L2T_R_VLAN 8 -#define M_L2T_R_VLAN 0xFFF -#define V_L2T_R_VLAN(x) ((x) << S_L2T_R_VLAN) -#define G_L2T_R_VLAN(x) (((x) >> S_L2T_R_VLAN) & M_L2T_R_VLAN) - -#define S_L2T_R_IFF 20 -#define M_L2T_R_IFF 0xF -#define V_L2T_R_IFF(x) ((x) << S_L2T_R_IFF) -#define G_L2T_R_IFF(x) (((x) >> S_L2T_R_IFF) & M_L2T_R_IFF) - -#define S_L2T_STATUS 24 -#define M_L2T_STATUS 0xFF -#define V_L2T_STATUS(x) ((x) << S_L2T_STATUS) -#define G_L2T_STATUS(x) (((x) >> S_L2T_STATUS) & M_L2T_STATUS) - -struct cpl_smt_write_req { - WR_HDR; - union opcode_tid ot; - __u8 rsvd0; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 mtu_idx:4; - __u8 iff:4; -#else - __u8 iff:4; - __u8 mtu_idx:4; -#endif - __be16 rsvd2; - __be16 rsvd3; - __u8 src_mac1[6]; - __be16 rsvd4; - __u8 src_mac0[6]; -}; - -struct cpl_smt_write_rpl { - RSS_HDR union opcode_tid ot; - __u8 status; - __u8 rsvd[3]; -}; - -struct cpl_smt_read_req { - WR_HDR; - union opcode_tid ot; - __u8 rsvd0; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8:4; - __u8 iff:4; -#else - __u8 iff:4; - __u8:4; -#endif - __be16 rsvd2; -}; - -struct cpl_smt_read_rpl { - RSS_HDR union opcode_tid ot; - __u8 status; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 mtu_idx:4; - __u8:4; -#else - __u8:4; - __u8 mtu_idx:4; -#endif - __be16 rsvd2; - __be16 rsvd3; - __u8 src_mac1[6]; - __be16 rsvd4; - __u8 src_mac0[6]; -}; - -struct cpl_rte_delete_req { - WR_HDR; - union opcode_tid ot; - __be32 params; -}; - -/* { cpl_rte_delete_req, cpl_rte_read_req }.params fields */ -#define S_RTE_REQ_LUT_IX 8 -#define M_RTE_REQ_LUT_IX 0x7FF -#define V_RTE_REQ_LUT_IX(x) ((x) << S_RTE_REQ_LUT_IX) -#define G_RTE_REQ_LUT_IX(x) (((x) >> S_RTE_REQ_LUT_IX) & M_RTE_REQ_LUT_IX) - -#define S_RTE_REQ_LUT_BASE 19 -#define M_RTE_REQ_LUT_BASE 0x7FF -#define V_RTE_REQ_LUT_BASE(x) ((x) << S_RTE_REQ_LUT_BASE) -#define G_RTE_REQ_LUT_BASE(x) (((x) >> S_RTE_REQ_LUT_BASE) & M_RTE_REQ_LUT_BASE) - -#define S_RTE_READ_REQ_SELECT 31 -#define V_RTE_READ_REQ_SELECT(x) ((x) << S_RTE_READ_REQ_SELECT) -#define F_RTE_READ_REQ_SELECT V_RTE_READ_REQ_SELECT(1U) - -struct cpl_rte_delete_rpl { - RSS_HDR union opcode_tid ot; - __u8 status; - __u8 rsvd[3]; -}; - -struct cpl_rte_write_req { - WR_HDR; - union opcode_tid ot; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8:6; - __u8 write_tcam:1; - __u8 write_l2t_lut:1; -#else - __u8 write_l2t_lut:1; - __u8 write_tcam:1; - __u8:6; -#endif - __u8 rsvd[3]; - __be32 lut_params; - __be16 rsvd2; - __be16 l2t_idx; - __be32 netmask; - __be32 faddr; -}; - -/* cpl_rte_write_req.lut_params fields */ -#define S_RTE_WRITE_REQ_LUT_IX 10 -#define M_RTE_WRITE_REQ_LUT_IX 0x7FF -#define V_RTE_WRITE_REQ_LUT_IX(x) ((x) << S_RTE_WRITE_REQ_LUT_IX) -#define G_RTE_WRITE_REQ_LUT_IX(x) (((x) >> S_RTE_WRITE_REQ_LUT_IX) & M_RTE_WRITE_REQ_LUT_IX) - -#define S_RTE_WRITE_REQ_LUT_BASE 21 -#define M_RTE_WRITE_REQ_LUT_BASE 0x7FF -#define V_RTE_WRITE_REQ_LUT_BASE(x) ((x) << S_RTE_WRITE_REQ_LUT_BASE) -#define G_RTE_WRITE_REQ_LUT_BASE(x) (((x) >> S_RTE_WRITE_REQ_LUT_BASE) & M_RTE_WRITE_REQ_LUT_BASE) - -struct cpl_rte_write_rpl { - RSS_HDR union opcode_tid ot; - __u8 status; - __u8 rsvd[3]; -}; - -struct cpl_rte_read_req { - WR_HDR; - union opcode_tid ot; - __be32 params; -}; - -struct cpl_rte_read_rpl { - RSS_HDR union opcode_tid ot; - __u8 status; - __u8 rsvd0; - __be16 l2t_idx; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8:7; - __u8 select:1; -#else - __u8 select:1; - __u8:7; -#endif - __u8 rsvd2[3]; - __be32 addr; -}; - -struct cpl_tid_release { - WR_HDR; - union opcode_tid ot; - __be32 rsvd; -}; - -struct cpl_barrier { - WR_HDR; - __u8 opcode; - __u8 rsvd[7]; -}; - -struct cpl_rdma_read_req { - __u8 opcode; - __u8 rsvd[15]; -}; - -struct cpl_rdma_terminate { -#ifdef CHELSIO_FW - __u8 opcode; - __u8 rsvd[2]; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 rspq:3; - __u8:5; -#else - __u8:5; - __u8 rspq:3; -#endif - __be32 tid_len; -#endif - __be32 msn; - __be32 mo; - __u8 data[0]; -}; - -/* cpl_rdma_terminate.tid_len fields */ -#define S_FLIT_CNT 0 -#define M_FLIT_CNT 0xFF -#define V_FLIT_CNT(x) ((x) << S_FLIT_CNT) -#define G_FLIT_CNT(x) (((x) >> S_FLIT_CNT) & M_FLIT_CNT) - -#define S_TERM_TID 8 -#define M_TERM_TID 0xFFFFF -#define V_TERM_TID(x) ((x) << S_TERM_TID) -#define G_TERM_TID(x) (((x) >> S_TERM_TID) & M_TERM_TID) -#endif /* T3_CPL_H */ diff --git a/trunk/drivers/net/cxgb3/t3_hw.c b/trunk/drivers/net/cxgb3/t3_hw.c deleted file mode 100644 index 365a7f5b1f94..000000000000 --- a/trunk/drivers/net/cxgb3/t3_hw.c +++ /dev/null @@ -1,3375 +0,0 @@ -/* - * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "common.h" -#include "regs.h" -#include "sge_defs.h" -#include "firmware_exports.h" - -/** - * t3_wait_op_done_val - wait until an operation is completed - * @adapter: the adapter performing the operation - * @reg: the register to check for completion - * @mask: a single-bit field within @reg that indicates completion - * @polarity: the value of the field when the operation is completed - * @attempts: number of check iterations - * @delay: delay in usecs between iterations - * @valp: where to store the value of the register at completion time - * - * Wait until an operation is completed by checking a bit in a register - * up to @attempts times. If @valp is not NULL the value of the register - * at the time it indicated completion is stored there. Returns 0 if the - * operation completes and -EAGAIN otherwise. - */ - -int t3_wait_op_done_val(struct adapter *adapter, int reg, u32 mask, - int polarity, int attempts, int delay, u32 *valp) -{ - while (1) { - u32 val = t3_read_reg(adapter, reg); - - if (!!(val & mask) == polarity) { - if (valp) - *valp = val; - return 0; - } - if (--attempts == 0) - return -EAGAIN; - if (delay) - udelay(delay); - } -} - -/** - * t3_write_regs - write a bunch of registers - * @adapter: the adapter to program - * @p: an array of register address/register value pairs - * @n: the number of address/value pairs - * @offset: register address offset - * - * Takes an array of register address/register value pairs and writes each - * value to the corresponding register. Register addresses are adjusted - * by the supplied offset. - */ -void t3_write_regs(struct adapter *adapter, const struct addr_val_pair *p, - int n, unsigned int offset) -{ - while (n--) { - t3_write_reg(adapter, p->reg_addr + offset, p->val); - p++; - } -} - -/** - * t3_set_reg_field - set a register field to a value - * @adapter: the adapter to program - * @addr: the register address - * @mask: specifies the portion of the register to modify - * @val: the new value for the register field - * - * Sets a register field specified by the supplied mask to the - * given value. - */ -void t3_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask, - u32 val) -{ - u32 v = t3_read_reg(adapter, addr) & ~mask; - - t3_write_reg(adapter, addr, v | val); - t3_read_reg(adapter, addr); /* flush */ -} - -/** - * t3_read_indirect - read indirectly addressed registers - * @adap: the adapter - * @addr_reg: register holding the indirect address - * @data_reg: register holding the value of the indirect register - * @vals: where the read register values are stored - * @start_idx: index of first indirect register to read - * @nregs: how many indirect registers to read - * - * Reads registers that are accessed indirectly through an address/data - * register pair. - */ -void t3_read_indirect(struct adapter *adap, unsigned int addr_reg, - unsigned int data_reg, u32 *vals, unsigned int nregs, - unsigned int start_idx) -{ - while (nregs--) { - t3_write_reg(adap, addr_reg, start_idx); - *vals++ = t3_read_reg(adap, data_reg); - start_idx++; - } -} - -/** - * t3_mc7_bd_read - read from MC7 through backdoor accesses - * @mc7: identifies MC7 to read from - * @start: index of first 64-bit word to read - * @n: number of 64-bit words to read - * @buf: where to store the read result - * - * Read n 64-bit words from MC7 starting at word start, using backdoor - * accesses. - */ -int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n, - u64 *buf) -{ - static const int shift[] = { 0, 0, 16, 24 }; - static const int step[] = { 0, 32, 16, 8 }; - - unsigned int size64 = mc7->size / 8; /* # of 64-bit words */ - struct adapter *adap = mc7->adapter; - - if (start >= size64 || start + n > size64) - return -EINVAL; - - start *= (8 << mc7->width); - while (n--) { - int i; - u64 val64 = 0; - - for (i = (1 << mc7->width) - 1; i >= 0; --i) { - int attempts = 10; - u32 val; - - t3_write_reg(adap, mc7->offset + A_MC7_BD_ADDR, start); - t3_write_reg(adap, mc7->offset + A_MC7_BD_OP, 0); - val = t3_read_reg(adap, mc7->offset + A_MC7_BD_OP); - while ((val & F_BUSY) && attempts--) - val = t3_read_reg(adap, - mc7->offset + A_MC7_BD_OP); - if (val & F_BUSY) - return -EIO; - - val = t3_read_reg(adap, mc7->offset + A_MC7_BD_DATA1); - if (mc7->width == 0) { - val64 = t3_read_reg(adap, - mc7->offset + - A_MC7_BD_DATA0); - val64 |= (u64) val << 32; - } else { - if (mc7->width > 1) - val >>= shift[mc7->width]; - val64 |= (u64) val << (step[mc7->width] * i); - } - start += 8; - } - *buf++ = val64; - } - return 0; -} - -/* - * Initialize MI1. - */ -static void mi1_init(struct adapter *adap, const struct adapter_info *ai) -{ - u32 clkdiv = adap->params.vpd.cclk / (2 * adap->params.vpd.mdc) - 1; - u32 val = F_PREEN | V_MDIINV(ai->mdiinv) | V_MDIEN(ai->mdien) | - V_CLKDIV(clkdiv); - - if (!(ai->caps & SUPPORTED_10000baseT_Full)) - val |= V_ST(1); - t3_write_reg(adap, A_MI1_CFG, val); -} - -#define MDIO_ATTEMPTS 10 - -/* - * MI1 read/write operations for direct-addressed PHYs. - */ -static int mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *valp) -{ - int ret; - u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); - - if (mmd_addr) - return -EINVAL; - - mutex_lock(&adapter->mdio_lock); - t3_write_reg(adapter, A_MI1_ADDR, addr); - t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); - if (!ret) - *valp = t3_read_reg(adapter, A_MI1_DATA); - mutex_unlock(&adapter->mdio_lock); - return ret; -} - -static int mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val) -{ - int ret; - u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); - - if (mmd_addr) - return -EINVAL; - - mutex_lock(&adapter->mdio_lock); - t3_write_reg(adapter, A_MI1_ADDR, addr); - t3_write_reg(adapter, A_MI1_DATA, val); - t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); - mutex_unlock(&adapter->mdio_lock); - return ret; -} - -static const struct mdio_ops mi1_mdio_ops = { - mi1_read, - mi1_write -}; - -/* - * MI1 read/write operations for indirect-addressed PHYs. - */ -static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *valp) -{ - int ret; - u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr); - - mutex_lock(&adapter->mdio_lock); - t3_write_reg(adapter, A_MI1_ADDR, addr); - t3_write_reg(adapter, A_MI1_DATA, reg_addr); - t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); - if (!ret) { - t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(3)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, - MDIO_ATTEMPTS, 20); - if (!ret) - *valp = t3_read_reg(adapter, A_MI1_DATA); - } - mutex_unlock(&adapter->mdio_lock); - return ret; -} - -static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val) -{ - int ret; - u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr); - - mutex_lock(&adapter->mdio_lock); - t3_write_reg(adapter, A_MI1_ADDR, addr); - t3_write_reg(adapter, A_MI1_DATA, reg_addr); - t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); - if (!ret) { - t3_write_reg(adapter, A_MI1_DATA, val); - t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, - MDIO_ATTEMPTS, 20); - } - mutex_unlock(&adapter->mdio_lock); - return ret; -} - -static const struct mdio_ops mi1_mdio_ext_ops = { - mi1_ext_read, - mi1_ext_write -}; - -/** - * t3_mdio_change_bits - modify the value of a PHY register - * @phy: the PHY to operate on - * @mmd: the device address - * @reg: the register address - * @clear: what part of the register value to mask off - * @set: what part of the register value to set - * - * Changes the value of a PHY register by applying a mask to its current - * value and ORing the result with a new value. - */ -int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear, - unsigned int set) -{ - int ret; - unsigned int val; - - ret = mdio_read(phy, mmd, reg, &val); - if (!ret) { - val &= ~clear; - ret = mdio_write(phy, mmd, reg, val | set); - } - return ret; -} - -/** - * t3_phy_reset - reset a PHY block - * @phy: the PHY to operate on - * @mmd: the device address of the PHY block to reset - * @wait: how long to wait for the reset to complete in 1ms increments - * - * Resets a PHY block and optionally waits for the reset to complete. - * @mmd should be 0 for 10/100/1000 PHYs and the device address to reset - * for 10G PHYs. - */ -int t3_phy_reset(struct cphy *phy, int mmd, int wait) -{ - int err; - unsigned int ctl; - - err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET); - if (err || !wait) - return err; - - do { - err = mdio_read(phy, mmd, MII_BMCR, &ctl); - if (err) - return err; - ctl &= BMCR_RESET; - if (ctl) - msleep(1); - } while (ctl && --wait); - - return ctl ? -1 : 0; -} - -/** - * t3_phy_advertise - set the PHY advertisement registers for autoneg - * @phy: the PHY to operate on - * @advert: bitmap of capabilities the PHY should advertise - * - * Sets a 10/100/1000 PHY's advertisement registers to advertise the - * requested capabilities. - */ -int t3_phy_advertise(struct cphy *phy, unsigned int advert) -{ - int err; - unsigned int val = 0; - - err = mdio_read(phy, 0, MII_CTRL1000, &val); - if (err) - return err; - - val &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); - if (advert & ADVERTISED_1000baseT_Half) - val |= ADVERTISE_1000HALF; - if (advert & ADVERTISED_1000baseT_Full) - val |= ADVERTISE_1000FULL; - - err = mdio_write(phy, 0, MII_CTRL1000, val); - if (err) - return err; - - val = 1; - if (advert & ADVERTISED_10baseT_Half) - val |= ADVERTISE_10HALF; - if (advert & ADVERTISED_10baseT_Full) - val |= ADVERTISE_10FULL; - if (advert & ADVERTISED_100baseT_Half) - val |= ADVERTISE_100HALF; - if (advert & ADVERTISED_100baseT_Full) - val |= ADVERTISE_100FULL; - if (advert & ADVERTISED_Pause) - val |= ADVERTISE_PAUSE_CAP; - if (advert & ADVERTISED_Asym_Pause) - val |= ADVERTISE_PAUSE_ASYM; - return mdio_write(phy, 0, MII_ADVERTISE, val); -} - -/** - * t3_set_phy_speed_duplex - force PHY speed and duplex - * @phy: the PHY to operate on - * @speed: requested PHY speed - * @duplex: requested PHY duplex - * - * Force a 10/100/1000 PHY's speed and duplex. This also disables - * auto-negotiation except for GigE, where auto-negotiation is mandatory. - */ -int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) -{ - int err; - unsigned int ctl; - - err = mdio_read(phy, 0, MII_BMCR, &ctl); - if (err) - return err; - - if (speed >= 0) { - ctl &= ~(BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE); - if (speed == SPEED_100) - ctl |= BMCR_SPEED100; - else if (speed == SPEED_1000) - ctl |= BMCR_SPEED1000; - } - if (duplex >= 0) { - ctl &= ~(BMCR_FULLDPLX | BMCR_ANENABLE); - if (duplex == DUPLEX_FULL) - ctl |= BMCR_FULLDPLX; - } - if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */ - ctl |= BMCR_ANENABLE; - return mdio_write(phy, 0, MII_BMCR, ctl); -} - -static const struct adapter_info t3_adap_info[] = { - {2, 0, 0, 0, - F_GPIO2_OEN | F_GPIO4_OEN | - F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, - SUPPORTED_OFFLOAD, - &mi1_mdio_ops, "Chelsio PE9000"}, - {2, 0, 0, 0, - F_GPIO2_OEN | F_GPIO4_OEN | - F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, - SUPPORTED_OFFLOAD, - &mi1_mdio_ops, "Chelsio T302"}, - {1, 0, 0, 0, - F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN | - F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0, - SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_OFFLOAD, - &mi1_mdio_ext_ops, "Chelsio T310"}, - {2, 0, 0, 0, - F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN | - F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL | - F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0, - SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_OFFLOAD, - &mi1_mdio_ext_ops, "Chelsio T320"}, -}; - -/* - * Return the adapter_info structure with a given index. Out-of-range indices - * return NULL. - */ -const struct adapter_info *t3_get_adapter_info(unsigned int id) -{ - return id < ARRAY_SIZE(t3_adap_info) ? &t3_adap_info[id] : NULL; -} - -#define CAPS_1G (SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | \ - SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII) -#define CAPS_10G (SUPPORTED_10000baseT_Full | SUPPORTED_AUI) - -static const struct port_type_info port_types[] = { - {NULL}, - {t3_ael1002_phy_prep, CAPS_10G | SUPPORTED_FIBRE, - "10GBASE-XR"}, - {t3_vsc8211_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ, - "10/100/1000BASE-T"}, - {NULL, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ, - "10/100/1000BASE-T"}, - {t3_xaui_direct_phy_prep, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"}, - {NULL, CAPS_10G, "10GBASE-KX4"}, - {t3_qt2045_phy_prep, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"}, - {t3_ael1006_phy_prep, CAPS_10G | SUPPORTED_FIBRE, - "10GBASE-SR"}, - {NULL, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"}, -}; - -#undef CAPS_1G -#undef CAPS_10G - -#define VPD_ENTRY(name, len) \ - u8 name##_kword[2]; u8 name##_len; u8 name##_data[len] - -/* - * Partial EEPROM Vital Product Data structure. Includes only the ID and - * VPD-R sections. - */ -struct t3_vpd { - u8 id_tag; - u8 id_len[2]; - u8 id_data[16]; - u8 vpdr_tag; - u8 vpdr_len[2]; - VPD_ENTRY(pn, 16); /* part number */ - VPD_ENTRY(ec, 16); /* EC level */ - VPD_ENTRY(sn, 16); /* serial number */ - VPD_ENTRY(na, 12); /* MAC address base */ - VPD_ENTRY(cclk, 6); /* core clock */ - VPD_ENTRY(mclk, 6); /* mem clock */ - VPD_ENTRY(uclk, 6); /* uP clk */ - VPD_ENTRY(mdc, 6); /* MDIO clk */ - VPD_ENTRY(mt, 2); /* mem timing */ - VPD_ENTRY(xaui0cfg, 6); /* XAUI0 config */ - VPD_ENTRY(xaui1cfg, 6); /* XAUI1 config */ - VPD_ENTRY(port0, 2); /* PHY0 complex */ - VPD_ENTRY(port1, 2); /* PHY1 complex */ - VPD_ENTRY(port2, 2); /* PHY2 complex */ - VPD_ENTRY(port3, 2); /* PHY3 complex */ - VPD_ENTRY(rv, 1); /* csum */ - u32 pad; /* for multiple-of-4 sizing and alignment */ -}; - -#define EEPROM_MAX_POLL 4 -#define EEPROM_STAT_ADDR 0x4000 -#define VPD_BASE 0xc00 - -/** - * t3_seeprom_read - read a VPD EEPROM location - * @adapter: adapter to read - * @addr: EEPROM address - * @data: where to store the read data - * - * Read a 32-bit word from a location in VPD EEPROM using the card's PCI - * VPD ROM capability. A zero is written to the flag bit when the - * addres is written to the control register. The hardware device will - * set the flag to 1 when 4 bytes have been read into the data register. - */ -int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data) -{ - u16 val; - int attempts = EEPROM_MAX_POLL; - unsigned int base = adapter->params.pci.vpd_cap_addr; - - if ((addr >= EEPROMSIZE && addr != EEPROM_STAT_ADDR) || (addr & 3)) - return -EINVAL; - - pci_write_config_word(adapter->pdev, base + PCI_VPD_ADDR, addr); - do { - udelay(10); - pci_read_config_word(adapter->pdev, base + PCI_VPD_ADDR, &val); - } while (!(val & PCI_VPD_ADDR_F) && --attempts); - - if (!(val & PCI_VPD_ADDR_F)) { - CH_ERR(adapter, "reading EEPROM address 0x%x failed\n", addr); - return -EIO; - } - pci_read_config_dword(adapter->pdev, base + PCI_VPD_DATA, data); - *data = le32_to_cpu(*data); - return 0; -} - -/** - * t3_seeprom_write - write a VPD EEPROM location - * @adapter: adapter to write - * @addr: EEPROM address - * @data: value to write - * - * Write a 32-bit word to a location in VPD EEPROM using the card's PCI - * VPD ROM capability. - */ -int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data) -{ - u16 val; - int attempts = EEPROM_MAX_POLL; - unsigned int base = adapter->params.pci.vpd_cap_addr; - - if ((addr >= EEPROMSIZE && addr != EEPROM_STAT_ADDR) || (addr & 3)) - return -EINVAL; - - pci_write_config_dword(adapter->pdev, base + PCI_VPD_DATA, - cpu_to_le32(data)); - pci_write_config_word(adapter->pdev,base + PCI_VPD_ADDR, - addr | PCI_VPD_ADDR_F); - do { - msleep(1); - pci_read_config_word(adapter->pdev, base + PCI_VPD_ADDR, &val); - } while ((val & PCI_VPD_ADDR_F) && --attempts); - - if (val & PCI_VPD_ADDR_F) { - CH_ERR(adapter, "write to EEPROM address 0x%x failed\n", addr); - return -EIO; - } - return 0; -} - -/** - * t3_seeprom_wp - enable/disable EEPROM write protection - * @adapter: the adapter - * @enable: 1 to enable write protection, 0 to disable it - * - * Enables or disables write protection on the serial EEPROM. - */ -int t3_seeprom_wp(struct adapter *adapter, int enable) -{ - return t3_seeprom_write(adapter, EEPROM_STAT_ADDR, enable ? 0xc : 0); -} - -/* - * Convert a character holding a hex digit to a number. - */ -static unsigned int hex2int(unsigned char c) -{ - return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10; -} - -/** - * get_vpd_params - read VPD parameters from VPD EEPROM - * @adapter: adapter to read - * @p: where to store the parameters - * - * Reads card parameters stored in VPD EEPROM. - */ -static int get_vpd_params(struct adapter *adapter, struct vpd_params *p) -{ - int i, addr, ret; - struct t3_vpd vpd; - - /* - * Card information is normally at VPD_BASE but some early cards had - * it at 0. - */ - ret = t3_seeprom_read(adapter, VPD_BASE, (u32 *)&vpd); - if (ret) - return ret; - addr = vpd.id_tag == 0x82 ? VPD_BASE : 0; - - for (i = 0; i < sizeof(vpd); i += 4) { - ret = t3_seeprom_read(adapter, addr + i, - (u32 *)((u8 *)&vpd + i)); - if (ret) - return ret; - } - - p->cclk = simple_strtoul(vpd.cclk_data, NULL, 10); - p->mclk = simple_strtoul(vpd.mclk_data, NULL, 10); - p->uclk = simple_strtoul(vpd.uclk_data, NULL, 10); - p->mdc = simple_strtoul(vpd.mdc_data, NULL, 10); - p->mem_timing = simple_strtoul(vpd.mt_data, NULL, 10); - - /* Old eeproms didn't have port information */ - if (adapter->params.rev == 0 && !vpd.port0_data[0]) { - p->port_type[0] = uses_xaui(adapter) ? 1 : 2; - p->port_type[1] = uses_xaui(adapter) ? 6 : 2; - } else { - p->port_type[0] = hex2int(vpd.port0_data[0]); - p->port_type[1] = hex2int(vpd.port1_data[0]); - p->xauicfg[0] = simple_strtoul(vpd.xaui0cfg_data, NULL, 16); - p->xauicfg[1] = simple_strtoul(vpd.xaui1cfg_data, NULL, 16); - } - - for (i = 0; i < 6; i++) - p->eth_base[i] = hex2int(vpd.na_data[2 * i]) * 16 + - hex2int(vpd.na_data[2 * i + 1]); - return 0; -} - -/* serial flash and firmware constants */ -enum { - SF_ATTEMPTS = 5, /* max retries for SF1 operations */ - SF_SEC_SIZE = 64 * 1024, /* serial flash sector size */ - SF_SIZE = SF_SEC_SIZE * 8, /* serial flash size */ - - /* flash command opcodes */ - SF_PROG_PAGE = 2, /* program page */ - SF_WR_DISABLE = 4, /* disable writes */ - SF_RD_STATUS = 5, /* read status register */ - SF_WR_ENABLE = 6, /* enable writes */ - SF_RD_DATA_FAST = 0xb, /* read flash */ - SF_ERASE_SECTOR = 0xd8, /* erase sector */ - - FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */ - FW_VERS_ADDR = 0x77ffc /* flash address holding FW version */ -}; - -/** - * sf1_read - read data from the serial flash - * @adapter: the adapter - * @byte_cnt: number of bytes to read - * @cont: whether another operation will be chained - * @valp: where to store the read data - * - * Reads up to 4 bytes of data from the serial flash. The location of - * the read needs to be specified prior to calling this by issuing the - * appropriate commands to the serial flash. - */ -static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont, - u32 *valp) -{ - int ret; - - if (!byte_cnt || byte_cnt > 4) - return -EINVAL; - if (t3_read_reg(adapter, A_SF_OP) & F_BUSY) - return -EBUSY; - t3_write_reg(adapter, A_SF_OP, V_CONT(cont) | V_BYTECNT(byte_cnt - 1)); - ret = t3_wait_op_done(adapter, A_SF_OP, F_BUSY, 0, SF_ATTEMPTS, 10); - if (!ret) - *valp = t3_read_reg(adapter, A_SF_DATA); - return ret; -} - -/** - * sf1_write - write data to the serial flash - * @adapter: the adapter - * @byte_cnt: number of bytes to write - * @cont: whether another operation will be chained - * @val: value to write - * - * Writes up to 4 bytes of data to the serial flash. The location of - * the write needs to be specified prior to calling this by issuing the - * appropriate commands to the serial flash. - */ -static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont, - u32 val) -{ - if (!byte_cnt || byte_cnt > 4) - return -EINVAL; - if (t3_read_reg(adapter, A_SF_OP) & F_BUSY) - return -EBUSY; - t3_write_reg(adapter, A_SF_DATA, val); - t3_write_reg(adapter, A_SF_OP, - V_CONT(cont) | V_BYTECNT(byte_cnt - 1) | V_OP(1)); - return t3_wait_op_done(adapter, A_SF_OP, F_BUSY, 0, SF_ATTEMPTS, 10); -} - -/** - * flash_wait_op - wait for a flash operation to complete - * @adapter: the adapter - * @attempts: max number of polls of the status register - * @delay: delay between polls in ms - * - * Wait for a flash operation to complete by polling the status register. - */ -static int flash_wait_op(struct adapter *adapter, int attempts, int delay) -{ - int ret; - u32 status; - - while (1) { - if ((ret = sf1_write(adapter, 1, 1, SF_RD_STATUS)) != 0 || - (ret = sf1_read(adapter, 1, 0, &status)) != 0) - return ret; - if (!(status & 1)) - return 0; - if (--attempts == 0) - return -EAGAIN; - if (delay) - msleep(delay); - } -} - -/** - * t3_read_flash - read words from serial flash - * @adapter: the adapter - * @addr: the start address for the read - * @nwords: how many 32-bit words to read - * @data: where to store the read data - * @byte_oriented: whether to store data as bytes or as words - * - * Read the specified number of 32-bit words from the serial flash. - * If @byte_oriented is set the read data is stored as a byte array - * (i.e., big-endian), otherwise as 32-bit words in the platform's - * natural endianess. - */ -int t3_read_flash(struct adapter *adapter, unsigned int addr, - unsigned int nwords, u32 *data, int byte_oriented) -{ - int ret; - - if (addr + nwords * sizeof(u32) > SF_SIZE || (addr & 3)) - return -EINVAL; - - addr = swab32(addr) | SF_RD_DATA_FAST; - - if ((ret = sf1_write(adapter, 4, 1, addr)) != 0 || - (ret = sf1_read(adapter, 1, 1, data)) != 0) - return ret; - - for (; nwords; nwords--, data++) { - ret = sf1_read(adapter, 4, nwords > 1, data); - if (ret) - return ret; - if (byte_oriented) - *data = htonl(*data); - } - return 0; -} - -/** - * t3_write_flash - write up to a page of data to the serial flash - * @adapter: the adapter - * @addr: the start address to write - * @n: length of data to write - * @data: the data to write - * - * Writes up to a page of data (256 bytes) to the serial flash starting - * at the given address. - */ -static int t3_write_flash(struct adapter *adapter, unsigned int addr, - unsigned int n, const u8 *data) -{ - int ret; - u32 buf[64]; - unsigned int i, c, left, val, offset = addr & 0xff; - - if (addr + n > SF_SIZE || offset + n > 256) - return -EINVAL; - - val = swab32(addr) | SF_PROG_PAGE; - - if ((ret = sf1_write(adapter, 1, 0, SF_WR_ENABLE)) != 0 || - (ret = sf1_write(adapter, 4, 1, val)) != 0) - return ret; - - for (left = n; left; left -= c) { - c = min(left, 4U); - for (val = 0, i = 0; i < c; ++i) - val = (val << 8) + *data++; - - ret = sf1_write(adapter, c, c != left, val); - if (ret) - return ret; - } - if ((ret = flash_wait_op(adapter, 5, 1)) != 0) - return ret; - - /* Read the page to verify the write succeeded */ - ret = t3_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1); - if (ret) - return ret; - - if (memcmp(data - n, (u8 *) buf + offset, n)) - return -EIO; - return 0; -} - -enum fw_version_type { - FW_VERSION_N3, - FW_VERSION_T3 -}; - -/** - * t3_get_fw_version - read the firmware version - * @adapter: the adapter - * @vers: where to place the version - * - * Reads the FW version from flash. - */ -int t3_get_fw_version(struct adapter *adapter, u32 *vers) -{ - return t3_read_flash(adapter, FW_VERS_ADDR, 1, vers, 0); -} - -/** - * t3_check_fw_version - check if the FW is compatible with this driver - * @adapter: the adapter - * - * Checks if an adapter's FW is compatible with the driver. Returns 0 - * if the versions are compatible, a negative error otherwise. - */ -int t3_check_fw_version(struct adapter *adapter) -{ - int ret; - u32 vers; - unsigned int type, major, minor; - - ret = t3_get_fw_version(adapter, &vers); - if (ret) - return ret; - - type = G_FW_VERSION_TYPE(vers); - major = G_FW_VERSION_MAJOR(vers); - minor = G_FW_VERSION_MINOR(vers); - - if (type == FW_VERSION_T3 && major == 3 && minor == 1) - return 0; - - CH_ERR(adapter, "found wrong FW version(%u.%u), " - "driver needs version 3.1\n", major, minor); - return -EINVAL; -} - -/** - * t3_flash_erase_sectors - erase a range of flash sectors - * @adapter: the adapter - * @start: the first sector to erase - * @end: the last sector to erase - * - * Erases the sectors in the given range. - */ -static int t3_flash_erase_sectors(struct adapter *adapter, int start, int end) -{ - while (start <= end) { - int ret; - - if ((ret = sf1_write(adapter, 1, 0, SF_WR_ENABLE)) != 0 || - (ret = sf1_write(adapter, 4, 0, - SF_ERASE_SECTOR | (start << 8))) != 0 || - (ret = flash_wait_op(adapter, 5, 500)) != 0) - return ret; - start++; - } - return 0; -} - -/* - * t3_load_fw - download firmware - * @adapter: the adapter - * @fw_data: the firrware image to write - * @size: image size - * - * Write the supplied firmware image to the card's serial flash. - * The FW image has the following sections: @size - 8 bytes of code and - * data, followed by 4 bytes of FW version, followed by the 32-bit - * 1's complement checksum of the whole image. - */ -int t3_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size) -{ - u32 csum; - unsigned int i; - const u32 *p = (const u32 *)fw_data; - int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16; - - if (size & 3) - return -EINVAL; - if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR) - return -EFBIG; - - for (csum = 0, i = 0; i < size / sizeof(csum); i++) - csum += ntohl(p[i]); - if (csum != 0xffffffff) { - CH_ERR(adapter, "corrupted firmware image, checksum %u\n", - csum); - return -EINVAL; - } - - ret = t3_flash_erase_sectors(adapter, fw_sector, fw_sector); - if (ret) - goto out; - - size -= 8; /* trim off version and checksum */ - for (addr = FW_FLASH_BOOT_ADDR; size;) { - unsigned int chunk_size = min(size, 256U); - - ret = t3_write_flash(adapter, addr, chunk_size, fw_data); - if (ret) - goto out; - - addr += chunk_size; - fw_data += chunk_size; - size -= chunk_size; - } - - ret = t3_write_flash(adapter, FW_VERS_ADDR, 4, fw_data); -out: - if (ret) - CH_ERR(adapter, "firmware download failed, error %d\n", ret); - return ret; -} - -#define CIM_CTL_BASE 0x2000 - -/** - * t3_cim_ctl_blk_read - read a block from CIM control region - * - * @adap: the adapter - * @addr: the start address within the CIM control region - * @n: number of words to read - * @valp: where to store the result - * - * Reads a block of 4-byte words from the CIM control region. - */ -int t3_cim_ctl_blk_read(struct adapter *adap, unsigned int addr, - unsigned int n, unsigned int *valp) -{ - int ret = 0; - - if (t3_read_reg(adap, A_CIM_HOST_ACC_CTRL) & F_HOSTBUSY) - return -EBUSY; - - for ( ; !ret && n--; addr += 4) { - t3_write_reg(adap, A_CIM_HOST_ACC_CTRL, CIM_CTL_BASE + addr); - ret = t3_wait_op_done(adap, A_CIM_HOST_ACC_CTRL, F_HOSTBUSY, - 0, 5, 2); - if (!ret) - *valp++ = t3_read_reg(adap, A_CIM_HOST_ACC_DATA); - } - return ret; -} - - -/** - * t3_link_changed - handle interface link changes - * @adapter: the adapter - * @port_id: the port index that changed link state - * - * Called when a port's link settings change to propagate the new values - * to the associated PHY and MAC. After performing the common tasks it - * invokes an OS-specific handler. - */ -void t3_link_changed(struct adapter *adapter, int port_id) -{ - int link_ok, speed, duplex, fc; - struct port_info *pi = adap2pinfo(adapter, port_id); - struct cphy *phy = &pi->phy; - struct cmac *mac = &pi->mac; - struct link_config *lc = &pi->link_config; - - phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); - - if (link_ok != lc->link_ok && adapter->params.rev > 0 && - uses_xaui(adapter)) { - if (link_ok) - t3b_pcs_reset(mac); - t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, - link_ok ? F_TXACTENABLE | F_RXEN : 0); - } - lc->link_ok = link_ok; - lc->speed = speed < 0 ? SPEED_INVALID : speed; - lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; - if (lc->requested_fc & PAUSE_AUTONEG) - fc &= lc->requested_fc; - else - fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); - - if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { - /* Set MAC speed, duplex, and flow control to match PHY. */ - t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc); - lc->fc = fc; - } - - t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc); -} - -/** - * t3_link_start - apply link configuration to MAC/PHY - * @phy: the PHY to setup - * @mac: the MAC to setup - * @lc: the requested link configuration - * - * Set up a port's MAC and PHY according to a desired link configuration. - * - If the PHY can auto-negotiate first decide what to advertise, then - * enable/disable auto-negotiation as desired, and reset. - * - If the PHY does not auto-negotiate just reset it. - * - If auto-negotiation is off set the MAC to the proper speed/duplex/FC, - * otherwise do it later based on the outcome of auto-negotiation. - */ -int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc) -{ - unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); - - lc->link_ok = 0; - if (lc->supported & SUPPORTED_Autoneg) { - lc->advertising &= ~(ADVERTISED_Asym_Pause | ADVERTISED_Pause); - if (fc) { - lc->advertising |= ADVERTISED_Asym_Pause; - if (fc & PAUSE_RX) - lc->advertising |= ADVERTISED_Pause; - } - phy->ops->advertise(phy, lc->advertising); - - if (lc->autoneg == AUTONEG_DISABLE) { - lc->speed = lc->requested_speed; - lc->duplex = lc->requested_duplex; - lc->fc = (unsigned char)fc; - t3_mac_set_speed_duplex_fc(mac, lc->speed, lc->duplex, - fc); - /* Also disables autoneg */ - phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); - phy->ops->reset(phy, 0); - } else - phy->ops->autoneg_enable(phy); - } else { - t3_mac_set_speed_duplex_fc(mac, -1, -1, fc); - lc->fc = (unsigned char)fc; - phy->ops->reset(phy, 0); - } - return 0; -} - -/** - * t3_set_vlan_accel - control HW VLAN extraction - * @adapter: the adapter - * @ports: bitmap of adapter ports to operate on - * @on: enable (1) or disable (0) HW VLAN extraction - * - * Enables or disables HW extraction of VLAN tags for the given port. - */ -void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on) -{ - t3_set_reg_field(adapter, A_TP_OUT_CONFIG, - ports << S_VLANEXTRACTIONENABLE, - on ? (ports << S_VLANEXTRACTIONENABLE) : 0); -} - -struct intr_info { - unsigned int mask; /* bits to check in interrupt status */ - const char *msg; /* message to print or NULL */ - short stat_idx; /* stat counter to increment or -1 */ - unsigned short fatal:1; /* whether the condition reported is fatal */ -}; - -/** - * t3_handle_intr_status - table driven interrupt handler - * @adapter: the adapter that generated the interrupt - * @reg: the interrupt status register to process - * @mask: a mask to apply to the interrupt status - * @acts: table of interrupt actions - * @stats: statistics counters tracking interrupt occurences - * - * A table driven interrupt handler that applies a set of masks to an - * interrupt status word and performs the corresponding actions if the - * interrupts described by the mask have occured. The actions include - * optionally printing a warning or alert message, and optionally - * incrementing a stat counter. The table is terminated by an entry - * specifying mask 0. Returns the number of fatal interrupt conditions. - */ -static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg, - unsigned int mask, - const struct intr_info *acts, - unsigned long *stats) -{ - int fatal = 0; - unsigned int status = t3_read_reg(adapter, reg) & mask; - - for (; acts->mask; ++acts) { - if (!(status & acts->mask)) - continue; - if (acts->fatal) { - fatal++; - CH_ALERT(adapter, "%s (0x%x)\n", - acts->msg, status & acts->mask); - } else if (acts->msg) - CH_WARN(adapter, "%s (0x%x)\n", - acts->msg, status & acts->mask); - if (acts->stat_idx >= 0) - stats[acts->stat_idx]++; - } - if (status) /* clear processed interrupts */ - t3_write_reg(adapter, reg, status); - return fatal; -} - -#define SGE_INTR_MASK (F_RSPQDISABLED) -#define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \ - F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \ - F_NFASRCHFAIL) -#define MC7_INTR_MASK (F_AE | F_UE | F_CE | V_PE(M_PE)) -#define XGM_INTR_MASK (V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR) | \ - V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR) | \ - F_TXFIFO_UNDERRUN | F_RXFIFO_OVERFLOW) -#define PCIX_INTR_MASK (F_MSTDETPARERR | F_SIGTARABT | F_RCVTARABT | \ - F_RCVMSTABT | F_SIGSYSERR | F_DETPARERR | \ - F_SPLCMPDIS | F_UNXSPLCMP | F_RCVSPLCMPERR | \ - F_DETCORECCERR | F_DETUNCECCERR | F_PIOPARERR | \ - V_WFPARERR(M_WFPARERR) | V_RFPARERR(M_RFPARERR) | \ - V_CFPARERR(M_CFPARERR) /* | V_MSIXPARERR(M_MSIXPARERR) */) -#define PCIE_INTR_MASK (F_UNXSPLCPLERRR | F_UNXSPLCPLERRC | F_PCIE_PIOPARERR |\ - F_PCIE_WFPARERR | F_PCIE_RFPARERR | F_PCIE_CFPARERR | \ - /* V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR) | */ \ - V_BISTERR(M_BISTERR) | F_PEXERR) -#define ULPRX_INTR_MASK F_PARERR -#define ULPTX_INTR_MASK 0 -#define CPLSW_INTR_MASK (F_TP_FRAMING_ERROR | \ - F_SGE_FRAMING_ERROR | F_CIM_FRAMING_ERROR | \ - F_ZERO_SWITCH_ERROR) -#define CIM_INTR_MASK (F_BLKWRPLINT | F_BLKRDPLINT | F_BLKWRCTLINT | \ - F_BLKRDCTLINT | F_BLKWRFLASHINT | F_BLKRDFLASHINT | \ - F_SGLWRFLASHINT | F_WRBLKFLASHINT | F_BLKWRBOOTINT | \ - F_FLASHRANGEINT | F_SDRAMRANGEINT | F_RSVDSPACEINT) -#define PMTX_INTR_MASK (F_ZERO_C_CMD_ERROR | ICSPI_FRM_ERR | OESPI_FRM_ERR | \ - V_ICSPI_PAR_ERROR(M_ICSPI_PAR_ERROR) | \ - V_OESPI_PAR_ERROR(M_OESPI_PAR_ERROR)) -#define PMRX_INTR_MASK (F_ZERO_E_CMD_ERROR | IESPI_FRM_ERR | OCSPI_FRM_ERR | \ - V_IESPI_PAR_ERROR(M_IESPI_PAR_ERROR) | \ - V_OCSPI_PAR_ERROR(M_OCSPI_PAR_ERROR)) -#define MPS_INTR_MASK (V_TX0TPPARERRENB(M_TX0TPPARERRENB) | \ - V_TX1TPPARERRENB(M_TX1TPPARERRENB) | \ - V_RXTPPARERRENB(M_RXTPPARERRENB) | \ - V_MCAPARERRENB(M_MCAPARERRENB)) -#define PL_INTR_MASK (F_T3DBG | F_XGMAC0_0 | F_XGMAC0_1 | F_MC5A | F_PM1_TX | \ - F_PM1_RX | F_ULP2_TX | F_ULP2_RX | F_TP1 | F_CIM | \ - F_MC7_CM | F_MC7_PMTX | F_MC7_PMRX | F_SGE3 | F_PCIM0 | \ - F_MPS0 | F_CPL_SWITCH) - -/* - * Interrupt handler for the PCIX1 module. - */ -static void pci_intr_handler(struct adapter *adapter) -{ - static const struct intr_info pcix1_intr_info[] = { - {F_MSTDETPARERR, "PCI master detected parity error", -1, 1}, - {F_SIGTARABT, "PCI signaled target abort", -1, 1}, - {F_RCVTARABT, "PCI received target abort", -1, 1}, - {F_RCVMSTABT, "PCI received master abort", -1, 1}, - {F_SIGSYSERR, "PCI signaled system error", -1, 1}, - {F_DETPARERR, "PCI detected parity error", -1, 1}, - {F_SPLCMPDIS, "PCI split completion discarded", -1, 1}, - {F_UNXSPLCMP, "PCI unexpected split completion error", -1, 1}, - {F_RCVSPLCMPERR, "PCI received split completion error", -1, - 1}, - {F_DETCORECCERR, "PCI correctable ECC error", - STAT_PCI_CORR_ECC, 0}, - {F_DETUNCECCERR, "PCI uncorrectable ECC error", -1, 1}, - {F_PIOPARERR, "PCI PIO FIFO parity error", -1, 1}, - {V_WFPARERR(M_WFPARERR), "PCI write FIFO parity error", -1, - 1}, - {V_RFPARERR(M_RFPARERR), "PCI read FIFO parity error", -1, - 1}, - {V_CFPARERR(M_CFPARERR), "PCI command FIFO parity error", -1, - 1}, - {V_MSIXPARERR(M_MSIXPARERR), "PCI MSI-X table/PBA parity " - "error", -1, 1}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_PCIX_INT_CAUSE, PCIX_INTR_MASK, - pcix1_intr_info, adapter->irq_stats)) - t3_fatal_err(adapter); -} - -/* - * Interrupt handler for the PCIE module. - */ -static void pcie_intr_handler(struct adapter *adapter) -{ - static const struct intr_info pcie_intr_info[] = { - {F_PEXERR, "PCI PEX error", -1, 1}, - {F_UNXSPLCPLERRR, - "PCI unexpected split completion DMA read error", -1, 1}, - {F_UNXSPLCPLERRC, - "PCI unexpected split completion DMA command error", -1, 1}, - {F_PCIE_PIOPARERR, "PCI PIO FIFO parity error", -1, 1}, - {F_PCIE_WFPARERR, "PCI write FIFO parity error", -1, 1}, - {F_PCIE_RFPARERR, "PCI read FIFO parity error", -1, 1}, - {F_PCIE_CFPARERR, "PCI command FIFO parity error", -1, 1}, - {V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR), - "PCI MSI-X table/PBA parity error", -1, 1}, - {V_BISTERR(M_BISTERR), "PCI BIST error", -1, 1}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_PCIE_INT_CAUSE, PCIE_INTR_MASK, - pcie_intr_info, adapter->irq_stats)) - t3_fatal_err(adapter); -} - -/* - * TP interrupt handler. - */ -static void tp_intr_handler(struct adapter *adapter) -{ - static const struct intr_info tp_intr_info[] = { - {0xffffff, "TP parity error", -1, 1}, - {0x1000000, "TP out of Rx pages", -1, 1}, - {0x2000000, "TP out of Tx pages", -1, 1}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_TP_INT_CAUSE, 0xffffffff, - tp_intr_info, NULL)) - t3_fatal_err(adapter); -} - -/* - * CIM interrupt handler. - */ -static void cim_intr_handler(struct adapter *adapter) -{ - static const struct intr_info cim_intr_info[] = { - {F_RSVDSPACEINT, "CIM reserved space write", -1, 1}, - {F_SDRAMRANGEINT, "CIM SDRAM address out of range", -1, 1}, - {F_FLASHRANGEINT, "CIM flash address out of range", -1, 1}, - {F_BLKWRBOOTINT, "CIM block write to boot space", -1, 1}, - {F_WRBLKFLASHINT, "CIM write to cached flash space", -1, 1}, - {F_SGLWRFLASHINT, "CIM single write to flash space", -1, 1}, - {F_BLKRDFLASHINT, "CIM block read from flash space", -1, 1}, - {F_BLKWRFLASHINT, "CIM block write to flash space", -1, 1}, - {F_BLKRDCTLINT, "CIM block read from CTL space", -1, 1}, - {F_BLKWRCTLINT, "CIM block write to CTL space", -1, 1}, - {F_BLKRDPLINT, "CIM block read from PL space", -1, 1}, - {F_BLKWRPLINT, "CIM block write to PL space", -1, 1}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_CIM_HOST_INT_CAUSE, 0xffffffff, - cim_intr_info, NULL)) - t3_fatal_err(adapter); -} - -/* - * ULP RX interrupt handler. - */ -static void ulprx_intr_handler(struct adapter *adapter) -{ - static const struct intr_info ulprx_intr_info[] = { - {F_PARERR, "ULP RX parity error", -1, 1}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_ULPRX_INT_CAUSE, 0xffffffff, - ulprx_intr_info, NULL)) - t3_fatal_err(adapter); -} - -/* - * ULP TX interrupt handler. - */ -static void ulptx_intr_handler(struct adapter *adapter) -{ - static const struct intr_info ulptx_intr_info[] = { - {F_PBL_BOUND_ERR_CH0, "ULP TX channel 0 PBL out of bounds", - STAT_ULP_CH0_PBL_OOB, 0}, - {F_PBL_BOUND_ERR_CH1, "ULP TX channel 1 PBL out of bounds", - STAT_ULP_CH1_PBL_OOB, 0}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_ULPTX_INT_CAUSE, 0xffffffff, - ulptx_intr_info, adapter->irq_stats)) - t3_fatal_err(adapter); -} - -#define ICSPI_FRM_ERR (F_ICSPI0_FIFO2X_RX_FRAMING_ERROR | \ - F_ICSPI1_FIFO2X_RX_FRAMING_ERROR | F_ICSPI0_RX_FRAMING_ERROR | \ - F_ICSPI1_RX_FRAMING_ERROR | F_ICSPI0_TX_FRAMING_ERROR | \ - F_ICSPI1_TX_FRAMING_ERROR) -#define OESPI_FRM_ERR (F_OESPI0_RX_FRAMING_ERROR | \ - F_OESPI1_RX_FRAMING_ERROR | F_OESPI0_TX_FRAMING_ERROR | \ - F_OESPI1_TX_FRAMING_ERROR | F_OESPI0_OFIFO2X_TX_FRAMING_ERROR | \ - F_OESPI1_OFIFO2X_TX_FRAMING_ERROR) - -/* - * PM TX interrupt handler. - */ -static void pmtx_intr_handler(struct adapter *adapter) -{ - static const struct intr_info pmtx_intr_info[] = { - {F_ZERO_C_CMD_ERROR, "PMTX 0-length pcmd", -1, 1}, - {ICSPI_FRM_ERR, "PMTX ispi framing error", -1, 1}, - {OESPI_FRM_ERR, "PMTX ospi framing error", -1, 1}, - {V_ICSPI_PAR_ERROR(M_ICSPI_PAR_ERROR), - "PMTX ispi parity error", -1, 1}, - {V_OESPI_PAR_ERROR(M_OESPI_PAR_ERROR), - "PMTX ospi parity error", -1, 1}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_PM1_TX_INT_CAUSE, 0xffffffff, - pmtx_intr_info, NULL)) - t3_fatal_err(adapter); -} - -#define IESPI_FRM_ERR (F_IESPI0_FIFO2X_RX_FRAMING_ERROR | \ - F_IESPI1_FIFO2X_RX_FRAMING_ERROR | F_IESPI0_RX_FRAMING_ERROR | \ - F_IESPI1_RX_FRAMING_ERROR | F_IESPI0_TX_FRAMING_ERROR | \ - F_IESPI1_TX_FRAMING_ERROR) -#define OCSPI_FRM_ERR (F_OCSPI0_RX_FRAMING_ERROR | \ - F_OCSPI1_RX_FRAMING_ERROR | F_OCSPI0_TX_FRAMING_ERROR | \ - F_OCSPI1_TX_FRAMING_ERROR | F_OCSPI0_OFIFO2X_TX_FRAMING_ERROR | \ - F_OCSPI1_OFIFO2X_TX_FRAMING_ERROR) - -/* - * PM RX interrupt handler. - */ -static void pmrx_intr_handler(struct adapter *adapter) -{ - static const struct intr_info pmrx_intr_info[] = { - {F_ZERO_E_CMD_ERROR, "PMRX 0-length pcmd", -1, 1}, - {IESPI_FRM_ERR, "PMRX ispi framing error", -1, 1}, - {OCSPI_FRM_ERR, "PMRX ospi framing error", -1, 1}, - {V_IESPI_PAR_ERROR(M_IESPI_PAR_ERROR), - "PMRX ispi parity error", -1, 1}, - {V_OCSPI_PAR_ERROR(M_OCSPI_PAR_ERROR), - "PMRX ospi parity error", -1, 1}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_PM1_RX_INT_CAUSE, 0xffffffff, - pmrx_intr_info, NULL)) - t3_fatal_err(adapter); -} - -/* - * CPL switch interrupt handler. - */ -static void cplsw_intr_handler(struct adapter *adapter) -{ - static const struct intr_info cplsw_intr_info[] = { -/* { F_CIM_OVFL_ERROR, "CPL switch CIM overflow", -1, 1 }, */ - {F_TP_FRAMING_ERROR, "CPL switch TP framing error", -1, 1}, - {F_SGE_FRAMING_ERROR, "CPL switch SGE framing error", -1, 1}, - {F_CIM_FRAMING_ERROR, "CPL switch CIM framing error", -1, 1}, - {F_ZERO_SWITCH_ERROR, "CPL switch no-switch error", -1, 1}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_CPL_INTR_CAUSE, 0xffffffff, - cplsw_intr_info, NULL)) - t3_fatal_err(adapter); -} - -/* - * MPS interrupt handler. - */ -static void mps_intr_handler(struct adapter *adapter) -{ - static const struct intr_info mps_intr_info[] = { - {0x1ff, "MPS parity error", -1, 1}, - {0} - }; - - if (t3_handle_intr_status(adapter, A_MPS_INT_CAUSE, 0xffffffff, - mps_intr_info, NULL)) - t3_fatal_err(adapter); -} - -#define MC7_INTR_FATAL (F_UE | V_PE(M_PE) | F_AE) - -/* - * MC7 interrupt handler. - */ -static void mc7_intr_handler(struct mc7 *mc7) -{ - struct adapter *adapter = mc7->adapter; - u32 cause = t3_read_reg(adapter, mc7->offset + A_MC7_INT_CAUSE); - - if (cause & F_CE) { - mc7->stats.corr_err++; - CH_WARN(adapter, "%s MC7 correctable error at addr 0x%x, " - "data 0x%x 0x%x 0x%x\n", mc7->name, - t3_read_reg(adapter, mc7->offset + A_MC7_CE_ADDR), - t3_read_reg(adapter, mc7->offset + A_MC7_CE_DATA0), - t3_read_reg(adapter, mc7->offset + A_MC7_CE_DATA1), - t3_read_reg(adapter, mc7->offset + A_MC7_CE_DATA2)); - } - - if (cause & F_UE) { - mc7->stats.uncorr_err++; - CH_ALERT(adapter, "%s MC7 uncorrectable error at addr 0x%x, " - "data 0x%x 0x%x 0x%x\n", mc7->name, - t3_read_reg(adapter, mc7->offset + A_MC7_UE_ADDR), - t3_read_reg(adapter, mc7->offset + A_MC7_UE_DATA0), - t3_read_reg(adapter, mc7->offset + A_MC7_UE_DATA1), - t3_read_reg(adapter, mc7->offset + A_MC7_UE_DATA2)); - } - - if (G_PE(cause)) { - mc7->stats.parity_err++; - CH_ALERT(adapter, "%s MC7 parity error 0x%x\n", - mc7->name, G_PE(cause)); - } - - if (cause & F_AE) { - u32 addr = 0; - - if (adapter->params.rev > 0) - addr = t3_read_reg(adapter, - mc7->offset + A_MC7_ERR_ADDR); - mc7->stats.addr_err++; - CH_ALERT(adapter, "%s MC7 address error: 0x%x\n", - mc7->name, addr); - } - - if (cause & MC7_INTR_FATAL) - t3_fatal_err(adapter); - - t3_write_reg(adapter, mc7->offset + A_MC7_INT_CAUSE, cause); -} - -#define XGM_INTR_FATAL (V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR) | \ - V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR)) -/* - * XGMAC interrupt handler. - */ -static int mac_intr_handler(struct adapter *adap, unsigned int idx) -{ - struct cmac *mac = &adap2pinfo(adap, idx)->mac; - u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset); - - if (cause & V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR)) { - mac->stats.tx_fifo_parity_err++; - CH_ALERT(adap, "port%d: MAC TX FIFO parity error\n", idx); - } - if (cause & V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR)) { - mac->stats.rx_fifo_parity_err++; - CH_ALERT(adap, "port%d: MAC RX FIFO parity error\n", idx); - } - if (cause & F_TXFIFO_UNDERRUN) - mac->stats.tx_fifo_urun++; - if (cause & F_RXFIFO_OVERFLOW) - mac->stats.rx_fifo_ovfl++; - if (cause & V_SERDES_LOS(M_SERDES_LOS)) - mac->stats.serdes_signal_loss++; - if (cause & F_XAUIPCSCTCERR) - mac->stats.xaui_pcs_ctc_err++; - if (cause & F_XAUIPCSALIGNCHANGE) - mac->stats.xaui_pcs_align_change++; - - t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause); - if (cause & XGM_INTR_FATAL) - t3_fatal_err(adap); - return cause != 0; -} - -/* - * Interrupt handler for PHY events. - */ -int t3_phy_intr_handler(struct adapter *adapter) -{ - static const int intr_gpio_bits[] = { 8, 0x20 }; - - u32 i, cause = t3_read_reg(adapter, A_T3DBG_INT_CAUSE); - - for_each_port(adapter, i) { - if (cause & intr_gpio_bits[i]) { - struct cphy *phy = &adap2pinfo(adapter, i)->phy; - int phy_cause = phy->ops->intr_handler(phy); - - if (phy_cause & cphy_cause_link_change) - t3_link_changed(adapter, i); - if (phy_cause & cphy_cause_fifo_error) - phy->fifo_errors++; - } - } - - t3_write_reg(adapter, A_T3DBG_INT_CAUSE, cause); - return 0; -} - -/* - * T3 slow path (non-data) interrupt handler. - */ -int t3_slow_intr_handler(struct adapter *adapter) -{ - u32 cause = t3_read_reg(adapter, A_PL_INT_CAUSE0); - - cause &= adapter->slow_intr_mask; - if (!cause) - return 0; - if (cause & F_PCIM0) { - if (is_pcie(adapter)) - pcie_intr_handler(adapter); - else - pci_intr_handler(adapter); - } - if (cause & F_SGE3) - t3_sge_err_intr_handler(adapter); - if (cause & F_MC7_PMRX) - mc7_intr_handler(&adapter->pmrx); - if (cause & F_MC7_PMTX) - mc7_intr_handler(&adapter->pmtx); - if (cause & F_MC7_CM) - mc7_intr_handler(&adapter->cm); - if (cause & F_CIM) - cim_intr_handler(adapter); - if (cause & F_TP1) - tp_intr_handler(adapter); - if (cause & F_ULP2_RX) - ulprx_intr_handler(adapter); - if (cause & F_ULP2_TX) - ulptx_intr_handler(adapter); - if (cause & F_PM1_RX) - pmrx_intr_handler(adapter); - if (cause & F_PM1_TX) - pmtx_intr_handler(adapter); - if (cause & F_CPL_SWITCH) - cplsw_intr_handler(adapter); - if (cause & F_MPS0) - mps_intr_handler(adapter); - if (cause & F_MC5A) - t3_mc5_intr_handler(&adapter->mc5); - if (cause & F_XGMAC0_0) - mac_intr_handler(adapter, 0); - if (cause & F_XGMAC0_1) - mac_intr_handler(adapter, 1); - if (cause & F_T3DBG) - t3_os_ext_intr_handler(adapter); - - /* Clear the interrupts just processed. */ - t3_write_reg(adapter, A_PL_INT_CAUSE0, cause); - t3_read_reg(adapter, A_PL_INT_CAUSE0); /* flush */ - return 1; -} - -/** - * t3_intr_enable - enable interrupts - * @adapter: the adapter whose interrupts should be enabled - * - * Enable interrupts by setting the interrupt enable registers of the - * various HW modules and then enabling the top-level interrupt - * concentrator. - */ -void t3_intr_enable(struct adapter *adapter) -{ - static const struct addr_val_pair intr_en_avp[] = { - {A_SG_INT_ENABLE, SGE_INTR_MASK}, - {A_MC7_INT_ENABLE, MC7_INTR_MASK}, - {A_MC7_INT_ENABLE - MC7_PMRX_BASE_ADDR + MC7_PMTX_BASE_ADDR, - MC7_INTR_MASK}, - {A_MC7_INT_ENABLE - MC7_PMRX_BASE_ADDR + MC7_CM_BASE_ADDR, - MC7_INTR_MASK}, - {A_MC5_DB_INT_ENABLE, MC5_INTR_MASK}, - {A_ULPRX_INT_ENABLE, ULPRX_INTR_MASK}, - {A_TP_INT_ENABLE, 0x3bfffff}, - {A_PM1_TX_INT_ENABLE, PMTX_INTR_MASK}, - {A_PM1_RX_INT_ENABLE, PMRX_INTR_MASK}, - {A_CIM_HOST_INT_ENABLE, CIM_INTR_MASK}, - {A_MPS_INT_ENABLE, MPS_INTR_MASK}, - }; - - adapter->slow_intr_mask = PL_INTR_MASK; - - t3_write_regs(adapter, intr_en_avp, ARRAY_SIZE(intr_en_avp), 0); - - if (adapter->params.rev > 0) { - t3_write_reg(adapter, A_CPL_INTR_ENABLE, - CPLSW_INTR_MASK | F_CIM_OVFL_ERROR); - t3_write_reg(adapter, A_ULPTX_INT_ENABLE, - ULPTX_INTR_MASK | F_PBL_BOUND_ERR_CH0 | - F_PBL_BOUND_ERR_CH1); - } else { - t3_write_reg(adapter, A_CPL_INTR_ENABLE, CPLSW_INTR_MASK); - t3_write_reg(adapter, A_ULPTX_INT_ENABLE, ULPTX_INTR_MASK); - } - - t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, - adapter_info(adapter)->gpio_intr); - t3_write_reg(adapter, A_T3DBG_INT_ENABLE, - adapter_info(adapter)->gpio_intr); - if (is_pcie(adapter)) - t3_write_reg(adapter, A_PCIE_INT_ENABLE, PCIE_INTR_MASK); - else - t3_write_reg(adapter, A_PCIX_INT_ENABLE, PCIX_INTR_MASK); - t3_write_reg(adapter, A_PL_INT_ENABLE0, adapter->slow_intr_mask); - t3_read_reg(adapter, A_PL_INT_ENABLE0); /* flush */ -} - -/** - * t3_intr_disable - disable a card's interrupts - * @adapter: the adapter whose interrupts should be disabled - * - * Disable interrupts. We only disable the top-level interrupt - * concentrator and the SGE data interrupts. - */ -void t3_intr_disable(struct adapter *adapter) -{ - t3_write_reg(adapter, A_PL_INT_ENABLE0, 0); - t3_read_reg(adapter, A_PL_INT_ENABLE0); /* flush */ - adapter->slow_intr_mask = 0; -} - -/** - * t3_intr_clear - clear all interrupts - * @adapter: the adapter whose interrupts should be cleared - * - * Clears all interrupts. - */ -void t3_intr_clear(struct adapter *adapter) -{ - static const unsigned int cause_reg_addr[] = { - A_SG_INT_CAUSE, - A_SG_RSPQ_FL_STATUS, - A_PCIX_INT_CAUSE, - A_MC7_INT_CAUSE, - A_MC7_INT_CAUSE - MC7_PMRX_BASE_ADDR + MC7_PMTX_BASE_ADDR, - A_MC7_INT_CAUSE - MC7_PMRX_BASE_ADDR + MC7_CM_BASE_ADDR, - A_CIM_HOST_INT_CAUSE, - A_TP_INT_CAUSE, - A_MC5_DB_INT_CAUSE, - A_ULPRX_INT_CAUSE, - A_ULPTX_INT_CAUSE, - A_CPL_INTR_CAUSE, - A_PM1_TX_INT_CAUSE, - A_PM1_RX_INT_CAUSE, - A_MPS_INT_CAUSE, - A_T3DBG_INT_CAUSE, - }; - unsigned int i; - - /* Clear PHY and MAC interrupts for each port. */ - for_each_port(adapter, i) - t3_port_intr_clear(adapter, i); - - for (i = 0; i < ARRAY_SIZE(cause_reg_addr); ++i) - t3_write_reg(adapter, cause_reg_addr[i], 0xffffffff); - - t3_write_reg(adapter, A_PL_INT_CAUSE0, 0xffffffff); - t3_read_reg(adapter, A_PL_INT_CAUSE0); /* flush */ -} - -/** - * t3_port_intr_enable - enable port-specific interrupts - * @adapter: associated adapter - * @idx: index of port whose interrupts should be enabled - * - * Enable port-specific (i.e., MAC and PHY) interrupts for the given - * adapter port. - */ -void t3_port_intr_enable(struct adapter *adapter, int idx) -{ - struct cphy *phy = &adap2pinfo(adapter, idx)->phy; - - t3_write_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx), XGM_INTR_MASK); - t3_read_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx)); /* flush */ - phy->ops->intr_enable(phy); -} - -/** - * t3_port_intr_disable - disable port-specific interrupts - * @adapter: associated adapter - * @idx: index of port whose interrupts should be disabled - * - * Disable port-specific (i.e., MAC and PHY) interrupts for the given - * adapter port. - */ -void t3_port_intr_disable(struct adapter *adapter, int idx) -{ - struct cphy *phy = &adap2pinfo(adapter, idx)->phy; - - t3_write_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx), 0); - t3_read_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx)); /* flush */ - phy->ops->intr_disable(phy); -} - -/** - * t3_port_intr_clear - clear port-specific interrupts - * @adapter: associated adapter - * @idx: index of port whose interrupts to clear - * - * Clear port-specific (i.e., MAC and PHY) interrupts for the given - * adapter port. - */ -void t3_port_intr_clear(struct adapter *adapter, int idx) -{ - struct cphy *phy = &adap2pinfo(adapter, idx)->phy; - - t3_write_reg(adapter, XGM_REG(A_XGM_INT_CAUSE, idx), 0xffffffff); - t3_read_reg(adapter, XGM_REG(A_XGM_INT_CAUSE, idx)); /* flush */ - phy->ops->intr_clear(phy); -} - -/** - * t3_sge_write_context - write an SGE context - * @adapter: the adapter - * @id: the context id - * @type: the context type - * - * Program an SGE context with the values already loaded in the - * CONTEXT_DATA? registers. - */ -static int t3_sge_write_context(struct adapter *adapter, unsigned int id, - unsigned int type) -{ - t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0xffffffff); - t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0xffffffff); - t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0xffffffff); - t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0xffffffff); - t3_write_reg(adapter, A_SG_CONTEXT_CMD, - V_CONTEXT_CMD_OPCODE(1) | type | V_CONTEXT(id)); - return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, - 0, 5, 1); -} - -/** - * t3_sge_init_ecntxt - initialize an SGE egress context - * @adapter: the adapter to configure - * @id: the context id - * @gts_enable: whether to enable GTS for the context - * @type: the egress context type - * @respq: associated response queue - * @base_addr: base address of queue - * @size: number of queue entries - * @token: uP token - * @gen: initial generation value for the context - * @cidx: consumer pointer - * - * Initialize an SGE egress context and make it ready for use. If the - * platform allows concurrent context operations, the caller is - * responsible for appropriate locking. - */ -int t3_sge_init_ecntxt(struct adapter *adapter, unsigned int id, int gts_enable, - enum sge_context_type type, int respq, u64 base_addr, - unsigned int size, unsigned int token, int gen, - unsigned int cidx) -{ - unsigned int credits = type == SGE_CNTXT_OFLD ? 0 : FW_WR_NUM; - - if (base_addr & 0xfff) /* must be 4K aligned */ - return -EINVAL; - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - base_addr >>= 12; - t3_write_reg(adapter, A_SG_CONTEXT_DATA0, V_EC_INDEX(cidx) | - V_EC_CREDITS(credits) | V_EC_GTS(gts_enable)); - t3_write_reg(adapter, A_SG_CONTEXT_DATA1, V_EC_SIZE(size) | - V_EC_BASE_LO(base_addr & 0xffff)); - base_addr >>= 16; - t3_write_reg(adapter, A_SG_CONTEXT_DATA2, base_addr); - base_addr >>= 32; - t3_write_reg(adapter, A_SG_CONTEXT_DATA3, - V_EC_BASE_HI(base_addr & 0xf) | V_EC_RESPQ(respq) | - V_EC_TYPE(type) | V_EC_GEN(gen) | V_EC_UP_TOKEN(token) | - F_EC_VALID); - return t3_sge_write_context(adapter, id, F_EGRESS); -} - -/** - * t3_sge_init_flcntxt - initialize an SGE free-buffer list context - * @adapter: the adapter to configure - * @id: the context id - * @gts_enable: whether to enable GTS for the context - * @base_addr: base address of queue - * @size: number of queue entries - * @bsize: size of each buffer for this queue - * @cong_thres: threshold to signal congestion to upstream producers - * @gen: initial generation value for the context - * @cidx: consumer pointer - * - * Initialize an SGE free list context and make it ready for use. The - * caller is responsible for ensuring only one context operation occurs - * at a time. - */ -int t3_sge_init_flcntxt(struct adapter *adapter, unsigned int id, - int gts_enable, u64 base_addr, unsigned int size, - unsigned int bsize, unsigned int cong_thres, int gen, - unsigned int cidx) -{ - if (base_addr & 0xfff) /* must be 4K aligned */ - return -EINVAL; - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - base_addr >>= 12; - t3_write_reg(adapter, A_SG_CONTEXT_DATA0, base_addr); - base_addr >>= 32; - t3_write_reg(adapter, A_SG_CONTEXT_DATA1, - V_FL_BASE_HI((u32) base_addr) | - V_FL_INDEX_LO(cidx & M_FL_INDEX_LO)); - t3_write_reg(adapter, A_SG_CONTEXT_DATA2, V_FL_SIZE(size) | - V_FL_GEN(gen) | V_FL_INDEX_HI(cidx >> 12) | - V_FL_ENTRY_SIZE_LO(bsize & M_FL_ENTRY_SIZE_LO)); - t3_write_reg(adapter, A_SG_CONTEXT_DATA3, - V_FL_ENTRY_SIZE_HI(bsize >> (32 - S_FL_ENTRY_SIZE_LO)) | - V_FL_CONG_THRES(cong_thres) | V_FL_GTS(gts_enable)); - return t3_sge_write_context(adapter, id, F_FREELIST); -} - -/** - * t3_sge_init_rspcntxt - initialize an SGE response queue context - * @adapter: the adapter to configure - * @id: the context id - * @irq_vec_idx: MSI-X interrupt vector index, 0 if no MSI-X, -1 if no IRQ - * @base_addr: base address of queue - * @size: number of queue entries - * @fl_thres: threshold for selecting the normal or jumbo free list - * @gen: initial generation value for the context - * @cidx: consumer pointer - * - * Initialize an SGE response queue context and make it ready for use. - * The caller is responsible for ensuring only one context operation - * occurs at a time. - */ -int t3_sge_init_rspcntxt(struct adapter *adapter, unsigned int id, - int irq_vec_idx, u64 base_addr, unsigned int size, - unsigned int fl_thres, int gen, unsigned int cidx) -{ - unsigned int intr = 0; - - if (base_addr & 0xfff) /* must be 4K aligned */ - return -EINVAL; - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - base_addr >>= 12; - t3_write_reg(adapter, A_SG_CONTEXT_DATA0, V_CQ_SIZE(size) | - V_CQ_INDEX(cidx)); - t3_write_reg(adapter, A_SG_CONTEXT_DATA1, base_addr); - base_addr >>= 32; - if (irq_vec_idx >= 0) - intr = V_RQ_MSI_VEC(irq_vec_idx) | F_RQ_INTR_EN; - t3_write_reg(adapter, A_SG_CONTEXT_DATA2, - V_CQ_BASE_HI((u32) base_addr) | intr | V_RQ_GEN(gen)); - t3_write_reg(adapter, A_SG_CONTEXT_DATA3, fl_thres); - return t3_sge_write_context(adapter, id, F_RESPONSEQ); -} - -/** - * t3_sge_init_cqcntxt - initialize an SGE completion queue context - * @adapter: the adapter to configure - * @id: the context id - * @base_addr: base address of queue - * @size: number of queue entries - * @rspq: response queue for async notifications - * @ovfl_mode: CQ overflow mode - * @credits: completion queue credits - * @credit_thres: the credit threshold - * - * Initialize an SGE completion queue context and make it ready for use. - * The caller is responsible for ensuring only one context operation - * occurs at a time. - */ -int t3_sge_init_cqcntxt(struct adapter *adapter, unsigned int id, u64 base_addr, - unsigned int size, int rspq, int ovfl_mode, - unsigned int credits, unsigned int credit_thres) -{ - if (base_addr & 0xfff) /* must be 4K aligned */ - return -EINVAL; - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - base_addr >>= 12; - t3_write_reg(adapter, A_SG_CONTEXT_DATA0, V_CQ_SIZE(size)); - t3_write_reg(adapter, A_SG_CONTEXT_DATA1, base_addr); - base_addr >>= 32; - t3_write_reg(adapter, A_SG_CONTEXT_DATA2, - V_CQ_BASE_HI((u32) base_addr) | V_CQ_RSPQ(rspq) | - V_CQ_GEN(1) | V_CQ_OVERFLOW_MODE(ovfl_mode)); - t3_write_reg(adapter, A_SG_CONTEXT_DATA3, V_CQ_CREDITS(credits) | - V_CQ_CREDIT_THRES(credit_thres)); - return t3_sge_write_context(adapter, id, F_CQ); -} - -/** - * t3_sge_enable_ecntxt - enable/disable an SGE egress context - * @adapter: the adapter - * @id: the egress context id - * @enable: enable (1) or disable (0) the context - * - * Enable or disable an SGE egress context. The caller is responsible for - * ensuring only one context operation occurs at a time. - */ -int t3_sge_enable_ecntxt(struct adapter *adapter, unsigned int id, int enable) -{ - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0); - t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0); - t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0); - t3_write_reg(adapter, A_SG_CONTEXT_MASK3, F_EC_VALID); - t3_write_reg(adapter, A_SG_CONTEXT_DATA3, V_EC_VALID(enable)); - t3_write_reg(adapter, A_SG_CONTEXT_CMD, - V_CONTEXT_CMD_OPCODE(1) | F_EGRESS | V_CONTEXT(id)); - return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, - 0, 5, 1); -} - -/** - * t3_sge_disable_fl - disable an SGE free-buffer list - * @adapter: the adapter - * @id: the free list context id - * - * Disable an SGE free-buffer list. The caller is responsible for - * ensuring only one context operation occurs at a time. - */ -int t3_sge_disable_fl(struct adapter *adapter, unsigned int id) -{ - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0); - t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0); - t3_write_reg(adapter, A_SG_CONTEXT_MASK2, V_FL_SIZE(M_FL_SIZE)); - t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0); - t3_write_reg(adapter, A_SG_CONTEXT_DATA2, 0); - t3_write_reg(adapter, A_SG_CONTEXT_CMD, - V_CONTEXT_CMD_OPCODE(1) | F_FREELIST | V_CONTEXT(id)); - return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, - 0, 5, 1); -} - -/** - * t3_sge_disable_rspcntxt - disable an SGE response queue - * @adapter: the adapter - * @id: the response queue context id - * - * Disable an SGE response queue. The caller is responsible for - * ensuring only one context operation occurs at a time. - */ -int t3_sge_disable_rspcntxt(struct adapter *adapter, unsigned int id) -{ - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - t3_write_reg(adapter, A_SG_CONTEXT_MASK0, V_CQ_SIZE(M_CQ_SIZE)); - t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0); - t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0); - t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0); - t3_write_reg(adapter, A_SG_CONTEXT_DATA0, 0); - t3_write_reg(adapter, A_SG_CONTEXT_CMD, - V_CONTEXT_CMD_OPCODE(1) | F_RESPONSEQ | V_CONTEXT(id)); - return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, - 0, 5, 1); -} - -/** - * t3_sge_disable_cqcntxt - disable an SGE completion queue - * @adapter: the adapter - * @id: the completion queue context id - * - * Disable an SGE completion queue. The caller is responsible for - * ensuring only one context operation occurs at a time. - */ -int t3_sge_disable_cqcntxt(struct adapter *adapter, unsigned int id) -{ - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - t3_write_reg(adapter, A_SG_CONTEXT_MASK0, V_CQ_SIZE(M_CQ_SIZE)); - t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0); - t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0); - t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0); - t3_write_reg(adapter, A_SG_CONTEXT_DATA0, 0); - t3_write_reg(adapter, A_SG_CONTEXT_CMD, - V_CONTEXT_CMD_OPCODE(1) | F_CQ | V_CONTEXT(id)); - return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, - 0, 5, 1); -} - -/** - * t3_sge_cqcntxt_op - perform an operation on a completion queue context - * @adapter: the adapter - * @id: the context id - * @op: the operation to perform - * - * Perform the selected operation on an SGE completion queue context. - * The caller is responsible for ensuring only one context operation - * occurs at a time. - */ -int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op, - unsigned int credits) -{ - u32 val; - - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - t3_write_reg(adapter, A_SG_CONTEXT_DATA0, credits << 16); - t3_write_reg(adapter, A_SG_CONTEXT_CMD, V_CONTEXT_CMD_OPCODE(op) | - V_CONTEXT(id) | F_CQ); - if (t3_wait_op_done_val(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, - 0, 5, 1, &val)) - return -EIO; - - if (op >= 2 && op < 7) { - if (adapter->params.rev > 0) - return G_CQ_INDEX(val); - - t3_write_reg(adapter, A_SG_CONTEXT_CMD, - V_CONTEXT_CMD_OPCODE(0) | F_CQ | V_CONTEXT(id)); - if (t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, - F_CONTEXT_CMD_BUSY, 0, 5, 1)) - return -EIO; - return G_CQ_INDEX(t3_read_reg(adapter, A_SG_CONTEXT_DATA0)); - } - return 0; -} - -/** - * t3_sge_read_context - read an SGE context - * @type: the context type - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE egress context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -static int t3_sge_read_context(unsigned int type, struct adapter *adapter, - unsigned int id, u32 data[4]) -{ - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - t3_write_reg(adapter, A_SG_CONTEXT_CMD, - V_CONTEXT_CMD_OPCODE(0) | type | V_CONTEXT(id)); - if (t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, 0, - 5, 1)) - return -EIO; - data[0] = t3_read_reg(adapter, A_SG_CONTEXT_DATA0); - data[1] = t3_read_reg(adapter, A_SG_CONTEXT_DATA1); - data[2] = t3_read_reg(adapter, A_SG_CONTEXT_DATA2); - data[3] = t3_read_reg(adapter, A_SG_CONTEXT_DATA3); - return 0; -} - -/** - * t3_sge_read_ecntxt - read an SGE egress context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE egress context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -int t3_sge_read_ecntxt(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= 65536) - return -EINVAL; - return t3_sge_read_context(F_EGRESS, adapter, id, data); -} - -/** - * t3_sge_read_cq - read an SGE CQ context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE CQ context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -int t3_sge_read_cq(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= 65536) - return -EINVAL; - return t3_sge_read_context(F_CQ, adapter, id, data); -} - -/** - * t3_sge_read_fl - read an SGE free-list context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE free-list context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -int t3_sge_read_fl(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= SGE_QSETS * 2) - return -EINVAL; - return t3_sge_read_context(F_FREELIST, adapter, id, data); -} - -/** - * t3_sge_read_rspq - read an SGE response queue context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE response queue context. The caller is responsible for - * ensuring only one context operation occurs at a time. - */ -int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= SGE_QSETS) - return -EINVAL; - return t3_sge_read_context(F_RESPONSEQ, adapter, id, data); -} - -/** - * t3_config_rss - configure Rx packet steering - * @adapter: the adapter - * @rss_config: RSS settings (written to TP_RSS_CONFIG) - * @cpus: values for the CPU lookup table (0xff terminated) - * @rspq: values for the response queue lookup table (0xffff terminated) - * - * Programs the receive packet steering logic. @cpus and @rspq provide - * the values for the CPU and response queue lookup tables. If they - * provide fewer values than the size of the tables the supplied values - * are used repeatedly until the tables are fully populated. - */ -void t3_config_rss(struct adapter *adapter, unsigned int rss_config, - const u8 * cpus, const u16 *rspq) -{ - int i, j, cpu_idx = 0, q_idx = 0; - - if (cpus) - for (i = 0; i < RSS_TABLE_SIZE; ++i) { - u32 val = i << 16; - - for (j = 0; j < 2; ++j) { - val |= (cpus[cpu_idx++] & 0x3f) << (8 * j); - if (cpus[cpu_idx] == 0xff) - cpu_idx = 0; - } - t3_write_reg(adapter, A_TP_RSS_LKP_TABLE, val); - } - - if (rspq) - for (i = 0; i < RSS_TABLE_SIZE; ++i) { - t3_write_reg(adapter, A_TP_RSS_MAP_TABLE, - (i << 16) | rspq[q_idx++]); - if (rspq[q_idx] == 0xffff) - q_idx = 0; - } - - t3_write_reg(adapter, A_TP_RSS_CONFIG, rss_config); -} - -/** - * t3_read_rss - read the contents of the RSS tables - * @adapter: the adapter - * @lkup: holds the contents of the RSS lookup table - * @map: holds the contents of the RSS map table - * - * Reads the contents of the receive packet steering tables. - */ -int t3_read_rss(struct adapter *adapter, u8 * lkup, u16 *map) -{ - int i; - u32 val; - - if (lkup) - for (i = 0; i < RSS_TABLE_SIZE; ++i) { - t3_write_reg(adapter, A_TP_RSS_LKP_TABLE, - 0xffff0000 | i); - val = t3_read_reg(adapter, A_TP_RSS_LKP_TABLE); - if (!(val & 0x80000000)) - return -EAGAIN; - *lkup++ = val; - *lkup++ = (val >> 8); - } - - if (map) - for (i = 0; i < RSS_TABLE_SIZE; ++i) { - t3_write_reg(adapter, A_TP_RSS_MAP_TABLE, - 0xffff0000 | i); - val = t3_read_reg(adapter, A_TP_RSS_MAP_TABLE); - if (!(val & 0x80000000)) - return -EAGAIN; - *map++ = val; - } - return 0; -} - -/** - * t3_tp_set_offload_mode - put TP in NIC/offload mode - * @adap: the adapter - * @enable: 1 to select offload mode, 0 for regular NIC - * - * Switches TP to NIC/offload mode. - */ -void t3_tp_set_offload_mode(struct adapter *adap, int enable) -{ - if (is_offload(adap) || !enable) - t3_set_reg_field(adap, A_TP_IN_CONFIG, F_NICMODE, - V_NICMODE(!enable)); -} - -/** - * pm_num_pages - calculate the number of pages of the payload memory - * @mem_size: the size of the payload memory - * @pg_size: the size of each payload memory page - * - * Calculate the number of pages, each of the given size, that fit in a - * memory of the specified size, respecting the HW requirement that the - * number of pages must be a multiple of 24. - */ -static inline unsigned int pm_num_pages(unsigned int mem_size, - unsigned int pg_size) -{ - unsigned int n = mem_size / pg_size; - - return n - n % 24; -} - -#define mem_region(adap, start, size, reg) \ - t3_write_reg((adap), A_ ## reg, (start)); \ - start += size - -/* - * partition_mem - partition memory and configure TP memory settings - * @adap: the adapter - * @p: the TP parameters - * - * Partitions context and payload memory and configures TP's memory - * registers. - */ -static void partition_mem(struct adapter *adap, const struct tp_params *p) -{ - unsigned int m, pstructs, tids = t3_mc5_size(&adap->mc5); - unsigned int timers = 0, timers_shift = 22; - - if (adap->params.rev > 0) { - if (tids <= 16 * 1024) { - timers = 1; - timers_shift = 16; - } else if (tids <= 64 * 1024) { - timers = 2; - timers_shift = 18; - } else if (tids <= 256 * 1024) { - timers = 3; - timers_shift = 20; - } - } - - t3_write_reg(adap, A_TP_PMM_SIZE, - p->chan_rx_size | (p->chan_tx_size >> 16)); - - t3_write_reg(adap, A_TP_PMM_TX_BASE, 0); - t3_write_reg(adap, A_TP_PMM_TX_PAGE_SIZE, p->tx_pg_size); - t3_write_reg(adap, A_TP_PMM_TX_MAX_PAGE, p->tx_num_pgs); - t3_set_reg_field(adap, A_TP_PARA_REG3, V_TXDATAACKIDX(M_TXDATAACKIDX), - V_TXDATAACKIDX(fls(p->tx_pg_size) - 12)); - - t3_write_reg(adap, A_TP_PMM_RX_BASE, 0); - t3_write_reg(adap, A_TP_PMM_RX_PAGE_SIZE, p->rx_pg_size); - t3_write_reg(adap, A_TP_PMM_RX_MAX_PAGE, p->rx_num_pgs); - - pstructs = p->rx_num_pgs + p->tx_num_pgs; - /* Add a bit of headroom and make multiple of 24 */ - pstructs += 48; - pstructs -= pstructs % 24; - t3_write_reg(adap, A_TP_CMM_MM_MAX_PSTRUCT, pstructs); - - m = tids * TCB_SIZE; - mem_region(adap, m, (64 << 10) * 64, SG_EGR_CNTX_BADDR); - mem_region(adap, m, (64 << 10) * 64, SG_CQ_CONTEXT_BADDR); - t3_write_reg(adap, A_TP_CMM_TIMER_BASE, V_CMTIMERMAXNUM(timers) | m); - m += ((p->ntimer_qs - 1) << timers_shift) + (1 << 22); - mem_region(adap, m, pstructs * 64, TP_CMM_MM_BASE); - mem_region(adap, m, 64 * (pstructs / 24), TP_CMM_MM_PS_FLST_BASE); - mem_region(adap, m, 64 * (p->rx_num_pgs / 24), TP_CMM_MM_RX_FLST_BASE); - mem_region(adap, m, 64 * (p->tx_num_pgs / 24), TP_CMM_MM_TX_FLST_BASE); - - m = (m + 4095) & ~0xfff; - t3_write_reg(adap, A_CIM_SDRAM_BASE_ADDR, m); - t3_write_reg(adap, A_CIM_SDRAM_ADDR_SIZE, p->cm_size - m); - - tids = (p->cm_size - m - (3 << 20)) / 3072 - 32; - m = t3_mc5_size(&adap->mc5) - adap->params.mc5.nservers - - adap->params.mc5.nfilters - adap->params.mc5.nroutes; - if (tids < m) - adap->params.mc5.nservers += m - tids; -} - -static inline void tp_wr_indirect(struct adapter *adap, unsigned int addr, - u32 val) -{ - t3_write_reg(adap, A_TP_PIO_ADDR, addr); - t3_write_reg(adap, A_TP_PIO_DATA, val); -} - -static void tp_config(struct adapter *adap, const struct tp_params *p) -{ - t3_write_reg(adap, A_TP_GLOBAL_CONFIG, F_TXPACINGENABLE | F_PATHMTU | - F_IPCHECKSUMOFFLOAD | F_UDPCHECKSUMOFFLOAD | - F_TCPCHECKSUMOFFLOAD | V_IPTTL(64)); - t3_write_reg(adap, A_TP_TCP_OPTIONS, V_MTUDEFAULT(576) | - F_MTUENABLE | V_WINDOWSCALEMODE(1) | - V_TIMESTAMPSMODE(1) | V_SACKMODE(1) | V_SACKRX(1)); - t3_write_reg(adap, A_TP_DACK_CONFIG, V_AUTOSTATE3(1) | - V_AUTOSTATE2(1) | V_AUTOSTATE1(0) | - V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) | - F_AUTOCAREFUL | F_AUTOENABLE | V_DACK_MODE(1)); - t3_set_reg_field(adap, A_TP_IN_CONFIG, F_IPV6ENABLE | F_NICMODE, - F_IPV6ENABLE | F_NICMODE); - t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814); - t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105); - t3_set_reg_field(adap, A_TP_PARA_REG6, - adap->params.rev > 0 ? F_ENABLEESND : F_T3A_ENABLEESND, - 0); - - t3_set_reg_field(adap, A_TP_PC_CONFIG, - F_ENABLEEPCMDAFULL | F_ENABLEOCSPIFULL, - F_TXDEFERENABLE | F_HEARBEATDACK | F_TXCONGESTIONMODE | - F_RXCONGESTIONMODE); - t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0); - - if (adap->params.rev > 0) { - tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE); - t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO, - F_TXPACEAUTO); - t3_set_reg_field(adap, A_TP_PC_CONFIG, F_LOCKTID, F_LOCKTID); - t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEAUTOSTRICT); - } else - t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED); - - t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0x12121212); - t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0x12121212); - t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0x1212); -} - -/* Desired TP timer resolution in usec */ -#define TP_TMR_RES 50 - -/* TCP timer values in ms */ -#define TP_DACK_TIMER 50 -#define TP_RTO_MIN 250 - -/** - * tp_set_timers - set TP timing parameters - * @adap: the adapter to set - * @core_clk: the core clock frequency in Hz - * - * Set TP's timing parameters, such as the various timer resolutions and - * the TCP timer values. - */ -static void tp_set_timers(struct adapter *adap, unsigned int core_clk) -{ - unsigned int tre = fls(core_clk / (1000000 / TP_TMR_RES)) - 1; - unsigned int dack_re = fls(core_clk / 5000) - 1; /* 200us */ - unsigned int tstamp_re = fls(core_clk / 1000); /* 1ms, at least */ - unsigned int tps = core_clk >> tre; - - t3_write_reg(adap, A_TP_TIMER_RESOLUTION, V_TIMERRESOLUTION(tre) | - V_DELAYEDACKRESOLUTION(dack_re) | - V_TIMESTAMPRESOLUTION(tstamp_re)); - t3_write_reg(adap, A_TP_DACK_TIMER, - (core_clk >> dack_re) / (1000 / TP_DACK_TIMER)); - t3_write_reg(adap, A_TP_TCP_BACKOFF_REG0, 0x3020100); - t3_write_reg(adap, A_TP_TCP_BACKOFF_REG1, 0x7060504); - t3_write_reg(adap, A_TP_TCP_BACKOFF_REG2, 0xb0a0908); - t3_write_reg(adap, A_TP_TCP_BACKOFF_REG3, 0xf0e0d0c); - t3_write_reg(adap, A_TP_SHIFT_CNT, V_SYNSHIFTMAX(6) | - V_RXTSHIFTMAXR1(4) | V_RXTSHIFTMAXR2(15) | - V_PERSHIFTBACKOFFMAX(8) | V_PERSHIFTMAX(8) | - V_KEEPALIVEMAX(9)); - -#define SECONDS * tps - - t3_write_reg(adap, A_TP_MSL, adap->params.rev > 0 ? 0 : 2 SECONDS); - t3_write_reg(adap, A_TP_RXT_MIN, tps / (1000 / TP_RTO_MIN)); - t3_write_reg(adap, A_TP_RXT_MAX, 64 SECONDS); - t3_write_reg(adap, A_TP_PERS_MIN, 5 SECONDS); - t3_write_reg(adap, A_TP_PERS_MAX, 64 SECONDS); - t3_write_reg(adap, A_TP_KEEP_IDLE, 7200 SECONDS); - t3_write_reg(adap, A_TP_KEEP_INTVL, 75 SECONDS); - t3_write_reg(adap, A_TP_INIT_SRTT, 3 SECONDS); - t3_write_reg(adap, A_TP_FINWAIT2_TIMER, 600 SECONDS); - -#undef SECONDS -} - -/** - * t3_tp_set_coalescing_size - set receive coalescing size - * @adap: the adapter - * @size: the receive coalescing size - * @psh: whether a set PSH bit should deliver coalesced data - * - * Set the receive coalescing size and PSH bit handling. - */ -int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh) -{ - u32 val; - - if (size > MAX_RX_COALESCING_LEN) - return -EINVAL; - - val = t3_read_reg(adap, A_TP_PARA_REG3); - val &= ~(F_RXCOALESCEENABLE | F_RXCOALESCEPSHEN); - - if (size) { - val |= F_RXCOALESCEENABLE; - if (psh) - val |= F_RXCOALESCEPSHEN; - t3_write_reg(adap, A_TP_PARA_REG2, V_RXCOALESCESIZE(size) | - V_MAXRXDATA(MAX_RX_COALESCING_LEN)); - } - t3_write_reg(adap, A_TP_PARA_REG3, val); - return 0; -} - -/** - * t3_tp_set_max_rxsize - set the max receive size - * @adap: the adapter - * @size: the max receive size - * - * Set TP's max receive size. This is the limit that applies when - * receive coalescing is disabled. - */ -void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size) -{ - t3_write_reg(adap, A_TP_PARA_REG7, - V_PMMAXXFERLEN0(size) | V_PMMAXXFERLEN1(size)); -} - -static void __devinit init_mtus(unsigned short mtus[]) -{ - /* - * See draft-mathis-plpmtud-00.txt for the values. The min is 88 so - * it can accomodate max size TCP/IP headers when SACK and timestamps - * are enabled and still have at least 8 bytes of payload. - */ - mtus[0] = 88; - mtus[1] = 256; - mtus[2] = 512; - mtus[3] = 576; - mtus[4] = 808; - mtus[5] = 1024; - mtus[6] = 1280; - mtus[7] = 1492; - mtus[8] = 1500; - mtus[9] = 2002; - mtus[10] = 2048; - mtus[11] = 4096; - mtus[12] = 4352; - mtus[13] = 8192; - mtus[14] = 9000; - mtus[15] = 9600; -} - -/* - * Initial congestion control parameters. - */ -static void __devinit init_cong_ctrl(unsigned short *a, unsigned short *b) -{ - a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1; - a[9] = 2; - a[10] = 3; - a[11] = 4; - a[12] = 5; - a[13] = 6; - a[14] = 7; - a[15] = 8; - a[16] = 9; - a[17] = 10; - a[18] = 14; - a[19] = 17; - a[20] = 21; - a[21] = 25; - a[22] = 30; - a[23] = 35; - a[24] = 45; - a[25] = 60; - a[26] = 80; - a[27] = 100; - a[28] = 200; - a[29] = 300; - a[30] = 400; - a[31] = 500; - - b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0; - b[9] = b[10] = 1; - b[11] = b[12] = 2; - b[13] = b[14] = b[15] = b[16] = 3; - b[17] = b[18] = b[19] = b[20] = b[21] = 4; - b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5; - b[28] = b[29] = 6; - b[30] = b[31] = 7; -} - -/* The minimum additive increment value for the congestion control table */ -#define CC_MIN_INCR 2U - -/** - * t3_load_mtus - write the MTU and congestion control HW tables - * @adap: the adapter - * @mtus: the unrestricted values for the MTU table - * @alphs: the values for the congestion control alpha parameter - * @beta: the values for the congestion control beta parameter - * @mtu_cap: the maximum permitted effective MTU - * - * Write the MTU table with the supplied MTUs capping each at &mtu_cap. - * Update the high-speed congestion control table with the supplied alpha, - * beta, and MTUs. - */ -void t3_load_mtus(struct adapter *adap, unsigned short mtus[NMTUS], - unsigned short alpha[NCCTRL_WIN], - unsigned short beta[NCCTRL_WIN], unsigned short mtu_cap) -{ - static const unsigned int avg_pkts[NCCTRL_WIN] = { - 2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640, - 896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480, - 28672, 40960, 57344, 81920, 114688, 163840, 229376 - }; - - unsigned int i, w; - - for (i = 0; i < NMTUS; ++i) { - unsigned int mtu = min(mtus[i], mtu_cap); - unsigned int log2 = fls(mtu); - - if (!(mtu & ((1 << log2) >> 2))) /* round */ - log2--; - t3_write_reg(adap, A_TP_MTU_TABLE, - (i << 24) | (log2 << 16) | mtu); - - for (w = 0; w < NCCTRL_WIN; ++w) { - unsigned int inc; - - inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w], - CC_MIN_INCR); - - t3_write_reg(adap, A_TP_CCTRL_TABLE, (i << 21) | - (w << 16) | (beta[w] << 13) | inc); - } - } -} - -/** - * t3_read_hw_mtus - returns the values in the HW MTU table - * @adap: the adapter - * @mtus: where to store the HW MTU values - * - * Reads the HW MTU table. - */ -void t3_read_hw_mtus(struct adapter *adap, unsigned short mtus[NMTUS]) -{ - int i; - - for (i = 0; i < NMTUS; ++i) { - unsigned int val; - - t3_write_reg(adap, A_TP_MTU_TABLE, 0xff000000 | i); - val = t3_read_reg(adap, A_TP_MTU_TABLE); - mtus[i] = val & 0x3fff; - } -} - -/** - * t3_get_cong_cntl_tab - reads the congestion control table - * @adap: the adapter - * @incr: where to store the alpha values - * - * Reads the additive increments programmed into the HW congestion - * control table. - */ -void t3_get_cong_cntl_tab(struct adapter *adap, - unsigned short incr[NMTUS][NCCTRL_WIN]) -{ - unsigned int mtu, w; - - for (mtu = 0; mtu < NMTUS; ++mtu) - for (w = 0; w < NCCTRL_WIN; ++w) { - t3_write_reg(adap, A_TP_CCTRL_TABLE, - 0xffff0000 | (mtu << 5) | w); - incr[mtu][w] = t3_read_reg(adap, A_TP_CCTRL_TABLE) & - 0x1fff; - } -} - -/** - * t3_tp_get_mib_stats - read TP's MIB counters - * @adap: the adapter - * @tps: holds the returned counter values - * - * Returns the values of TP's MIB counters. - */ -void t3_tp_get_mib_stats(struct adapter *adap, struct tp_mib_stats *tps) -{ - t3_read_indirect(adap, A_TP_MIB_INDEX, A_TP_MIB_RDATA, (u32 *) tps, - sizeof(*tps) / sizeof(u32), 0); -} - -#define ulp_region(adap, name, start, len) \ - t3_write_reg((adap), A_ULPRX_ ## name ## _LLIMIT, (start)); \ - t3_write_reg((adap), A_ULPRX_ ## name ## _ULIMIT, \ - (start) + (len) - 1); \ - start += len - -#define ulptx_region(adap, name, start, len) \ - t3_write_reg((adap), A_ULPTX_ ## name ## _LLIMIT, (start)); \ - t3_write_reg((adap), A_ULPTX_ ## name ## _ULIMIT, \ - (start) + (len) - 1) - -static void ulp_config(struct adapter *adap, const struct tp_params *p) -{ - unsigned int m = p->chan_rx_size; - - ulp_region(adap, ISCSI, m, p->chan_rx_size / 8); - ulp_region(adap, TDDP, m, p->chan_rx_size / 8); - ulptx_region(adap, TPT, m, p->chan_rx_size / 4); - ulp_region(adap, STAG, m, p->chan_rx_size / 4); - ulp_region(adap, RQ, m, p->chan_rx_size / 4); - ulptx_region(adap, PBL, m, p->chan_rx_size / 4); - ulp_region(adap, PBL, m, p->chan_rx_size / 4); - t3_write_reg(adap, A_ULPRX_TDDP_TAGMASK, 0xffffffff); -} - -void t3_config_trace_filter(struct adapter *adapter, - const struct trace_params *tp, int filter_index, - int invert, int enable) -{ - u32 addr, key[4], mask[4]; - - key[0] = tp->sport | (tp->sip << 16); - key[1] = (tp->sip >> 16) | (tp->dport << 16); - key[2] = tp->dip; - key[3] = tp->proto | (tp->vlan << 8) | (tp->intf << 20); - - mask[0] = tp->sport_mask | (tp->sip_mask << 16); - mask[1] = (tp->sip_mask >> 16) | (tp->dport_mask << 16); - mask[2] = tp->dip_mask; - mask[3] = tp->proto_mask | (tp->vlan_mask << 8) | (tp->intf_mask << 20); - - if (invert) - key[3] |= (1 << 29); - if (enable) - key[3] |= (1 << 28); - - addr = filter_index ? A_TP_RX_TRC_KEY0 : A_TP_TX_TRC_KEY0; - tp_wr_indirect(adapter, addr++, key[0]); - tp_wr_indirect(adapter, addr++, mask[0]); - tp_wr_indirect(adapter, addr++, key[1]); - tp_wr_indirect(adapter, addr++, mask[1]); - tp_wr_indirect(adapter, addr++, key[2]); - tp_wr_indirect(adapter, addr++, mask[2]); - tp_wr_indirect(adapter, addr++, key[3]); - tp_wr_indirect(adapter, addr, mask[3]); - t3_read_reg(adapter, A_TP_PIO_DATA); -} - -/** - * t3_config_sched - configure a HW traffic scheduler - * @adap: the adapter - * @kbps: target rate in Kbps - * @sched: the scheduler index - * - * Configure a HW scheduler for the target rate - */ -int t3_config_sched(struct adapter *adap, unsigned int kbps, int sched) -{ - unsigned int v, tps, cpt, bpt, delta, mindelta = ~0; - unsigned int clk = adap->params.vpd.cclk * 1000; - unsigned int selected_cpt = 0, selected_bpt = 0; - - if (kbps > 0) { - kbps *= 125; /* -> bytes */ - for (cpt = 1; cpt <= 255; cpt++) { - tps = clk / cpt; - bpt = (kbps + tps / 2) / tps; - if (bpt > 0 && bpt <= 255) { - v = bpt * tps; - delta = v >= kbps ? v - kbps : kbps - v; - if (delta <= mindelta) { - mindelta = delta; - selected_cpt = cpt; - selected_bpt = bpt; - } - } else if (selected_cpt) - break; - } - if (!selected_cpt) - return -EINVAL; - } - t3_write_reg(adap, A_TP_TM_PIO_ADDR, - A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2); - v = t3_read_reg(adap, A_TP_TM_PIO_DATA); - if (sched & 1) - v = (v & 0xffff) | (selected_cpt << 16) | (selected_bpt << 24); - else - v = (v & 0xffff0000) | selected_cpt | (selected_bpt << 8); - t3_write_reg(adap, A_TP_TM_PIO_DATA, v); - return 0; -} - -static int tp_init(struct adapter *adap, const struct tp_params *p) -{ - int busy = 0; - - tp_config(adap, p); - t3_set_vlan_accel(adap, 3, 0); - - if (is_offload(adap)) { - tp_set_timers(adap, adap->params.vpd.cclk * 1000); - t3_write_reg(adap, A_TP_RESET, F_FLSTINITENABLE); - busy = t3_wait_op_done(adap, A_TP_RESET, F_FLSTINITENABLE, - 0, 1000, 5); - if (busy) - CH_ERR(adap, "TP initialization timed out\n"); - } - - if (!busy) - t3_write_reg(adap, A_TP_RESET, F_TPRESET); - return busy; -} - -int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask) -{ - if (port_mask & ~((1 << adap->params.nports) - 1)) - return -EINVAL; - t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE | F_PORT0ACTIVE, - port_mask << S_PORT0ACTIVE); - return 0; -} - -/* - * Perform the bits of HW initialization that are dependent on the number - * of available ports. - */ -static void init_hw_for_avail_ports(struct adapter *adap, int nports) -{ - int i; - - if (nports == 1) { - t3_set_reg_field(adap, A_ULPRX_CTL, F_ROUND_ROBIN, 0); - t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0); - t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN | - F_PORT0ACTIVE | F_ENFORCEPKT); - t3_write_reg(adap, A_PM1_TX_CFG, 0xc000c000); - } else { - t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN); - t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB); - t3_write_reg(adap, A_ULPTX_DMA_WEIGHT, - V_D1_WEIGHT(16) | V_D0_WEIGHT(16)); - t3_write_reg(adap, A_MPS_CFG, F_TPTXPORT0EN | F_TPTXPORT1EN | - F_TPRXPORTEN | F_PORT0ACTIVE | F_PORT1ACTIVE | - F_ENFORCEPKT); - t3_write_reg(adap, A_PM1_TX_CFG, 0x80008000); - t3_set_reg_field(adap, A_TP_PC_CONFIG, 0, F_TXTOSQUEUEMAPMODE); - t3_write_reg(adap, A_TP_TX_MOD_QUEUE_REQ_MAP, - V_TX_MOD_QUEUE_REQ_MAP(0xaa)); - for (i = 0; i < 16; i++) - t3_write_reg(adap, A_TP_TX_MOD_QUE_TABLE, - (i << 16) | 0x1010); - } -} - -static int calibrate_xgm(struct adapter *adapter) -{ - if (uses_xaui(adapter)) { - unsigned int v, i; - - for (i = 0; i < 5; ++i) { - t3_write_reg(adapter, A_XGM_XAUI_IMP, 0); - t3_read_reg(adapter, A_XGM_XAUI_IMP); - msleep(1); - v = t3_read_reg(adapter, A_XGM_XAUI_IMP); - if (!(v & (F_XGM_CALFAULT | F_CALBUSY))) { - t3_write_reg(adapter, A_XGM_XAUI_IMP, - V_XAUIIMP(G_CALIMP(v) >> 2)); - return 0; - } - } - CH_ERR(adapter, "MAC calibration failed\n"); - return -1; - } else { - t3_write_reg(adapter, A_XGM_RGMII_IMP, - V_RGMIIIMPPD(2) | V_RGMIIIMPPU(3)); - t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_XGM_IMPSETUPDATE, - F_XGM_IMPSETUPDATE); - } - return 0; -} - -static void calibrate_xgm_t3b(struct adapter *adapter) -{ - if (!uses_xaui(adapter)) { - t3_write_reg(adapter, A_XGM_RGMII_IMP, F_CALRESET | - F_CALUPDATE | V_RGMIIIMPPD(2) | V_RGMIIIMPPU(3)); - t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_CALRESET, 0); - t3_set_reg_field(adapter, A_XGM_RGMII_IMP, 0, - F_XGM_IMPSETUPDATE); - t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_XGM_IMPSETUPDATE, - 0); - t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_CALUPDATE, 0); - t3_set_reg_field(adapter, A_XGM_RGMII_IMP, 0, F_CALUPDATE); - } -} - -struct mc7_timing_params { - unsigned char ActToPreDly; - unsigned char ActToRdWrDly; - unsigned char PreCyc; - unsigned char RefCyc[5]; - unsigned char BkCyc; - unsigned char WrToRdDly; - unsigned char RdToWrDly; -}; - -/* - * Write a value to a register and check that the write completed. These - * writes normally complete in a cycle or two, so one read should suffice. - * The very first read exists to flush the posted write to the device. - */ -static int wrreg_wait(struct adapter *adapter, unsigned int addr, u32 val) -{ - t3_write_reg(adapter, addr, val); - t3_read_reg(adapter, addr); /* flush */ - if (!(t3_read_reg(adapter, addr) & F_BUSY)) - return 0; - CH_ERR(adapter, "write to MC7 register 0x%x timed out\n", addr); - return -EIO; -} - -static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type) -{ - static const unsigned int mc7_mode[] = { - 0x632, 0x642, 0x652, 0x432, 0x442 - }; - static const struct mc7_timing_params mc7_timings[] = { - {12, 3, 4, {20, 28, 34, 52, 0}, 15, 6, 4}, - {12, 4, 5, {20, 28, 34, 52, 0}, 16, 7, 4}, - {12, 5, 6, {20, 28, 34, 52, 0}, 17, 8, 4}, - {9, 3, 4, {15, 21, 26, 39, 0}, 12, 6, 4}, - {9, 4, 5, {15, 21, 26, 39, 0}, 13, 7, 4} - }; - - u32 val; - unsigned int width, density, slow, attempts; - struct adapter *adapter = mc7->adapter; - const struct mc7_timing_params *p = &mc7_timings[mem_type]; - - val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG); - slow = val & F_SLOW; - width = G_WIDTH(val); - density = G_DEN(val); - - t3_write_reg(adapter, mc7->offset + A_MC7_CFG, val | F_IFEN); - val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG); /* flush */ - msleep(1); - - if (!slow) { - t3_write_reg(adapter, mc7->offset + A_MC7_CAL, F_SGL_CAL_EN); - t3_read_reg(adapter, mc7->offset + A_MC7_CAL); - msleep(1); - if (t3_read_reg(adapter, mc7->offset + A_MC7_CAL) & - (F_BUSY | F_SGL_CAL_EN | F_CAL_FAULT)) { - CH_ERR(adapter, "%s MC7 calibration timed out\n", - mc7->name); - goto out_fail; - } - } - - t3_write_reg(adapter, mc7->offset + A_MC7_PARM, - V_ACTTOPREDLY(p->ActToPreDly) | - V_ACTTORDWRDLY(p->ActToRdWrDly) | V_PRECYC(p->PreCyc) | - V_REFCYC(p->RefCyc[density]) | V_BKCYC(p->BkCyc) | - V_WRTORDDLY(p->WrToRdDly) | V_RDTOWRDLY(p->RdToWrDly)); - - t3_write_reg(adapter, mc7->offset + A_MC7_CFG, - val | F_CLKEN | F_TERM150); - t3_read_reg(adapter, mc7->offset + A_MC7_CFG); /* flush */ - - if (!slow) - t3_set_reg_field(adapter, mc7->offset + A_MC7_DLL, F_DLLENB, - F_DLLENB); - udelay(1); - - val = slow ? 3 : 6; - if (wrreg_wait(adapter, mc7->offset + A_MC7_PRE, 0) || - wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE2, 0) || - wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE3, 0) || - wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE1, val)) - goto out_fail; - - if (!slow) { - t3_write_reg(adapter, mc7->offset + A_MC7_MODE, 0x100); - t3_set_reg_field(adapter, mc7->offset + A_MC7_DLL, F_DLLRST, 0); - udelay(5); - } - - if (wrreg_wait(adapter, mc7->offset + A_MC7_PRE, 0) || - wrreg_wait(adapter, mc7->offset + A_MC7_REF, 0) || - wrreg_wait(adapter, mc7->offset + A_MC7_REF, 0) || - wrreg_wait(adapter, mc7->offset + A_MC7_MODE, - mc7_mode[mem_type]) || - wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE1, val | 0x380) || - wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE1, val)) - goto out_fail; - - /* clock value is in KHz */ - mc7_clock = mc7_clock * 7812 + mc7_clock / 2; /* ns */ - mc7_clock /= 1000000; /* KHz->MHz, ns->us */ - - t3_write_reg(adapter, mc7->offset + A_MC7_REF, - F_PERREFEN | V_PREREFDIV(mc7_clock)); - t3_read_reg(adapter, mc7->offset + A_MC7_REF); /* flush */ - - t3_write_reg(adapter, mc7->offset + A_MC7_ECC, F_ECCGENEN | F_ECCCHKEN); - t3_write_reg(adapter, mc7->offset + A_MC7_BIST_DATA, 0); - t3_write_reg(adapter, mc7->offset + A_MC7_BIST_ADDR_BEG, 0); - t3_write_reg(adapter, mc7->offset + A_MC7_BIST_ADDR_END, - (mc7->size << width) - 1); - t3_write_reg(adapter, mc7->offset + A_MC7_BIST_OP, V_OP(1)); - t3_read_reg(adapter, mc7->offset + A_MC7_BIST_OP); /* flush */ - - attempts = 50; - do { - msleep(250); - val = t3_read_reg(adapter, mc7->offset + A_MC7_BIST_OP); - } while ((val & F_BUSY) && --attempts); - if (val & F_BUSY) { - CH_ERR(adapter, "%s MC7 BIST timed out\n", mc7->name); - goto out_fail; - } - - /* Enable normal memory accesses. */ - t3_set_reg_field(adapter, mc7->offset + A_MC7_CFG, 0, F_RDY); - return 0; - -out_fail: - return -1; -} - -static void config_pcie(struct adapter *adap) -{ - static const u16 ack_lat[4][6] = { - {237, 416, 559, 1071, 2095, 4143}, - {128, 217, 289, 545, 1057, 2081}, - {73, 118, 154, 282, 538, 1050}, - {67, 107, 86, 150, 278, 534} - }; - static const u16 rpl_tmr[4][6] = { - {711, 1248, 1677, 3213, 6285, 12429}, - {384, 651, 867, 1635, 3171, 6243}, - {219, 354, 462, 846, 1614, 3150}, - {201, 321, 258, 450, 834, 1602} - }; - - u16 val; - unsigned int log2_width, pldsize; - unsigned int fst_trn_rx, fst_trn_tx, acklat, rpllmt; - - pci_read_config_word(adap->pdev, - adap->params.pci.pcie_cap_addr + PCI_EXP_DEVCTL, - &val); - pldsize = (val & PCI_EXP_DEVCTL_PAYLOAD) >> 5; - pci_read_config_word(adap->pdev, - adap->params.pci.pcie_cap_addr + PCI_EXP_LNKCTL, - &val); - - fst_trn_tx = G_NUMFSTTRNSEQ(t3_read_reg(adap, A_PCIE_PEX_CTRL0)); - fst_trn_rx = adap->params.rev == 0 ? fst_trn_tx : - G_NUMFSTTRNSEQRX(t3_read_reg(adap, A_PCIE_MODE)); - log2_width = fls(adap->params.pci.width) - 1; - acklat = ack_lat[log2_width][pldsize]; - if (val & 1) /* check LOsEnable */ - acklat += fst_trn_tx * 4; - rpllmt = rpl_tmr[log2_width][pldsize] + fst_trn_rx * 4; - - if (adap->params.rev == 0) - t3_set_reg_field(adap, A_PCIE_PEX_CTRL1, - V_T3A_ACKLAT(M_T3A_ACKLAT), - V_T3A_ACKLAT(acklat)); - else - t3_set_reg_field(adap, A_PCIE_PEX_CTRL1, V_ACKLAT(M_ACKLAT), - V_ACKLAT(acklat)); - - t3_set_reg_field(adap, A_PCIE_PEX_CTRL0, V_REPLAYLMT(M_REPLAYLMT), - V_REPLAYLMT(rpllmt)); - - t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff); - t3_set_reg_field(adap, A_PCIE_CFG, F_PCIE_CLIDECEN, F_PCIE_CLIDECEN); -} - -/* - * Initialize and configure T3 HW modules. This performs the - * initialization steps that need to be done once after a card is reset. - * MAC and PHY initialization is handled separarely whenever a port is enabled. - * - * fw_params are passed to FW and their value is platform dependent. Only the - * top 8 bits are available for use, the rest must be 0. - */ -int t3_init_hw(struct adapter *adapter, u32 fw_params) -{ - int err = -EIO, attempts = 100; - const struct vpd_params *vpd = &adapter->params.vpd; - - if (adapter->params.rev > 0) - calibrate_xgm_t3b(adapter); - else if (calibrate_xgm(adapter)) - goto out_err; - - if (vpd->mclk) { - partition_mem(adapter, &adapter->params.tp); - - if (mc7_init(&adapter->pmrx, vpd->mclk, vpd->mem_timing) || - mc7_init(&adapter->pmtx, vpd->mclk, vpd->mem_timing) || - mc7_init(&adapter->cm, vpd->mclk, vpd->mem_timing) || - t3_mc5_init(&adapter->mc5, adapter->params.mc5.nservers, - adapter->params.mc5.nfilters, - adapter->params.mc5.nroutes)) - goto out_err; - } - - if (tp_init(adapter, &adapter->params.tp)) - goto out_err; - - t3_tp_set_coalescing_size(adapter, - min(adapter->params.sge.max_pkt_size, - MAX_RX_COALESCING_LEN), 1); - t3_tp_set_max_rxsize(adapter, - min(adapter->params.sge.max_pkt_size, 16384U)); - ulp_config(adapter, &adapter->params.tp); - - if (is_pcie(adapter)) - config_pcie(adapter); - else - t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN); - - t3_write_reg(adapter, A_PM1_RX_CFG, 0xf000f000); - init_hw_for_avail_ports(adapter, adapter->params.nports); - t3_sge_init(adapter, &adapter->params.sge); - - t3_write_reg(adapter, A_CIM_HOST_ACC_DATA, vpd->uclk | fw_params); - t3_write_reg(adapter, A_CIM_BOOT_CFG, - V_BOOTADDR(FW_FLASH_BOOT_ADDR >> 2)); - t3_read_reg(adapter, A_CIM_BOOT_CFG); /* flush */ - - do { /* wait for uP to initialize */ - msleep(20); - } while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts); - if (!attempts) - goto out_err; - - err = 0; -out_err: - return err; -} - -/** - * get_pci_mode - determine a card's PCI mode - * @adapter: the adapter - * @p: where to store the PCI settings - * - * Determines a card's PCI mode and associated parameters, such as speed - * and width. - */ -static void __devinit get_pci_mode(struct adapter *adapter, - struct pci_params *p) -{ - static unsigned short speed_map[] = { 33, 66, 100, 133 }; - u32 pci_mode, pcie_cap; - - pcie_cap = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); - if (pcie_cap) { - u16 val; - - p->variant = PCI_VARIANT_PCIE; - p->pcie_cap_addr = pcie_cap; - pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA, - &val); - p->width = (val >> 4) & 0x3f; - return; - } - - pci_mode = t3_read_reg(adapter, A_PCIX_MODE); - p->speed = speed_map[G_PCLKRANGE(pci_mode)]; - p->width = (pci_mode & F_64BIT) ? 64 : 32; - pci_mode = G_PCIXINITPAT(pci_mode); - if (pci_mode == 0) - p->variant = PCI_VARIANT_PCI; - else if (pci_mode < 4) - p->variant = PCI_VARIANT_PCIX_MODE1_PARITY; - else if (pci_mode < 8) - p->variant = PCI_VARIANT_PCIX_MODE1_ECC; - else - p->variant = PCI_VARIANT_PCIX_266_MODE2; -} - -/** - * init_link_config - initialize a link's SW state - * @lc: structure holding the link state - * @ai: information about the current card - * - * Initializes the SW state maintained for each link, including the link's - * capabilities and default speed/duplex/flow-control/autonegotiation - * settings. - */ -static void __devinit init_link_config(struct link_config *lc, - unsigned int caps) -{ - lc->supported = caps; - lc->requested_speed = lc->speed = SPEED_INVALID; - lc->requested_duplex = lc->duplex = DUPLEX_INVALID; - lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; - if (lc->supported & SUPPORTED_Autoneg) { - lc->advertising = lc->supported; - lc->autoneg = AUTONEG_ENABLE; - lc->requested_fc |= PAUSE_AUTONEG; - } else { - lc->advertising = 0; - lc->autoneg = AUTONEG_DISABLE; - } -} - -/** - * mc7_calc_size - calculate MC7 memory size - * @cfg: the MC7 configuration - * - * Calculates the size of an MC7 memory in bytes from the value of its - * configuration register. - */ -static unsigned int __devinit mc7_calc_size(u32 cfg) -{ - unsigned int width = G_WIDTH(cfg); - unsigned int banks = !!(cfg & F_BKS) + 1; - unsigned int org = !!(cfg & F_ORG) + 1; - unsigned int density = G_DEN(cfg); - unsigned int MBs = ((256 << density) * banks) / (org << width); - - return MBs << 20; -} - -static void __devinit mc7_prep(struct adapter *adapter, struct mc7 *mc7, - unsigned int base_addr, const char *name) -{ - u32 cfg; - - mc7->adapter = adapter; - mc7->name = name; - mc7->offset = base_addr - MC7_PMRX_BASE_ADDR; - cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG); - mc7->size = mc7_calc_size(cfg); - mc7->width = G_WIDTH(cfg); -} - -void mac_prep(struct cmac *mac, struct adapter *adapter, int index) -{ - mac->adapter = adapter; - mac->offset = (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR) * index; - mac->nucast = 1; - - if (adapter->params.rev == 0 && uses_xaui(adapter)) { - t3_write_reg(adapter, A_XGM_SERDES_CTRL + mac->offset, - is_10G(adapter) ? 0x2901c04 : 0x2301c04); - t3_set_reg_field(adapter, A_XGM_PORT_CFG + mac->offset, - F_ENRGMII, 0); - } -} - -void early_hw_init(struct adapter *adapter, const struct adapter_info *ai) -{ - u32 val = V_PORTSPEED(is_10G(adapter) ? 3 : 2); - - mi1_init(adapter, ai); - t3_write_reg(adapter, A_I2C_CFG, /* set for 80KHz */ - V_I2C_CLKDIV(adapter->params.vpd.cclk / 80 - 1)); - t3_write_reg(adapter, A_T3DBG_GPIO_EN, - ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL); - - if (adapter->params.rev == 0 || !uses_xaui(adapter)) - val |= F_ENRGMII; - - /* Enable MAC clocks so we can access the registers */ - t3_write_reg(adapter, A_XGM_PORT_CFG, val); - t3_read_reg(adapter, A_XGM_PORT_CFG); - - val |= F_CLKDIVRESET_; - t3_write_reg(adapter, A_XGM_PORT_CFG, val); - t3_read_reg(adapter, A_XGM_PORT_CFG); - t3_write_reg(adapter, XGM_REG(A_XGM_PORT_CFG, 1), val); - t3_read_reg(adapter, A_XGM_PORT_CFG); -} - -/* - * Reset the adapter. PCIe cards lose their config space during reset, PCI-X - * ones don't. - */ -int t3_reset_adapter(struct adapter *adapter) -{ - int i; - uint16_t devid = 0; - - if (is_pcie(adapter)) - pci_save_state(adapter->pdev); - t3_write_reg(adapter, A_PL_RST, F_CRSTWRM | F_CRSTWRMMODE); - - /* - * Delay. Give Some time to device to reset fully. - * XXX The delay time should be modified. - */ - for (i = 0; i < 10; i++) { - msleep(50); - pci_read_config_word(adapter->pdev, 0x00, &devid); - if (devid == 0x1425) - break; - } - - if (devid != 0x1425) - return -1; - - if (is_pcie(adapter)) - pci_restore_state(adapter->pdev); - return 0; -} - -/* - * Initialize adapter SW state for the various HW modules, set initial values - * for some adapter tunables, take PHYs out of reset, and initialize the MDIO - * interface. - */ -int __devinit t3_prep_adapter(struct adapter *adapter, - const struct adapter_info *ai, int reset) -{ - int ret; - unsigned int i, j = 0; - - get_pci_mode(adapter, &adapter->params.pci); - - adapter->params.info = ai; - adapter->params.nports = ai->nports; - adapter->params.rev = t3_read_reg(adapter, A_PL_REV); - adapter->params.linkpoll_period = 0; - adapter->params.stats_update_period = is_10G(adapter) ? - MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10); - adapter->params.pci.vpd_cap_addr = - pci_find_capability(adapter->pdev, PCI_CAP_ID_VPD); - ret = get_vpd_params(adapter, &adapter->params.vpd); - if (ret < 0) - return ret; - - if (reset && t3_reset_adapter(adapter)) - return -1; - - t3_sge_prep(adapter, &adapter->params.sge); - - if (adapter->params.vpd.mclk) { - struct tp_params *p = &adapter->params.tp; - - mc7_prep(adapter, &adapter->pmrx, MC7_PMRX_BASE_ADDR, "PMRX"); - mc7_prep(adapter, &adapter->pmtx, MC7_PMTX_BASE_ADDR, "PMTX"); - mc7_prep(adapter, &adapter->cm, MC7_CM_BASE_ADDR, "CM"); - - p->nchan = ai->nports; - p->pmrx_size = t3_mc7_size(&adapter->pmrx); - p->pmtx_size = t3_mc7_size(&adapter->pmtx); - p->cm_size = t3_mc7_size(&adapter->cm); - p->chan_rx_size = p->pmrx_size / 2; /* only 1 Rx channel */ - p->chan_tx_size = p->pmtx_size / p->nchan; - p->rx_pg_size = 64 * 1024; - p->tx_pg_size = is_10G(adapter) ? 64 * 1024 : 16 * 1024; - p->rx_num_pgs = pm_num_pages(p->chan_rx_size, p->rx_pg_size); - p->tx_num_pgs = pm_num_pages(p->chan_tx_size, p->tx_pg_size); - p->ntimer_qs = p->cm_size >= (128 << 20) || - adapter->params.rev > 0 ? 12 : 6; - - adapter->params.mc5.nservers = DEFAULT_NSERVERS; - adapter->params.mc5.nfilters = adapter->params.rev > 0 ? - DEFAULT_NFILTERS : 0; - adapter->params.mc5.nroutes = 0; - t3_mc5_prep(adapter, &adapter->mc5, MC5_MODE_144_BIT); - - init_mtus(adapter->params.mtus); - init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); - } - - early_hw_init(adapter, ai); - - for_each_port(adapter, i) { - u8 hw_addr[6]; - struct port_info *p = adap2pinfo(adapter, i); - - while (!adapter->params.vpd.port_type[j]) - ++j; - - p->port_type = &port_types[adapter->params.vpd.port_type[j]]; - p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, - ai->mdio_ops); - mac_prep(&p->mac, adapter, j); - ++j; - - /* - * The VPD EEPROM stores the base Ethernet address for the - * card. A port's address is derived from the base by adding - * the port's index to the base's low octet. - */ - memcpy(hw_addr, adapter->params.vpd.eth_base, 5); - hw_addr[5] = adapter->params.vpd.eth_base[5] + i; - - memcpy(adapter->port[i]->dev_addr, hw_addr, - ETH_ALEN); - memcpy(adapter->port[i]->perm_addr, hw_addr, - ETH_ALEN); - init_link_config(&p->link_config, p->port_type->caps); - p->phy.ops->power_down(&p->phy, 1); - if (!(p->port_type->caps & SUPPORTED_IRQ)) - adapter->params.linkpoll_period = 10; - } - - return 0; -} - -void t3_led_ready(struct adapter *adapter) -{ - t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, - F_GPIO0_OUT_VAL); -} diff --git a/trunk/drivers/net/cxgb3/t3cdev.h b/trunk/drivers/net/cxgb3/t3cdev.h deleted file mode 100644 index 9af3bcd64b3b..000000000000 --- a/trunk/drivers/net/cxgb3/t3cdev.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2006-2007 Chelsio Communications. All rights reserved. - * Copyright (C) 2006-2007 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _T3CDEV_H_ -#define _T3CDEV_H_ - -#include -#include -#include -#include -#include -#include -#include - -#define T3CNAMSIZ 16 - -/* Get the t3cdev associated with a net_device */ -#define T3CDEV(netdev) (struct t3cdev *)(netdev->priv) - -struct cxgb3_client; - -enum t3ctype { - T3A = 0, - T3B -}; - -struct t3cdev { - char name[T3CNAMSIZ]; /* T3C device name */ - enum t3ctype type; - struct list_head ofld_dev_list; /* for list linking */ - struct net_device *lldev; /* LL dev associated with T3C messages */ - struct proc_dir_entry *proc_dir; /* root of proc dir for this T3C */ - int (*send)(struct t3cdev *dev, struct sk_buff *skb); - int (*recv)(struct t3cdev *dev, struct sk_buff **skb, int n); - int (*ctl)(struct t3cdev *dev, unsigned int req, void *data); - void (*neigh_update)(struct t3cdev *dev, struct neighbour *neigh); - void *priv; /* driver private data */ - void *l2opt; /* optional layer 2 data */ - void *l3opt; /* optional layer 3 data */ - void *l4opt; /* optional layer 4 data */ - void *ulp; /* ulp stuff */ -}; - -#endif /* _T3CDEV_H_ */ diff --git a/trunk/drivers/net/cxgb3/version.h b/trunk/drivers/net/cxgb3/version.h deleted file mode 100644 index 2b67dd523cc1..000000000000 --- a/trunk/drivers/net/cxgb3/version.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/* $Date: 2006/10/31 18:57:51 $ $RCSfile: version.h,v $ $Revision: 1.3 $ */ -#ifndef __CHELSIO_VERSION_H -#define __CHELSIO_VERSION_H -#define DRV_DESC "Chelsio T3 Network Driver" -#define DRV_NAME "cxgb3" -/* Driver version */ -#define DRV_VERSION "1.0" -#endif /* __CHELSIO_VERSION_H */ diff --git a/trunk/drivers/net/cxgb3/vsc8211.c b/trunk/drivers/net/cxgb3/vsc8211.c deleted file mode 100644 index eee4285b31be..000000000000 --- a/trunk/drivers/net/cxgb3/vsc8211.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "common.h" - -/* VSC8211 PHY specific registers. */ -enum { - VSC8211_INTR_ENABLE = 25, - VSC8211_INTR_STATUS = 26, - VSC8211_AUX_CTRL_STAT = 28, -}; - -enum { - VSC_INTR_RX_ERR = 1 << 0, - VSC_INTR_MS_ERR = 1 << 1, /* master/slave resolution error */ - VSC_INTR_CABLE = 1 << 2, /* cable impairment */ - VSC_INTR_FALSE_CARR = 1 << 3, /* false carrier */ - VSC_INTR_MEDIA_CHG = 1 << 4, /* AMS media change */ - VSC_INTR_RX_FIFO = 1 << 5, /* Rx FIFO over/underflow */ - VSC_INTR_TX_FIFO = 1 << 6, /* Tx FIFO over/underflow */ - VSC_INTR_DESCRAMBL = 1 << 7, /* descrambler lock-lost */ - VSC_INTR_SYMBOL_ERR = 1 << 8, /* symbol error */ - VSC_INTR_NEG_DONE = 1 << 10, /* autoneg done */ - VSC_INTR_NEG_ERR = 1 << 11, /* autoneg error */ - VSC_INTR_LINK_CHG = 1 << 13, /* link change */ - VSC_INTR_ENABLE = 1 << 15, /* interrupt enable */ -}; - -#define CFG_CHG_INTR_MASK (VSC_INTR_LINK_CHG | VSC_INTR_NEG_ERR | \ - VSC_INTR_NEG_DONE) -#define INTR_MASK (CFG_CHG_INTR_MASK | VSC_INTR_TX_FIFO | VSC_INTR_RX_FIFO | \ - VSC_INTR_ENABLE) - -/* PHY specific auxiliary control & status register fields */ -#define S_ACSR_ACTIPHY_TMR 0 -#define M_ACSR_ACTIPHY_TMR 0x3 -#define V_ACSR_ACTIPHY_TMR(x) ((x) << S_ACSR_ACTIPHY_TMR) - -#define S_ACSR_SPEED 3 -#define M_ACSR_SPEED 0x3 -#define G_ACSR_SPEED(x) (((x) >> S_ACSR_SPEED) & M_ACSR_SPEED) - -#define S_ACSR_DUPLEX 5 -#define F_ACSR_DUPLEX (1 << S_ACSR_DUPLEX) - -#define S_ACSR_ACTIPHY 6 -#define F_ACSR_ACTIPHY (1 << S_ACSR_ACTIPHY) - -/* - * Reset the PHY. This PHY completes reset immediately so we never wait. - */ -static int vsc8211_reset(struct cphy *cphy, int wait) -{ - return t3_phy_reset(cphy, 0, 0); -} - -static int vsc8211_intr_enable(struct cphy *cphy) -{ - return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, INTR_MASK); -} - -static int vsc8211_intr_disable(struct cphy *cphy) -{ - return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, 0); -} - -static int vsc8211_intr_clear(struct cphy *cphy) -{ - u32 val; - - /* Clear PHY interrupts by reading the register. */ - return mdio_read(cphy, 0, VSC8211_INTR_STATUS, &val); -} - -static int vsc8211_autoneg_enable(struct cphy *cphy) -{ - return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, - BMCR_ANENABLE | BMCR_ANRESTART); -} - -static int vsc8211_autoneg_restart(struct cphy *cphy) -{ - return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, - BMCR_ANRESTART); -} - -static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok, - int *speed, int *duplex, int *fc) -{ - unsigned int bmcr, status, lpa, adv; - int err, sp = -1, dplx = -1, pause = 0; - - err = mdio_read(cphy, 0, MII_BMCR, &bmcr); - if (!err) - err = mdio_read(cphy, 0, MII_BMSR, &status); - if (err) - return err; - - if (link_ok) { - /* - * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it - * once more to get the current link state. - */ - if (!(status & BMSR_LSTATUS)) - err = mdio_read(cphy, 0, MII_BMSR, &status); - if (err) - return err; - *link_ok = (status & BMSR_LSTATUS) != 0; - } - if (!(bmcr & BMCR_ANENABLE)) { - dplx = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; - if (bmcr & BMCR_SPEED1000) - sp = SPEED_1000; - else if (bmcr & BMCR_SPEED100) - sp = SPEED_100; - else - sp = SPEED_10; - } else if (status & BMSR_ANEGCOMPLETE) { - err = mdio_read(cphy, 0, VSC8211_AUX_CTRL_STAT, &status); - if (err) - return err; - - dplx = (status & F_ACSR_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF; - sp = G_ACSR_SPEED(status); - if (sp == 0) - sp = SPEED_10; - else if (sp == 1) - sp = SPEED_100; - else - sp = SPEED_1000; - - if (fc && dplx == DUPLEX_FULL) { - err = mdio_read(cphy, 0, MII_LPA, &lpa); - if (!err) - err = mdio_read(cphy, 0, MII_ADVERTISE, &adv); - if (err) - return err; - - if (lpa & adv & ADVERTISE_PAUSE_CAP) - pause = PAUSE_RX | PAUSE_TX; - else if ((lpa & ADVERTISE_PAUSE_CAP) && - (lpa & ADVERTISE_PAUSE_ASYM) && - (adv & ADVERTISE_PAUSE_ASYM)) - pause = PAUSE_TX; - else if ((lpa & ADVERTISE_PAUSE_ASYM) && - (adv & ADVERTISE_PAUSE_CAP)) - pause = PAUSE_RX; - } - } - if (speed) - *speed = sp; - if (duplex) - *duplex = dplx; - if (fc) - *fc = pause; - return 0; -} - -static int vsc8211_power_down(struct cphy *cphy, int enable) -{ - return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN, - enable ? BMCR_PDOWN : 0); -} - -static int vsc8211_intr_handler(struct cphy *cphy) -{ - unsigned int cause; - int err, cphy_cause = 0; - - err = mdio_read(cphy, 0, VSC8211_INTR_STATUS, &cause); - if (err) - return err; - - cause &= INTR_MASK; - if (cause & CFG_CHG_INTR_MASK) - cphy_cause |= cphy_cause_link_change; - if (cause & (VSC_INTR_RX_FIFO | VSC_INTR_TX_FIFO)) - cphy_cause |= cphy_cause_fifo_error; - return cphy_cause; -} - -static struct cphy_ops vsc8211_ops = { - .reset = vsc8211_reset, - .intr_enable = vsc8211_intr_enable, - .intr_disable = vsc8211_intr_disable, - .intr_clear = vsc8211_intr_clear, - .intr_handler = vsc8211_intr_handler, - .autoneg_enable = vsc8211_autoneg_enable, - .autoneg_restart = vsc8211_autoneg_restart, - .advertise = t3_phy_advertise, - .set_speed_duplex = t3_set_phy_speed_duplex, - .get_link_status = vsc8211_get_link_status, - .power_down = vsc8211_power_down, -}; - -void t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops) -{ - cphy_init(phy, adapter, phy_addr, &vsc8211_ops, mdio_ops); -} diff --git a/trunk/drivers/net/cxgb3/xgmac.c b/trunk/drivers/net/cxgb3/xgmac.c deleted file mode 100644 index 907a272ae32d..000000000000 --- a/trunk/drivers/net/cxgb3/xgmac.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "common.h" -#include "regs.h" - -/* - * # of exact address filters. The first one is used for the station address, - * the rest are available for multicast addresses. - */ -#define EXACT_ADDR_FILTERS 8 - -static inline int macidx(const struct cmac *mac) -{ - return mac->offset / (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR); -} - -static void xaui_serdes_reset(struct cmac *mac) -{ - static const unsigned int clear[] = { - F_PWRDN0 | F_PWRDN1, F_RESETPLL01, F_RESET0 | F_RESET1, - F_PWRDN2 | F_PWRDN3, F_RESETPLL23, F_RESET2 | F_RESET3 - }; - - int i; - struct adapter *adap = mac->adapter; - u32 ctrl = A_XGM_SERDES_CTRL0 + mac->offset; - - t3_write_reg(adap, ctrl, adap->params.vpd.xauicfg[macidx(mac)] | - F_RESET3 | F_RESET2 | F_RESET1 | F_RESET0 | - F_PWRDN3 | F_PWRDN2 | F_PWRDN1 | F_PWRDN0 | - F_RESETPLL23 | F_RESETPLL01); - t3_read_reg(adap, ctrl); - udelay(15); - - for (i = 0; i < ARRAY_SIZE(clear); i++) { - t3_set_reg_field(adap, ctrl, clear[i], 0); - udelay(15); - } -} - -void t3b_pcs_reset(struct cmac *mac) -{ - t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset, - F_PCS_RESET_, 0); - udelay(20); - t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset, 0, - F_PCS_RESET_); -} - -int t3_mac_reset(struct cmac *mac) -{ - static const struct addr_val_pair mac_reset_avp[] = { - {A_XGM_TX_CTRL, 0}, - {A_XGM_RX_CTRL, 0}, - {A_XGM_RX_CFG, F_DISPAUSEFRAMES | F_EN1536BFRAMES | - F_RMFCS | F_ENJUMBO | F_ENHASHMCAST}, - {A_XGM_RX_HASH_LOW, 0}, - {A_XGM_RX_HASH_HIGH, 0}, - {A_XGM_RX_EXACT_MATCH_LOW_1, 0}, - {A_XGM_RX_EXACT_MATCH_LOW_2, 0}, - {A_XGM_RX_EXACT_MATCH_LOW_3, 0}, - {A_XGM_RX_EXACT_MATCH_LOW_4, 0}, - {A_XGM_RX_EXACT_MATCH_LOW_5, 0}, - {A_XGM_RX_EXACT_MATCH_LOW_6, 0}, - {A_XGM_RX_EXACT_MATCH_LOW_7, 0}, - {A_XGM_RX_EXACT_MATCH_LOW_8, 0}, - {A_XGM_STAT_CTRL, F_CLRSTATS} - }; - u32 val; - struct adapter *adap = mac->adapter; - unsigned int oft = mac->offset; - - t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_); - t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ - - t3_write_regs(adap, mac_reset_avp, ARRAY_SIZE(mac_reset_avp), oft); - t3_set_reg_field(adap, A_XGM_RXFIFO_CFG + oft, - F_RXSTRFRWRD | F_DISERRFRAMES, - uses_xaui(adap) ? 0 : F_RXSTRFRWRD); - - if (uses_xaui(adap)) { - if (adap->params.rev == 0) { - t3_set_reg_field(adap, A_XGM_SERDES_CTRL + oft, 0, - F_RXENABLE | F_TXENABLE); - if (t3_wait_op_done(adap, A_XGM_SERDES_STATUS1 + oft, - F_CMULOCK, 1, 5, 2)) { - CH_ERR(adap, - "MAC %d XAUI SERDES CMU lock failed\n", - macidx(mac)); - return -1; - } - t3_set_reg_field(adap, A_XGM_SERDES_CTRL + oft, 0, - F_SERDESRESET_); - } else - xaui_serdes_reset(mac); - } - - if (adap->params.rev > 0) - t3_write_reg(adap, A_XGM_PAUSE_TIMER + oft, 0xf000); - - val = F_MAC_RESET_; - if (is_10G(adap)) - val |= F_PCS_RESET_; - else if (uses_xaui(adap)) - val |= F_PCS_RESET_ | F_XG2G_RESET_; - else - val |= F_RGMII_RESET_ | F_XG2G_RESET_; - t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val); - t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ - if ((val & F_PCS_RESET_) && adap->params.rev) { - msleep(1); - t3b_pcs_reset(mac); - } - - memset(&mac->stats, 0, sizeof(mac->stats)); - return 0; -} - -/* - * Set the exact match register 'idx' to recognize the given Ethernet address. - */ -static void set_addr_filter(struct cmac *mac, int idx, const u8 * addr) -{ - u32 addr_lo, addr_hi; - unsigned int oft = mac->offset + idx * 8; - - addr_lo = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; - addr_hi = (addr[5] << 8) | addr[4]; - - t3_write_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1 + oft, addr_lo); - t3_write_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_HIGH_1 + oft, addr_hi); -} - -/* Set one of the station's unicast MAC addresses. */ -int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]) -{ - if (idx >= mac->nucast) - return -EINVAL; - set_addr_filter(mac, idx, addr); - return 0; -} - -/* - * Specify the number of exact address filters that should be reserved for - * unicast addresses. Caller should reload the unicast and multicast addresses - * after calling this. - */ -int t3_mac_set_num_ucast(struct cmac *mac, int n) -{ - if (n > EXACT_ADDR_FILTERS) - return -EINVAL; - mac->nucast = n; - return 0; -} - -/* Calculate the RX hash filter index of an Ethernet address */ -static int hash_hw_addr(const u8 * addr) -{ - int hash = 0, octet, bit, i = 0, c; - - for (octet = 0; octet < 6; ++octet) - for (c = addr[octet], bit = 0; bit < 8; c >>= 1, ++bit) { - hash ^= (c & 1) << i; - if (++i == 6) - i = 0; - } - return hash; -} - -int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm) -{ - u32 val, hash_lo, hash_hi; - struct adapter *adap = mac->adapter; - unsigned int oft = mac->offset; - - val = t3_read_reg(adap, A_XGM_RX_CFG + oft) & ~F_COPYALLFRAMES; - if (rm->dev->flags & IFF_PROMISC) - val |= F_COPYALLFRAMES; - t3_write_reg(adap, A_XGM_RX_CFG + oft, val); - - if (rm->dev->flags & IFF_ALLMULTI) - hash_lo = hash_hi = 0xffffffff; - else { - u8 *addr; - int exact_addr_idx = mac->nucast; - - hash_lo = hash_hi = 0; - while ((addr = t3_get_next_mcaddr(rm))) - if (exact_addr_idx < EXACT_ADDR_FILTERS) - set_addr_filter(mac, exact_addr_idx++, addr); - else { - int hash = hash_hw_addr(addr); - - if (hash < 32) - hash_lo |= (1 << hash); - else - hash_hi |= (1 << (hash - 32)); - } - } - - t3_write_reg(adap, A_XGM_RX_HASH_LOW + oft, hash_lo); - t3_write_reg(adap, A_XGM_RX_HASH_HIGH + oft, hash_hi); - return 0; -} - -int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) -{ - int hwm, lwm; - unsigned int thres, v; - struct adapter *adap = mac->adapter; - - /* - * MAX_FRAME_SIZE inludes header + FCS, mtu doesn't. The HW max - * packet size register includes header, but not FCS. - */ - mtu += 14; - if (mtu > MAX_FRAME_SIZE - 4) - return -EINVAL; - t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu); - - /* - * Adjust the PAUSE frame watermarks. We always set the LWM, and the - * HWM only if flow-control is enabled. - */ - hwm = max(MAC_RXFIFO_SIZE - 3 * mtu, MAC_RXFIFO_SIZE / 2U); - hwm = min(hwm, 3 * MAC_RXFIFO_SIZE / 4 + 1024); - lwm = hwm - 1024; - v = t3_read_reg(adap, A_XGM_RXFIFO_CFG + mac->offset); - v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM); - v |= V_RXFIFOPAUSELWM(lwm / 8); - if (G_RXFIFOPAUSEHWM(v)) - v = (v & ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM)) | - V_RXFIFOPAUSEHWM(hwm / 8); - t3_write_reg(adap, A_XGM_RXFIFO_CFG + mac->offset, v); - - /* Adjust the TX FIFO threshold based on the MTU */ - thres = (adap->params.vpd.cclk * 1000) / 15625; - thres = (thres * mtu) / 1000; - if (is_10G(adap)) - thres /= 10; - thres = mtu > thres ? (mtu - thres + 7) / 8 : 0; - thres = max(thres, 8U); /* need at least 8 */ - t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset, - V_TXFIFOTHRESH(M_TXFIFOTHRESH), V_TXFIFOTHRESH(thres)); - return 0; -} - -int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc) -{ - u32 val; - struct adapter *adap = mac->adapter; - unsigned int oft = mac->offset; - - if (duplex >= 0 && duplex != DUPLEX_FULL) - return -EINVAL; - if (speed >= 0) { - if (speed == SPEED_10) - val = V_PORTSPEED(0); - else if (speed == SPEED_100) - val = V_PORTSPEED(1); - else if (speed == SPEED_1000) - val = V_PORTSPEED(2); - else if (speed == SPEED_10000) - val = V_PORTSPEED(3); - else - return -EINVAL; - - t3_set_reg_field(adap, A_XGM_PORT_CFG + oft, - V_PORTSPEED(M_PORTSPEED), val); - } - - val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft); - val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM); - if (fc & PAUSE_TX) - val |= V_RXFIFOPAUSEHWM(G_RXFIFOPAUSELWM(val) + 128); /* +1KB */ - t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val); - - t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN, - (fc & PAUSE_RX) ? F_TXPAUSEEN : 0); - return 0; -} - -int t3_mac_enable(struct cmac *mac, int which) -{ - int idx = macidx(mac); - struct adapter *adap = mac->adapter; - unsigned int oft = mac->offset; - - if (which & MAC_DIRECTION_TX) { - t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN); - t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); - t3_write_reg(adap, A_TP_PIO_DATA, 0xbf000001); - t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE); - t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx); - } - if (which & MAC_DIRECTION_RX) - t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN); - return 0; -} - -int t3_mac_disable(struct cmac *mac, int which) -{ - int idx = macidx(mac); - struct adapter *adap = mac->adapter; - - if (which & MAC_DIRECTION_TX) { - t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0); - t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); - t3_write_reg(adap, A_TP_PIO_DATA, 0xc000001f); - t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE); - t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 0); - } - if (which & MAC_DIRECTION_RX) - t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0); - return 0; -} - -/* - * This function is called periodically to accumulate the current values of the - * RMON counters into the port statistics. Since the packet counters are only - * 32 bits they can overflow in ~286 secs at 10G, so the function should be - * called more frequently than that. The byte counters are 45-bit wide, they - * would overflow in ~7.8 hours. - */ -const struct mac_stats *t3_mac_update_stats(struct cmac *mac) -{ -#define RMON_READ(mac, addr) t3_read_reg(mac->adapter, addr + mac->offset) -#define RMON_UPDATE(mac, name, reg) \ - (mac)->stats.name += (u64)RMON_READ(mac, A_XGM_STAT_##reg) -#define RMON_UPDATE64(mac, name, reg_lo, reg_hi) \ - (mac)->stats.name += RMON_READ(mac, A_XGM_STAT_##reg_lo) + \ - ((u64)RMON_READ(mac, A_XGM_STAT_##reg_hi) << 32) - - u32 v, lo; - - RMON_UPDATE64(mac, rx_octets, RX_BYTES_LOW, RX_BYTES_HIGH); - RMON_UPDATE64(mac, rx_frames, RX_FRAMES_LOW, RX_FRAMES_HIGH); - RMON_UPDATE(mac, rx_mcast_frames, RX_MCAST_FRAMES); - RMON_UPDATE(mac, rx_bcast_frames, RX_BCAST_FRAMES); - RMON_UPDATE(mac, rx_fcs_errs, RX_CRC_ERR_FRAMES); - RMON_UPDATE(mac, rx_pause, RX_PAUSE_FRAMES); - RMON_UPDATE(mac, rx_jabber, RX_JABBER_FRAMES); - RMON_UPDATE(mac, rx_short, RX_SHORT_FRAMES); - RMON_UPDATE(mac, rx_symbol_errs, RX_SYM_CODE_ERR_FRAMES); - - RMON_UPDATE(mac, rx_too_long, RX_OVERSIZE_FRAMES); - mac->stats.rx_too_long += RMON_READ(mac, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT); - - RMON_UPDATE(mac, rx_frames_64, RX_64B_FRAMES); - RMON_UPDATE(mac, rx_frames_65_127, RX_65_127B_FRAMES); - RMON_UPDATE(mac, rx_frames_128_255, RX_128_255B_FRAMES); - RMON_UPDATE(mac, rx_frames_256_511, RX_256_511B_FRAMES); - RMON_UPDATE(mac, rx_frames_512_1023, RX_512_1023B_FRAMES); - RMON_UPDATE(mac, rx_frames_1024_1518, RX_1024_1518B_FRAMES); - RMON_UPDATE(mac, rx_frames_1519_max, RX_1519_MAXB_FRAMES); - - RMON_UPDATE64(mac, tx_octets, TX_BYTE_LOW, TX_BYTE_HIGH); - RMON_UPDATE64(mac, tx_frames, TX_FRAME_LOW, TX_FRAME_HIGH); - RMON_UPDATE(mac, tx_mcast_frames, TX_MCAST); - RMON_UPDATE(mac, tx_bcast_frames, TX_BCAST); - RMON_UPDATE(mac, tx_pause, TX_PAUSE); - /* This counts error frames in general (bad FCS, underrun, etc). */ - RMON_UPDATE(mac, tx_underrun, TX_ERR_FRAMES); - - RMON_UPDATE(mac, tx_frames_64, TX_64B_FRAMES); - RMON_UPDATE(mac, tx_frames_65_127, TX_65_127B_FRAMES); - RMON_UPDATE(mac, tx_frames_128_255, TX_128_255B_FRAMES); - RMON_UPDATE(mac, tx_frames_256_511, TX_256_511B_FRAMES); - RMON_UPDATE(mac, tx_frames_512_1023, TX_512_1023B_FRAMES); - RMON_UPDATE(mac, tx_frames_1024_1518, TX_1024_1518B_FRAMES); - RMON_UPDATE(mac, tx_frames_1519_max, TX_1519_MAXB_FRAMES); - - /* The next stat isn't clear-on-read. */ - t3_write_reg(mac->adapter, A_TP_MIB_INDEX, mac->offset ? 51 : 50); - v = t3_read_reg(mac->adapter, A_TP_MIB_RDATA); - lo = (u32) mac->stats.rx_cong_drops; - mac->stats.rx_cong_drops += (u64) (v - lo); - - return &mac->stats; -} diff --git a/trunk/drivers/net/declance.c b/trunk/drivers/net/declance.c index 9f7e1db8ce62..4ae0fed7122e 100644 --- a/trunk/drivers/net/declance.c +++ b/trunk/drivers/net/declance.c @@ -5,7 +5,7 @@ * * adopted from sunlance.c by Richard van den Berg * - * Copyright (C) 2002, 2003, 2005, 2006 Maciej W. Rozycki + * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki * * additional sources: * - PMAD-AA TURBOchannel Ethernet Module Functional Specification, @@ -44,8 +44,6 @@ * v0.010: Fixes for the PMAD mapping of the LANCE buffer and for the * PMAX requirement to only use halfword accesses to the * buffer. macro - * - * v0.011: Converted the PMAD to the driver model. macro */ #include @@ -60,7 +58,6 @@ #include #include #include -#include #include #include @@ -72,16 +69,15 @@ #include #include #include +#include static char version[] __devinitdata = -"declance.c: v0.011 by Linux MIPS DECstation task force\n"; +"declance.c: v0.010 by Linux MIPS DECstation task force\n"; MODULE_AUTHOR("Linux MIPS DECstation task force"); MODULE_DESCRIPTION("DEC LANCE (DECstation onboard, PMAD-xx) driver"); MODULE_LICENSE("GPL"); -#define __unused __attribute__ ((unused)) - /* * card types */ @@ -250,6 +246,7 @@ struct lance_init_block { struct lance_private { struct net_device *next; int type; + int slot; int dma_irq; volatile struct lance_regs *ll; @@ -291,7 +288,6 @@ struct lance_regs { int dec_lance_debug = 2; -static struct tc_driver dec_lance_tc_driver; static struct net_device *root_lance_dev; static inline void writereg(volatile unsigned short *regptr, short value) @@ -1027,7 +1023,7 @@ static void lance_set_multicast_retry(unsigned long _opaque) lance_set_multicast(dev); } -static int __init dec_lance_probe(struct device *bdev, const int type) +static int __init dec_lance_init(const int type, const int slot) { static unsigned version_printed; static const char fmt[] = "declance%d"; @@ -1035,7 +1031,6 @@ static int __init dec_lance_probe(struct device *bdev, const int type) struct net_device *dev; struct lance_private *lp; volatile struct lance_regs *ll; - resource_size_t start = 0, len = 0; int i, ret; unsigned long esar_base; unsigned char *esar; @@ -1043,18 +1038,14 @@ static int __init dec_lance_probe(struct device *bdev, const int type) if (dec_lance_debug && version_printed++ == 0) printk(version); - if (bdev) - snprintf(name, sizeof(name), "%s", bdev->bus_id); - else { - i = 0; - dev = root_lance_dev; - while (dev) { - i++; - lp = (struct lance_private *)dev->priv; - dev = lp->next; - } - snprintf(name, sizeof(name), fmt, i); + i = 0; + dev = root_lance_dev; + while (dev) { + i++; + lp = (struct lance_private *)dev->priv; + dev = lp->next; } + snprintf(name, sizeof(name), fmt, i); dev = alloc_etherdev(sizeof(struct lance_private)); if (!dev) { @@ -1072,6 +1063,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type) spin_lock_init(&lp->lock); lp->type = type; + lp->slot = slot; switch (type) { case ASIC_LANCE: dev->base_addr = CKSEG1ADDR(dec_kn_slot_base + IOASIC_LANCE); @@ -1118,22 +1110,12 @@ static int __init dec_lance_probe(struct device *bdev, const int type) break; #ifdef CONFIG_TC case PMAD_LANCE: - dev_set_drvdata(bdev, dev); - - start = to_tc_dev(bdev)->resource.start; - len = to_tc_dev(bdev)->resource.end - start + 1; - if (!request_mem_region(start, len, bdev->bus_id)) { - printk(KERN_ERR - "%s: Unable to reserve MMIO resource\n", - bdev->bus_id); - ret = -EBUSY; - goto err_out_dev; - } + claim_tc_card(slot); - dev->mem_start = CKSEG1ADDR(start); + dev->mem_start = CKSEG1ADDR(get_tc_base_addr(slot)); dev->mem_end = dev->mem_start + 0x100000; dev->base_addr = dev->mem_start + 0x100000; - dev->irq = to_tc_dev(bdev)->interrupt; + dev->irq = get_tc_irq_nr(slot); esar_base = dev->mem_start + 0x1c0002; lp->dma_irq = -1; @@ -1192,7 +1174,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type) printk(KERN_ERR "%s: declance_init called with unknown type\n", name); ret = -ENODEV; - goto err_out_dev; + goto err_out_free_dev; } ll = (struct lance_regs *) dev->base_addr; @@ -1206,7 +1188,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type) "%s: Ethernet station address prom not found!\n", name); ret = -ENODEV; - goto err_out_resource; + goto err_out_free_dev; } /* Check the prom contents */ for (i = 0; i < 8; i++) { @@ -1216,7 +1198,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type) printk(KERN_ERR "%s: Something is wrong with the " "ethernet station address prom!\n", name); ret = -ENODEV; - goto err_out_resource; + goto err_out_free_dev; } } @@ -1273,51 +1255,48 @@ static int __init dec_lance_probe(struct device *bdev, const int type) if (ret) { printk(KERN_ERR "%s: Unable to register netdev, aborting.\n", name); - goto err_out_resource; + goto err_out_free_dev; } - if (!bdev) { - lp->next = root_lance_dev; - root_lance_dev = dev; - } + lp->next = root_lance_dev; + root_lance_dev = dev; printk("%s: registered as %s.\n", name, dev->name); return 0; -err_out_resource: - if (bdev) - release_mem_region(start, len); - -err_out_dev: +err_out_free_dev: free_netdev(dev); err_out: return ret; } -static void __exit dec_lance_remove(struct device *bdev) -{ - struct net_device *dev = dev_get_drvdata(bdev); - resource_size_t start, len; - - unregister_netdev(dev); - start = to_tc_dev(bdev)->resource.start; - len = to_tc_dev(bdev)->resource.end - start + 1; - release_mem_region(start, len); - free_netdev(dev); -} /* Find all the lance cards on the system and initialize them */ -static int __init dec_lance_platform_probe(void) +static int __init dec_lance_probe(void) { int count = 0; + /* Scan slots for PMAD-AA cards first. */ +#ifdef CONFIG_TC + if (TURBOCHANNEL) { + int slot; + + while ((slot = search_tc_card("PMAD-AA")) >= 0) { + if (dec_lance_init(PMAD_LANCE, slot) < 0) + break; + count++; + } + } +#endif + + /* Then handle onboard devices. */ if (dec_interrupt[DEC_IRQ_LANCE] >= 0) { if (dec_interrupt[DEC_IRQ_LANCE_MERR] >= 0) { - if (dec_lance_probe(NULL, ASIC_LANCE) >= 0) + if (dec_lance_init(ASIC_LANCE, -1) >= 0) count++; } else if (!TURBOCHANNEL) { - if (dec_lance_probe(NULL, PMAX_LANCE) >= 0) + if (dec_lance_init(PMAX_LANCE, -1) >= 0) count++; } } @@ -1325,70 +1304,21 @@ static int __init dec_lance_platform_probe(void) return (count > 0) ? 0 : -ENODEV; } -static void __exit dec_lance_platform_remove(void) +static void __exit dec_lance_cleanup(void) { while (root_lance_dev) { struct net_device *dev = root_lance_dev; struct lance_private *lp = netdev_priv(dev); unregister_netdev(dev); +#ifdef CONFIG_TC + if (lp->slot >= 0) + release_tc_card(lp->slot); +#endif root_lance_dev = lp->next; free_netdev(dev); } } -#ifdef CONFIG_TC -static int __init dec_lance_tc_probe(struct device *dev); -static int __exit dec_lance_tc_remove(struct device *dev); - -static const struct tc_device_id dec_lance_tc_table[] = { - { "DEC ", "PMAD-AA " }, - { } -}; -MODULE_DEVICE_TABLE(tc, dec_lance_tc_table); - -static struct tc_driver dec_lance_tc_driver = { - .id_table = dec_lance_tc_table, - .driver = { - .name = "declance", - .bus = &tc_bus_type, - .probe = dec_lance_tc_probe, - .remove = __exit_p(dec_lance_tc_remove), - }, -}; - -static int __init dec_lance_tc_probe(struct device *dev) -{ - int status = dec_lance_probe(dev, PMAD_LANCE); - if (!status) - get_device(dev); - return status; -} - -static int __exit dec_lance_tc_remove(struct device *dev) -{ - put_device(dev); - dec_lance_remove(dev); - return 0; -} -#endif - -static int __init dec_lance_init(void) -{ - int status; - - status = tc_register_driver(&dec_lance_tc_driver); - if (!status) - dec_lance_platform_probe(); - return status; -} - -static void __exit dec_lance_exit(void) -{ - dec_lance_platform_remove(); - tc_unregister_driver(&dec_lance_tc_driver); -} - - -module_init(dec_lance_init); -module_exit(dec_lance_exit); +module_init(dec_lance_probe); +module_exit(dec_lance_cleanup); diff --git a/trunk/drivers/net/e1000/e1000.h b/trunk/drivers/net/e1000/e1000.h index 689f158a469e..f091042b146e 100644 --- a/trunk/drivers/net/e1000/e1000.h +++ b/trunk/drivers/net/e1000/e1000.h @@ -59,13 +59,17 @@ #include #include #include +#ifdef NETIF_F_TSO6 #include +#endif #include #include #include #include #include +#ifdef NETIF_F_TSO #include +#endif #include #include #include @@ -253,6 +257,7 @@ struct e1000_adapter { spinlock_t tx_queue_lock; #endif atomic_t irq_sem; + unsigned int detect_link; unsigned int total_tx_bytes; unsigned int total_tx_packets; unsigned int total_rx_bytes; @@ -343,7 +348,9 @@ struct e1000_adapter { boolean_t have_msi; #endif /* to not mess up cache alignment, always add to the bottom */ +#ifdef NETIF_F_TSO boolean_t tso_force; +#endif boolean_t smart_power_down; /* phy smart power down */ boolean_t quad_port_a; unsigned long flags; diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index 44ebc72962dc..fb96c87f9e56 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -338,6 +338,7 @@ e1000_set_tx_csum(struct net_device *netdev, uint32_t data) return 0; } +#ifdef NETIF_F_TSO static int e1000_set_tso(struct net_device *netdev, uint32_t data) { @@ -351,15 +352,18 @@ e1000_set_tso(struct net_device *netdev, uint32_t data) else netdev->features &= ~NETIF_F_TSO; +#ifdef NETIF_F_TSO6 if (data) netdev->features |= NETIF_F_TSO6; else netdev->features &= ~NETIF_F_TSO6; +#endif DPRINTK(PROBE, INFO, "TSO is %s\n", data ? "Enabled" : "Disabled"); adapter->tso_force = TRUE; return 0; } +#endif /* NETIF_F_TSO */ static uint32_t e1000_get_msglevel(struct net_device *netdev) @@ -1967,8 +1971,10 @@ static const struct ethtool_ops e1000_ethtool_ops = { .set_tx_csum = e1000_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, +#ifdef NETIF_F_TSO .get_tso = ethtool_op_get_tso, .set_tso = e1000_set_tso, +#endif .self_test_count = e1000_diag_test_count, .self_test = e1000_diag_test, .get_strings = e1000_get_strings, diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 619c89218b4b..c6259c7127f6 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -36,7 +36,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "7.3.20-k2"DRIVERNAPI +#define DRV_VERSION "7.3.15-k2"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -990,12 +990,16 @@ e1000_probe(struct pci_dev *pdev, netdev->features &= ~NETIF_F_HW_VLAN_FILTER; } +#ifdef NETIF_F_TSO if ((adapter->hw.mac_type >= e1000_82544) && (adapter->hw.mac_type != e1000_82547)) netdev->features |= NETIF_F_TSO; +#ifdef NETIF_F_TSO6 if (adapter->hw.mac_type > e1000_82547_rev_2) netdev->features |= NETIF_F_TSO6; +#endif +#endif if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -2579,22 +2583,15 @@ e1000_watchdog(unsigned long data) if (link) { if (!netif_carrier_ok(netdev)) { - uint32_t ctrl; boolean_t txb2b = 1; e1000_get_speed_and_duplex(&adapter->hw, &adapter->link_speed, &adapter->link_duplex); - ctrl = E1000_READ_REG(&adapter->hw, CTRL); - DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s, " - "Flow Control: %s\n", - adapter->link_speed, - adapter->link_duplex == FULL_DUPLEX ? - "Full Duplex" : "Half Duplex", - ((ctrl & E1000_CTRL_TFCE) && (ctrl & - E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl & - E1000_CTRL_RFCE) ? "RX" : ((ctrl & - E1000_CTRL_TFCE) ? "TX" : "None" ))); + DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s\n", + adapter->link_speed, + adapter->link_duplex == FULL_DUPLEX ? + "Full Duplex" : "Half Duplex"); /* tweak tx_queue_len according to speed/duplex * and adjust the timeout factor */ @@ -2622,6 +2619,7 @@ e1000_watchdog(unsigned long data) E1000_WRITE_REG(&adapter->hw, TARC0, tarc0); } +#ifdef NETIF_F_TSO /* disable TSO for pcie and 10/100 speeds, to avoid * some hardware issues */ if (!adapter->tso_force && @@ -2632,17 +2630,22 @@ e1000_watchdog(unsigned long data) DPRINTK(PROBE,INFO, "10/100 speed: disabling TSO\n"); netdev->features &= ~NETIF_F_TSO; +#ifdef NETIF_F_TSO6 netdev->features &= ~NETIF_F_TSO6; +#endif break; case SPEED_1000: netdev->features |= NETIF_F_TSO; +#ifdef NETIF_F_TSO6 netdev->features |= NETIF_F_TSO6; +#endif break; default: /* oops */ break; } } +#endif /* enable transmits in the hardware, need to do this * after setting TARC0 */ @@ -2872,6 +2875,7 @@ static int e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, struct sk_buff *skb) { +#ifdef NETIF_F_TSO struct e1000_context_desc *context_desc; struct e1000_buffer *buffer_info; unsigned int i; @@ -2900,6 +2904,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, 0); cmd_length = E1000_TXD_CMD_IP; ipcse = skb->h.raw - skb->data - 1; +#ifdef NETIF_F_TSO6 } else if (skb->protocol == htons(ETH_P_IPV6)) { skb->nh.ipv6h->payload_len = 0; skb->h.th->check = @@ -2909,6 +2914,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, IPPROTO_TCP, 0); ipcse = 0; +#endif } ipcss = skb->nh.raw - skb->data; ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data; @@ -2941,6 +2947,8 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, return TRUE; } +#endif + return FALSE; } @@ -2960,9 +2968,8 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, buffer_info = &tx_ring->buffer_info[i]; context_desc = E1000_CONTEXT_DESC(*tx_ring, i); - context_desc->lower_setup.ip_config = 0; context_desc->upper_setup.tcp_fields.tucss = css; - context_desc->upper_setup.tcp_fields.tucso = css + skb->csum; + context_desc->upper_setup.tcp_fields.tucso = css + skb->csum_offset; context_desc->upper_setup.tcp_fields.tucse = 0; context_desc->tcp_seg_setup.data = 0; context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT); @@ -2998,6 +3005,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, while (len) { buffer_info = &tx_ring->buffer_info[i]; size = min(len, max_per_txd); +#ifdef NETIF_F_TSO /* Workaround for Controller erratum -- * descriptor for non-tso packet in a linear SKB that follows a * tso gets written back prematurely before the data is fully @@ -3012,6 +3020,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, * in TSO mode. Append 4-byte sentinel desc */ if (unlikely(mss && !nr_frags && size == len && size > 8)) size -= 4; +#endif /* work-around for errata 10 and it applies * to all controllers in PCI-X mode * The fix is to make sure that the first descriptor of a @@ -3053,10 +3062,12 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, while (len) { buffer_info = &tx_ring->buffer_info[i]; size = min(len, max_per_txd); +#ifdef NETIF_F_TSO /* Workaround for premature desc write-backs * in TSO mode. Append 4-byte sentinel desc */ if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8)) size -= 4; +#endif /* Workaround for potential 82544 hang in PCI-X. * Avoid terminating buffers within evenly-aligned * dwords. */ @@ -3281,6 +3292,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (adapter->hw.mac_type >= e1000_82571) max_per_txd = 8192; +#ifdef NETIF_F_TSO mss = skb_shinfo(skb)->gso_size; /* The controller does a simple calculation to * make sure there is enough room in the FIFO before @@ -3334,10 +3346,16 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL)) count++; count++; +#else + if (skb->ip_summed == CHECKSUM_PARTIAL) + count++; +#endif +#ifdef NETIF_F_TSO /* Controller Erratum workaround */ if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb)) count++; +#endif count += TXD_USE_COUNT(len, max_txd_pwr); @@ -3584,7 +3602,7 @@ e1000_update_stats(struct e1000_adapter *adapter) */ if (adapter->link_speed == 0) return; - if (pci_channel_offline(pdev)) + if (pdev->error_state && pdev->error_state != pci_channel_io_normal) return; spin_lock_irqsave(&adapter->stats_lock, flags); @@ -3747,8 +3765,8 @@ e1000_update_stats(struct e1000_adapter *adapter) * @data: pointer to a network interface device structure **/ -static irqreturn_t -e1000_intr_msi(int irq, void *data) +static +irqreturn_t e1000_intr_msi(int irq, void *data) { struct net_device *netdev = data; struct e1000_adapter *adapter = netdev_priv(netdev); @@ -3756,27 +3774,49 @@ e1000_intr_msi(int irq, void *data) #ifndef CONFIG_E1000_NAPI int i; #endif - uint32_t icr = E1000_READ_REG(hw, ICR); + /* this code avoids the read of ICR but has to get 1000 interrupts + * at every link change event before it will notice the change */ + if (++adapter->detect_link >= 1000) { + uint32_t icr = E1000_READ_REG(hw, ICR); #ifdef CONFIG_E1000_NAPI - /* read ICR disables interrupts using IAM, so keep up with our - * enable/disable accounting */ - atomic_inc(&adapter->irq_sem); + /* read ICR disables interrupts using IAM, so keep up with our + * enable/disable accounting */ + atomic_inc(&adapter->irq_sem); #endif - if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - hw->get_link_status = 1; - /* 80003ES2LAN workaround-- For packet buffer work-around on - * link down event; disable receives here in the ISR and reset - * adapter in watchdog */ - if (netif_carrier_ok(netdev) && - (adapter->hw.mac_type == e1000_80003es2lan)) { - /* disable receives */ - uint32_t rctl = E1000_READ_REG(hw, RCTL); - E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); + adapter->detect_link = 0; + if ((icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) && + (icr & E1000_ICR_INT_ASSERTED)) { + hw->get_link_status = 1; + /* 80003ES2LAN workaround-- + * For packet buffer work-around on link down event; + * disable receives here in the ISR and + * reset adapter in watchdog + */ + if (netif_carrier_ok(netdev) && + (adapter->hw.mac_type == e1000_80003es2lan)) { + /* disable receives */ + uint32_t rctl = E1000_READ_REG(hw, RCTL); + E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); + } + /* guard against interrupt when we're going down */ + if (!test_bit(__E1000_DOWN, &adapter->flags)) + mod_timer(&adapter->watchdog_timer, + jiffies + 1); } - /* guard against interrupt when we're going down */ - if (!test_bit(__E1000_DOWN, &adapter->flags)) - mod_timer(&adapter->watchdog_timer, jiffies + 1); + } else { + E1000_WRITE_REG(hw, ICR, (0xffffffff & ~(E1000_ICR_RXSEQ | + E1000_ICR_LSC))); + /* bummer we have to flush here, but things break otherwise as + * some event appears to be lost or delayed and throughput + * drops. In almost all tests this flush is un-necessary */ + E1000_WRITE_FLUSH(hw); +#ifdef CONFIG_E1000_NAPI + /* Interrupt Auto-Mask (IAM)...upon writing ICR, interrupts are + * masked. No need for the IMC write, but it does mean we + * should account for it ASAP. */ + atomic_inc(&adapter->irq_sem); +#endif } #ifdef CONFIG_E1000_NAPI @@ -3796,7 +3836,7 @@ e1000_intr_msi(int irq, void *data) for (i = 0; i < E1000_MAX_INTR; i++) if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) & - e1000_clean_tx_irq(adapter, adapter->tx_ring))) + !e1000_clean_tx_irq(adapter, adapter->tx_ring))) break; if (likely(adapter->itr_setting & 3)) @@ -3899,7 +3939,7 @@ e1000_intr(int irq, void *data) for (i = 0; i < E1000_MAX_INTR; i++) if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) & - e1000_clean_tx_irq(adapter, adapter->tx_ring))) + !e1000_clean_tx_irq(adapter, adapter->tx_ring))) break; if (likely(adapter->itr_setting & 3)) @@ -3949,7 +3989,7 @@ e1000_clean(struct net_device *poll_dev, int *budget) poll_dev->quota -= work_done; /* If no Tx and not enough Rx work done, exit the polling mode */ - if ((tx_cleaned && (work_done < work_to_do)) || + if ((!tx_cleaned && (work_done == 0)) || !netif_running(poll_dev)) { quit_polling: if (likely(adapter->itr_setting & 3)) @@ -3979,7 +4019,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, #ifdef CONFIG_E1000_NAPI unsigned int count = 0; #endif - boolean_t cleaned = TRUE; + boolean_t cleaned = FALSE; unsigned int total_tx_bytes=0, total_tx_packets=0; i = tx_ring->next_to_clean; @@ -3994,13 +4034,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, if (cleaned) { struct sk_buff *skb = buffer_info->skb; - unsigned int segs, bytecount; - segs = skb_shinfo(skb)->gso_segs ?: 1; - /* multiply data chunks by size of headers */ - bytecount = ((segs - 1) * skb_headlen(skb)) + - skb->len; + unsigned int segs = skb_shinfo(skb)->gso_segs; total_tx_packets += segs; - total_tx_bytes += bytecount; + total_tx_packets++; + total_tx_bytes += skb->len; } e1000_unmap_and_free_tx_resource(adapter, buffer_info); tx_desc->upper.data = 0; @@ -4013,10 +4050,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, #ifdef CONFIG_E1000_NAPI #define E1000_TX_WEIGHT 64 /* weight of a sort for tx, to avoid endless transmit cleanup */ - if (count++ == E1000_TX_WEIGHT) { - cleaned = FALSE; - break; - } + if (count++ == E1000_TX_WEIGHT) break; #endif } diff --git a/trunk/drivers/net/e1000/e1000_osdep.h b/trunk/drivers/net/e1000/e1000_osdep.h index 10af742d8a20..18afc0c25dac 100644 --- a/trunk/drivers/net/e1000/e1000_osdep.h +++ b/trunk/drivers/net/e1000/e1000_osdep.h @@ -48,6 +48,8 @@ typedef enum { TRUE = 1 } boolean_t; +#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B) + #ifdef DBG #define DEBUGOUT(S) printk(KERN_DEBUG S "\n") #define DEBUGOUT1(S, A...) printk(KERN_DEBUG S "\n", A) @@ -56,7 +58,7 @@ typedef enum { #define DEBUGOUT1(S, A...) #endif -#define DEBUGFUNC(F) DEBUGOUT(F "\n") +#define DEBUGFUNC(F) DEBUGOUT(F) #define DEBUGOUT2 DEBUGOUT1 #define DEBUGOUT3 DEBUGOUT2 #define DEBUGOUT7 DEBUGOUT3 diff --git a/trunk/drivers/net/e1000/e1000_param.c b/trunk/drivers/net/e1000/e1000_param.c index f8862e203ac9..cf2a279307e1 100644 --- a/trunk/drivers/net/e1000/e1000_param.c +++ b/trunk/drivers/net/e1000/e1000_param.c @@ -760,13 +760,22 @@ e1000_check_copper_options(struct e1000_adapter *adapter) case SPEED_1000: DPRINTK(PROBE, INFO, "1000 Mbps Speed specified without " "Duplex\n"); - goto full_duplex_only; + DPRINTK(PROBE, INFO, + "Using Autonegotiation at 1000 Mbps " + "Full Duplex only\n"); + adapter->hw.autoneg = adapter->fc_autoneg = 1; + adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; + break; case SPEED_1000 + HALF_DUPLEX: DPRINTK(PROBE, INFO, "Half Duplex is not supported at 1000 Mbps\n"); - /* fall through */ + DPRINTK(PROBE, INFO, + "Using Autonegotiation at 1000 Mbps " + "Full Duplex only\n"); + adapter->hw.autoneg = adapter->fc_autoneg = 1; + adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; + break; case SPEED_1000 + FULL_DUPLEX: -full_duplex_only: DPRINTK(PROBE, INFO, "Using Autonegotiation at 1000 Mbps Full Duplex only\n"); adapter->hw.autoneg = adapter->fc_autoneg = 1; diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index a363148d0198..93f2b7a22160 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -111,7 +111,6 @@ * 0.57: 14 May 2006: Mac address set in probe/remove and order corrections. * 0.58: 30 Oct 2006: Added support for sideband management unit. * 0.59: 30 Oct 2006: Added support for recoverable error. - * 0.60: 20 Jan 2007: Code optimizations for rings, rx & tx data paths, and stats. * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -128,7 +127,7 @@ #else #define DRIVERNAPI #endif -#define FORCEDETH_VERSION "0.60" +#define FORCEDETH_VERSION "0.59" #define DRV_NAME "forcedeth" #include @@ -174,10 +173,9 @@ #define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ #define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ #define DEV_HAS_PAUSEFRAME_TX 0x0200 /* device supports tx pause frames */ -#define DEV_HAS_STATISTICS_V1 0x0400 /* device supports hw statistics version 1 */ -#define DEV_HAS_STATISTICS_V2 0x0800 /* device supports hw statistics version 2 */ -#define DEV_HAS_TEST_EXTENDED 0x1000 /* device supports extended diagnostic test */ -#define DEV_HAS_MGMT_UNIT 0x2000 /* device supports management unit */ +#define DEV_HAS_STATISTICS 0x0400 /* device supports hw statistics */ +#define DEV_HAS_TEST_EXTENDED 0x0800 /* device supports extended diagnostic test */ +#define DEV_HAS_MGMT_UNIT 0x1000 /* device supports management unit */ enum { NvRegIrqStatus = 0x000, @@ -212,7 +210,7 @@ enum { * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms */ NvRegPollingInterval = 0x00c, -#define NVREG_POLL_DEFAULT_THROUGHPUT 970 /* backup tx cleanup if loop max reached */ +#define NVREG_POLL_DEFAULT_THROUGHPUT 970 #define NVREG_POLL_DEFAULT_CPU 13 NvRegMSIMap0 = 0x020, NvRegMSIMap1 = 0x024, @@ -306,8 +304,8 @@ enum { #define NVREG_TXRXCTL_RESET 0x0010 #define NVREG_TXRXCTL_RXCHECK 0x0400 #define NVREG_TXRXCTL_DESC_1 0 -#define NVREG_TXRXCTL_DESC_2 0x002100 -#define NVREG_TXRXCTL_DESC_3 0xc02200 +#define NVREG_TXRXCTL_DESC_2 0x02100 +#define NVREG_TXRXCTL_DESC_3 0x02200 #define NVREG_TXRXCTL_VLANSTRIP 0x00040 #define NVREG_TXRXCTL_VLANINS 0x00080 NvRegTxRingPhysAddrHigh = 0x148, @@ -489,8 +487,7 @@ union ring_type { /* Miscelaneous hardware related defines: */ #define NV_PCI_REGSZ_VER1 0x270 -#define NV_PCI_REGSZ_VER2 0x2d4 -#define NV_PCI_REGSZ_VER3 0x604 +#define NV_PCI_REGSZ_VER2 0x604 /* various timeout delays: all in usec */ #define NV_TXRX_RESET_DELAY 4 @@ -521,6 +518,12 @@ union ring_type { #define TX_RING_MIN 64 #define RING_MAX_DESC_VER_1 1024 #define RING_MAX_DESC_VER_2_3 16384 +/* + * Difference between the get and put pointers for the tx ring. + * This is used to throttle the amount of data outstanding in the + * tx ring. + */ +#define TX_LIMIT_DIFFERENCE 1 /* rx/tx mac addr + type + vlan + align + slack*/ #define NV_RX_HEADERS (64) @@ -608,6 +611,9 @@ static const struct nv_ethtool_str nv_estats_str[] = { { "tx_carrier_errors" }, { "tx_excess_deferral" }, { "tx_retry_error" }, + { "tx_deferral" }, + { "tx_packets" }, + { "tx_pause" }, { "rx_frame_error" }, { "rx_extra_byte" }, { "rx_late_collision" }, @@ -620,17 +626,11 @@ static const struct nv_ethtool_str nv_estats_str[] = { { "rx_unicast" }, { "rx_multicast" }, { "rx_broadcast" }, - { "rx_packets" }, - { "rx_errors_total" }, - { "tx_errors_total" }, - - /* version 2 stats */ - { "tx_deferral" }, - { "tx_packets" }, { "rx_bytes" }, - { "tx_pause" }, { "rx_pause" }, - { "rx_drop_frame" } + { "rx_drop_frame" }, + { "rx_packets" }, + { "rx_errors_total" } }; struct nv_ethtool_stats { @@ -643,6 +643,9 @@ struct nv_ethtool_stats { u64 tx_carrier_errors; u64 tx_excess_deferral; u64 tx_retry_error; + u64 tx_deferral; + u64 tx_packets; + u64 tx_pause; u64 rx_frame_error; u64 rx_extra_byte; u64 rx_late_collision; @@ -655,22 +658,13 @@ struct nv_ethtool_stats { u64 rx_unicast; u64 rx_multicast; u64 rx_broadcast; - u64 rx_packets; - u64 rx_errors_total; - u64 tx_errors_total; - - /* version 2 stats */ - u64 tx_deferral; - u64 tx_packets; u64 rx_bytes; - u64 tx_pause; u64 rx_pause; u64 rx_drop_frame; + u64 rx_packets; + u64 rx_errors_total; }; -#define NV_DEV_STATISTICS_V2_COUNT (sizeof(struct nv_ethtool_stats)/sizeof(u64)) -#define NV_DEV_STATISTICS_V1_COUNT (NV_DEV_STATISTICS_V2_COUNT - 6) - /* diagnostics */ #define NV_TEST_COUNT_BASE 3 #define NV_TEST_COUNT_EXTENDED 4 @@ -697,12 +691,6 @@ static const struct register_test nv_registers_test[] = { { 0,0 } }; -struct nv_skb_map { - struct sk_buff *skb; - dma_addr_t dma; - unsigned int dma_len; -}; - /* * SMP locking: * All hardware access under dev->priv->lock, except the performance @@ -753,12 +741,10 @@ struct fe_priv { /* rx specific fields. * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); */ - union ring_type get_rx, put_rx, first_rx, last_rx; - struct nv_skb_map *get_rx_ctx, *put_rx_ctx; - struct nv_skb_map *first_rx_ctx, *last_rx_ctx; - struct nv_skb_map *rx_skb; - union ring_type rx_ring; + unsigned int cur_rx, refill_rx; + struct sk_buff **rx_skbuff; + dma_addr_t *rx_dma; unsigned int rx_buf_sz; unsigned int pkt_limit; struct timer_list oom_kick; @@ -775,15 +761,15 @@ struct fe_priv { /* * tx specific fields. */ - union ring_type get_tx, put_tx, first_tx, last_tx; - struct nv_skb_map *get_tx_ctx, *put_tx_ctx; - struct nv_skb_map *first_tx_ctx, *last_tx_ctx; - struct nv_skb_map *tx_skb; - union ring_type tx_ring; + unsigned int next_tx, nic_tx; + struct sk_buff **tx_skbuff; + dma_addr_t *tx_dma; + unsigned int *tx_dma_len; u32 tx_flags; int tx_ring_size; - int tx_stop; + int tx_limit_start; + int tx_limit_stop; /* vlan fields */ struct vlan_group *vlangrp; @@ -935,10 +921,16 @@ static void free_rings(struct net_device *dev) pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (np->rx_ring_size + np->tx_ring_size), np->rx_ring.ex, np->ring_addr); } - if (np->rx_skb) - kfree(np->rx_skb); - if (np->tx_skb) - kfree(np->tx_skb); + if (np->rx_skbuff) + kfree(np->rx_skbuff); + if (np->rx_dma) + kfree(np->rx_dma); + if (np->tx_skbuff) + kfree(np->tx_skbuff); + if (np->tx_dma) + kfree(np->tx_dma); + if (np->tx_dma_len) + kfree(np->tx_dma_len); } static int using_multi_irqs(struct net_device *dev) @@ -1287,61 +1279,6 @@ static void nv_mac_reset(struct net_device *dev) pci_push(base); } -static void nv_get_hw_stats(struct net_device *dev) -{ - struct fe_priv *np = netdev_priv(dev); - u8 __iomem *base = get_hwbase(dev); - - np->estats.tx_bytes += readl(base + NvRegTxCnt); - np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt); - np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt); - np->estats.tx_many_rexmt += readl(base + NvRegTxManyReXmt); - np->estats.tx_late_collision += readl(base + NvRegTxLateCol); - np->estats.tx_fifo_errors += readl(base + NvRegTxUnderflow); - np->estats.tx_carrier_errors += readl(base + NvRegTxLossCarrier); - np->estats.tx_excess_deferral += readl(base + NvRegTxExcessDef); - np->estats.tx_retry_error += readl(base + NvRegTxRetryErr); - np->estats.rx_frame_error += readl(base + NvRegRxFrameErr); - np->estats.rx_extra_byte += readl(base + NvRegRxExtraByte); - np->estats.rx_late_collision += readl(base + NvRegRxLateCol); - np->estats.rx_runt += readl(base + NvRegRxRunt); - np->estats.rx_frame_too_long += readl(base + NvRegRxFrameTooLong); - np->estats.rx_over_errors += readl(base + NvRegRxOverflow); - np->estats.rx_crc_errors += readl(base + NvRegRxFCSErr); - np->estats.rx_frame_align_error += readl(base + NvRegRxFrameAlignErr); - np->estats.rx_length_error += readl(base + NvRegRxLenErr); - np->estats.rx_unicast += readl(base + NvRegRxUnicast); - np->estats.rx_multicast += readl(base + NvRegRxMulticast); - np->estats.rx_broadcast += readl(base + NvRegRxBroadcast); - np->estats.rx_packets = - np->estats.rx_unicast + - np->estats.rx_multicast + - np->estats.rx_broadcast; - np->estats.rx_errors_total = - np->estats.rx_crc_errors + - np->estats.rx_over_errors + - np->estats.rx_frame_error + - (np->estats.rx_frame_align_error - np->estats.rx_extra_byte) + - np->estats.rx_late_collision + - np->estats.rx_runt + - np->estats.rx_frame_too_long; - np->estats.tx_errors_total = - np->estats.tx_late_collision + - np->estats.tx_fifo_errors + - np->estats.tx_carrier_errors + - np->estats.tx_excess_deferral + - np->estats.tx_retry_error; - - if (np->driver_data & DEV_HAS_STATISTICS_V2) { - np->estats.tx_deferral += readl(base + NvRegTxDef); - np->estats.tx_packets += readl(base + NvRegTxFrame); - np->estats.rx_bytes += readl(base + NvRegRxCnt); - np->estats.tx_pause += readl(base + NvRegTxPause); - np->estats.rx_pause += readl(base + NvRegRxPause); - np->estats.rx_drop_frame += readl(base + NvRegRxDropFrame); - } -} - /* * nv_get_stats: dev->get_stats function * Get latest stats value from the nic. @@ -1352,19 +1289,10 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - /* If the nic supports hw counters then retrieve latest values */ - if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) { - nv_get_hw_stats(dev); - - /* copy to net_device stats */ - np->stats.tx_bytes = np->estats.tx_bytes; - np->stats.tx_fifo_errors = np->estats.tx_fifo_errors; - np->stats.tx_carrier_errors = np->estats.tx_carrier_errors; - np->stats.rx_crc_errors = np->estats.rx_crc_errors; - np->stats.rx_over_errors = np->estats.rx_over_errors; - np->stats.rx_errors = np->estats.rx_errors_total; - np->stats.tx_errors = np->estats.tx_errors_total; - } + /* It seems that the nic always generates interrupts and doesn't + * accumulate errors internally. Thus the current values in np->stats + * are already up to date. + */ return &np->stats; } @@ -1376,63 +1304,43 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev) static int nv_alloc_rx(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - struct ring_desc* less_rx; + unsigned int refill_rx = np->refill_rx; + int nr; - less_rx = np->get_rx.orig; - if (less_rx-- == np->first_rx.orig) - less_rx = np->last_rx.orig; - - while (np->put_rx.orig != less_rx) { - struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD); - if (skb) { - skb->dev = dev; - np->put_rx_ctx->skb = skb; - np->put_rx_ctx->dma = pci_map_single(np->pci_dev, skb->data, - skb->end-skb->data, PCI_DMA_FROMDEVICE); - np->put_rx_ctx->dma_len = skb->end-skb->data; - np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma); - wmb(); - np->put_rx.orig->flaglen = cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL); - if (unlikely(np->put_rx.orig++ == np->last_rx.orig)) - np->put_rx.orig = np->first_rx.orig; - if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) - np->put_rx_ctx = np->first_rx_ctx; - } else { - return 1; - } - } - return 0; -} + while (np->cur_rx != refill_rx) { + struct sk_buff *skb; -static int nv_alloc_rx_optimized(struct net_device *dev) -{ - struct fe_priv *np = netdev_priv(dev); - struct ring_desc_ex* less_rx; + nr = refill_rx % np->rx_ring_size; + if (np->rx_skbuff[nr] == NULL) { - less_rx = np->get_rx.ex; - if (less_rx-- == np->first_rx.ex) - less_rx = np->last_rx.ex; + skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD); + if (!skb) + break; - while (np->put_rx.ex != less_rx) { - struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD); - if (skb) { skb->dev = dev; - np->put_rx_ctx->skb = skb; - np->put_rx_ctx->dma = pci_map_single(np->pci_dev, skb->data, - skb->end-skb->data, PCI_DMA_FROMDEVICE); - np->put_rx_ctx->dma_len = skb->end-skb->data; - np->put_rx.ex->bufhigh = cpu_to_le64(np->put_rx_ctx->dma) >> 32; - np->put_rx.ex->buflow = cpu_to_le64(np->put_rx_ctx->dma) & 0x0FFFFFFFF; + np->rx_skbuff[nr] = skb; + } else { + skb = np->rx_skbuff[nr]; + } + np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, + skb->end-skb->data, PCI_DMA_FROMDEVICE); + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + np->rx_ring.orig[nr].buf = cpu_to_le32(np->rx_dma[nr]); wmb(); - np->put_rx.ex->flaglen = cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL); - if (unlikely(np->put_rx.ex++ == np->last_rx.ex)) - np->put_rx.ex = np->first_rx.ex; - if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) - np->put_rx_ctx = np->first_rx_ctx; + np->rx_ring.orig[nr].flaglen = cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL); } else { - return 1; + np->rx_ring.ex[nr].bufhigh = cpu_to_le64(np->rx_dma[nr]) >> 32; + np->rx_ring.ex[nr].buflow = cpu_to_le64(np->rx_dma[nr]) & 0x0FFFFFFFF; + wmb(); + np->rx_ring.ex[nr].flaglen = cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL); } + dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", + dev->name, refill_rx); + refill_rx++; } + np->refill_rx = refill_rx; + if (np->cur_rx - refill_rx == np->rx_ring_size) + return 1; return 0; } @@ -1450,7 +1358,6 @@ static void nv_do_rx_refill(unsigned long data) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); - int retcode; if (!using_multi_irqs(dev)) { if (np->msi_flags & NV_MSI_X_ENABLED) @@ -1460,11 +1367,7 @@ static void nv_do_rx_refill(unsigned long data) } else { disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); } - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - retcode = nv_alloc_rx(dev); - else - retcode = nv_alloc_rx_optimized(dev); - if (retcode) { + if (nv_alloc_rx(dev)) { spin_lock_irq(&np->lock); if (!np->in_shutdown) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); @@ -1485,81 +1388,56 @@ static void nv_init_rx(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); int i; - np->get_rx = np->put_rx = np->first_rx = np->rx_ring; - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - np->last_rx.orig = &np->rx_ring.orig[np->rx_ring_size-1]; - else - np->last_rx.ex = &np->rx_ring.ex[np->rx_ring_size-1]; - np->get_rx_ctx = np->put_rx_ctx = np->first_rx_ctx = np->rx_skb; - np->last_rx_ctx = &np->rx_skb[np->rx_ring_size-1]; - for (i = 0; i < np->rx_ring_size; i++) { - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + np->cur_rx = np->rx_ring_size; + np->refill_rx = 0; + for (i = 0; i < np->rx_ring_size; i++) + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) np->rx_ring.orig[i].flaglen = 0; - np->rx_ring.orig[i].buf = 0; - } else { + else np->rx_ring.ex[i].flaglen = 0; - np->rx_ring.ex[i].txvlan = 0; - np->rx_ring.ex[i].bufhigh = 0; - np->rx_ring.ex[i].buflow = 0; - } - np->rx_skb[i].skb = NULL; - np->rx_skb[i].dma = 0; - } } static void nv_init_tx(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); int i; - np->get_tx = np->put_tx = np->first_tx = np->tx_ring; - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - np->last_tx.orig = &np->tx_ring.orig[np->tx_ring_size-1]; - else - np->last_tx.ex = &np->tx_ring.ex[np->tx_ring_size-1]; - np->get_tx_ctx = np->put_tx_ctx = np->first_tx_ctx = np->tx_skb; - np->last_tx_ctx = &np->tx_skb[np->tx_ring_size-1]; + np->next_tx = np->nic_tx = 0; for (i = 0; i < np->tx_ring_size; i++) { - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) np->tx_ring.orig[i].flaglen = 0; - np->tx_ring.orig[i].buf = 0; - } else { + else np->tx_ring.ex[i].flaglen = 0; - np->tx_ring.ex[i].txvlan = 0; - np->tx_ring.ex[i].bufhigh = 0; - np->tx_ring.ex[i].buflow = 0; - } - np->tx_skb[i].skb = NULL; - np->tx_skb[i].dma = 0; + np->tx_skbuff[i] = NULL; + np->tx_dma[i] = 0; } } static int nv_init_ring(struct net_device *dev) { - struct fe_priv *np = netdev_priv(dev); - nv_init_tx(dev); nv_init_rx(dev); - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - return nv_alloc_rx(dev); - else - return nv_alloc_rx_optimized(dev); + return nv_alloc_rx(dev); } -static int nv_release_txskb(struct net_device *dev, struct nv_skb_map* tx_skb) +static int nv_release_txskb(struct net_device *dev, unsigned int skbnr) { struct fe_priv *np = netdev_priv(dev); - if (tx_skb->dma) { - pci_unmap_page(np->pci_dev, tx_skb->dma, - tx_skb->dma_len, + dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d\n", + dev->name, skbnr); + + if (np->tx_dma[skbnr]) { + pci_unmap_page(np->pci_dev, np->tx_dma[skbnr], + np->tx_dma_len[skbnr], PCI_DMA_TODEVICE); - tx_skb->dma = 0; + np->tx_dma[skbnr] = 0; } - if (tx_skb->skb) { - dev_kfree_skb_any(tx_skb->skb); - tx_skb->skb = NULL; + + if (np->tx_skbuff[skbnr]) { + dev_kfree_skb_any(np->tx_skbuff[skbnr]); + np->tx_skbuff[skbnr] = NULL; return 1; } else { return 0; @@ -1572,16 +1450,11 @@ static void nv_drain_tx(struct net_device *dev) unsigned int i; for (i = 0; i < np->tx_ring_size; i++) { - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) np->tx_ring.orig[i].flaglen = 0; - np->tx_ring.orig[i].buf = 0; - } else { + else np->tx_ring.ex[i].flaglen = 0; - np->tx_ring.ex[i].txvlan = 0; - np->tx_ring.ex[i].bufhigh = 0; - np->tx_ring.ex[i].buflow = 0; - } - if (nv_release_txskb(dev, &np->tx_skb[i])) + if (nv_release_txskb(dev, i)) np->stats.tx_dropped++; } } @@ -1590,24 +1463,18 @@ static void nv_drain_rx(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); int i; - for (i = 0; i < np->rx_ring_size; i++) { - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) np->rx_ring.orig[i].flaglen = 0; - np->rx_ring.orig[i].buf = 0; - } else { + else np->rx_ring.ex[i].flaglen = 0; - np->rx_ring.ex[i].txvlan = 0; - np->rx_ring.ex[i].bufhigh = 0; - np->rx_ring.ex[i].buflow = 0; - } wmb(); - if (np->rx_skb[i].skb) { - pci_unmap_single(np->pci_dev, np->rx_skb[i].dma, - np->rx_skb[i].skb->end-np->rx_skb[i].skb->data, + if (np->rx_skbuff[i]) { + pci_unmap_single(np->pci_dev, np->rx_dma[i], + np->rx_skbuff[i]->end-np->rx_skbuff[i]->data, PCI_DMA_FROMDEVICE); - dev_kfree_skb(np->rx_skb[i].skb); - np->rx_skb[i].skb = NULL; + dev_kfree_skb(np->rx_skbuff[i]); + np->rx_skbuff[i] = NULL; } } } @@ -1618,11 +1485,6 @@ static void drain_ring(struct net_device *dev) nv_drain_rx(dev); } -static inline u32 nv_get_empty_tx_slots(struct fe_priv *np) -{ - return (u32)(np->tx_ring_size - ((np->tx_ring_size + (np->put_tx_ctx - np->get_tx_ctx)) % np->tx_ring_size)); -} - /* * nv_start_xmit: dev->hard_start_xmit function * Called with netif_tx_lock held. @@ -1633,16 +1495,14 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 tx_flags = 0; u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET); unsigned int fragments = skb_shinfo(skb)->nr_frags; + unsigned int nr = (np->next_tx - 1) % np->tx_ring_size; + unsigned int start_nr = np->next_tx % np->tx_ring_size; unsigned int i; u32 offset = 0; u32 bcnt; u32 size = skb->len-skb->data_len; u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); - u32 empty_slots; - struct ring_desc* put_tx; - struct ring_desc* start_tx; - struct ring_desc* prev_tx; - struct nv_skb_map* prev_tx_ctx; + u32 tx_flags_vlan = 0; /* add fragments to entries count */ for (i = 0; i < fragments; i++) { @@ -1650,152 +1510,34 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) ((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); } - empty_slots = nv_get_empty_tx_slots(np); - if (unlikely(empty_slots <= entries)) { - spin_lock_irq(&np->lock); - netif_stop_queue(dev); - np->tx_stop = 1; - spin_unlock_irq(&np->lock); - return NETDEV_TX_BUSY; - } - - start_tx = put_tx = np->put_tx.orig; - - /* setup the header buffer */ - do { - prev_tx = put_tx; - prev_tx_ctx = np->put_tx_ctx; - bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; - np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt, - PCI_DMA_TODEVICE); - np->put_tx_ctx->dma_len = bcnt; - put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma); - put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); - - tx_flags = np->tx_flags; - offset += bcnt; - size -= bcnt; - if (unlikely(put_tx++ == np->last_tx.orig)) - put_tx = np->first_tx.orig; - if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) - np->put_tx_ctx = np->first_tx_ctx; - } while (size); - - /* setup the fragments */ - for (i = 0; i < fragments; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - u32 size = frag->size; - offset = 0; - - do { - prev_tx = put_tx; - prev_tx_ctx = np->put_tx_ctx; - bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; - np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt, - PCI_DMA_TODEVICE); - np->put_tx_ctx->dma_len = bcnt; - put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma); - put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); - - offset += bcnt; - size -= bcnt; - if (unlikely(put_tx++ == np->last_tx.orig)) - put_tx = np->first_tx.orig; - if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) - np->put_tx_ctx = np->first_tx_ctx; - } while (size); - } - - /* set last fragment flag */ - prev_tx->flaglen |= cpu_to_le32(tx_flags_extra); - - /* save skb in this slot's context area */ - prev_tx_ctx->skb = skb; - - if (skb_is_gso(skb)) - tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); - else - tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ? - NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0; - spin_lock_irq(&np->lock); - /* set tx flags */ - start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); - np->put_tx.orig = put_tx; - - spin_unlock_irq(&np->lock); - - dprintk(KERN_DEBUG "%s: nv_start_xmit: entries %d queued for transmission. tx_flags_extra: %x\n", - dev->name, entries, tx_flags_extra); - { - int j; - for (j=0; j<64; j++) { - if ((j%16) == 0) - dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char*)skb->data)[j]); - } - dprintk("\n"); - } - - dev->trans_start = jiffies; - writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); - return NETDEV_TX_OK; -} - -static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) -{ - struct fe_priv *np = netdev_priv(dev); - u32 tx_flags = 0; - u32 tx_flags_extra; - unsigned int fragments = skb_shinfo(skb)->nr_frags; - unsigned int i; - u32 offset = 0; - u32 bcnt; - u32 size = skb->len-skb->data_len; - u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); - u32 empty_slots; - struct ring_desc_ex* put_tx; - struct ring_desc_ex* start_tx; - struct ring_desc_ex* prev_tx; - struct nv_skb_map* prev_tx_ctx; - - /* add fragments to entries count */ - for (i = 0; i < fragments; i++) { - entries += (skb_shinfo(skb)->frags[i].size >> NV_TX2_TSO_MAX_SHIFT) + - ((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); - } - - empty_slots = nv_get_empty_tx_slots(np); - if (unlikely(empty_slots <= entries)) { - spin_lock_irq(&np->lock); - netif_stop_queue(dev); - np->tx_stop = 1; + if ((np->next_tx - np->nic_tx + entries - 1) > np->tx_limit_stop) { spin_unlock_irq(&np->lock); + netif_stop_queue(dev); return NETDEV_TX_BUSY; } - start_tx = put_tx = np->put_tx.ex; - /* setup the header buffer */ do { - prev_tx = put_tx; - prev_tx_ctx = np->put_tx_ctx; bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; - np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt, + nr = (nr + 1) % np->tx_ring_size; + + np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data + offset, bcnt, PCI_DMA_TODEVICE); - np->put_tx_ctx->dma_len = bcnt; - put_tx->bufhigh = cpu_to_le64(np->put_tx_ctx->dma) >> 32; - put_tx->buflow = cpu_to_le64(np->put_tx_ctx->dma) & 0x0FFFFFFFF; - put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); + np->tx_dma_len[nr] = bcnt; - tx_flags = NV_TX2_VALID; + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + np->tx_ring.orig[nr].buf = cpu_to_le32(np->tx_dma[nr]); + np->tx_ring.orig[nr].flaglen = cpu_to_le32((bcnt-1) | tx_flags); + } else { + np->tx_ring.ex[nr].bufhigh = cpu_to_le64(np->tx_dma[nr]) >> 32; + np->tx_ring.ex[nr].buflow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; + np->tx_ring.ex[nr].flaglen = cpu_to_le32((bcnt-1) | tx_flags); + } + tx_flags = np->tx_flags; offset += bcnt; size -= bcnt; - if (unlikely(put_tx++ == np->last_tx.ex)) - put_tx = np->first_tx.ex; - if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) - np->put_tx_ctx = np->first_tx_ctx; } while (size); /* setup the fragments */ @@ -1805,57 +1547,58 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) offset = 0; do { - prev_tx = put_tx; - prev_tx_ctx = np->put_tx_ctx; bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; - np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt, - PCI_DMA_TODEVICE); - np->put_tx_ctx->dma_len = bcnt; - put_tx->bufhigh = cpu_to_le64(np->put_tx_ctx->dma) >> 32; - put_tx->buflow = cpu_to_le64(np->put_tx_ctx->dma) & 0x0FFFFFFFF; - put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); + nr = (nr + 1) % np->tx_ring_size; + np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt, + PCI_DMA_TODEVICE); + np->tx_dma_len[nr] = bcnt; + + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + np->tx_ring.orig[nr].buf = cpu_to_le32(np->tx_dma[nr]); + np->tx_ring.orig[nr].flaglen = cpu_to_le32((bcnt-1) | tx_flags); + } else { + np->tx_ring.ex[nr].bufhigh = cpu_to_le64(np->tx_dma[nr]) >> 32; + np->tx_ring.ex[nr].buflow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; + np->tx_ring.ex[nr].flaglen = cpu_to_le32((bcnt-1) | tx_flags); + } offset += bcnt; size -= bcnt; - if (unlikely(put_tx++ == np->last_tx.ex)) - put_tx = np->first_tx.ex; - if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx)) - np->put_tx_ctx = np->first_tx_ctx; } while (size); } /* set last fragment flag */ - prev_tx->flaglen |= cpu_to_le32(NV_TX2_LASTPACKET); + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + np->tx_ring.orig[nr].flaglen |= cpu_to_le32(tx_flags_extra); + } else { + np->tx_ring.ex[nr].flaglen |= cpu_to_le32(tx_flags_extra); + } - /* save skb in this slot's context area */ - prev_tx_ctx->skb = skb; + np->tx_skbuff[nr] = skb; +#ifdef NETIF_F_TSO if (skb_is_gso(skb)) tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); else - tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ? +#endif + tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ? NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0; /* vlan tag */ - if (likely(!np->vlangrp)) { - start_tx->txvlan = 0; - } else { - if (vlan_tx_tag_present(skb)) - start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb)); - else - start_tx->txvlan = 0; + if (np->vlangrp && vlan_tx_tag_present(skb)) { + tx_flags_vlan = NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb); } - spin_lock_irq(&np->lock); - /* set tx flags */ - start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); - np->put_tx.ex = put_tx; - - spin_unlock_irq(&np->lock); + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + np->tx_ring.orig[start_nr].flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); + } else { + np->tx_ring.ex[start_nr].txvlan = cpu_to_le32(tx_flags_vlan); + np->tx_ring.ex[start_nr].flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); + } - dprintk(KERN_DEBUG "%s: nv_start_xmit_optimized: entries %d queued for transmission. tx_flags_extra: %x\n", - dev->name, entries, tx_flags_extra); + dprintk(KERN_DEBUG "%s: nv_start_xmit: packet %d (entries %d) queued for transmission. tx_flags_extra: %x\n", + dev->name, np->next_tx, entries, tx_flags_extra); { int j; for (j=0; j<64; j++) { @@ -1866,8 +1609,12 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) dprintk("\n"); } + np->next_tx += entries; + dev->trans_start = jiffies; + spin_unlock_irq(&np->lock); writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + pci_push(get_hwbase(dev)); return NETDEV_TX_OK; } @@ -1880,22 +1627,26 @@ static void nv_tx_done(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); u32 flags; - struct ring_desc* orig_get_tx = np->get_tx.orig; - - while ((np->get_tx.orig != np->put_tx.orig) && - !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID)) { + unsigned int i; + struct sk_buff *skb; - dprintk(KERN_DEBUG "%s: nv_tx_done: flags 0x%x.\n", - dev->name, flags); + while (np->nic_tx != np->next_tx) { + i = np->nic_tx % np->tx_ring_size; - pci_unmap_page(np->pci_dev, np->get_tx_ctx->dma, - np->get_tx_ctx->dma_len, - PCI_DMA_TODEVICE); - np->get_tx_ctx->dma = 0; + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) + flags = le32_to_cpu(np->tx_ring.orig[i].flaglen); + else + flags = le32_to_cpu(np->tx_ring.ex[i].flaglen); + dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, flags 0x%x.\n", + dev->name, np->nic_tx, flags); + if (flags & NV_TX_VALID) + break; if (np->desc_ver == DESC_VER_1) { if (flags & NV_TX_LASTPACKET) { - if (flags & NV_TX_ERROR) { + skb = np->tx_skbuff[i]; + if (flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION| + NV_TX_UNDERFLOW|NV_TX_ERROR)) { if (flags & NV_TX_UNDERFLOW) np->stats.tx_fifo_errors++; if (flags & NV_TX_CARRIERLOST) @@ -1903,14 +1654,14 @@ static void nv_tx_done(struct net_device *dev) np->stats.tx_errors++; } else { np->stats.tx_packets++; - np->stats.tx_bytes += np->get_tx_ctx->skb->len; + np->stats.tx_bytes += skb->len; } - dev_kfree_skb_any(np->get_tx_ctx->skb); - np->get_tx_ctx->skb = NULL; } } else { if (flags & NV_TX2_LASTPACKET) { - if (flags & NV_TX2_ERROR) { + skb = np->tx_skbuff[i]; + if (flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION| + NV_TX2_UNDERFLOW|NV_TX2_ERROR)) { if (flags & NV_TX2_UNDERFLOW) np->stats.tx_fifo_errors++; if (flags & NV_TX2_CARRIERLOST) @@ -1918,56 +1669,15 @@ static void nv_tx_done(struct net_device *dev) np->stats.tx_errors++; } else { np->stats.tx_packets++; - np->stats.tx_bytes += np->get_tx_ctx->skb->len; + np->stats.tx_bytes += skb->len; } - dev_kfree_skb_any(np->get_tx_ctx->skb); - np->get_tx_ctx->skb = NULL; } } - if (unlikely(np->get_tx.orig++ == np->last_tx.orig)) - np->get_tx.orig = np->first_tx.orig; - if (unlikely(np->get_tx_ctx++ == np->last_tx_ctx)) - np->get_tx_ctx = np->first_tx_ctx; + nv_release_txskb(dev, i); + np->nic_tx++; } - if (unlikely((np->tx_stop == 1) && (np->get_tx.orig != orig_get_tx))) { - np->tx_stop = 0; + if (np->next_tx - np->nic_tx < np->tx_limit_start) netif_wake_queue(dev); - } -} - -static void nv_tx_done_optimized(struct net_device *dev, int limit) -{ - struct fe_priv *np = netdev_priv(dev); - u32 flags; - struct ring_desc_ex* orig_get_tx = np->get_tx.ex; - - while ((np->get_tx.ex != np->put_tx.ex) && - !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX_VALID) && - (limit-- > 0)) { - - dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n", - dev->name, flags); - - pci_unmap_page(np->pci_dev, np->get_tx_ctx->dma, - np->get_tx_ctx->dma_len, - PCI_DMA_TODEVICE); - np->get_tx_ctx->dma = 0; - - if (flags & NV_TX2_LASTPACKET) { - if (!(flags & NV_TX2_ERROR)) - np->stats.tx_packets++; - dev_kfree_skb_any(np->get_tx_ctx->skb); - np->get_tx_ctx->skb = NULL; - } - if (unlikely(np->get_tx.ex++ == np->last_tx.ex)) - np->get_tx.ex = np->first_tx.ex; - if (unlikely(np->get_tx_ctx++ == np->last_tx_ctx)) - np->get_tx_ctx = np->first_tx_ctx; - } - if (unlikely((np->tx_stop == 1) && (np->get_tx.ex != orig_get_tx))) { - np->tx_stop = 0; - netif_wake_queue(dev); - } } /* @@ -1990,8 +1700,9 @@ static void nv_tx_timeout(struct net_device *dev) { int i; - printk(KERN_INFO "%s: Ring at %lx\n", - dev->name, (unsigned long)np->ring_addr); + printk(KERN_INFO "%s: Ring at %lx: next %d nic %d\n", + dev->name, (unsigned long)np->ring_addr, + np->next_tx, np->nic_tx); printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); for (i=0;i<=np->register_size;i+= 32) { printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", @@ -2039,16 +1750,13 @@ static void nv_tx_timeout(struct net_device *dev) nv_stop_tx(dev); /* 2) check that the packets were not sent already: */ - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - nv_tx_done(dev); - else - nv_tx_done_optimized(dev, np->tx_ring_size); + nv_tx_done(dev); /* 3) if there are dead entries: clear everything */ - if (np->get_tx_ctx != np->put_tx_ctx) { + if (np->next_tx != np->nic_tx) { printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name); nv_drain_tx(dev); - nv_init_tx(dev); + np->next_tx = np->nic_tx = 0; setup_hw_rings(dev, NV_SETUP_TX_RING); netif_wake_queue(dev); } @@ -2096,184 +1804,59 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen) */ dprintk(KERN_DEBUG "%s: nv_getlen: discarding long packet.\n", dev->name); - return -1; - } - } else { - /* short packet. Accept only if 802 values are also short */ - if (protolen > ETH_ZLEN) { - dprintk(KERN_DEBUG "%s: nv_getlen: discarding short packet.\n", - dev->name); - return -1; - } - dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n", - dev->name, datalen); - return datalen; - } -} - -static int nv_rx_process(struct net_device *dev, int limit) -{ - struct fe_priv *np = netdev_priv(dev); - u32 flags; - u32 rx_processed_cnt = 0; - struct sk_buff *skb; - int len; - - while((np->get_rx.orig != np->put_rx.orig) && - !((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) && - (rx_processed_cnt++ < limit)) { - - dprintk(KERN_DEBUG "%s: nv_rx_process: flags 0x%x.\n", - dev->name, flags); - - /* - * the packet is for us - immediately tear down the pci mapping. - * TODO: check if a prefetch of the first cacheline improves - * the performance. - */ - pci_unmap_single(np->pci_dev, np->get_rx_ctx->dma, - np->get_rx_ctx->dma_len, - PCI_DMA_FROMDEVICE); - skb = np->get_rx_ctx->skb; - np->get_rx_ctx->skb = NULL; - - { - int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",flags); - for (j=0; j<64; j++) { - if ((j%16) == 0) - dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char*)skb->data)[j]); - } - dprintk("\n"); - } - /* look at what we actually got: */ - if (np->desc_ver == DESC_VER_1) { - if (likely(flags & NV_RX_DESCRIPTORVALID)) { - len = flags & LEN_MASK_V1; - if (unlikely(flags & NV_RX_ERROR)) { - if (flags & NV_RX_ERROR4) { - len = nv_getlen(dev, skb->data, len); - if (len < 0) { - np->stats.rx_errors++; - dev_kfree_skb(skb); - goto next_pkt; - } - } - /* framing errors are soft errors */ - else if (flags & NV_RX_FRAMINGERR) { - if (flags & NV_RX_SUBSTRACT1) { - len--; - } - } - /* the rest are hard errors */ - else { - if (flags & NV_RX_MISSEDFRAME) - np->stats.rx_missed_errors++; - if (flags & NV_RX_CRCERR) - np->stats.rx_crc_errors++; - if (flags & NV_RX_OVERFLOW) - np->stats.rx_over_errors++; - np->stats.rx_errors++; - dev_kfree_skb(skb); - goto next_pkt; - } - } - } else { - dev_kfree_skb(skb); - goto next_pkt; - } - } else { - if (likely(flags & NV_RX2_DESCRIPTORVALID)) { - len = flags & LEN_MASK_V2; - if (unlikely(flags & NV_RX2_ERROR)) { - if (flags & NV_RX2_ERROR4) { - len = nv_getlen(dev, skb->data, len); - if (len < 0) { - np->stats.rx_errors++; - dev_kfree_skb(skb); - goto next_pkt; - } - } - /* framing errors are soft errors */ - else if (flags & NV_RX2_FRAMINGERR) { - if (flags & NV_RX2_SUBSTRACT1) { - len--; - } - } - /* the rest are hard errors */ - else { - if (flags & NV_RX2_CRCERR) - np->stats.rx_crc_errors++; - if (flags & NV_RX2_OVERFLOW) - np->stats.rx_over_errors++; - np->stats.rx_errors++; - dev_kfree_skb(skb); - goto next_pkt; - } - } - if ((flags & NV_RX2_CHECKSUMMASK) == NV_RX2_CHECKSUMOK2)/*ip and tcp */ { - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else { - if ((flags & NV_RX2_CHECKSUMMASK) == NV_RX2_CHECKSUMOK1 || - (flags & NV_RX2_CHECKSUMMASK) == NV_RX2_CHECKSUMOK3) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - } - } - } else { - dev_kfree_skb(skb); - goto next_pkt; - } + return -1; } - /* got a valid packet - forward it to the network core */ - skb_put(skb, len); - skb->protocol = eth_type_trans(skb, dev); - dprintk(KERN_DEBUG "%s: nv_rx_process: %d bytes, proto %d accepted.\n", - dev->name, len, skb->protocol); -#ifdef CONFIG_FORCEDETH_NAPI - netif_receive_skb(skb); -#else - netif_rx(skb); -#endif - dev->last_rx = jiffies; - np->stats.rx_packets++; - np->stats.rx_bytes += len; -next_pkt: - if (unlikely(np->get_rx.orig++ == np->last_rx.orig)) - np->get_rx.orig = np->first_rx.orig; - if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx)) - np->get_rx_ctx = np->first_rx_ctx; + } else { + /* short packet. Accept only if 802 values are also short */ + if (protolen > ETH_ZLEN) { + dprintk(KERN_DEBUG "%s: nv_getlen: discarding short packet.\n", + dev->name); + return -1; + } + dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n", + dev->name, datalen); + return datalen; } - - return rx_processed_cnt; } -static int nv_rx_process_optimized(struct net_device *dev, int limit) +static int nv_rx_process(struct net_device *dev, int limit) { struct fe_priv *np = netdev_priv(dev); u32 flags; u32 vlanflags = 0; - u32 rx_processed_cnt = 0; - struct sk_buff *skb; - int len; + int count; - while((np->get_rx.ex != np->put_rx.ex) && - !((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) && - (rx_processed_cnt++ < limit)) { + for (count = 0; count < limit; ++count) { + struct sk_buff *skb; + int len; + int i; + if (np->cur_rx - np->refill_rx >= np->rx_ring_size) + break; /* we scanned the whole ring - do not continue */ + + i = np->cur_rx % np->rx_ring_size; + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + flags = le32_to_cpu(np->rx_ring.orig[i].flaglen); + len = nv_descr_getlength(&np->rx_ring.orig[i], np->desc_ver); + } else { + flags = le32_to_cpu(np->rx_ring.ex[i].flaglen); + len = nv_descr_getlength_ex(&np->rx_ring.ex[i], np->desc_ver); + vlanflags = le32_to_cpu(np->rx_ring.ex[i].buflow); + } + + dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, flags 0x%x.\n", + dev->name, np->cur_rx, flags); - dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: flags 0x%x.\n", - dev->name, flags); + if (flags & NV_RX_AVAIL) + break; /* still owned by hardware, */ /* * the packet is for us - immediately tear down the pci mapping. * TODO: check if a prefetch of the first cacheline improves * the performance. */ - pci_unmap_single(np->pci_dev, np->get_rx_ctx->dma, - np->get_rx_ctx->dma_len, + pci_unmap_single(np->pci_dev, np->rx_dma[i], + np->rx_skbuff[i]->end-np->rx_skbuff[i]->data, PCI_DMA_FROMDEVICE); - skb = np->get_rx_ctx->skb; - np->get_rx_ctx->skb = NULL; { int j; @@ -2281,90 +1864,123 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) for (j=0; j<64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char*)skb->data)[j]); + dprintk(" %02x", ((unsigned char*)np->rx_skbuff[i]->data)[j]); } dprintk("\n"); } /* look at what we actually got: */ - if (likely(flags & NV_RX2_DESCRIPTORVALID)) { - len = flags & LEN_MASK_V2; - if (unlikely(flags & NV_RX2_ERROR)) { + if (np->desc_ver == DESC_VER_1) { + if (!(flags & NV_RX_DESCRIPTORVALID)) + goto next_pkt; + + if (flags & NV_RX_ERROR) { + if (flags & NV_RX_MISSEDFRAME) { + np->stats.rx_missed_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) { + np->stats.rx_errors++; + goto next_pkt; + } + if (flags & NV_RX_CRCERR) { + np->stats.rx_crc_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (flags & NV_RX_OVERFLOW) { + np->stats.rx_over_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (flags & NV_RX_ERROR4) { + len = nv_getlen(dev, np->rx_skbuff[i]->data, len); + if (len < 0) { + np->stats.rx_errors++; + goto next_pkt; + } + } + /* framing errors are soft errors. */ + if (flags & NV_RX_FRAMINGERR) { + if (flags & NV_RX_SUBSTRACT1) { + len--; + } + } + } + } else { + if (!(flags & NV_RX2_DESCRIPTORVALID)) + goto next_pkt; + + if (flags & NV_RX2_ERROR) { + if (flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) { + np->stats.rx_errors++; + goto next_pkt; + } + if (flags & NV_RX2_CRCERR) { + np->stats.rx_crc_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (flags & NV_RX2_OVERFLOW) { + np->stats.rx_over_errors++; + np->stats.rx_errors++; + goto next_pkt; + } if (flags & NV_RX2_ERROR4) { - len = nv_getlen(dev, skb->data, len); + len = nv_getlen(dev, np->rx_skbuff[i]->data, len); if (len < 0) { - dev_kfree_skb(skb); + np->stats.rx_errors++; goto next_pkt; } } /* framing errors are soft errors */ - else if (flags & NV_RX2_FRAMINGERR) { + if (flags & NV_RX2_FRAMINGERR) { if (flags & NV_RX2_SUBSTRACT1) { len--; } } - /* the rest are hard errors */ - else { - dev_kfree_skb(skb); - goto next_pkt; - } } - - if ((flags & NV_RX2_CHECKSUMMASK) == NV_RX2_CHECKSUMOK2)/*ip and tcp */ { - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else { - if ((flags & NV_RX2_CHECKSUMMASK) == NV_RX2_CHECKSUMOK1 || - (flags & NV_RX2_CHECKSUMMASK) == NV_RX2_CHECKSUMOK3) { - skb->ip_summed = CHECKSUM_UNNECESSARY; + if (np->rx_csum) { + flags &= NV_RX2_CHECKSUMMASK; + if (flags == NV_RX2_CHECKSUMOK1 || + flags == NV_RX2_CHECKSUMOK2 || + flags == NV_RX2_CHECKSUMOK3) { + dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name); + np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY; + } else { + dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name); } } + } + /* got a valid packet - forward it to the network core */ + skb = np->rx_skbuff[i]; + np->rx_skbuff[i] = NULL; - /* got a valid packet - forward it to the network core */ - skb_put(skb, len); - skb->protocol = eth_type_trans(skb, dev); - prefetch(skb->data); - - dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: %d bytes, proto %d accepted.\n", - dev->name, len, skb->protocol); - - if (likely(!np->vlangrp)) { -#ifdef CONFIG_FORCEDETH_NAPI - netif_receive_skb(skb); -#else - netif_rx(skb); -#endif - } else { - vlanflags = le32_to_cpu(np->get_rx.ex->buflow); - if (vlanflags & NV_RX3_VLAN_TAG_PRESENT) { -#ifdef CONFIG_FORCEDETH_NAPI - vlan_hwaccel_receive_skb(skb, np->vlangrp, - vlanflags & NV_RX3_VLAN_TAG_MASK); -#else - vlan_hwaccel_rx(skb, np->vlangrp, - vlanflags & NV_RX3_VLAN_TAG_MASK); -#endif - } else { + skb_put(skb, len); + skb->protocol = eth_type_trans(skb, dev); + dprintk(KERN_DEBUG "%s: nv_rx_process: packet %d with %d bytes, proto %d accepted.\n", + dev->name, np->cur_rx, len, skb->protocol); #ifdef CONFIG_FORCEDETH_NAPI - netif_receive_skb(skb); + if (np->vlangrp && (vlanflags & NV_RX3_VLAN_TAG_PRESENT)) + vlan_hwaccel_receive_skb(skb, np->vlangrp, + vlanflags & NV_RX3_VLAN_TAG_MASK); + else + netif_receive_skb(skb); #else - netif_rx(skb); + if (np->vlangrp && (vlanflags & NV_RX3_VLAN_TAG_PRESENT)) + vlan_hwaccel_rx(skb, np->vlangrp, + vlanflags & NV_RX3_VLAN_TAG_MASK); + else + netif_rx(skb); #endif - } - } - - dev->last_rx = jiffies; - np->stats.rx_packets++; - np->stats.rx_bytes += len; - } else { - dev_kfree_skb(skb); - } + dev->last_rx = jiffies; + np->stats.rx_packets++; + np->stats.rx_bytes += len; next_pkt: - if (unlikely(np->get_rx.ex++ == np->last_rx.ex)) - np->get_rx.ex = np->first_rx.ex; - if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx)) - np->get_rx_ctx = np->first_rx_ctx; + np->cur_rx++; } - return rx_processed_cnt; + return count; } static void set_bufsize(struct net_device *dev) @@ -2840,6 +2456,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data) events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); } + pci_push(base); dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); if (!(events & np->irqmask)) break; @@ -2848,46 +2465,22 @@ static irqreturn_t nv_nic_irq(int foo, void *data) nv_tx_done(dev); spin_unlock(&np->lock); -#ifdef CONFIG_FORCEDETH_NAPI - if (events & NVREG_IRQ_RX_ALL) { - netif_rx_schedule(dev); - - /* Disable furthur receive irq's */ - spin_lock(&np->lock); - np->irqmask &= ~NVREG_IRQ_RX_ALL; - - if (np->msi_flags & NV_MSI_X_ENABLED) - writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); - else - writel(np->irqmask, base + NvRegIrqMask); - spin_unlock(&np->lock); - } -#else - if (nv_rx_process(dev, dev->weight)) { - if (unlikely(nv_alloc_rx(dev))) { - spin_lock(&np->lock); - if (!np->in_shutdown) - mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock(&np->lock); - } - } -#endif - if (unlikely(events & NVREG_IRQ_LINK)) { + if (events & NVREG_IRQ_LINK) { spin_lock(&np->lock); nv_link_irq(dev); spin_unlock(&np->lock); } - if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) { + if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { spin_lock(&np->lock); nv_linkchange(dev); spin_unlock(&np->lock); np->link_timeout = jiffies + LINK_TIMEOUT; } - if (unlikely(events & (NVREG_IRQ_TX_ERR))) { + if (events & (NVREG_IRQ_TX_ERR)) { dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", dev->name, events); } - if (unlikely(events & (NVREG_IRQ_UNKNOWN))) { + if (events & (NVREG_IRQ_UNKNOWN)) { printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n", dev->name, events); } @@ -2908,63 +2501,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data) spin_unlock(&np->lock); break; } - if (unlikely(i > max_interrupt_work)) { - spin_lock(&np->lock); - /* disable interrupts on the nic */ - if (!(np->msi_flags & NV_MSI_X_ENABLED)) - writel(0, base + NvRegIrqMask); - else - writel(np->irqmask, base + NvRegIrqMask); - pci_push(base); - - if (!np->in_shutdown) { - np->nic_poll_irq = np->irqmask; - mod_timer(&np->nic_poll, jiffies + POLL_WAIT); - } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); - spin_unlock(&np->lock); - break; - } - - } - dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name); - - return IRQ_RETVAL(i); -} - -#define TX_WORK_PER_LOOP 64 -#define RX_WORK_PER_LOOP 64 -/** - * All _optimized functions are used to help increase performance - * (reduce CPU and increase throughput). They use descripter version 3, - * compiler directives, and reduce memory accesses. - */ -static irqreturn_t nv_nic_irq_optimized(int foo, void *data) -{ - struct net_device *dev = (struct net_device *) data; - struct fe_priv *np = netdev_priv(dev); - u8 __iomem *base = get_hwbase(dev); - u32 events; - int i; - - dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized\n", dev->name); - - for (i=0; ; i++) { - if (!(np->msi_flags & NV_MSI_X_ENABLED)) { - events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; - writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); - } else { - events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; - writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); - } - dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); - if (!(events & np->irqmask)) - break; - - spin_lock(&np->lock); - nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); - spin_unlock(&np->lock); - #ifdef CONFIG_FORCEDETH_NAPI if (events & NVREG_IRQ_RX_ALL) { netif_rx_schedule(dev); @@ -2980,53 +2516,15 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) spin_unlock(&np->lock); } #else - if (nv_rx_process_optimized(dev, dev->weight)) { - if (unlikely(nv_alloc_rx_optimized(dev))) { - spin_lock(&np->lock); - if (!np->in_shutdown) - mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock(&np->lock); - } - } -#endif - if (unlikely(events & NVREG_IRQ_LINK)) { - spin_lock(&np->lock); - nv_link_irq(dev); - spin_unlock(&np->lock); - } - if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) { - spin_lock(&np->lock); - nv_linkchange(dev); - spin_unlock(&np->lock); - np->link_timeout = jiffies + LINK_TIMEOUT; - } - if (unlikely(events & (NVREG_IRQ_TX_ERR))) { - dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", - dev->name, events); - } - if (unlikely(events & (NVREG_IRQ_UNKNOWN))) { - printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n", - dev->name, events); - } - if (unlikely(events & NVREG_IRQ_RECOVER_ERROR)) { + nv_rx_process(dev, dev->weight); + if (nv_alloc_rx(dev)) { spin_lock(&np->lock); - /* disable interrupts on the nic */ - if (!(np->msi_flags & NV_MSI_X_ENABLED)) - writel(0, base + NvRegIrqMask); - else - writel(np->irqmask, base + NvRegIrqMask); - pci_push(base); - - if (!np->in_shutdown) { - np->nic_poll_irq = np->irqmask; - np->recover_error = 1; - mod_timer(&np->nic_poll, jiffies + POLL_WAIT); - } + if (!np->in_shutdown) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); spin_unlock(&np->lock); - break; } - - if (unlikely(i > max_interrupt_work)) { +#endif + if (i > max_interrupt_work) { spin_lock(&np->lock); /* disable interrupts on the nic */ if (!(np->msi_flags & NV_MSI_X_ENABLED)) @@ -3045,7 +2543,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) } } - dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized completed\n", dev->name); + dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name); return IRQ_RETVAL(i); } @@ -3064,19 +2562,20 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) for (i=0; ; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL; writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus); + pci_push(base); dprintk(KERN_DEBUG "%s: tx irq: %08x\n", dev->name, events); if (!(events & np->irqmask)) break; spin_lock_irqsave(&np->lock, flags); - nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); + nv_tx_done(dev); spin_unlock_irqrestore(&np->lock, flags); - if (unlikely(events & (NVREG_IRQ_TX_ERR))) { + if (events & (NVREG_IRQ_TX_ERR)) { dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", dev->name, events); } - if (unlikely(i > max_interrupt_work)) { + if (i > max_interrupt_work) { spin_lock_irqsave(&np->lock, flags); /* disable interrupts on the nic */ writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask); @@ -3105,10 +2604,7 @@ static int nv_napi_poll(struct net_device *dev, int *budget) u8 __iomem *base = get_hwbase(dev); unsigned long flags; - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - pkts = nv_rx_process(dev, limit); - else - pkts = nv_rx_process_optimized(dev, limit); + pkts = nv_rx_process(dev, limit); if (nv_alloc_rx(dev)) { spin_lock_irqsave(&np->lock, flags); @@ -3174,20 +2670,20 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) for (i=0; ; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus); + pci_push(base); dprintk(KERN_DEBUG "%s: rx irq: %08x\n", dev->name, events); if (!(events & np->irqmask)) break; - if (nv_rx_process_optimized(dev, dev->weight)) { - if (unlikely(nv_alloc_rx_optimized(dev))) { - spin_lock_irqsave(&np->lock, flags); - if (!np->in_shutdown) - mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock_irqrestore(&np->lock, flags); - } + nv_rx_process(dev, dev->weight); + if (nv_alloc_rx(dev)) { + spin_lock_irqsave(&np->lock, flags); + if (!np->in_shutdown) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); + spin_unlock_irqrestore(&np->lock, flags); } - if (unlikely(i > max_interrupt_work)) { + if (i > max_interrupt_work) { spin_lock_irqsave(&np->lock, flags); /* disable interrupts on the nic */ writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); @@ -3222,15 +2718,11 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) for (i=0; ; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER; writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus); + pci_push(base); dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); if (!(events & np->irqmask)) break; - /* check tx in case we reached max loop limit in tx isr */ - spin_lock_irqsave(&np->lock, flags); - nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); - spin_unlock_irqrestore(&np->lock, flags); - if (events & NVREG_IRQ_LINK) { spin_lock_irqsave(&np->lock, flags); nv_link_irq(dev); @@ -3260,7 +2752,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n", dev->name, events); } - if (unlikely(i > max_interrupt_work)) { + if (i > max_interrupt_work) { spin_lock_irqsave(&np->lock, flags); /* disable interrupts on the nic */ writel(NVREG_IRQ_OTHER, base + NvRegIrqMask); @@ -3343,16 +2835,6 @@ static int nv_request_irq(struct net_device *dev, int intr_test) u8 __iomem *base = get_hwbase(dev); int ret = 1; int i; - irqreturn_t (*handler)(int foo, void *data); - - if (intr_test) { - handler = nv_nic_irq_test; - } else { - if (np->desc_ver == DESC_VER_3) - handler = nv_nic_irq_optimized; - else - handler = nv_nic_irq; - } if (np->msi_flags & NV_MSI_X_CAPABLE) { for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { @@ -3390,7 +2872,10 @@ static int nv_request_irq(struct net_device *dev, int intr_test) set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER); } else { /* Request irq for all interrupts */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, handler, IRQF_SHARED, dev->name, dev) != 0) { + if ((!intr_test && + request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) || + (intr_test && + request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) { printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; @@ -3406,7 +2891,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { if ((ret = pci_enable_msi(np->pci_dev)) == 0) { np->msi_flags |= NV_MSI_ENABLED; - if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { + if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) || + (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) { printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); pci_disable_msi(np->pci_dev); np->msi_flags &= ~NV_MSI_ENABLED; @@ -3421,7 +2907,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } } if (ret != 0) { - if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) + if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) || + (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) goto out_err; } @@ -3564,8 +3051,47 @@ static void nv_do_stats_poll(unsigned long data) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); + u8 __iomem *base = get_hwbase(dev); - nv_get_hw_stats(dev); + np->estats.tx_bytes += readl(base + NvRegTxCnt); + np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt); + np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt); + np->estats.tx_many_rexmt += readl(base + NvRegTxManyReXmt); + np->estats.tx_late_collision += readl(base + NvRegTxLateCol); + np->estats.tx_fifo_errors += readl(base + NvRegTxUnderflow); + np->estats.tx_carrier_errors += readl(base + NvRegTxLossCarrier); + np->estats.tx_excess_deferral += readl(base + NvRegTxExcessDef); + np->estats.tx_retry_error += readl(base + NvRegTxRetryErr); + np->estats.tx_deferral += readl(base + NvRegTxDef); + np->estats.tx_packets += readl(base + NvRegTxFrame); + np->estats.tx_pause += readl(base + NvRegTxPause); + np->estats.rx_frame_error += readl(base + NvRegRxFrameErr); + np->estats.rx_extra_byte += readl(base + NvRegRxExtraByte); + np->estats.rx_late_collision += readl(base + NvRegRxLateCol); + np->estats.rx_runt += readl(base + NvRegRxRunt); + np->estats.rx_frame_too_long += readl(base + NvRegRxFrameTooLong); + np->estats.rx_over_errors += readl(base + NvRegRxOverflow); + np->estats.rx_crc_errors += readl(base + NvRegRxFCSErr); + np->estats.rx_frame_align_error += readl(base + NvRegRxFrameAlignErr); + np->estats.rx_length_error += readl(base + NvRegRxLenErr); + np->estats.rx_unicast += readl(base + NvRegRxUnicast); + np->estats.rx_multicast += readl(base + NvRegRxMulticast); + np->estats.rx_broadcast += readl(base + NvRegRxBroadcast); + np->estats.rx_bytes += readl(base + NvRegRxCnt); + np->estats.rx_pause += readl(base + NvRegRxPause); + np->estats.rx_drop_frame += readl(base + NvRegRxDropFrame); + np->estats.rx_packets = + np->estats.rx_unicast + + np->estats.rx_multicast + + np->estats.rx_broadcast; + np->estats.rx_errors_total = + np->estats.rx_crc_errors + + np->estats.rx_over_errors + + np->estats.rx_frame_error + + (np->estats.rx_frame_align_error - np->estats.rx_extra_byte) + + np->estats.rx_late_collision + + np->estats.rx_runt + + np->estats.rx_frame_too_long; if (!np->in_shutdown) mod_timer(&np->stats_poll, jiffies + STATS_INTERVAL); @@ -3939,7 +3465,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - u8 *rxtx_ring, *rx_skbuff, *tx_skbuff; + u8 *rxtx_ring, *rx_skbuff, *tx_skbuff, *rx_dma, *tx_dma, *tx_dma_len; dma_addr_t ring_addr; if (ring->rx_pending < RX_RING_MIN || @@ -3965,9 +3491,12 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri sizeof(struct ring_desc_ex) * (ring->rx_pending + ring->tx_pending), &ring_addr); } - rx_skbuff = kmalloc(sizeof(struct nv_skb_map) * ring->rx_pending, GFP_KERNEL); - tx_skbuff = kmalloc(sizeof(struct nv_skb_map) * ring->tx_pending, GFP_KERNEL); - if (!rxtx_ring || !rx_skbuff || !tx_skbuff) { + rx_skbuff = kmalloc(sizeof(struct sk_buff*) * ring->rx_pending, GFP_KERNEL); + rx_dma = kmalloc(sizeof(dma_addr_t) * ring->rx_pending, GFP_KERNEL); + tx_skbuff = kmalloc(sizeof(struct sk_buff*) * ring->tx_pending, GFP_KERNEL); + tx_dma = kmalloc(sizeof(dma_addr_t) * ring->tx_pending, GFP_KERNEL); + tx_dma_len = kmalloc(sizeof(unsigned int) * ring->tx_pending, GFP_KERNEL); + if (!rxtx_ring || !rx_skbuff || !rx_dma || !tx_skbuff || !tx_dma || !tx_dma_len) { /* fall back to old rings */ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { if (rxtx_ring) @@ -3980,8 +3509,14 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri } if (rx_skbuff) kfree(rx_skbuff); + if (rx_dma) + kfree(rx_dma); if (tx_skbuff) kfree(tx_skbuff); + if (tx_dma) + kfree(tx_dma); + if (tx_dma_len) + kfree(tx_dma_len); goto exit; } @@ -4003,6 +3538,8 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri /* set new values */ np->rx_ring_size = ring->rx_pending; np->tx_ring_size = ring->tx_pending; + np->tx_limit_stop = ring->tx_pending - TX_LIMIT_DIFFERENCE; + np->tx_limit_start = ring->tx_pending - TX_LIMIT_DIFFERENCE - 1; if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { np->rx_ring.orig = (struct ring_desc*)rxtx_ring; np->tx_ring.orig = &np->rx_ring.orig[np->rx_ring_size]; @@ -4010,12 +3547,18 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri np->rx_ring.ex = (struct ring_desc_ex*)rxtx_ring; np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size]; } - np->rx_skb = (struct nv_skb_map*)rx_skbuff; - np->tx_skb = (struct nv_skb_map*)tx_skbuff; + np->rx_skbuff = (struct sk_buff**)rx_skbuff; + np->rx_dma = (dma_addr_t*)rx_dma; + np->tx_skbuff = (struct sk_buff**)tx_skbuff; + np->tx_dma = (dma_addr_t*)tx_dma; + np->tx_dma_len = (unsigned int*)tx_dma_len; np->ring_addr = ring_addr; - memset(np->rx_skb, 0, sizeof(struct nv_skb_map) * np->rx_ring_size); - memset(np->tx_skb, 0, sizeof(struct nv_skb_map) * np->tx_ring_size); + memset(np->rx_skbuff, 0, sizeof(struct sk_buff*) * np->rx_ring_size); + memset(np->rx_dma, 0, sizeof(dma_addr_t) * np->rx_ring_size); + memset(np->tx_skbuff, 0, sizeof(struct sk_buff*) * np->tx_ring_size); + memset(np->tx_dma, 0, sizeof(dma_addr_t) * np->tx_ring_size); + memset(np->tx_dma_len, 0, sizeof(unsigned int) * np->tx_ring_size); if (netif_running(dev)) { /* reinit driver view of the queues */ @@ -4184,10 +3727,8 @@ static int nv_get_stats_count(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - if (np->driver_data & DEV_HAS_STATISTICS_V1) - return NV_DEV_STATISTICS_V1_COUNT; - else if (np->driver_data & DEV_HAS_STATISTICS_V2) - return NV_DEV_STATISTICS_V2_COUNT; + if (np->driver_data & DEV_HAS_STATISTICS) + return sizeof(struct nv_ethtool_stats)/sizeof(u64); else return 0; } @@ -4414,7 +3955,7 @@ static int nv_loopback_test(struct net_device *dev) dprintk(KERN_DEBUG "%s: loopback len mismatch %d vs %d\n", dev->name, len, pkt_len); } else { - rx_skb = np->rx_skb[0].skb; + rx_skb = np->rx_skbuff[0]; for (i = 0; i < pkt_len; i++) { if (rx_skb->data[i] != (u8)(i & 0xff)) { ret = 0; @@ -4774,7 +4315,7 @@ static int nv_open(struct net_device *dev) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); /* start statistics timer */ - if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) + if (np->driver_data & DEV_HAS_STATISTICS) mod_timer(&np->stats_poll, jiffies + STATS_INTERVAL); spin_unlock_irq(&np->lock); @@ -4871,9 +4412,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i if (err < 0) goto out_disable; - if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V2)) - np->register_size = NV_PCI_REGSZ_VER3; - else if (id->driver_data & DEV_HAS_STATISTICS_V1) + if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS)) np->register_size = NV_PCI_REGSZ_VER2; else np->register_size = NV_PCI_REGSZ_VER1; @@ -4936,8 +4475,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->rx_csum = 1; np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; +#ifdef NETIF_F_TSO dev->features |= NETIF_F_TSO; - } +#endif + } np->vlanctl_bits = 0; if (id->driver_data & DEV_HAS_VLAN) { @@ -4971,6 +4512,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->rx_ring_size = RX_RING_DEFAULT; np->tx_ring_size = TX_RING_DEFAULT; + np->tx_limit_stop = np->tx_ring_size - TX_LIMIT_DIFFERENCE; + np->tx_limit_start = np->tx_ring_size - TX_LIMIT_DIFFERENCE - 1; if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { np->rx_ring.orig = pci_alloc_consistent(pci_dev, @@ -4987,19 +4530,22 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i goto out_unmap; np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size]; } - np->rx_skb = kmalloc(sizeof(struct nv_skb_map) * np->rx_ring_size, GFP_KERNEL); - np->tx_skb = kmalloc(sizeof(struct nv_skb_map) * np->tx_ring_size, GFP_KERNEL); - if (!np->rx_skb || !np->tx_skb) + np->rx_skbuff = kmalloc(sizeof(struct sk_buff*) * np->rx_ring_size, GFP_KERNEL); + np->rx_dma = kmalloc(sizeof(dma_addr_t) * np->rx_ring_size, GFP_KERNEL); + np->tx_skbuff = kmalloc(sizeof(struct sk_buff*) * np->tx_ring_size, GFP_KERNEL); + np->tx_dma = kmalloc(sizeof(dma_addr_t) * np->tx_ring_size, GFP_KERNEL); + np->tx_dma_len = kmalloc(sizeof(unsigned int) * np->tx_ring_size, GFP_KERNEL); + if (!np->rx_skbuff || !np->rx_dma || !np->tx_skbuff || !np->tx_dma || !np->tx_dma_len) goto out_freering; - memset(np->rx_skb, 0, sizeof(struct nv_skb_map) * np->rx_ring_size); - memset(np->tx_skb, 0, sizeof(struct nv_skb_map) * np->tx_ring_size); + memset(np->rx_skbuff, 0, sizeof(struct sk_buff*) * np->rx_ring_size); + memset(np->rx_dma, 0, sizeof(dma_addr_t) * np->rx_ring_size); + memset(np->tx_skbuff, 0, sizeof(struct sk_buff*) * np->tx_ring_size); + memset(np->tx_dma, 0, sizeof(dma_addr_t) * np->tx_ring_size); + memset(np->tx_dma_len, 0, sizeof(unsigned int) * np->tx_ring_size); dev->open = nv_open; dev->stop = nv_close; - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - dev->hard_start_xmit = nv_start_xmit; - else - dev->hard_start_xmit = nv_start_xmit_optimized; + dev->hard_start_xmit = nv_start_xmit; dev->get_stats = nv_get_stats; dev->change_mtu = nv_change_mtu; dev->set_mac_address = nv_set_mac_address; @@ -5007,7 +4553,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = nv_poll_controller; #endif - dev->weight = RX_WORK_PER_LOOP; + dev->weight = 64; #ifdef CONFIG_FORCEDETH_NAPI dev->poll = nv_napi_poll; #endif @@ -5322,83 +4868,83 @@ static struct pci_device_id pci_tbl[] = { }, { /* CK804 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA, }, { /* CK804 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA, }, { /* MCP04 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA, }, { /* MCP04 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA, }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, {0,}, }; diff --git a/trunk/drivers/net/fs_enet/fs_enet.h b/trunk/drivers/net/fs_enet/fs_enet.h index 569be225cd05..92590d8fc24b 100644 --- a/trunk/drivers/net/fs_enet/fs_enet.h +++ b/trunk/drivers/net/fs_enet/fs_enet.h @@ -9,7 +9,6 @@ #include #include -#include #ifdef CONFIG_CPM1 #include diff --git a/trunk/drivers/net/gianfar_ethtool.c b/trunk/drivers/net/gianfar_ethtool.c index 0d6943d67096..6d71bea5e900 100644 --- a/trunk/drivers/net/gianfar_ethtool.c +++ b/trunk/drivers/net/gianfar_ethtool.c @@ -42,6 +42,8 @@ #include "gianfar.h" +#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) + extern void gfar_start(struct net_device *dev); extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); diff --git a/trunk/drivers/net/hp100.c b/trunk/drivers/net/hp100.c index 7dc5185aa2c0..844c136e9920 100644 --- a/trunk/drivers/net/hp100.c +++ b/trunk/drivers/net/hp100.c @@ -3034,7 +3034,7 @@ static int __init hp100_module_init(void) goto out2; #endif #ifdef CONFIG_PCI - err = pci_register_driver(&hp100_pci_driver); + err = pci_module_init(&hp100_pci_driver); if (err && err != -ENODEV) goto out3; #endif diff --git a/trunk/drivers/net/iseries_veth.c b/trunk/drivers/net/iseries_veth.c index 0e9ba3c3faf7..2194b567239f 100644 --- a/trunk/drivers/net/iseries_veth.c +++ b/trunk/drivers/net/iseries_veth.c @@ -1102,7 +1102,7 @@ static struct net_device * __init veth_probe_one(int vlan, } kobject_init(&port->kobject); - port->kobject.parent = &dev->dev.kobj; + port->kobject.parent = &dev->class_dev.kobj; port->kobject.ktype = &veth_port_ktype; kobject_set_name(&port->kobject, "veth_port"); if (0 != kobject_add(&port->kobject)) diff --git a/trunk/drivers/net/ixgb/ixgb.h b/trunk/drivers/net/ixgb/ixgb.h index cf30a1059ce0..f4aba4355b19 100644 --- a/trunk/drivers/net/ixgb/ixgb.h +++ b/trunk/drivers/net/ixgb/ixgb.h @@ -61,7 +61,9 @@ #include #include #include +#ifdef NETIF_F_TSO #include +#endif #include #include diff --git a/trunk/drivers/net/ixgb/ixgb_ethtool.c b/trunk/drivers/net/ixgb/ixgb_ethtool.c index d6628bd9590a..82c044d6e08a 100644 --- a/trunk/drivers/net/ixgb/ixgb_ethtool.c +++ b/trunk/drivers/net/ixgb/ixgb_ethtool.c @@ -82,8 +82,10 @@ static struct ixgb_stats ixgb_gstrings_stats[] = { {"tx_restart_queue", IXGB_STAT(restart_queue) }, {"rx_long_length_errors", IXGB_STAT(stats.roc)}, {"rx_short_length_errors", IXGB_STAT(stats.ruc)}, +#ifdef NETIF_F_TSO {"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)}, {"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)}, +#endif {"rx_flow_control_xon", IXGB_STAT(stats.xonrxc)}, {"rx_flow_control_xoff", IXGB_STAT(stats.xoffrxc)}, {"tx_flow_control_xon", IXGB_STAT(stats.xontxc)}, @@ -238,6 +240,7 @@ ixgb_set_tx_csum(struct net_device *netdev, uint32_t data) return 0; } +#ifdef NETIF_F_TSO static int ixgb_set_tso(struct net_device *netdev, uint32_t data) { @@ -247,6 +250,7 @@ ixgb_set_tso(struct net_device *netdev, uint32_t data) netdev->features &= ~NETIF_F_TSO; return 0; } +#endif /* NETIF_F_TSO */ static uint32_t ixgb_get_msglevel(struct net_device *netdev) @@ -718,8 +722,10 @@ static const struct ethtool_ops ixgb_ethtool_ops = { .set_sg = ethtool_op_set_sg, .get_msglevel = ixgb_get_msglevel, .set_msglevel = ixgb_set_msglevel, +#ifdef NETIF_F_TSO .get_tso = ethtool_op_get_tso, .set_tso = ixgb_set_tso, +#endif .get_strings = ixgb_get_strings, .phys_id = ixgb_phys_id, .get_stats_count = ixgb_get_stats_count, diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index 0c3682889344..a083a9189230 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -456,7 +456,9 @@ ixgb_probe(struct pci_dev *pdev, NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; +#ifdef NETIF_F_TSO netdev->features |= NETIF_F_TSO; +#endif #ifdef NETIF_F_LLTX netdev->features |= NETIF_F_LLTX; #endif @@ -1174,6 +1176,7 @@ ixgb_watchdog(unsigned long data) static int ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) { +#ifdef NETIF_F_TSO struct ixgb_context_desc *context_desc; unsigned int i; uint8_t ipcss, ipcso, tucss, tucso, hdr_len; @@ -1230,6 +1233,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) return 1; } +#endif return 0; } @@ -1605,7 +1609,7 @@ ixgb_update_stats(struct ixgb_adapter *adapter) struct pci_dev *pdev = adapter->pdev; /* Prevent stats update while adapter is being reset */ - if (pci_channel_offline(pdev)) + if (pdev->error_state && pdev->error_state != pci_channel_io_normal) return; if((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) || diff --git a/trunk/drivers/net/macb.c b/trunk/drivers/net/macb.c index e67361e2bf5d..25b559b5d5ed 100644 --- a/trunk/drivers/net/macb.c +++ b/trunk/drivers/net/macb.c @@ -27,6 +27,8 @@ #include "macb.h" +#define to_net_dev(class) container_of(class, struct net_device, class_dev) + #define RX_BUFFER_SIZE 128 #define RX_RING_SIZE 512 #define RX_RING_BYTES (sizeof(struct dma_desc) * RX_RING_SIZE) @@ -943,10 +945,10 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return ret; } -static ssize_t macb_mii_show(const struct device *_dev, char *buf, +static ssize_t macb_mii_show(const struct class_device *cd, char *buf, unsigned long addr) { - struct net_device *dev = to_net_dev(_dev); + struct net_device *dev = to_net_dev(cd); struct macb *bp = netdev_priv(dev); ssize_t ret = -EINVAL; @@ -960,13 +962,11 @@ static ssize_t macb_mii_show(const struct device *_dev, char *buf, } #define MII_ENTRY(name, addr) \ -static ssize_t show_##name(struct device *_dev, \ - struct device_attribute *attr, \ - char *buf) \ +static ssize_t show_##name(struct class_device *cd, char *buf) \ { \ - return macb_mii_show(_dev, buf, addr); \ + return macb_mii_show(cd, buf, addr); \ } \ -static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) MII_ENTRY(bmcr, MII_BMCR); MII_ENTRY(bmsr, MII_BMSR); @@ -977,13 +977,13 @@ MII_ENTRY(lpa, MII_LPA); MII_ENTRY(expansion, MII_EXPANSION); static struct attribute *macb_mii_attrs[] = { - &dev_attr_bmcr.attr, - &dev_attr_bmsr.attr, - &dev_attr_physid1.attr, - &dev_attr_physid2.attr, - &dev_attr_advertise.attr, - &dev_attr_lpa.attr, - &dev_attr_expansion.attr, + &class_device_attr_bmcr.attr, + &class_device_attr_bmsr.attr, + &class_device_attr_physid1.attr, + &class_device_attr_physid2.attr, + &class_device_attr_advertise.attr, + &class_device_attr_lpa.attr, + &class_device_attr_expansion.attr, NULL, }; @@ -994,17 +994,17 @@ static struct attribute_group macb_mii_group = { static void macb_unregister_sysfs(struct net_device *net) { - struct device *_dev = &net->dev; + struct class_device *class_dev = &net->class_dev; - sysfs_remove_group(&_dev->kobj, &macb_mii_group); + sysfs_remove_group(&class_dev->kobj, &macb_mii_group); } static int macb_register_sysfs(struct net_device *net) { - struct device *_dev = &net->dev; + struct class_device *class_dev = &net->class_dev; int ret; - ret = sysfs_create_group(&_dev->kobj, &macb_mii_group); + ret = sysfs_create_group(&class_dev->kobj, &macb_mii_group); if (ret) printk(KERN_WARNING "%s: sysfs mii attribute registration failed: %d\n", @@ -1046,14 +1046,6 @@ static int __devinit macb_probe(struct platform_device *pdev) spin_lock_init(&bp->lock); -#if defined(CONFIG_ARCH_AT91) - bp->pclk = clk_get(&pdev->dev, "macb_clk"); - if (IS_ERR(bp->pclk)) { - dev_err(&pdev->dev, "failed to get macb_clk\n"); - goto err_out_free_dev; - } - clk_enable(bp->pclk); -#else bp->pclk = clk_get(&pdev->dev, "pclk"); if (IS_ERR(bp->pclk)) { dev_err(&pdev->dev, "failed to get pclk\n"); @@ -1067,7 +1059,6 @@ static int __devinit macb_probe(struct platform_device *pdev) clk_enable(bp->pclk); clk_enable(bp->hclk); -#endif bp->regs = ioremap(regs->start, regs->end - regs->start + 1); if (!bp->regs) { @@ -1128,17 +1119,9 @@ static int __devinit macb_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; if (pdata && pdata->is_rmii) -#if defined(CONFIG_ARCH_AT91) - macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) ); -#else macb_writel(bp, USRIO, 0); -#endif else -#if defined(CONFIG_ARCH_AT91) - macb_writel(bp, USRIO, MACB_BIT(CLKEN)); -#else macb_writel(bp, USRIO, MACB_BIT(MII)); -#endif bp->tx_pending = DEF_TX_RING_PENDING; @@ -1165,11 +1148,9 @@ static int __devinit macb_probe(struct platform_device *pdev) err_out_iounmap: iounmap(bp->regs); err_out_disable_clocks: -#ifndef CONFIG_ARCH_AT91 clk_disable(bp->hclk); - clk_put(bp->hclk); -#endif clk_disable(bp->pclk); + clk_put(bp->hclk); err_out_put_pclk: clk_put(bp->pclk); err_out_free_dev: @@ -1192,11 +1173,9 @@ static int __devexit macb_remove(struct platform_device *pdev) unregister_netdev(dev); free_irq(dev->irq, dev); iounmap(bp->regs); -#ifndef CONFIG_ARCH_AT91 clk_disable(bp->hclk); - clk_put(bp->hclk); -#endif clk_disable(bp->pclk); + clk_put(bp->hclk); clk_put(bp->pclk); free_netdev(dev); platform_set_drvdata(pdev, NULL); diff --git a/trunk/drivers/net/macb.h b/trunk/drivers/net/macb.h index b3bb2182edd1..27bf0ae0f0bb 100644 --- a/trunk/drivers/net/macb.h +++ b/trunk/drivers/net/macb.h @@ -200,7 +200,7 @@ #define MACB_SOF_OFFSET 30 #define MACB_SOF_SIZE 2 -/* Bitfields in USRIO (AVR32) */ +/* Bitfields in USRIO */ #define MACB_MII_OFFSET 0 #define MACB_MII_SIZE 1 #define MACB_EAM_OFFSET 1 @@ -210,12 +210,6 @@ #define MACB_TX_PAUSE_ZERO_OFFSET 3 #define MACB_TX_PAUSE_ZERO_SIZE 1 -/* Bitfields in USRIO (AT91) */ -#define MACB_RMII_OFFSET 0 -#define MACB_RMII_SIZE 1 -#define MACB_CLKEN_OFFSET 1 -#define MACB_CLKEN_SIZE 1 - /* Bitfields in WOL */ #define MACB_IP_OFFSET 0 #define MACB_IP_SIZE 16 diff --git a/trunk/drivers/net/mace.c b/trunk/drivers/net/mace.c index 9ec24f0d5d68..2907cfb12ada 100644 --- a/trunk/drivers/net/mace.c +++ b/trunk/drivers/net/mace.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -75,6 +74,7 @@ struct mace_data { #define PRIV_BYTES (sizeof(struct mace_data) \ + (N_RX_RING + NCMDS_TX * N_TX_RING + 3) * sizeof(struct dbdma_cmd)) +static int bitrev(int); static int mace_open(struct net_device *dev); static int mace_close(struct net_device *dev); static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev); @@ -96,6 +96,18 @@ static void __mace_set_address(struct net_device *dev, void *addr); */ static unsigned char *dummy_buf; +/* Bit-reverse one byte of an ethernet hardware address. */ +static inline int +bitrev(int b) +{ + int d = 0, i; + + for (i = 0; i < 8; ++i, b >>= 1) + d = (d << 1) | (b & 1); + return d; +} + + static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match) { struct device_node *mace = macio_get_of_node(mdev); @@ -161,7 +173,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i rev = addr[0] == 0 && addr[1] == 0xA0; for (j = 0; j < 6; ++j) { - dev->dev_addr[j] = rev ? bitrev8(addr[j]): addr[j]; + dev->dev_addr[j] = rev? bitrev(addr[j]): addr[j]; } mp->chipid = (in_8(&mp->mace->chipid_hi) << 8) | in_8(&mp->mace->chipid_lo); diff --git a/trunk/drivers/net/macmace.c b/trunk/drivers/net/macmace.c index 5d541e873041..464e4a6f3d5f 100644 --- a/trunk/drivers/net/macmace.c +++ b/trunk/drivers/net/macmace.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -82,6 +81,19 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id); static irqreturn_t mace_dma_intr(int irq, void *dev_id); static void mace_tx_timeout(struct net_device *dev); +/* Bit-reverse one byte of an ethernet hardware address. */ + +static int bitrev(int b) +{ + int d = 0, i; + + for (i = 0; i < 8; ++i, b >>= 1) { + d = (d << 1) | (b & 1); + } + + return d; +} + /* * Load a receive DMA channel with a base address and ring length */ @@ -207,12 +219,12 @@ struct net_device *mace_probe(int unit) addr = (void *)MACE_PROM; for (j = 0; j < 6; ++j) { - u8 v = bitrev8(addr[j<<4]); + u8 v=bitrev(addr[j<<4]); checksum ^= v; dev->dev_addr[j] = v; } for (; j < 8; ++j) { - checksum ^= bitrev8(addr[j<<4]); + checksum ^= bitrev(addr[j<<4]); } if (checksum != 0xFF) { diff --git a/trunk/drivers/net/macsonic.c b/trunk/drivers/net/macsonic.c index 24f6050fbf33..393d995f1919 100644 --- a/trunk/drivers/net/macsonic.c +++ b/trunk/drivers/net/macsonic.c @@ -121,12 +121,16 @@ enum macsonic_type { * For reversing the PROM address */ +static unsigned char nibbletab[] = {0, 8, 4, 12, 2, 10, 6, 14, + 1, 9, 5, 13, 3, 11, 7, 15}; + static inline void bit_reverse_addr(unsigned char addr[6]) { int i; for(i = 0; i < 6; i++) - addr[i] = bitrev8(addr[i]); + addr[i] = ((nibbletab[addr[i] & 0xf] << 4) | + nibbletab[(addr[i] >> 4) &0xf]); } int __init macsonic_init(struct net_device* dev) diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 030924fb1ab3..61cbd4a60446 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -1412,8 +1412,10 @@ static const struct ethtool_ops myri10ge_ethtool_ops = { .set_tx_csum = ethtool_op_set_tx_hw_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, +#ifdef NETIF_F_TSO .get_tso = ethtool_op_get_tso, .set_tso = ethtool_op_set_tso, +#endif .get_strings = myri10ge_get_strings, .get_stats_count = myri10ge_get_stats_count, .get_ethtool_stats = myri10ge_get_ethtool_stats, @@ -1973,11 +1975,13 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) mss = 0; max_segments = MXGEFW_MAX_SEND_DESC; +#ifdef NETIF_F_TSO if (skb->len > (dev->mtu + ETH_HLEN)) { mss = skb_shinfo(skb)->gso_size; if (mss != 0) max_segments = MYRI10GE_MAX_SEND_DESC_TSO; } +#endif /*NETIF_F_TSO */ if ((unlikely(avail < max_segments))) { /* we are out of transmit resources */ @@ -2009,6 +2013,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) cum_len = 0; +#ifdef NETIF_F_TSO if (mss) { /* TSO */ /* this removes any CKSUM flag from before */ flags = (MXGEFW_FLAGS_TSO_HDR | MXGEFW_FLAGS_FIRST); @@ -2024,6 +2029,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) * the checksum by parsing the header. */ pseudo_hdr_offset = mss; } else +#endif /*NETIF_F_TSO */ /* Mark small packets, and pad out tiny packets */ if (skb->len <= MXGEFW_SEND_SMALL_SIZE) { flags |= MXGEFW_FLAGS_SMALL; @@ -2091,6 +2097,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) seglen = len; flags_next = flags & ~MXGEFW_FLAGS_FIRST; cum_len_next = cum_len + seglen; +#ifdef NETIF_F_TSO if (mss) { /* TSO */ (req - rdma_count)->rdma_count = rdma_count + 1; @@ -2117,6 +2124,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) (small * MXGEFW_FLAGS_SMALL); } } +#endif /* NETIF_F_TSO */ req->addr_high = high_swapped; req->addr_low = htonl(low); req->pseudo_hdr_offset = htons(pseudo_hdr_offset); @@ -2153,12 +2161,14 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) } (req - rdma_count)->rdma_count = rdma_count; +#ifdef NETIF_F_TSO if (mss) do { req--; req->flags |= MXGEFW_FLAGS_TSO_LAST; } while (!(req->flags & (MXGEFW_FLAGS_TSO_CHOP | MXGEFW_FLAGS_FIRST))); +#endif idx = ((count - 1) + tx->req) & tx->mask; tx->info[idx].last = 1; if (tx->wc_fifo == NULL) diff --git a/trunk/drivers/net/netxen/netxen_nic.h b/trunk/drivers/net/netxen/netxen_nic.h index 3f3896e98879..e8598b809228 100644 --- a/trunk/drivers/net/netxen/netxen_nic.h +++ b/trunk/drivers/net/netxen/netxen_nic.h @@ -63,14 +63,11 @@ #include "netxen_nic_hw.h" +#define NETXEN_NIC_BUILD_NO "2" #define _NETXEN_NIC_LINUX_MAJOR 3 #define _NETXEN_NIC_LINUX_MINOR 3 #define _NETXEN_NIC_LINUX_SUBVERSION 3 -#define NETXEN_NIC_LINUX_VERSIONID "3.3.3" - -#define NUM_FLASH_SECTORS (64) -#define FLASH_SECTOR_SIZE (64 * 1024) -#define FLASH_TOTAL_SIZE (NUM_FLASH_SECTORS * FLASH_SECTOR_SIZE) +#define NETXEN_NIC_LINUX_VERSIONID "3.3.3" "-" NETXEN_NIC_BUILD_NO #define RCV_DESC_RINGSIZE \ (sizeof(struct rcv_desc) * adapter->max_rx_desc_count) @@ -88,7 +85,6 @@ #define NETXEN_RCV_PRODUCER_OFFSET 0 #define NETXEN_RCV_PEG_DB_ID 2 #define NETXEN_HOST_DUMMY_DMA_SIZE 1024 -#define FLASH_SUCCESS 0 #define ADDR_IN_WINDOW1(off) \ ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0 @@ -1032,15 +1028,6 @@ void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); void netxen_load_firmware(struct netxen_adapter *adapter); int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); -int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, - u8 *bytes, size_t size); -int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, - u8 *bytes, size_t size); -int netxen_flash_unlock(struct netxen_adapter *adapter); -int netxen_backup_crbinit(struct netxen_adapter *adapter); -int netxen_flash_erase_secondary(struct netxen_adapter *adapter); -int netxen_flash_erase_primary(struct netxen_adapter *adapter); - int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data); int netxen_rom_se(struct netxen_adapter *adapter, int addr); int netxen_do_rom_se(struct netxen_adapter *adapter, int addr); diff --git a/trunk/drivers/net/netxen/netxen_nic_ethtool.c b/trunk/drivers/net/netxen/netxen_nic_ethtool.c index cc0efe213e01..c381d77a7336 100644 --- a/trunk/drivers/net/netxen/netxen_nic_ethtool.c +++ b/trunk/drivers/net/netxen/netxen_nic_ethtool.c @@ -32,7 +32,6 @@ */ #include -#include #include #include #include @@ -95,7 +94,17 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = { static int netxen_nic_get_eeprom_len(struct net_device *dev) { - return FLASH_TOTAL_SIZE; + struct netxen_port *port = netdev_priv(dev); + struct netxen_adapter *adapter = port->adapter; + int n; + + if ((netxen_rom_fast_read(adapter, 0, &n) == 0) + && (n & NETXEN_ROM_ROUNDUP)) { + n &= ~NETXEN_ROM_ROUNDUP; + if (n < NETXEN_MAX_EEPROM_LEN) + return n; + } + return 0; } static void @@ -431,92 +440,18 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; int offset; - int ret; if (eeprom->len == 0) return -EINVAL; eeprom->magic = (port->pdev)->vendor | ((port->pdev)->device << 16); - offset = eeprom->offset; - - ret = netxen_rom_fast_read_words(adapter, offset, bytes, - eeprom->len); - if (ret < 0) - return ret; - + for (offset = 0; offset < eeprom->len; offset++) + if (netxen_rom_fast_read + (adapter, (8 * offset) + 8, (int *)eeprom->data) == -1) + return -EIO; return 0; } -static int -netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, - u8 * bytes) -{ - struct netxen_port *port = netdev_priv(dev); - struct netxen_adapter *adapter = port->adapter; - int offset = eeprom->offset; - static int flash_start; - static int ready_to_flash; - int ret; - - if (flash_start == 0) { - ret = netxen_flash_unlock(adapter); - if (ret < 0) { - printk(KERN_ERR "%s: Flash unlock failed.\n", - netxen_nic_driver_name); - return ret; - } - printk(KERN_INFO "%s: flash unlocked. \n", - netxen_nic_driver_name); - ret = netxen_flash_erase_secondary(adapter); - if (ret != FLASH_SUCCESS) { - printk(KERN_ERR "%s: Flash erase failed.\n", - netxen_nic_driver_name); - return ret; - } - printk(KERN_INFO "%s: secondary flash erased successfully.\n", - netxen_nic_driver_name); - flash_start = 1; - return 0; - } - - if (offset == BOOTLD_START) { - ret = netxen_flash_erase_primary(adapter); - if (ret != FLASH_SUCCESS) { - printk(KERN_ERR "%s: Flash erase failed.\n", - netxen_nic_driver_name); - return ret; - } - - ret = netxen_rom_se(adapter, USER_START); - if (ret != FLASH_SUCCESS) - return ret; - ret = netxen_rom_se(adapter, FIXED_START); - if (ret != FLASH_SUCCESS) - return ret; - - printk(KERN_INFO "%s: primary flash erased successfully\n", - netxen_nic_driver_name); - - ret = netxen_backup_crbinit(adapter); - if (ret != FLASH_SUCCESS) { - printk(KERN_ERR "%s: CRBinit backup failed.\n", - netxen_nic_driver_name); - return ret; - } - printk(KERN_INFO "%s: CRBinit backup done.\n", - netxen_nic_driver_name); - ready_to_flash = 1; - } - - if (!ready_to_flash) { - printk(KERN_ERR "%s: Invalid write sequence, returning...\n", - netxen_nic_driver_name); - return -EINVAL; - } - - return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len); -} - static void netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) { @@ -786,7 +721,6 @@ struct ethtool_ops netxen_nic_ethtool_ops = { .get_link = netxen_nic_get_link, .get_eeprom_len = netxen_nic_get_eeprom_len, .get_eeprom = netxen_nic_get_eeprom, - .set_eeprom = netxen_nic_set_eeprom, .get_ringparam = netxen_nic_get_ringparam, .get_pauseparam = netxen_nic_get_pauseparam, .set_pauseparam = netxen_nic_set_pauseparam, diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c index f7bb8c90537c..973af96337a9 100644 --- a/trunk/drivers/net/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/netxen/netxen_nic_init.c @@ -110,7 +110,6 @@ static void crb_addr_transform_setup(void) crb_addr_transform(CAM); crb_addr_transform(C2C1); crb_addr_transform(C2C0); - crb_addr_transform(SMB); } int netxen_init_firmware(struct netxen_adapter *adapter) @@ -277,7 +276,6 @@ unsigned long netxen_decode_crb_addr(unsigned long addr) static long rom_max_timeout = 10000; static long rom_lock_timeout = 1000000; -static long rom_write_timeout = 700; static inline int rom_lock(struct netxen_adapter *adapter) { @@ -406,7 +404,7 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) { netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); - udelay(70); /* prevent bursting on CRB */ + udelay(100); /* prevent bursting on CRB */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); if (netxen_wait_rom_done(adapter)) { @@ -415,46 +413,13 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) } /* reset abyte_cnt and dummy_byte_cnt */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); - udelay(70); /* prevent bursting on CRB */ + udelay(100); /* prevent bursting on CRB */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA); return 0; } -static inline int -do_rom_fast_read_words(struct netxen_adapter *adapter, int addr, - u8 *bytes, size_t size) -{ - int addridx; - int ret = 0; - - for (addridx = addr; addridx < (addr + size); addridx += 4) { - ret = do_rom_fast_read(adapter, addridx, (int *)bytes); - if (ret != 0) - break; - bytes += 4; - } - - return ret; -} - -int -netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, - u8 *bytes, size_t size) -{ - int ret; - - ret = rom_lock(adapter); - if (ret < 0) - return ret; - - ret = do_rom_fast_read_words(adapter, addr, bytes, size); - - netxen_rom_unlock(adapter); - return ret; -} - int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) { int ret; @@ -478,152 +443,6 @@ int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data) netxen_rom_unlock(adapter); return ret; } - -static inline int do_rom_fast_write_words(struct netxen_adapter *adapter, - int addr, u8 *bytes, size_t size) -{ - int addridx = addr; - int ret = 0; - - while (addridx < (addr + size)) { - int last_attempt = 0; - int timeout = 0; - int data; - - data = *(u32*)bytes; - - ret = do_rom_fast_write(adapter, addridx, data); - if (ret < 0) - return ret; - - while(1) { - int data1; - - do_rom_fast_read(adapter, addridx, &data1); - if (data1 == data) - break; - - if (timeout++ >= rom_write_timeout) { - if (last_attempt++ < 4) { - ret = do_rom_fast_write(adapter, - addridx, data); - if (ret < 0) - return ret; - } - else { - printk(KERN_INFO "Data write did not " - "succeed at address 0x%x\n", addridx); - break; - } - } - } - - bytes += 4; - addridx += 4; - } - - return ret; -} - -int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, - u8 *bytes, size_t size) -{ - int ret = 0; - - ret = rom_lock(adapter); - if (ret < 0) - return ret; - - ret = do_rom_fast_write_words(adapter, addr, bytes, size); - netxen_rom_unlock(adapter); - - return ret; -} - -int netxen_rom_wrsr(struct netxen_adapter *adapter, int data) -{ - int ret; - - ret = netxen_rom_wren(adapter); - if (ret < 0) - return ret; - - netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data); - netxen_crb_writelit_adapter(adapter, - NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1); - - ret = netxen_wait_rom_done(adapter); - if (ret < 0) - return ret; - - return netxen_rom_wip_poll(adapter); -} - -int netxen_rom_rdsr(struct netxen_adapter *adapter) -{ - int ret; - - ret = rom_lock(adapter); - if (ret < 0) - return ret; - - ret = netxen_do_rom_rdsr(adapter); - netxen_rom_unlock(adapter); - return ret; -} - -int netxen_backup_crbinit(struct netxen_adapter *adapter) -{ - int ret = FLASH_SUCCESS; - int val; - char *buffer = kmalloc(FLASH_SECTOR_SIZE, GFP_KERNEL); - - if (!buffer) - return -ENOMEM; - /* unlock sector 63 */ - val = netxen_rom_rdsr(adapter); - val = val & 0xe3; - ret = netxen_rom_wrsr(adapter, val); - if (ret != FLASH_SUCCESS) - goto out_kfree; - - ret = netxen_rom_wip_poll(adapter); - if (ret != FLASH_SUCCESS) - goto out_kfree; - - /* copy sector 0 to sector 63 */ - ret = netxen_rom_fast_read_words(adapter, CRBINIT_START, - buffer, FLASH_SECTOR_SIZE); - if (ret != FLASH_SUCCESS) - goto out_kfree; - - ret = netxen_rom_fast_write_words(adapter, FIXED_START, - buffer, FLASH_SECTOR_SIZE); - if (ret != FLASH_SUCCESS) - goto out_kfree; - - /* lock sector 63 */ - val = netxen_rom_rdsr(adapter); - if (!(val & 0x8)) { - val |= (0x1 << 2); - /* lock sector 63 */ - if (netxen_rom_wrsr(adapter, val) == 0) { - ret = netxen_rom_wip_poll(adapter); - if (ret != FLASH_SUCCESS) - goto out_kfree; - - /* lock SR writes */ - ret = netxen_rom_wip_poll(adapter); - if (ret != FLASH_SUCCESS) - goto out_kfree; - } - } - -out_kfree: - kfree(buffer); - return ret; -} - int netxen_do_rom_se(struct netxen_adapter *adapter, int addr) { netxen_rom_wren(adapter); @@ -638,27 +457,6 @@ int netxen_do_rom_se(struct netxen_adapter *adapter, int addr) return netxen_rom_wip_poll(adapter); } -void check_erased_flash(struct netxen_adapter *adapter, int addr) -{ - int i; - int val; - int count = 0, erased_errors = 0; - int range; - - range = (addr == USER_START) ? FIXED_START : addr + FLASH_SECTOR_SIZE; - - for (i = addr; i < range; i += 4) { - netxen_rom_fast_read(adapter, i, &val); - if (val != 0xffffffff) - erased_errors++; - count++; - } - - if (erased_errors) - printk(KERN_INFO "0x%x out of 0x%x words fail to be erased " - "for sector address: %x\n", erased_errors, count, addr); -} - int netxen_rom_se(struct netxen_adapter *adapter, int addr) { int ret = 0; @@ -667,68 +465,6 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr) } ret = netxen_do_rom_se(adapter, addr); netxen_rom_unlock(adapter); - msleep(30); - check_erased_flash(adapter, addr); - - return ret; -} - -int -netxen_flash_erase_sections(struct netxen_adapter *adapter, int start, int end) -{ - int ret = FLASH_SUCCESS; - int i; - - for (i = start; i < end; i++) { - ret = netxen_rom_se(adapter, i * FLASH_SECTOR_SIZE); - if (ret) - break; - ret = netxen_rom_wip_poll(adapter); - if (ret < 0) - return ret; - } - - return ret; -} - -int -netxen_flash_erase_secondary(struct netxen_adapter *adapter) -{ - int ret = FLASH_SUCCESS; - int start, end; - - start = SECONDARY_START / FLASH_SECTOR_SIZE; - end = USER_START / FLASH_SECTOR_SIZE; - ret = netxen_flash_erase_sections(adapter, start, end); - - return ret; -} - -int -netxen_flash_erase_primary(struct netxen_adapter *adapter) -{ - int ret = FLASH_SUCCESS; - int start, end; - - start = PRIMARY_START / FLASH_SECTOR_SIZE; - end = SECONDARY_START / FLASH_SECTOR_SIZE; - ret = netxen_flash_erase_sections(adapter, start, end); - - return ret; -} - -int netxen_flash_unlock(struct netxen_adapter *adapter) -{ - int ret = 0; - - ret = netxen_rom_wrsr(adapter, 0); - if (ret < 0) - return ret; - - ret = netxen_rom_wren(adapter); - if (ret < 0) - return ret; - return ret; } @@ -807,13 +543,9 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) } for (i = 0; i < n; i++) { - off = netxen_decode_crb_addr((unsigned long)buf[i].addr); - if (off == NETXEN_ADDR_ERROR) { - printk(KERN_ERR"CRB init value out of range %lx\n", - buf[i].addr); - continue; - } - off += NETXEN_PCI_CRBSPACE; + off = + netxen_decode_crb_addr((unsigned long)buf[i].addr) + + NETXEN_PCI_CRBSPACE; /* skipping cold reboot MAGIC */ if (off == NETXEN_CAM_RAM(0x1fc)) continue; @@ -930,7 +662,6 @@ void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) int loops = 0; if (!pegtune_val) { - val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); while (val != PHAN_INITIALIZE_COMPLETE && loops < 200000) { udelay(100); schedule(); diff --git a/trunk/drivers/net/oaknet.c b/trunk/drivers/net/oaknet.c new file mode 100644 index 000000000000..702e3e95612a --- /dev/null +++ b/trunk/drivers/net/oaknet.c @@ -0,0 +1,666 @@ +/* + * + * Copyright (c) 1999-2000 Grant Erickson + * + * Module name: oaknet.c + * + * Description: + * Driver for the National Semiconductor DP83902AV Ethernet controller + * on-board the IBM PowerPC "Oak" evaluation board. Adapted from the + * various other 8390 drivers written by Donald Becker and Paul Gortmaker. + * + * Additional inspiration from the "tcd8390.c" driver from TiVo, Inc. + * and "enetLib.c" from IBM. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "8390.h" + + +/* Preprocessor Defines */ + +#if !defined(TRUE) || TRUE != 1 +#define TRUE 1 +#endif + +#if !defined(FALSE) || FALSE != 0 +#define FALSE 0 +#endif + +#define OAKNET_START_PG 0x20 /* First page of TX buffer */ +#define OAKNET_STOP_PG 0x40 /* Last pagge +1 of RX ring */ + +#define OAKNET_WAIT (2 * HZ / 100) /* 20 ms */ + +/* Experimenting with some fixes for a broken driver... */ + +#define OAKNET_DISINT +#define OAKNET_HEADCHECK +#define OAKNET_RWFIX + + +/* Global Variables */ + +static const char *name = "National DP83902AV"; + +static struct net_device *oaknet_devs; + + +/* Function Prototypes */ + +static int oaknet_open(struct net_device *dev); +static int oaknet_close(struct net_device *dev); + +static void oaknet_reset_8390(struct net_device *dev); +static void oaknet_get_8390_hdr(struct net_device *dev, + struct e8390_pkt_hdr *hdr, int ring_page); +static void oaknet_block_input(struct net_device *dev, int count, + struct sk_buff *skb, int ring_offset); +static void oaknet_block_output(struct net_device *dev, int count, + const unsigned char *buf, int start_page); + +static void oaknet_dma_error(struct net_device *dev, const char *name); + + +/* + * int oaknet_init() + * + * Description: + * This routine performs all the necessary platform-specific initiali- + * zation and set-up for the IBM "Oak" evaluation board's National + * Semiconductor DP83902AV "ST-NIC" Ethernet controller. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if OK, otherwise system error number on error. + * + */ +static int __init oaknet_init(void) +{ + register int i; + int reg0, regd; + int ret = -ENOMEM; + struct net_device *dev; +#if 0 + unsigned long ioaddr = OAKNET_IO_BASE; +#else + unsigned long ioaddr = ioremap(OAKNET_IO_BASE, OAKNET_IO_SIZE); +#endif + bd_t *bip = (bd_t *)__res; + + if (!ioaddr) + return -ENOMEM; + + dev = alloc_ei_netdev(); + if (!dev) + goto out_unmap; + + ret = -EBUSY; + if (!request_region(OAKNET_IO_BASE, OAKNET_IO_SIZE, name)) + goto out_dev; + + /* Quick register check to see if the device is really there. */ + + ret = -ENODEV; + if ((reg0 = ei_ibp(ioaddr)) == 0xFF) + goto out_region; + + /* + * That worked. Now a more thorough check, using the multicast + * address registers, that the device is definitely out there + * and semi-functional. + */ + + ei_obp(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD); + regd = ei_ibp(ioaddr + 0x0D); + ei_obp(0xFF, ioaddr + 0x0D); + ei_obp(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD); + ei_ibp(ioaddr + EN0_COUNTER0); + + /* It's no good. Fix things back up and leave. */ + + ret = -ENODEV; + if (ei_ibp(ioaddr + EN0_COUNTER0) != 0) { + ei_obp(reg0, ioaddr); + ei_obp(regd, ioaddr + 0x0D); + goto out_region; + } + + SET_MODULE_OWNER(dev); + + /* + * This controller is on an embedded board, so the base address + * and interrupt assignments are pre-assigned and unchageable. + */ + + dev->base_addr = ioaddr; + dev->irq = OAKNET_INT; + + /* + * Disable all chip interrupts for now and ACK all pending + * interrupts. + */ + + ei_obp(0x0, ioaddr + EN0_IMR); + ei_obp(0xFF, ioaddr + EN0_ISR); + + /* Attempt to get the interrupt line */ + + ret = -EAGAIN; + if (request_irq(dev->irq, ei_interrupt, 0, name, dev)) { + printk("%s: unable to request interrupt %d.\n", + name, dev->irq); + goto out_region; + } + + /* Tell the world about what and where we've found. */ + + printk("%s: %s at", dev->name, name); + for (i = 0; i < ETHER_ADDR_LEN; ++i) { + dev->dev_addr[i] = bip->bi_enetaddr[i]; + printk("%c%.2x", (i ? ':' : ' '), dev->dev_addr[i]); + } + printk(", found at %#lx, using IRQ %d.\n", dev->base_addr, dev->irq); + + /* Set up some required driver fields and then we're done. */ + + ei_status.name = name; + ei_status.word16 = FALSE; + ei_status.tx_start_page = OAKNET_START_PG; + ei_status.rx_start_page = OAKNET_START_PG + TX_PAGES; + ei_status.stop_page = OAKNET_STOP_PG; + + ei_status.reset_8390 = &oaknet_reset_8390; + ei_status.block_input = &oaknet_block_input; + ei_status.block_output = &oaknet_block_output; + ei_status.get_8390_hdr = &oaknet_get_8390_hdr; + + dev->open = oaknet_open; + dev->stop = oaknet_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif + + NS8390_init(dev, FALSE); + ret = register_netdev(dev); + if (ret) + goto out_irq; + + oaknet_devs = dev; + return 0; + +out_irq; + free_irq(dev->irq, dev); +out_region: + release_region(OAKNET_IO_BASE, OAKNET_IO_SIZE); +out_dev: + free_netdev(dev); +out_unmap: + iounmap(ioaddr); + return ret; +} + +/* + * static int oaknet_open() + * + * Description: + * This routine is a modest wrapper around ei_open, the 8390-generic, + * driver open routine. This just increments the module usage count + * and passes along the status from ei_open. + * + * Input(s): + * *dev - Pointer to the device structure for this driver. + * + * Output(s): + * *dev - Pointer to the device structure for this driver, potentially + * modified by ei_open. + * + * Returns: + * 0 if OK, otherwise < 0 on error. + * + */ +static int +oaknet_open(struct net_device *dev) +{ + int status = ei_open(dev); + return (status); +} + +/* + * static int oaknet_close() + * + * Description: + * This routine is a modest wrapper around ei_close, the 8390-generic, + * driver close routine. This just decrements the module usage count + * and passes along the status from ei_close. + * + * Input(s): + * *dev - Pointer to the device structure for this driver. + * + * Output(s): + * *dev - Pointer to the device structure for this driver, potentially + * modified by ei_close. + * + * Returns: + * 0 if OK, otherwise < 0 on error. + * + */ +static int +oaknet_close(struct net_device *dev) +{ + int status = ei_close(dev); + return (status); +} + +/* + * static void oaknet_reset_8390() + * + * Description: + * This routine resets the DP83902 chip. + * + * Input(s): + * *dev - Pointer to the device structure for this driver. + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +static void +oaknet_reset_8390(struct net_device *dev) +{ + int base = E8390_BASE; + + /* + * We have no provision of reseting the controller as is done + * in other drivers, such as "ne.c". However, the following + * seems to work well enough in the TiVo driver. + */ + + printk("Resetting %s...\n", dev->name); + ei_obp(E8390_STOP | E8390_NODMA | E8390_PAGE0, base + E8390_CMD); + ei_status.txing = 0; + ei_status.dmaing = 0; +} + +/* + * static void oaknet_get_8390_hdr() + * + * Description: + * This routine grabs the 8390-specific header. It's similar to the + * block input routine, but we don't need to be concerned with ring wrap + * as the header will be at the start of a page, so we optimize accordingly. + * + * Input(s): + * *dev - Pointer to the device structure for this driver. + * *hdr - Pointer to storage for the 8390-specific packet header. + * ring_page - ? + * + * Output(s): + * *hdr - Pointer to the 8390-specific packet header for the just- + * received frame. + * + * Returns: + * N/A + * + */ +static void +oaknet_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, + int ring_page) +{ + int base = dev->base_addr; + + /* + * This should NOT happen. If it does, it is the LAST thing you'll + * see. + */ + + if (ei_status.dmaing) { + oaknet_dma_error(dev, "oaknet_get_8390_hdr"); + return; + } + + ei_status.dmaing |= 0x01; + outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, base + OAKNET_CMD); + outb_p(sizeof(struct e8390_pkt_hdr), base + EN0_RCNTLO); + outb_p(0, base + EN0_RCNTHI); + outb_p(0, base + EN0_RSARLO); /* On page boundary */ + outb_p(ring_page, base + EN0_RSARHI); + outb_p(E8390_RREAD + E8390_START, base + OAKNET_CMD); + + if (ei_status.word16) + insw(base + OAKNET_DATA, hdr, + sizeof(struct e8390_pkt_hdr) >> 1); + else + insb(base + OAKNET_DATA, hdr, + sizeof(struct e8390_pkt_hdr)); + + /* Byte-swap the packet byte count */ + + hdr->count = le16_to_cpu(hdr->count); + + outb_p(ENISR_RDC, base + EN0_ISR); /* ACK Remote DMA interrupt */ + ei_status.dmaing &= ~0x01; +} + +/* + * XXX - Document me. + */ +static void +oaknet_block_input(struct net_device *dev, int count, struct sk_buff *skb, + int ring_offset) +{ + int base = OAKNET_BASE; + char *buf = skb->data; + + /* + * This should NOT happen. If it does, it is the LAST thing you'll + * see. + */ + + if (ei_status.dmaing) { + oaknet_dma_error(dev, "oaknet_block_input"); + return; + } + +#ifdef OAKNET_DISINT + save_flags(flags); + cli(); +#endif + + ei_status.dmaing |= 0x01; + ei_obp(E8390_NODMA + E8390_PAGE0 + E8390_START, base + E8390_CMD); + ei_obp(count & 0xff, base + EN0_RCNTLO); + ei_obp(count >> 8, base + EN0_RCNTHI); + ei_obp(ring_offset & 0xff, base + EN0_RSARLO); + ei_obp(ring_offset >> 8, base + EN0_RSARHI); + ei_obp(E8390_RREAD + E8390_START, base + E8390_CMD); + if (ei_status.word16) { + ei_isw(base + E8390_DATA, buf, count >> 1); + if (count & 0x01) { + buf[count - 1] = ei_ib(base + E8390_DATA); +#ifdef OAKNET_HEADCHECK + bytes++; +#endif + } + } else { + ei_isb(base + E8390_DATA, buf, count); + } +#ifdef OAKNET_HEADCHECK + /* + * This was for the ALPHA version only, but enough people have + * been encountering problems so it is still here. If you see + * this message you either 1) have a slightly incompatible clone + * or 2) have noise/speed problems with your bus. + */ + + /* DMA termination address check... */ + { + int addr, tries = 20; + do { + /* DON'T check for 'ei_ibp(EN0_ISR) & ENISR_RDC' here + -- it's broken for Rx on some cards! */ + int high = ei_ibp(base + EN0_RSARHI); + int low = ei_ibp(base + EN0_RSARLO); + addr = (high << 8) + low; + if (((ring_offset + bytes) & 0xff) == low) + break; + } while (--tries > 0); + if (tries <= 0) + printk("%s: RX transfer address mismatch," + "%#4.4x (expected) vs. %#4.4x (actual).\n", + dev->name, ring_offset + bytes, addr); + } +#endif + ei_obp(ENISR_RDC, base + EN0_ISR); /* ACK Remote DMA interrupt */ + ei_status.dmaing &= ~0x01; + +#ifdef OAKNET_DISINT + restore_flags(flags); +#endif +} + +/* + * static void oaknet_block_output() + * + * Description: + * This routine... + * + * Input(s): + * *dev - Pointer to the device structure for this driver. + * count - Number of bytes to be transferred. + * *buf - + * start_page - + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +static void +oaknet_block_output(struct net_device *dev, int count, + const unsigned char *buf, int start_page) +{ + int base = E8390_BASE; +#if 0 + int bug; +#endif + unsigned long start; +#ifdef OAKNET_DISINT + unsigned long flags; +#endif +#ifdef OAKNET_HEADCHECK + int retries = 0; +#endif + + /* Round the count up for word writes. */ + + if (ei_status.word16 && (count & 0x1)) + count++; + + /* + * This should NOT happen. If it does, it is the LAST thing you'll + * see. + */ + + if (ei_status.dmaing) { + oaknet_dma_error(dev, "oaknet_block_output"); + return; + } + +#ifdef OAKNET_DISINT + save_flags(flags); + cli(); +#endif + + ei_status.dmaing |= 0x01; + + /* Make sure we are in page 0. */ + + ei_obp(E8390_PAGE0 + E8390_START + E8390_NODMA, base + E8390_CMD); + +#ifdef OAKNET_HEADCHECK +retry: +#endif + +#if 0 + /* + * The 83902 documentation states that the processor needs to + * do a "dummy read" before doing the remote write to work + * around a chip bug they don't feel like fixing. + */ + + bug = 0; + while (1) { + unsigned int rdhi; + unsigned int rdlo; + + /* Now the normal output. */ + ei_obp(ENISR_RDC, base + EN0_ISR); + ei_obp(count & 0xff, base + EN0_RCNTLO); + ei_obp(count >> 8, base + EN0_RCNTHI); + ei_obp(0x00, base + EN0_RSARLO); + ei_obp(start_page, base + EN0_RSARHI); + + if (bug++) + break; + + /* Perform the dummy read */ + rdhi = ei_ibp(base + EN0_CRDAHI); + rdlo = ei_ibp(base + EN0_CRDALO); + ei_obp(E8390_RREAD + E8390_START, base + E8390_CMD); + + while (1) { + unsigned int nrdhi; + unsigned int nrdlo; + nrdhi = ei_ibp(base + EN0_CRDAHI); + nrdlo = ei_ibp(base + EN0_CRDALO); + if ((rdhi != nrdhi) || (rdlo != nrdlo)) + break; + } + } +#else +#ifdef OAKNET_RWFIX + /* + * Handle the read-before-write bug the same way as the + * Crynwr packet driver -- the Nat'l Semi. method doesn't work. + * Actually this doesn't always work either, but if you have + * problems with your 83902 this is better than nothing! + */ + + ei_obp(0x42, base + EN0_RCNTLO); + ei_obp(0x00, base + EN0_RCNTHI); + ei_obp(0x42, base + EN0_RSARLO); + ei_obp(0x00, base + EN0_RSARHI); + ei_obp(E8390_RREAD + E8390_START, base + E8390_CMD); + /* Make certain that the dummy read has occurred. */ + udelay(6); +#endif + + ei_obp(ENISR_RDC, base + EN0_ISR); + + /* Now the normal output. */ + ei_obp(count & 0xff, base + EN0_RCNTLO); + ei_obp(count >> 8, base + EN0_RCNTHI); + ei_obp(0x00, base + EN0_RSARLO); + ei_obp(start_page, base + EN0_RSARHI); +#endif /* 0/1 */ + + ei_obp(E8390_RWRITE + E8390_START, base + E8390_CMD); + if (ei_status.word16) { + ei_osw(E8390_BASE + E8390_DATA, buf, count >> 1); + } else { + ei_osb(E8390_BASE + E8390_DATA, buf, count); + } + +#ifdef OAKNET_DISINT + restore_flags(flags); +#endif + + start = jiffies; + +#ifdef OAKNET_HEADCHECK + /* + * This was for the ALPHA version only, but enough people have + * been encountering problems so it is still here. + */ + + { + /* DMA termination address check... */ + int addr, tries = 20; + do { + int high = ei_ibp(base + EN0_RSARHI); + int low = ei_ibp(base + EN0_RSARLO); + addr = (high << 8) + low; + if ((start_page << 8) + count == addr) + break; + } while (--tries > 0); + + if (tries <= 0) { + printk("%s: Tx packet transfer address mismatch," + "%#4.4x (expected) vs. %#4.4x (actual).\n", + dev->name, (start_page << 8) + count, addr); + if (retries++ == 0) + goto retry; + } + } +#endif + + while ((ei_ibp(base + EN0_ISR) & ENISR_RDC) == 0) { + if (time_after(jiffies, start + OAKNET_WAIT)) { + printk("%s: timeout waiting for Tx RDC.\n", dev->name); + oaknet_reset_8390(dev); + NS8390_init(dev, TRUE); + break; + } + } + + ei_obp(ENISR_RDC, base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; +} + +/* + * static void oaknet_dma_error() + * + * Description: + * This routine prints out a last-ditch informative message to the console + * indicating that a DMA error occurred. If you see this, it's the last + * thing you'll see. + * + * Input(s): + * *dev - Pointer to the device structure for this driver. + * *name - Informative text (e.g. function name) indicating where the + * DMA error occurred. + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +static void +oaknet_dma_error(struct net_device *dev, const char *name) +{ + printk(KERN_EMERG "%s: DMAing conflict in %s." + "[DMAstat:%d][irqlock:%d][intr:%ld]\n", + dev->name, name, ei_status.dmaing, ei_status.irqlock, + dev->interrupt); +} + +/* + * Oak Ethernet module unload interface. + */ +static void __exit oaknet_cleanup_module (void) +{ + /* Convert to loop once driver supports multiple devices. */ + unregister_netdev(oaknet_dev); + free_irq(oaknet_devs->irq, oaknet_devs); + release_region(oaknet_devs->base_addr, OAKNET_IO_SIZE); + iounmap(ioaddr); + free_netdev(oaknet_devs); +} + +module_init(oaknet_init); +module_exit(oaknet_cleanup_module); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/pasemi_mac.c b/trunk/drivers/net/pasemi_mac.c deleted file mode 100644 index d670ac74824f..000000000000 --- a/trunk/drivers/net/pasemi_mac.c +++ /dev/null @@ -1,1019 +0,0 @@ -/* - * Copyright (C) 2006-2007 PA Semi, Inc - * - * Driver for the PA Semi PWRficient onchip 1G/10G Ethernet MACs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "pasemi_mac.h" - - -/* TODO list - * - * - Get rid of pci_{read,write}_config(), map registers with ioremap - * for performance - * - PHY support - * - Multicast support - * - Large MTU support - * - Other performance improvements - */ - - -/* Must be a power of two */ -#define RX_RING_SIZE 512 -#define TX_RING_SIZE 512 - -#define TX_DESC(mac, num) ((mac)->tx->desc[(num) & (TX_RING_SIZE-1)]) -#define TX_DESC_INFO(mac, num) ((mac)->tx->desc_info[(num) & (TX_RING_SIZE-1)]) -#define RX_DESC(mac, num) ((mac)->rx->desc[(num) & (RX_RING_SIZE-1)]) -#define RX_DESC_INFO(mac, num) ((mac)->rx->desc_info[(num) & (RX_RING_SIZE-1)]) -#define RX_BUFF(mac, num) ((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)]) - -#define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */ - -/* XXXOJN these should come out of the device tree some day */ -#define PAS_DMA_CAP_BASE 0xe00d0040 -#define PAS_DMA_CAP_SIZE 0x100 -#define PAS_DMA_COM_BASE 0xe00d0100 -#define PAS_DMA_COM_SIZE 0x100 - -static struct pasdma_status *dma_status; - -static int pasemi_get_mac_addr(struct pasemi_mac *mac) -{ - struct pci_dev *pdev = mac->pdev; - struct device_node *dn = pci_device_to_OF_node(pdev); - const u8 *maddr; - u8 addr[6]; - - if (!dn) { - dev_dbg(&pdev->dev, - "No device node for mac, not configuring\n"); - return -ENOENT; - } - - maddr = get_property(dn, "mac-address", NULL); - if (maddr == NULL) { - dev_warn(&pdev->dev, - "no mac address in device tree, not configuring\n"); - return -ENOENT; - } - - if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0], - &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) { - dev_warn(&pdev->dev, - "can't parse mac address, not configuring\n"); - return -EINVAL; - } - - memcpy(mac->mac_addr, addr, sizeof(addr)); - return 0; -} - -static int pasemi_mac_setup_rx_resources(struct net_device *dev) -{ - struct pasemi_mac_rxring *ring; - struct pasemi_mac *mac = netdev_priv(dev); - int chan_id = mac->dma_rxch; - - ring = kzalloc(sizeof(*ring), GFP_KERNEL); - - if (!ring) - goto out_ring; - - spin_lock_init(&ring->lock); - - ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) * - RX_RING_SIZE, GFP_KERNEL); - - if (!ring->desc_info) - goto out_desc_info; - - /* Allocate descriptors */ - ring->desc = dma_alloc_coherent(&mac->dma_pdev->dev, - RX_RING_SIZE * - sizeof(struct pas_dma_xct_descr), - &ring->dma, GFP_KERNEL); - - if (!ring->desc) - goto out_desc; - - memset(ring->desc, 0, RX_RING_SIZE * sizeof(struct pas_dma_xct_descr)); - - ring->buffers = dma_alloc_coherent(&mac->dma_pdev->dev, - RX_RING_SIZE * sizeof(u64), - &ring->buf_dma, GFP_KERNEL); - if (!ring->buffers) - goto out_buffers; - - memset(ring->buffers, 0, RX_RING_SIZE * sizeof(u64)); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_BASEL(chan_id), - PAS_DMA_RXCHAN_BASEL_BRBL(ring->dma)); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_BASEU(chan_id), - PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) | - PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2)); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_CFG(chan_id), - PAS_DMA_RXCHAN_CFG_HBU(1)); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_BASEL(mac->dma_if), - PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers))); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_BASEU(mac->dma_if), - PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) | - PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3)); - - ring->next_to_fill = 0; - ring->next_to_clean = 0; - - snprintf(ring->irq_name, sizeof(ring->irq_name), - "%s rx", dev->name); - mac->rx = ring; - - return 0; - -out_buffers: - dma_free_coherent(&mac->dma_pdev->dev, - RX_RING_SIZE * sizeof(struct pas_dma_xct_descr), - mac->rx->desc, mac->rx->dma); -out_desc: - kfree(ring->desc_info); -out_desc_info: - kfree(ring); -out_ring: - return -ENOMEM; -} - - -static int pasemi_mac_setup_tx_resources(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - u32 val; - int chan_id = mac->dma_txch; - struct pasemi_mac_txring *ring; - - ring = kzalloc(sizeof(*ring), GFP_KERNEL); - if (!ring) - goto out_ring; - - spin_lock_init(&ring->lock); - - ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) * - TX_RING_SIZE, GFP_KERNEL); - if (!ring->desc_info) - goto out_desc_info; - - /* Allocate descriptors */ - ring->desc = dma_alloc_coherent(&mac->dma_pdev->dev, - TX_RING_SIZE * - sizeof(struct pas_dma_xct_descr), - &ring->dma, GFP_KERNEL); - if (!ring->desc) - goto out_desc; - - memset(ring->desc, 0, TX_RING_SIZE * sizeof(struct pas_dma_xct_descr)); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_BASEL(chan_id), - PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma)); - val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32); - val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_BASEU(chan_id), val); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_CFG(chan_id), - PAS_DMA_TXCHAN_CFG_TY_IFACE | - PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) | - PAS_DMA_TXCHAN_CFG_UP | - PAS_DMA_TXCHAN_CFG_WT(2)); - - ring->next_to_use = 0; - ring->next_to_clean = 0; - - snprintf(ring->irq_name, sizeof(ring->irq_name), - "%s tx", dev->name); - mac->tx = ring; - - return 0; - -out_desc: - kfree(ring->desc_info); -out_desc_info: - kfree(ring); -out_ring: - return -ENOMEM; -} - -static void pasemi_mac_free_tx_resources(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - unsigned int i; - struct pasemi_mac_buffer *info; - struct pas_dma_xct_descr *dp; - - for (i = 0; i < TX_RING_SIZE; i++) { - info = &TX_DESC_INFO(mac, i); - dp = &TX_DESC(mac, i); - if (info->dma) { - if (info->skb) { - pci_unmap_single(mac->dma_pdev, - info->dma, - info->skb->len, - PCI_DMA_TODEVICE); - dev_kfree_skb_any(info->skb); - } - info->dma = 0; - info->skb = NULL; - dp->mactx = 0; - dp->ptr = 0; - } - } - - dma_free_coherent(&mac->dma_pdev->dev, - TX_RING_SIZE * sizeof(struct pas_dma_xct_descr), - mac->tx->desc, mac->tx->dma); - - kfree(mac->tx->desc_info); - kfree(mac->tx); - mac->tx = NULL; -} - -static void pasemi_mac_free_rx_resources(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - unsigned int i; - struct pasemi_mac_buffer *info; - struct pas_dma_xct_descr *dp; - - for (i = 0; i < RX_RING_SIZE; i++) { - info = &RX_DESC_INFO(mac, i); - dp = &RX_DESC(mac, i); - if (info->dma) { - if (info->skb) { - pci_unmap_single(mac->dma_pdev, - info->dma, - info->skb->len, - PCI_DMA_FROMDEVICE); - dev_kfree_skb_any(info->skb); - } - info->dma = 0; - info->skb = NULL; - dp->macrx = 0; - dp->ptr = 0; - } - } - - dma_free_coherent(&mac->dma_pdev->dev, - RX_RING_SIZE * sizeof(struct pas_dma_xct_descr), - mac->rx->desc, mac->rx->dma); - - dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64), - mac->rx->buffers, mac->rx->buf_dma); - - kfree(mac->rx->desc_info); - kfree(mac->rx); - mac->rx = NULL; -} - -static void pasemi_mac_replenish_rx_ring(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - unsigned int i; - int start = mac->rx->next_to_fill; - unsigned int count; - - count = (mac->rx->next_to_clean + RX_RING_SIZE - - mac->rx->next_to_fill) & (RX_RING_SIZE - 1); - - /* Check to see if we're doing first-time setup */ - if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0)) - count = RX_RING_SIZE; - - if (count <= 0) - return; - - for (i = start; i < start + count; i++) { - struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i); - u64 *buff = &RX_BUFF(mac, i); - struct sk_buff *skb; - dma_addr_t dma; - - skb = dev_alloc_skb(BUF_SIZE); - - if (!skb) { - count = i - start; - break; - } - - skb->dev = dev; - - dma = pci_map_single(mac->dma_pdev, skb->data, skb->len, - PCI_DMA_FROMDEVICE); - - if (dma_mapping_error(dma)) { - dev_kfree_skb_irq(info->skb); - count = i - start; - break; - } - - info->skb = skb; - info->dma = dma; - *buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma); - } - - wmb(); - - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_INCR(mac->dma_rxch), - count); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_INCR(mac->dma_if), - count); - - mac->rx->next_to_fill += count; -} - -static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) -{ - unsigned int i; - int start, count; - - spin_lock(&mac->rx->lock); - - start = mac->rx->next_to_clean; - count = 0; - - for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) { - struct pas_dma_xct_descr *dp; - struct pasemi_mac_buffer *info; - struct sk_buff *skb; - unsigned int j, len; - dma_addr_t dma; - - rmb(); - - dp = &RX_DESC(mac, i); - - if (!(dp->macrx & XCT_MACRX_O)) - break; - - count++; - - info = NULL; - - /* We have to scan for our skb since there's no way - * to back-map them from the descriptor, and if we - * have several receive channels then they might not - * show up in the same order as they were put on the - * interface ring. - */ - - dma = (dp->ptr & XCT_PTR_ADDR_M); - for (j = start; j < (start + RX_RING_SIZE); j++) { - info = &RX_DESC_INFO(mac, j); - if (info->dma == dma) - break; - } - - BUG_ON(!info); - BUG_ON(info->dma != dma); - - pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len, - PCI_DMA_FROMDEVICE); - - skb = info->skb; - - len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; - - skb_put(skb, len); - - skb->protocol = eth_type_trans(skb, mac->netdev); - - if ((dp->macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) { - skb->ip_summed = CHECKSUM_COMPLETE; - skb->csum = (dp->macrx & XCT_MACRX_CSUM_M) >> - XCT_MACRX_CSUM_S; - } else - skb->ip_summed = CHECKSUM_NONE; - - mac->stats.rx_bytes += len; - mac->stats.rx_packets++; - - netif_receive_skb(skb); - - info->dma = 0; - info->skb = NULL; - dp->ptr = 0; - dp->macrx = 0; - } - - mac->rx->next_to_clean += count; - pasemi_mac_replenish_rx_ring(mac->netdev); - - spin_unlock(&mac->rx->lock); - - return count; -} - -static int pasemi_mac_clean_tx(struct pasemi_mac *mac) -{ - int i; - struct pasemi_mac_buffer *info; - struct pas_dma_xct_descr *dp; - int start, count; - int flags; - - spin_lock_irqsave(&mac->tx->lock, flags); - - start = mac->tx->next_to_clean; - count = 0; - - for (i = start; i < mac->tx->next_to_use; i++) { - dp = &TX_DESC(mac, i); - if (!dp || (dp->mactx & XCT_MACTX_O)) - break; - - count++; - - info = &TX_DESC_INFO(mac, i); - - pci_unmap_single(mac->dma_pdev, info->dma, - info->skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb_irq(info->skb); - - info->skb = NULL; - info->dma = 0; - dp->mactx = 0; - dp->ptr = 0; - } - mac->tx->next_to_clean += count; - spin_unlock_irqrestore(&mac->tx->lock, flags); - - return count; -} - - -static irqreturn_t pasemi_mac_rx_intr(int irq, void *data) -{ - struct net_device *dev = data; - struct pasemi_mac *mac = netdev_priv(dev); - unsigned int reg; - - if (!(*mac->rx_status & PAS_STATUS_INT)) - return IRQ_NONE; - - netif_rx_schedule(dev); - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0)); - - reg = PAS_IOB_DMA_RXCH_RESET_PINTC | PAS_IOB_DMA_RXCH_RESET_SINTC | - PAS_IOB_DMA_RXCH_RESET_DINTC; - if (*mac->rx_status & PAS_STATUS_TIMER) - reg |= PAS_IOB_DMA_RXCH_RESET_TINTC; - - pci_write_config_dword(mac->iob_pdev, - PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg); - - - return IRQ_HANDLED; -} - -static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) -{ - struct net_device *dev = data; - struct pasemi_mac *mac = netdev_priv(dev); - unsigned int reg; - int was_full; - - was_full = mac->tx->next_to_clean - mac->tx->next_to_use == TX_RING_SIZE; - - if (!(*mac->tx_status & PAS_STATUS_INT)) - return IRQ_NONE; - - pasemi_mac_clean_tx(mac); - - reg = PAS_IOB_DMA_TXCH_RESET_PINTC | PAS_IOB_DMA_TXCH_RESET_SINTC; - if (*mac->tx_status & PAS_STATUS_TIMER) - reg |= PAS_IOB_DMA_TXCH_RESET_TINTC; - - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), - reg); - - if (was_full) - netif_wake_queue(dev); - - return IRQ_HANDLED; -} - -static int pasemi_mac_open(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - unsigned int flags; - int ret; - - /* enable rx section */ - pci_write_config_dword(mac->dma_pdev, PAS_DMA_COM_RXCMD, - PAS_DMA_COM_RXCMD_EN); - - /* enable tx section */ - pci_write_config_dword(mac->dma_pdev, PAS_DMA_COM_TXCMD, - PAS_DMA_COM_TXCMD_EN); - - flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) | - PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) | - PAS_MAC_CFG_TXP_TIFT(8) | PAS_MAC_CFG_TXP_TIFG(12); - - pci_write_config_dword(mac->pdev, PAS_MAC_CFG_TXP, flags); - - flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE | - PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE; - - flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G; - - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), - PAS_IOB_DMA_RXCH_CFG_CNTTH(30)); - - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000)); - - pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags); - - ret = pasemi_mac_setup_rx_resources(dev); - if (ret) - goto out_rx_resources; - - ret = pasemi_mac_setup_tx_resources(dev); - if (ret) - goto out_tx_resources; - - pci_write_config_dword(mac->pdev, PAS_MAC_IPC_CHNL, - PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) | - PAS_MAC_IPC_CHNL_BCH(mac->dma_rxch)); - - /* enable rx if */ - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_RCMDSTA(mac->dma_if), - PAS_DMA_RXINT_RCMDSTA_EN); - - /* enable rx channel */ - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), - PAS_DMA_RXCHAN_CCMDSTA_EN | - PAS_DMA_RXCHAN_CCMDSTA_DU); - - /* enable tx channel */ - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), - PAS_DMA_TXCHAN_TCMDSTA_EN); - - pasemi_mac_replenish_rx_ring(dev); - - netif_start_queue(dev); - netif_poll_enable(dev); - - ret = request_irq(mac->dma_pdev->irq + mac->dma_txch, - &pasemi_mac_tx_intr, IRQF_DISABLED, - mac->tx->irq_name, dev); - if (ret) { - dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", - mac->dma_pdev->irq + mac->dma_txch, ret); - goto out_tx_int; - } - - ret = request_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, - &pasemi_mac_rx_intr, IRQF_DISABLED, - mac->rx->irq_name, dev); - if (ret) { - dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", - mac->dma_pdev->irq + 20 + mac->dma_rxch, ret); - goto out_rx_int; - } - - return 0; - -out_rx_int: - free_irq(mac->dma_pdev->irq + mac->dma_txch, dev); -out_tx_int: - netif_poll_disable(dev); - netif_stop_queue(dev); - pasemi_mac_free_tx_resources(dev); -out_tx_resources: - pasemi_mac_free_rx_resources(dev); -out_rx_resources: - - return ret; -} - -#define MAX_RETRIES 5000 - -static int pasemi_mac_close(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - unsigned int stat; - int retries; - - netif_stop_queue(dev); - - /* Clean out any pending buffers */ - pasemi_mac_clean_tx(mac); - pasemi_mac_clean_rx(mac, RX_RING_SIZE); - - /* Disable interface */ - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), - PAS_DMA_TXCHAN_TCMDSTA_ST); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_RCMDSTA(mac->dma_if), - PAS_DMA_RXINT_RCMDSTA_ST); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), - PAS_DMA_RXCHAN_CCMDSTA_ST); - - for (retries = 0; retries < MAX_RETRIES; retries++) { - pci_read_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), - &stat); - if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT) - break; - cond_resched(); - } - - if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)) { - dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n"); - } - - for (retries = 0; retries < MAX_RETRIES; retries++) { - pci_read_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), - &stat); - if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT) - break; - cond_resched(); - } - - if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)) { - dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n"); - } - - for (retries = 0; retries < MAX_RETRIES; retries++) { - pci_read_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_RCMDSTA(mac->dma_if), - &stat); - if (stat & PAS_DMA_RXINT_RCMDSTA_ACT) - break; - cond_resched(); - } - - if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT)) { - dev_err(&mac->dma_pdev->dev, "Failed to stop rx interface\n"); - } - - /* Then, disable the channel. This must be done separately from - * stopping, since you can't disable when active. - */ - - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), 0); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0); - - free_irq(mac->dma_pdev->irq + mac->dma_txch, dev); - free_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, dev); - - /* Free resources */ - pasemi_mac_free_rx_resources(dev); - pasemi_mac_free_tx_resources(dev); - - return 0; -} - -static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - struct pasemi_mac_txring *txring; - struct pasemi_mac_buffer *info; - struct pas_dma_xct_descr *dp; - u64 dflags; - dma_addr_t map; - int flags; - - dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_SS | XCT_MACTX_CRC_PAD; - - if (skb->ip_summed == CHECKSUM_PARTIAL) { - switch (skb->nh.iph->protocol) { - case IPPROTO_TCP: - dflags |= XCT_MACTX_CSUM_TCP; - dflags |= XCT_MACTX_IPH((skb->h.raw - skb->nh.raw) >> 2); - dflags |= XCT_MACTX_IPO(skb->nh.raw - skb->data); - break; - case IPPROTO_UDP: - dflags |= XCT_MACTX_CSUM_UDP; - dflags |= XCT_MACTX_IPH((skb->h.raw - skb->nh.raw) >> 2); - dflags |= XCT_MACTX_IPO(skb->nh.raw - skb->data); - break; - } - } - - map = pci_map_single(mac->dma_pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - - if (dma_mapping_error(map)) - return NETDEV_TX_BUSY; - - txring = mac->tx; - - spin_lock_irqsave(&txring->lock, flags); - - if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) { - spin_unlock_irqrestore(&txring->lock, flags); - pasemi_mac_clean_tx(mac); - spin_lock_irqsave(&txring->lock, flags); - - if (txring->next_to_clean - txring->next_to_use == - TX_RING_SIZE) { - /* Still no room -- stop the queue and wait for tx - * intr when there's room. - */ - netif_stop_queue(dev); - goto out_err; - } - } - - - dp = &TX_DESC(mac, txring->next_to_use); - info = &TX_DESC_INFO(mac, txring->next_to_use); - - dp->mactx = dflags | XCT_MACTX_LLEN(skb->len); - dp->ptr = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map); - info->dma = map; - info->skb = skb; - - txring->next_to_use++; - mac->stats.tx_packets++; - mac->stats.tx_bytes += skb->len; - - spin_unlock_irqrestore(&txring->lock, flags); - - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_INCR(mac->dma_txch), 1); - - return NETDEV_TX_OK; - -out_err: - spin_unlock_irqrestore(&txring->lock, flags); - pci_unmap_single(mac->dma_pdev, map, skb->len, PCI_DMA_TODEVICE); - return NETDEV_TX_BUSY; -} - -static struct net_device_stats *pasemi_mac_get_stats(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - - return &mac->stats; -} - -static void pasemi_mac_set_rx_mode(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - unsigned int flags; - - pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags); - - /* Set promiscuous */ - if (dev->flags & IFF_PROMISC) - flags |= PAS_MAC_CFG_PCFG_PR; - else - flags &= ~PAS_MAC_CFG_PCFG_PR; - - pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags); -} - - -static int pasemi_mac_poll(struct net_device *dev, int *budget) -{ - int pkts, limit = min(*budget, dev->quota); - struct pasemi_mac *mac = netdev_priv(dev); - - pkts = pasemi_mac_clean_rx(mac, limit); - - if (pkts < limit) { - /* all done, no more packets present */ - netif_rx_complete(dev); - - /* re-enable receive interrupts */ - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000)); - return 0; - } else { - /* used up our quantum, so reschedule */ - dev->quota -= pkts; - *budget -= pkts; - return 1; - } -} - -static int __devinit -pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - static int index = 0; - struct net_device *dev; - struct pasemi_mac *mac; - int err; - - err = pci_enable_device(pdev); - if (err) - return err; - - dev = alloc_etherdev(sizeof(struct pasemi_mac)); - if (dev == NULL) { - dev_err(&pdev->dev, - "pasemi_mac: Could not allocate ethernet device.\n"); - err = -ENOMEM; - goto out_disable_device; - } - - SET_MODULE_OWNER(dev); - pci_set_drvdata(pdev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); - - mac = netdev_priv(dev); - - mac->pdev = pdev; - mac->netdev = dev; - mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); - - if (!mac->dma_pdev) { - dev_err(&pdev->dev, "Can't find DMA Controller\n"); - err = -ENODEV; - goto out_free_netdev; - } - - mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL); - - if (!mac->iob_pdev) { - dev_err(&pdev->dev, "Can't find I/O Bridge\n"); - err = -ENODEV; - goto out_put_dma_pdev; - } - - /* These should come out of the device tree eventually */ - mac->dma_txch = index; - mac->dma_rxch = index; - - /* We probe GMAC before XAUI, but the DMA interfaces are - * in XAUI, GMAC order. - */ - if (index < 4) - mac->dma_if = index + 2; - else - mac->dma_if = index - 4; - index++; - - switch (pdev->device) { - case 0xa005: - mac->type = MAC_TYPE_GMAC; - break; - case 0xa006: - mac->type = MAC_TYPE_XAUI; - break; - default: - err = -ENODEV; - goto out; - } - - /* get mac addr from device tree */ - if (pasemi_get_mac_addr(mac) || !is_valid_ether_addr(mac->mac_addr)) { - err = -ENODEV; - goto out; - } - memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr)); - - dev->open = pasemi_mac_open; - dev->stop = pasemi_mac_close; - dev->hard_start_xmit = pasemi_mac_start_tx; - dev->get_stats = pasemi_mac_get_stats; - dev->set_multicast_list = pasemi_mac_set_rx_mode; - dev->weight = 64; - dev->poll = pasemi_mac_poll; - dev->features = NETIF_F_HW_CSUM; - - /* The dma status structure is located in the I/O bridge, and - * is cache coherent. - */ - if (!dma_status) - /* XXXOJN This should come from the device tree */ - dma_status = __ioremap(0xfd800000, 0x1000, 0); - - mac->rx_status = &dma_status->rx_sta[mac->dma_rxch]; - mac->tx_status = &dma_status->tx_sta[mac->dma_txch]; - - err = register_netdev(dev); - - if (err) { - dev_err(&mac->pdev->dev, "register_netdev failed with error %d\n", - err); - goto out; - } else - printk(KERN_INFO "%s: PA Semi %s: intf %d, txch %d, rxch %d, " - "hw addr %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI", - mac->dma_if, mac->dma_txch, mac->dma_rxch, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - - return err; - -out: - pci_dev_put(mac->iob_pdev); -out_put_dma_pdev: - pci_dev_put(mac->dma_pdev); -out_free_netdev: - free_netdev(dev); -out_disable_device: - pci_disable_device(pdev); - return err; - -} - -static void __devexit pasemi_mac_remove(struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct pasemi_mac *mac; - - if (!netdev) - return; - - mac = netdev_priv(netdev); - - unregister_netdev(netdev); - - pci_disable_device(pdev); - pci_dev_put(mac->dma_pdev); - pci_dev_put(mac->iob_pdev); - - pci_set_drvdata(pdev, NULL); - free_netdev(netdev); -} - -static struct pci_device_id pasemi_mac_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) }, - { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) }, -}; - -MODULE_DEVICE_TABLE(pci, pasemi_mac_pci_tbl); - -static struct pci_driver pasemi_mac_driver = { - .name = "pasemi_mac", - .id_table = pasemi_mac_pci_tbl, - .probe = pasemi_mac_probe, - .remove = __devexit_p(pasemi_mac_remove), -}; - -static void __exit pasemi_mac_cleanup_module(void) -{ - pci_unregister_driver(&pasemi_mac_driver); - __iounmap(dma_status); - dma_status = NULL; -} - -int pasemi_mac_init_module(void) -{ - return pci_register_driver(&pasemi_mac_driver); -} - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR ("Olof Johansson "); -MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver"); - -module_init(pasemi_mac_init_module); -module_exit(pasemi_mac_cleanup_module); diff --git a/trunk/drivers/net/pasemi_mac.h b/trunk/drivers/net/pasemi_mac.h deleted file mode 100644 index c3e37e46a18a..000000000000 --- a/trunk/drivers/net/pasemi_mac.h +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (C) 2006 PA Semi, Inc - * - * Driver for the PA6T-1682M onchip 1G/10G Ethernet MACs, soft state and - * hardware register layouts. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PASEMI_MAC_H -#define PASEMI_MAC_H - -#include -#include -#include - -struct pasemi_mac_txring { - spinlock_t lock; - struct pas_dma_xct_descr *desc; - dma_addr_t dma; - unsigned int size; - unsigned int next_to_use; - unsigned int next_to_clean; - struct pasemi_mac_buffer *desc_info; - char irq_name[10]; /* "eth%d tx" */ -}; - -struct pasemi_mac_rxring { - spinlock_t lock; - struct pas_dma_xct_descr *desc; /* RX channel descriptor ring */ - dma_addr_t dma; - u64 *buffers; /* RX interface buffer ring */ - dma_addr_t buf_dma; - unsigned int size; - unsigned int next_to_fill; - unsigned int next_to_clean; - struct pasemi_mac_buffer *desc_info; - char irq_name[10]; /* "eth%d rx" */ -}; - -struct pasemi_mac { - struct net_device *netdev; - struct pci_dev *pdev; - struct pci_dev *dma_pdev; - struct pci_dev *iob_pdev; - struct net_device_stats stats; - - /* Pointer to the cacheable per-channel status registers */ - u64 *rx_status; - u64 *tx_status; - - u8 type; -#define MAC_TYPE_GMAC 1 -#define MAC_TYPE_XAUI 2 - u32 dma_txch; - u32 dma_if; - u32 dma_rxch; - - u8 mac_addr[6]; - - struct timer_list rxtimer; - - struct pasemi_mac_txring *tx; - struct pasemi_mac_rxring *rx; -}; - -/* Software status descriptor (desc_info) */ -struct pasemi_mac_buffer { - struct sk_buff *skb; - dma_addr_t dma; -}; - - -/* status register layout in IOB region, at 0xfb800000 */ -struct pasdma_status { - u64 rx_sta[64]; - u64 tx_sta[20]; -}; - -/* descriptor structure */ -struct pas_dma_xct_descr { - union { - u64 mactx; - u64 macrx; - }; - union { - u64 ptr; - u64 rxb; - }; -}; - -/* MAC CFG register offsets */ - -enum { - PAS_MAC_CFG_PCFG = 0x80, - PAS_MAC_CFG_TXP = 0x98, - PAS_MAC_IPC_CHNL = 0x208, -}; - -/* MAC CFG register fields */ -#define PAS_MAC_CFG_PCFG_PE 0x80000000 -#define PAS_MAC_CFG_PCFG_CE 0x40000000 -#define PAS_MAC_CFG_PCFG_BU 0x20000000 -#define PAS_MAC_CFG_PCFG_TT 0x10000000 -#define PAS_MAC_CFG_PCFG_TSR_M 0x0c000000 -#define PAS_MAC_CFG_PCFG_TSR_10M 0x00000000 -#define PAS_MAC_CFG_PCFG_TSR_100M 0x04000000 -#define PAS_MAC_CFG_PCFG_TSR_1G 0x08000000 -#define PAS_MAC_CFG_PCFG_TSR_10G 0x0c000000 -#define PAS_MAC_CFG_PCFG_T24 0x02000000 -#define PAS_MAC_CFG_PCFG_PR 0x01000000 -#define PAS_MAC_CFG_PCFG_CRO_M 0x00ff0000 -#define PAS_MAC_CFG_PCFG_CRO_S 16 -#define PAS_MAC_CFG_PCFG_IPO_M 0x0000ff00 -#define PAS_MAC_CFG_PCFG_IPO_S 8 -#define PAS_MAC_CFG_PCFG_S1 0x00000080 -#define PAS_MAC_CFG_PCFG_IO_M 0x00000060 -#define PAS_MAC_CFG_PCFG_IO_MAC 0x00000000 -#define PAS_MAC_CFG_PCFG_IO_OFF 0x00000020 -#define PAS_MAC_CFG_PCFG_IO_IND_ETH 0x00000040 -#define PAS_MAC_CFG_PCFG_IO_IND_IP 0x00000060 -#define PAS_MAC_CFG_PCFG_LP 0x00000010 -#define PAS_MAC_CFG_PCFG_TS 0x00000008 -#define PAS_MAC_CFG_PCFG_HD 0x00000004 -#define PAS_MAC_CFG_PCFG_SPD_M 0x00000003 -#define PAS_MAC_CFG_PCFG_SPD_10M 0x00000000 -#define PAS_MAC_CFG_PCFG_SPD_100M 0x00000001 -#define PAS_MAC_CFG_PCFG_SPD_1G 0x00000002 -#define PAS_MAC_CFG_PCFG_SPD_10G 0x00000003 -#define PAS_MAC_CFG_TXP_FCF 0x01000000 -#define PAS_MAC_CFG_TXP_FCE 0x00800000 -#define PAS_MAC_CFG_TXP_FC 0x00400000 -#define PAS_MAC_CFG_TXP_FPC_M 0x00300000 -#define PAS_MAC_CFG_TXP_FPC_S 20 -#define PAS_MAC_CFG_TXP_FPC(x) (((x) << PAS_MAC_CFG_TXP_FPC_S) & \ - PAS_MAC_CFG_TXP_FPC_M) -#define PAS_MAC_CFG_TXP_RT 0x00080000 -#define PAS_MAC_CFG_TXP_BL 0x00040000 -#define PAS_MAC_CFG_TXP_SL_M 0x00030000 -#define PAS_MAC_CFG_TXP_SL_S 16 -#define PAS_MAC_CFG_TXP_SL(x) (((x) << PAS_MAC_CFG_TXP_SL_S) & \ - PAS_MAC_CFG_TXP_SL_M) -#define PAS_MAC_CFG_TXP_COB_M 0x0000f000 -#define PAS_MAC_CFG_TXP_COB_S 12 -#define PAS_MAC_CFG_TXP_COB(x) (((x) << PAS_MAC_CFG_TXP_COB_S) & \ - PAS_MAC_CFG_TXP_COB_M) -#define PAS_MAC_CFG_TXP_TIFT_M 0x00000f00 -#define PAS_MAC_CFG_TXP_TIFT_S 8 -#define PAS_MAC_CFG_TXP_TIFT(x) (((x) << PAS_MAC_CFG_TXP_TIFT_S) & \ - PAS_MAC_CFG_TXP_TIFT_M) -#define PAS_MAC_CFG_TXP_TIFG_M 0x000000ff -#define PAS_MAC_CFG_TXP_TIFG_S 0 -#define PAS_MAC_CFG_TXP_TIFG(x) (((x) << PAS_MAC_CFG_TXP_TIFG_S) & \ - PAS_MAC_CFG_TXP_TIFG_M) - -#define PAS_MAC_IPC_CHNL_DCHNO_M 0x003f0000 -#define PAS_MAC_IPC_CHNL_DCHNO_S 16 -#define PAS_MAC_IPC_CHNL_DCHNO(x) (((x) << PAS_MAC_IPC_CHNL_DCHNO_S) & \ - PAS_MAC_IPC_CHNL_DCHNO_M) -#define PAS_MAC_IPC_CHNL_BCH_M 0x0000003f -#define PAS_MAC_IPC_CHNL_BCH_S 0 -#define PAS_MAC_IPC_CHNL_BCH(x) (((x) << PAS_MAC_IPC_CHNL_BCH_S) & \ - PAS_MAC_IPC_CHNL_BCH_M) - -/* All these registers live in the PCI configuration space for the DMA PCI - * device. Use the normal PCI config access functions for them. - */ -enum { - PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */ - PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */ - PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */ - PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */ -}; -#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */ -#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */ -#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */ -#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */ - - -/* Per-interface and per-channel registers */ -#define _PAS_DMA_RXINT_STRIDE 0x20 -#define PAS_DMA_RXINT_RCMDSTA(i) (0x200+(i)*_PAS_DMA_RXINT_STRIDE) -#define PAS_DMA_RXINT_RCMDSTA_EN 0x00000001 -#define PAS_DMA_RXINT_RCMDSTA_ST 0x00000002 -#define PAS_DMA_RXINT_RCMDSTA_OO 0x00000100 -#define PAS_DMA_RXINT_RCMDSTA_BP 0x00000200 -#define PAS_DMA_RXINT_RCMDSTA_DR 0x00000400 -#define PAS_DMA_RXINT_RCMDSTA_BT 0x00000800 -#define PAS_DMA_RXINT_RCMDSTA_TB 0x00001000 -#define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000 -#define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000 -#define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17 -#define PAS_DMA_RXINT_INCR(i) (0x210+(i)*_PAS_DMA_RXINT_STRIDE) -#define PAS_DMA_RXINT_INCR_INCR_M 0x0000ffff -#define PAS_DMA_RXINT_INCR_INCR_S 0 -#define PAS_DMA_RXINT_INCR_INCR(x) ((x) & 0x0000ffff) -#define PAS_DMA_RXINT_BASEL(i) (0x218+(i)*_PAS_DMA_RXINT_STRIDE) -#define PAS_DMA_RXINT_BASEL_BRBL(x) ((x) & ~0x3f) -#define PAS_DMA_RXINT_BASEU(i) (0x21c+(i)*_PAS_DMA_RXINT_STRIDE) -#define PAS_DMA_RXINT_BASEU_BRBH(x) ((x) & 0xfff) -#define PAS_DMA_RXINT_BASEU_SIZ_M 0x3fff0000 /* # of cache lines worth of buffer ring */ -#define PAS_DMA_RXINT_BASEU_SIZ_S 16 /* 0 = 16K */ -#define PAS_DMA_RXINT_BASEU_SIZ(x) (((x) << PAS_DMA_RXINT_BASEU_SIZ_S) & \ - PAS_DMA_RXINT_BASEU_SIZ_M) - - -#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */ -#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */ -#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */ -#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */ -#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */ -#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */ -#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */ -#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */ -#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */ -#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */ -#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */ -#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */ -#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c -#define PAS_DMA_TXCHAN_CFG_TATTR_S 2 -#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \ - PAS_DMA_TXCHAN_CFG_TATTR_M) -#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0 -#define PAS_DMA_TXCHAN_CFG_WT_S 6 -#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \ - PAS_DMA_TXCHAN_CFG_WT_M) -#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */ -#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */ -#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */ -#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0 -#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0 -#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \ - PAS_DMA_TXCHAN_BASEL_BRBL_M) -#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff -#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0 -#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \ - PAS_DMA_TXCHAN_BASEU_BRBH_M) -/* # of cache lines worth of buffer ring */ -#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000 -#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */ -#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \ - PAS_DMA_TXCHAN_BASEU_SIZ_M) - -#define _PAS_DMA_RXCHAN_STRIDE 0x20 /* Size per channel */ -#define _PAS_DMA_RXCHAN_CCMDSTA 0x800 /* Command / Status */ -#define _PAS_DMA_RXCHAN_CFG 0x804 /* Configuration */ -#define _PAS_DMA_RXCHAN_INCR 0x810 /* Descriptor increment */ -#define _PAS_DMA_RXCHAN_CNT 0x814 /* Descriptor count/offset */ -#define _PAS_DMA_RXCHAN_BASEL 0x818 /* Descriptor ring base (low) */ -#define _PAS_DMA_RXCHAN_BASEU 0x81c /* (high) */ -#define PAS_DMA_RXCHAN_CCMDSTA(c) (0x800+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_CCMDSTA_EN 0x00000001 /* Enabled */ -#define PAS_DMA_RXCHAN_CCMDSTA_ST 0x00000002 /* Stop interface */ -#define PAS_DMA_RXCHAN_CCMDSTA_ACT 0x00010000 /* Active */ -#define PAS_DMA_RXCHAN_CCMDSTA_DU 0x00020000 -#define PAS_DMA_RXCHAN_CFG(c) (0x804+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_CFG_HBU_M 0x00000380 -#define PAS_DMA_RXCHAN_CFG_HBU_S 7 -#define PAS_DMA_RXCHAN_CFG_HBU(x) (((x) << PAS_DMA_RXCHAN_CFG_HBU_S) & \ - PAS_DMA_RXCHAN_CFG_HBU_M) -#define PAS_DMA_RXCHAN_INCR(c) (0x810+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_BASEL(c) (0x818+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_BASEL_BRBL_M 0xffffffc0 -#define PAS_DMA_RXCHAN_BASEL_BRBL_S 0 -#define PAS_DMA_RXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_RXCHAN_BASEL_BRBL_S) & \ - PAS_DMA_RXCHAN_BASEL_BRBL_M) -#define PAS_DMA_RXCHAN_BASEU(c) (0x81c+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_BASEU_BRBH_M 0x00000fff -#define PAS_DMA_RXCHAN_BASEU_BRBH_S 0 -#define PAS_DMA_RXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_RXCHAN_BASEU_BRBH_S) & \ - PAS_DMA_RXCHAN_BASEU_BRBH_M) -/* # of cache lines worth of buffer ring */ -#define PAS_DMA_RXCHAN_BASEU_SIZ_M 0x3fff0000 -#define PAS_DMA_RXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */ -#define PAS_DMA_RXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_RXCHAN_BASEU_SIZ_S) & \ - PAS_DMA_RXCHAN_BASEU_SIZ_M) - -#define PAS_STATUS_PCNT_M 0x000000000000ffffull -#define PAS_STATUS_PCNT_S 0 -#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull -#define PAS_STATUS_DCNT_S 16 -#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull -#define PAS_STATUS_BPCNT_S 32 -#define PAS_STATUS_TIMER 0x1000000000000000ull -#define PAS_STATUS_ERROR 0x2000000000000000ull -#define PAS_STATUS_SOFT 0x4000000000000000ull -#define PAS_STATUS_INT 0x8000000000000000ull - -#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4) -#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff -#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0 -#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \ - PAS_IOB_DMA_RXCH_CFG_CNTTH_M) -#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4) -#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff -#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0 -#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \ - PAS_IOB_DMA_TXCH_CFG_CNTTH_M) -#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4) -#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000 -#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff -#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0 -#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\ - PAS_IOB_DMA_RXCH_STAT_CNTDEL_M) -#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4) -#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000 -#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff -#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0 -#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\ - PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) -#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4) -#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000 -#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 0 -#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \ - PAS_IOB_DMA_RXCH_RESET_PCNT_M) -#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020 -#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010 -#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008 -#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004 -#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002 -#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001 -#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4) -#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000 -#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 0 -#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \ - PAS_IOB_DMA_TXCH_RESET_PCNT_M) -#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020 -#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010 -#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008 -#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004 -#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002 -#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001 - -#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700 -#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff -#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0 -#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \ - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M) - -/* Transmit descriptor fields */ -#define XCT_MACTX_T 0x8000000000000000ull -#define XCT_MACTX_ST 0x4000000000000000ull -#define XCT_MACTX_NORES 0x0000000000000000ull -#define XCT_MACTX_8BRES 0x1000000000000000ull -#define XCT_MACTX_24BRES 0x2000000000000000ull -#define XCT_MACTX_40BRES 0x3000000000000000ull -#define XCT_MACTX_I 0x0800000000000000ull -#define XCT_MACTX_O 0x0400000000000000ull -#define XCT_MACTX_E 0x0200000000000000ull -#define XCT_MACTX_VLAN_M 0x0180000000000000ull -#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull -#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull -#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull -#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull -#define XCT_MACTX_CRC_M 0x0060000000000000ull -#define XCT_MACTX_CRC_NOP 0x0000000000000000ull -#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull -#define XCT_MACTX_CRC_PAD 0x0040000000000000ull -#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull -#define XCT_MACTX_SS 0x0010000000000000ull -#define XCT_MACTX_LLEN_M 0x00007fff00000000ull -#define XCT_MACTX_LLEN_S 32ull -#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \ - XCT_MACTX_LLEN_M) -#define XCT_MACTX_IPH_M 0x00000000f8000000ull -#define XCT_MACTX_IPH_S 27ull -#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \ - XCT_MACTX_IPH_M) -#define XCT_MACTX_IPO_M 0x0000000007c00000ull -#define XCT_MACTX_IPO_S 22ull -#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \ - XCT_MACTX_IPO_M) -#define XCT_MACTX_CSUM_M 0x0000000000000060ull -#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull -#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull -#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull -#define XCT_MACTX_V6 0x0000000000000010ull -#define XCT_MACTX_C 0x0000000000000004ull -#define XCT_MACTX_AL2 0x0000000000000002ull - -/* Receive descriptor fields */ -#define XCT_MACRX_T 0x8000000000000000ull -#define XCT_MACRX_ST 0x4000000000000000ull -#define XCT_MACRX_NORES 0x0000000000000000ull -#define XCT_MACRX_8BRES 0x1000000000000000ull -#define XCT_MACRX_24BRES 0x2000000000000000ull -#define XCT_MACRX_40BRES 0x3000000000000000ull -#define XCT_MACRX_O 0x0400000000000000ull -#define XCT_MACRX_E 0x0200000000000000ull -#define XCT_MACRX_FF 0x0100000000000000ull -#define XCT_MACRX_PF 0x0080000000000000ull -#define XCT_MACRX_OB 0x0040000000000000ull -#define XCT_MACRX_OD 0x0020000000000000ull -#define XCT_MACRX_FS 0x0010000000000000ull -#define XCT_MACRX_NB_M 0x000fc00000000000ull -#define XCT_MACRX_NB_S 46ULL -#define XCT_MACRX_NB(x) ((((long)(x)) << XCT_MACRX_NB_S) & \ - XCT_MACRX_NB_M) -#define XCT_MACRX_LLEN_M 0x00003fff00000000ull -#define XCT_MACRX_LLEN_S 32ULL -#define XCT_MACRX_LLEN(x) ((((long)(x)) << XCT_MACRX_LLEN_S) & \ - XCT_MACRX_LLEN_M) -#define XCT_MACRX_CRC 0x0000000080000000ull -#define XCT_MACRX_LEN_M 0x0000000060000000ull -#define XCT_MACRX_LEN_TOOSHORT 0x0000000020000000ull -#define XCT_MACRX_LEN_BELOWMIN 0x0000000040000000ull -#define XCT_MACRX_LEN_TRUNC 0x0000000060000000ull -#define XCT_MACRX_CAST_M 0x0000000018000000ull -#define XCT_MACRX_CAST_UNI 0x0000000000000000ull -#define XCT_MACRX_CAST_MULTI 0x0000000008000000ull -#define XCT_MACRX_CAST_BROAD 0x0000000010000000ull -#define XCT_MACRX_CAST_PAUSE 0x0000000018000000ull -#define XCT_MACRX_VLC_M 0x0000000006000000ull -#define XCT_MACRX_FM 0x0000000001000000ull -#define XCT_MACRX_HTY_M 0x0000000000c00000ull -#define XCT_MACRX_HTY_IPV4_OK 0x0000000000000000ull -#define XCT_MACRX_HTY_IPV6 0x0000000000400000ull -#define XCT_MACRX_HTY_IPV4_BAD 0x0000000000800000ull -#define XCT_MACRX_HTY_NONIP 0x0000000000c00000ull -#define XCT_MACRX_IPP_M 0x00000000003f0000ull -#define XCT_MACRX_IPP_S 16 -#define XCT_MACRX_CSUM_M 0x000000000000ffffull -#define XCT_MACRX_CSUM_S 0 - -#define XCT_PTR_T 0x8000000000000000ull -#define XCT_PTR_LEN_M 0x7ffff00000000000ull -#define XCT_PTR_LEN_S 44 -#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \ - XCT_PTR_LEN_M) -#define XCT_PTR_ADDR_M 0x00000fffffffffffull -#define XCT_PTR_ADDR_S 0 -#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \ - XCT_PTR_ADDR_M) - -/* Receive interface buffer fields */ -#define XCT_RXB_LEN_M 0x0ffff00000000000ull -#define XCT_RXB_LEN_S 44 -#define XCT_RXB_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & XCT_PTR_LEN_M) -#define XCT_RXB_ADDR_M 0x00000fffffffffffull -#define XCT_RXB_ADDR_S 0 -#define XCT_RXB_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & XCT_PTR_ADDR_M) - - -#endif /* PASEMI_MAC_H */ diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c old mode 100755 new mode 100644 index 2429b274f0b0..8844c20eac2d --- a/trunk/drivers/net/qla3xxx.c +++ b/trunk/drivers/net/qla3xxx.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -64,7 +63,6 @@ MODULE_PARM_DESC(msi, "Turn on Message Signaled Interrupts."); static struct pci_device_id ql3xxx_pci_tbl[] __devinitdata = { {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QL3022_DEVICE_ID)}, - {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QL3032_DEVICE_ID)}, /* required last entry */ {0,} }; @@ -1477,10 +1475,6 @@ static int ql_mii_setup(struct ql3_adapter *qdev) 2) << 7)) return -1; - if (qdev->device_id == QL3032_DEVICE_ID) - ql_write_page0_reg(qdev, - &port_regs->macMIIMgmtControlReg, 0x0f00000); - /* Divide 125MHz clock by 28 to meet PHY timing requirements */ reg = MAC_MII_CONTROL_CLK_SEL_DIV28; @@ -1712,42 +1706,18 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, struct ob_mac_iocb_rsp *mac_rsp) { struct ql_tx_buf_cb *tx_cb; - int i; tx_cb = &qdev->tx_buf[mac_rsp->transaction_id]; pci_unmap_single(qdev->pdev, - pci_unmap_addr(&tx_cb->map[0], mapaddr), - pci_unmap_len(&tx_cb->map[0], maplen), - PCI_DMA_TODEVICE); - tx_cb->seg_count--; - if (tx_cb->seg_count) { - for (i = 1; i < tx_cb->seg_count; i++) { - pci_unmap_page(qdev->pdev, - pci_unmap_addr(&tx_cb->map[i], - mapaddr), - pci_unmap_len(&tx_cb->map[i], maplen), - PCI_DMA_TODEVICE); - } - } + pci_unmap_addr(tx_cb, mapaddr), + pci_unmap_len(tx_cb, maplen), PCI_DMA_TODEVICE); + dev_kfree_skb_irq(tx_cb->skb); qdev->stats.tx_packets++; qdev->stats.tx_bytes += tx_cb->skb->len; - dev_kfree_skb_irq(tx_cb->skb); tx_cb->skb = NULL; atomic_inc(&qdev->tx_count); } -/* - * The difference between 3022 and 3032 for inbound completions: - * 3022 uses two buffers per completion. The first buffer contains - * (some) header info, the second the remainder of the headers plus - * the data. For this chip we reserve some space at the top of the - * receive buffer so that the header info in buffer one can be - * prepended to the buffer two. Buffer two is the sent up while - * buffer one is returned to the hardware to be reused. - * 3032 receives all of it's data and headers in one buffer for a - * simpler process. 3032 also supports checksum verification as - * can be seen in ql_process_macip_rx_intr(). - */ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp_ptr) { @@ -1770,17 +1740,14 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, qdev->last_rsp_offset = qdev->small_buf_phy_addr_low + offset; qdev->small_buf_release_cnt++; - if (qdev->device_id == QL3022_DEVICE_ID) { - /* start of first buffer (3022 only) */ - lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); - lrg_buf_cb1 = &qdev->lrg_buf[qdev->lrg_buf_index]; - qdev->lrg_buf_release_cnt++; - if (++qdev->lrg_buf_index == NUM_LARGE_BUFFERS) { - qdev->lrg_buf_index = 0; - } - curr_ial_ptr++; /* 64-bit pointers require two incs. */ - curr_ial_ptr++; - } + /* start of first buffer */ + lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); + lrg_buf_cb1 = &qdev->lrg_buf[qdev->lrg_buf_index]; + qdev->lrg_buf_release_cnt++; + if (++qdev->lrg_buf_index == NUM_LARGE_BUFFERS) + qdev->lrg_buf_index = 0; + curr_ial_ptr++; /* 64-bit pointers require two incs. */ + curr_ial_ptr++; /* start of second buffer */ lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); @@ -1811,8 +1778,7 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, qdev->ndev->last_rx = jiffies; lrg_buf_cb2->skb = NULL; - if (qdev->device_id == QL3022_DEVICE_ID) - ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb1); + ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb1); ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb2); } @@ -1824,7 +1790,7 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, struct ql_rcv_buf_cb *lrg_buf_cb1 = NULL; struct ql_rcv_buf_cb *lrg_buf_cb2 = NULL; u32 *curr_ial_ptr; - struct sk_buff *skb1 = NULL, *skb2; + struct sk_buff *skb1, *skb2; struct net_device *ndev = qdev->ndev; u16 length = le16_to_cpu(ib_ip_rsp_ptr->length); u16 size = 0; @@ -1840,20 +1806,16 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, qdev->last_rsp_offset = qdev->small_buf_phy_addr_low + offset; qdev->small_buf_release_cnt++; - if (qdev->device_id == QL3022_DEVICE_ID) { - /* start of first buffer on 3022 */ - lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); - lrg_buf_cb1 = &qdev->lrg_buf[qdev->lrg_buf_index]; - qdev->lrg_buf_release_cnt++; - if (++qdev->lrg_buf_index == NUM_LARGE_BUFFERS) - qdev->lrg_buf_index = 0; - skb1 = lrg_buf_cb1->skb; - curr_ial_ptr++; /* 64-bit pointers require two incs. */ - curr_ial_ptr++; - size = ETH_HLEN; - if (*((u16 *) skb1->data) != 0xFFFF) - size += VLAN_ETH_HLEN - ETH_HLEN; - } + /* start of first buffer */ + lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); + lrg_buf_cb1 = &qdev->lrg_buf[qdev->lrg_buf_index]; + + qdev->lrg_buf_release_cnt++; + if (++qdev->lrg_buf_index == NUM_LARGE_BUFFERS) + qdev->lrg_buf_index = 0; + skb1 = lrg_buf_cb1->skb; + curr_ial_ptr++; /* 64-bit pointers require two incs. */ + curr_ial_ptr++; /* start of second buffer */ lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); @@ -1863,6 +1825,18 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, if (++qdev->lrg_buf_index == NUM_LARGE_BUFFERS) qdev->lrg_buf_index = 0; + qdev->stats.rx_packets++; + qdev->stats.rx_bytes += length; + + /* + * Copy the ethhdr from first buffer to second. This + * is necessary for IP completions. + */ + if (*((u16 *) skb1->data) != 0xFFFF) + size = VLAN_ETH_HLEN; + else + size = ETH_HLEN; + skb_put(skb2, length); /* Just the second buffer length here. */ pci_unmap_single(qdev->pdev, pci_unmap_addr(lrg_buf_cb2, mapaddr), @@ -1870,40 +1844,16 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, PCI_DMA_FROMDEVICE); prefetch(skb2->data); - skb2->ip_summed = CHECKSUM_NONE; - if (qdev->device_id == QL3022_DEVICE_ID) { - /* - * Copy the ethhdr from first buffer to second. This - * is necessary for 3022 IP completions. - */ - memcpy(skb_push(skb2, size), skb1->data + VLAN_ID_LEN, size); - } else { - u16 checksum = le16_to_cpu(ib_ip_rsp_ptr->checksum); - if (checksum & - (IB_IP_IOCB_RSP_3032_ICE | - IB_IP_IOCB_RSP_3032_CE | - IB_IP_IOCB_RSP_3032_NUC)) { - printk(KERN_ERR - "%s: Bad checksum for this %s packet, checksum = %x.\n", - __func__, - ((checksum & - IB_IP_IOCB_RSP_3032_TCP) ? "TCP" : - "UDP"),checksum); - } else if (checksum & IB_IP_IOCB_RSP_3032_TCP) { - skb2->ip_summed = CHECKSUM_UNNECESSARY; - } - } + memcpy(skb_push(skb2, size), skb1->data + VLAN_ID_LEN, size); skb2->dev = qdev->ndev; + skb2->ip_summed = CHECKSUM_NONE; skb2->protocol = eth_type_trans(skb2, qdev->ndev); netif_receive_skb(skb2); - qdev->stats.rx_packets++; - qdev->stats.rx_bytes += length; ndev->last_rx = jiffies; lrg_buf_cb2->skb = NULL; - if (qdev->device_id == QL3022_DEVICE_ID) - ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb1); + ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb1); ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb2); } @@ -1930,14 +1880,12 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev, break; case OPCODE_IB_MAC_IOCB: - case OPCODE_IB_3032_MAC_IOCB: ql_process_mac_rx_intr(qdev, (struct ib_mac_iocb_rsp *) net_rsp); (*rx_cleaned)++; break; case OPCODE_IB_IP_IOCB: - case OPCODE_IB_3032_IP_IOCB: ql_process_macip_rx_intr(qdev, (struct ib_ip_iocb_rsp *) net_rsp); (*rx_cleaned)++; @@ -2084,96 +2032,13 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id) return IRQ_RETVAL(handled); } -/* - * Get the total number of segments needed for the - * given number of fragments. This is necessary because - * outbound address lists (OAL) will be used when more than - * two frags are given. Each address list has 5 addr/len - * pairs. The 5th pair in each AOL is used to point to - * the next AOL if more frags are coming. - * That is why the frags:segment count ratio is not linear. - */ -static int ql_get_seg_count(unsigned short frags) -{ - switch(frags) { - case 0: return 1; /* just the skb->data seg */ - case 1: return 2; /* skb->data + 1 frag */ - case 2: return 3; /* skb->data + 2 frags */ - case 3: return 5; /* skb->data + 1 frag + 1 AOL containting 2 frags */ - case 4: return 6; - case 5: return 7; - case 6: return 8; - case 7: return 10; - case 8: return 11; - case 9: return 12; - case 10: return 13; - case 11: return 15; - case 12: return 16; - case 13: return 17; - case 14: return 18; - case 15: return 20; - case 16: return 21; - case 17: return 22; - case 18: return 23; - } - return -1; -} - -static void ql_hw_csum_setup(struct sk_buff *skb, - struct ob_mac_iocb_req *mac_iocb_ptr) -{ - struct ethhdr *eth; - struct iphdr *ip = NULL; - u8 offset = ETH_HLEN; - - eth = (struct ethhdr *)(skb->data); - - if (eth->h_proto == __constant_htons(ETH_P_IP)) { - ip = (struct iphdr *)&skb->data[ETH_HLEN]; - } else if (eth->h_proto == htons(ETH_P_8021Q) && - ((struct vlan_ethhdr *)skb->data)-> - h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP)) { - ip = (struct iphdr *)&skb->data[VLAN_ETH_HLEN]; - offset = VLAN_ETH_HLEN; - } - - if (ip) { - if (ip->protocol == IPPROTO_TCP) { - mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_TC; - mac_iocb_ptr->ip_hdr_off = offset; - mac_iocb_ptr->ip_hdr_len = ip->ihl; - } else if (ip->protocol == IPPROTO_UDP) { - mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_UC; - mac_iocb_ptr->ip_hdr_off = offset; - mac_iocb_ptr->ip_hdr_len = ip->ihl; - } - } -} - -/* - * The difference between 3022 and 3032 sends: - * 3022 only supports a simple single segment transmission. - * 3032 supports checksumming and scatter/gather lists (fragments). - * The 3032 supports sglists by using the 3 addr/len pairs (ALP) - * in the IOCB plus a chain of outbound address lists (OAL) that - * each contain 5 ALPs. The last ALP of the IOCB (3rd) or OAL (5th) - * will used to point to an OAL when more ALP entries are required. - * The IOCB is always the top of the chain followed by one or more - * OALs (when necessary). - */ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) { struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; struct ql_tx_buf_cb *tx_cb; - u32 tot_len = skb->len; - struct oal *oal; - struct oal_entry *oal_entry; - int len; struct ob_mac_iocb_req *mac_iocb_ptr; u64 map; - int seg_cnt, seg = 0; - int frag_cnt = (int)skb_shinfo(skb)->nr_frags; if (unlikely(atomic_read(&qdev->tx_count) < 2)) { if (!netif_queue_stopped(ndev)) @@ -2181,79 +2046,21 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_BUSY; } tx_cb = &qdev->tx_buf[qdev->req_producer_index] ; - seg_cnt = tx_cb->seg_count = ql_get_seg_count((skb_shinfo(skb)->nr_frags)); - if(seg_cnt == -1) { - printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__); - return NETDEV_TX_OK; - - } mac_iocb_ptr = tx_cb->queue_entry; memset((void *)mac_iocb_ptr, 0, sizeof(struct ob_mac_iocb_req)); mac_iocb_ptr->opcode = qdev->mac_ob_opcode; mac_iocb_ptr->flags |= qdev->mb_bit_mask; mac_iocb_ptr->transaction_id = qdev->req_producer_index; - mac_iocb_ptr->data_len = cpu_to_le16((u16) tot_len); + mac_iocb_ptr->data_len = cpu_to_le16((u16) skb->len); tx_cb->skb = skb; - if (skb->ip_summed == CHECKSUM_PARTIAL) - ql_hw_csum_setup(skb, mac_iocb_ptr); - len = skb_headlen(skb); - map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); - oal_entry = (struct oal_entry *)&mac_iocb_ptr->buf_addr0_low; - oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); - oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); - oal_entry->len = cpu_to_le32(len); - pci_unmap_addr_set(&tx_cb->map[seg], mapaddr, map); - pci_unmap_len_set(&tx_cb->map[seg], maplen, len); - seg++; - - if (!skb_shinfo(skb)->nr_frags) { - /* Terminate the last segment. */ - oal_entry->len = - cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY); - } else { - int i; - oal = tx_cb->oal; - for (i=0; ifrags[i]; - oal_entry++; - if ((seg == 2 && seg_cnt > 3) || /* Check for continuation */ - (seg == 7 && seg_cnt > 8) || /* requirements. It's strange */ - (seg == 12 && seg_cnt > 13) || /* but necessary. */ - (seg == 17 && seg_cnt > 18)) { - /* Continuation entry points to outbound address list. */ - map = pci_map_single(qdev->pdev, oal, - sizeof(struct oal), - PCI_DMA_TODEVICE); - oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); - oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); - oal_entry->len = - cpu_to_le32(sizeof(struct oal) | - OAL_CONT_ENTRY); - pci_unmap_addr_set(&tx_cb->map[seg], mapaddr, - map); - pci_unmap_len_set(&tx_cb->map[seg], maplen, - len); - oal_entry = (struct oal_entry *)oal; - oal++; - seg++; - } + map = pci_map_single(qdev->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + mac_iocb_ptr->buf_addr0_low = cpu_to_le32(LS_64BITS(map)); + mac_iocb_ptr->buf_addr0_high = cpu_to_le32(MS_64BITS(map)); + mac_iocb_ptr->buf_0_len = cpu_to_le32(skb->len | OB_MAC_IOCB_REQ_E); + pci_unmap_addr_set(tx_cb, mapaddr, map); + pci_unmap_len_set(tx_cb, maplen, skb->len); + atomic_dec(&qdev->tx_count); - map = - pci_map_page(qdev->pdev, frag->page, - frag->page_offset, frag->size, - PCI_DMA_TODEVICE); - oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); - oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); - oal_entry->len = cpu_to_le32(frag->size); - pci_unmap_addr_set(&tx_cb->map[seg], mapaddr, map); - pci_unmap_len_set(&tx_cb->map[seg], maplen, - frag->size); - } - /* Terminate the last segment. */ - oal_entry->len = - cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY); - } - wmb(); qdev->req_producer_index++; if (qdev->req_producer_index == NUM_REQ_Q_ENTRIES) qdev->req_producer_index = 0; @@ -2267,10 +2074,8 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) printk(KERN_DEBUG PFX "%s: tx queued, slot %d, len %d\n", ndev->name, qdev->req_producer_index, skb->len); - atomic_dec(&qdev->tx_count); return NETDEV_TX_OK; } - static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) { qdev->req_q_size = @@ -2554,22 +2359,7 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev) return 0; } -static void ql_free_send_free_list(struct ql3_adapter *qdev) -{ - struct ql_tx_buf_cb *tx_cb; - int i; - - tx_cb = &qdev->tx_buf[0]; - for (i = 0; i < NUM_REQ_Q_ENTRIES; i++) { - if (tx_cb->oal) { - kfree(tx_cb->oal); - tx_cb->oal = NULL; - } - tx_cb++; - } -} - -static int ql_create_send_free_list(struct ql3_adapter *qdev) +static void ql_create_send_free_list(struct ql3_adapter *qdev) { struct ql_tx_buf_cb *tx_cb; int i; @@ -2578,16 +2368,11 @@ static int ql_create_send_free_list(struct ql3_adapter *qdev) /* Create free list of transmit buffers */ for (i = 0; i < NUM_REQ_Q_ENTRIES; i++) { - tx_cb = &qdev->tx_buf[i]; tx_cb->skb = NULL; tx_cb->queue_entry = req_q_curr; req_q_curr++; - tx_cb->oal = kmalloc(512, GFP_KERNEL); - if (tx_cb->oal == NULL) - return -1; } - return 0; } static int ql_alloc_mem_resources(struct ql3_adapter *qdev) @@ -2662,14 +2447,12 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev) /* Initialize the large buffer queue. */ ql_init_large_buffers(qdev); - if (ql_create_send_free_list(qdev)) - goto err_free_list; + ql_create_send_free_list(qdev); qdev->rsp_current = qdev->rsp_q_virt_addr; return 0; -err_free_list: - ql_free_send_free_list(qdev); + err_small_buffers: ql_free_buffer_queues(qdev); err_buffer_queues: @@ -2685,7 +2468,6 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev) static void ql_free_mem_resources(struct ql3_adapter *qdev) { - ql_free_send_free_list(qdev); ql_free_large_buffers(qdev); ql_free_small_buffers(qdev); ql_free_buffer_queues(qdev); @@ -2984,20 +2766,11 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) } /* Enable Ethernet Function */ - if (qdev->device_id == QL3032_DEVICE_ID) { - value = - (QL3032_PORT_CONTROL_EF | QL3032_PORT_CONTROL_KIE | - QL3032_PORT_CONTROL_EIv6 | QL3032_PORT_CONTROL_EIv4); - ql_write_page0_reg(qdev, &port_regs->functionControl, - ((value << 16) | value)); - } else { - value = - (PORT_CONTROL_EF | PORT_CONTROL_ET | PORT_CONTROL_EI | - PORT_CONTROL_HH); - ql_write_page0_reg(qdev, &port_regs->portControl, - ((value << 16) | value)); - } - + value = + (PORT_CONTROL_EF | PORT_CONTROL_ET | PORT_CONTROL_EI | + PORT_CONTROL_HH); + ql_write_page0_reg(qdev, &port_regs->portControl, + ((value << 16) | value)); out: return status; @@ -3144,10 +2917,8 @@ static void ql_display_dev_info(struct net_device *ndev) struct pci_dev *pdev = qdev->pdev; printk(KERN_INFO PFX - "\n%s Adapter %d RevisionID %d found %s on PCI slot %d.\n", - DRV_NAME, qdev->index, qdev->chip_rev_id, - (qdev->device_id == QL3032_DEVICE_ID) ? "QLA3032" : "QLA3022", - qdev->pci_slot); + "\n%s Adapter %d RevisionID %d found on PCI slot %d.\n", + DRV_NAME, qdev->index, qdev->chip_rev_id, qdev->pci_slot); printk(KERN_INFO PFX "%s Interface.\n", test_bit(QL_LINK_OPTICAL,&qdev->flags) ? "OPTICAL" : "COPPER"); @@ -3441,22 +3212,15 @@ static void ql_reset_work(struct work_struct *work) * Loop through the active list and return the skb. */ for (i = 0; i < NUM_REQ_Q_ENTRIES; i++) { - int j; tx_cb = &qdev->tx_buf[i]; if (tx_cb->skb) { + printk(KERN_DEBUG PFX "%s: Freeing lost SKB.\n", qdev->ndev->name); pci_unmap_single(qdev->pdev, - pci_unmap_addr(&tx_cb->map[0], mapaddr), - pci_unmap_len(&tx_cb->map[0], maplen), - PCI_DMA_TODEVICE); - for(j=1;jseg_count;j++) { - pci_unmap_page(qdev->pdev, - pci_unmap_addr(&tx_cb->map[j],mapaddr), - pci_unmap_len(&tx_cb->map[j],maplen), - PCI_DMA_TODEVICE); - } + pci_unmap_addr(tx_cb, mapaddr), + pci_unmap_len(tx_cb, maplen), PCI_DMA_TODEVICE); dev_kfree_skb(tx_cb->skb); tx_cb->skb = NULL; } @@ -3615,24 +3379,21 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); + if (pci_using_dac) + ndev->features |= NETIF_F_HIGHDMA; + pci_set_drvdata(pdev, ndev); qdev = netdev_priv(ndev); qdev->index = cards_found; qdev->ndev = ndev; qdev->pdev = pdev; - qdev->device_id = pci_entry->device; qdev->port_link_state = LS_DOWN; if (msi) qdev->msi = 1; qdev->msg_enable = netif_msg_init(debug, default_msg); - if (pci_using_dac) - ndev->features |= NETIF_F_HIGHDMA; - if (qdev->device_id == QL3032_DEVICE_ID) - ndev->features |= (NETIF_F_HW_CSUM | NETIF_F_SG); - qdev->mem_map_registers = ioremap_nocache(pci_resource_start(pdev, 1), pci_resource_len(qdev->pdev, 1)); diff --git a/trunk/drivers/net/qla3xxx.h b/trunk/drivers/net/qla3xxx.h old mode 100755 new mode 100644 index b2d76ea68827..ea94de7fd071 --- a/trunk/drivers/net/qla3xxx.h +++ b/trunk/drivers/net/qla3xxx.h @@ -21,9 +21,7 @@ #define OPCODE_UPDATE_NCB_IOCB 0xF0 #define OPCODE_IB_MAC_IOCB 0xF9 -#define OPCODE_IB_3032_MAC_IOCB 0x09 #define OPCODE_IB_IP_IOCB 0xFA -#define OPCODE_IB_3032_IP_IOCB 0x0A #define OPCODE_IB_TCP_IOCB 0xFB #define OPCODE_DUMP_PROTO_IOCB 0xFE #define OPCODE_BUFFER_ALERT_IOCB 0xFB @@ -39,23 +37,18 @@ struct ob_mac_iocb_req { u8 opcode; u8 flags; -#define OB_MAC_IOCB_REQ_MA 0xe0 -#define OB_MAC_IOCB_REQ_F 0x10 -#define OB_MAC_IOCB_REQ_X 0x08 +#define OB_MAC_IOCB_REQ_MA 0xC0 +#define OB_MAC_IOCB_REQ_F 0x20 +#define OB_MAC_IOCB_REQ_X 0x10 #define OB_MAC_IOCB_REQ_D 0x02 #define OB_MAC_IOCB_REQ_I 0x01 - u8 flags1; -#define OB_3032MAC_IOCB_REQ_IC 0x04 -#define OB_3032MAC_IOCB_REQ_TC 0x02 -#define OB_3032MAC_IOCB_REQ_UC 0x01 - u8 reserved0; + __le16 reserved0; __le32 transaction_id; __le16 data_len; - u8 ip_hdr_off; - u8 ip_hdr_len; - __le32 reserved1; + __le16 reserved1; __le32 reserved2; + __le32 reserved3; __le32 buf_addr0_low; __le32 buf_addr0_high; __le32 buf_0_len; @@ -65,8 +58,8 @@ struct ob_mac_iocb_req { __le32 buf_addr2_low; __le32 buf_addr2_high; __le32 buf_2_len; - __le32 reserved3; __le32 reserved4; + __le32 reserved5; }; /* * The following constants define control bits for buffer @@ -81,7 +74,6 @@ struct ob_mac_iocb_rsp { u8 opcode; u8 flags; #define OB_MAC_IOCB_RSP_P 0x08 -#define OB_MAC_IOCB_RSP_L 0x04 #define OB_MAC_IOCB_RSP_S 0x02 #define OB_MAC_IOCB_RSP_I 0x01 @@ -93,7 +85,6 @@ struct ob_mac_iocb_rsp { struct ib_mac_iocb_rsp { u8 opcode; -#define IB_MAC_IOCB_RSP_V 0x80 u8 flags; #define IB_MAC_IOCB_RSP_S 0x80 #define IB_MAC_IOCB_RSP_H1 0x40 @@ -147,7 +138,6 @@ struct ob_ip_iocb_req { struct ob_ip_iocb_rsp { u8 opcode; u8 flags; -#define OB_MAC_IOCB_RSP_H 0x10 #define OB_MAC_IOCB_RSP_E 0x08 #define OB_MAC_IOCB_RSP_L 0x04 #define OB_MAC_IOCB_RSP_S 0x02 @@ -230,10 +220,6 @@ struct ob_tcp_iocb_rsp { struct ib_ip_iocb_rsp { u8 opcode; -#define IB_IP_IOCB_RSP_3032_V 0x80 -#define IB_IP_IOCB_RSP_3032_O 0x40 -#define IB_IP_IOCB_RSP_3032_I 0x20 -#define IB_IP_IOCB_RSP_3032_R 0x10 u8 flags; #define IB_IP_IOCB_RSP_S 0x80 #define IB_IP_IOCB_RSP_H1 0x40 @@ -244,12 +230,6 @@ struct ib_ip_iocb_rsp { __le16 length; __le16 checksum; -#define IB_IP_IOCB_RSP_3032_ICE 0x01 -#define IB_IP_IOCB_RSP_3032_CE 0x02 -#define IB_IP_IOCB_RSP_3032_NUC 0x04 -#define IB_IP_IOCB_RSP_3032_UDP 0x08 -#define IB_IP_IOCB_RSP_3032_TCP 0x10 -#define IB_IP_IOCB_RSP_3032_IPE 0x20 __le16 reserved; #define IB_IP_IOCB_RSP_R 0x01 __le32 ial_low; @@ -544,21 +524,6 @@ enum { IP_ADDR_INDEX_REG_FUNC_2_SEC = 0x0005, IP_ADDR_INDEX_REG_FUNC_3_PRI = 0x0006, IP_ADDR_INDEX_REG_FUNC_3_SEC = 0x0007, - IP_ADDR_INDEX_REG_6 = 0x0008, - IP_ADDR_INDEX_REG_OFFSET_MASK = 0x0030, - IP_ADDR_INDEX_REG_E = 0x0040, -}; -enum { - QL3032_PORT_CONTROL_DS = 0x0001, - QL3032_PORT_CONTROL_HH = 0x0002, - QL3032_PORT_CONTROL_EIv6 = 0x0004, - QL3032_PORT_CONTROL_EIv4 = 0x0008, - QL3032_PORT_CONTROL_ET = 0x0010, - QL3032_PORT_CONTROL_EF = 0x0020, - QL3032_PORT_CONTROL_DRM = 0x0040, - QL3032_PORT_CONTROL_RLB = 0x0080, - QL3032_PORT_CONTROL_RCB = 0x0100, - QL3032_PORT_CONTROL_KIE = 0x0200, }; enum { @@ -692,8 +657,7 @@ struct ql3xxx_port_registers { u32 internalRamWDataReg; u32 reclaimedBufferAddrRegLow; u32 reclaimedBufferAddrRegHigh; - u32 tcpConfiguration; - u32 functionControl; + u32 reserved[2]; u32 fpgaRevID; u32 localRamAddr; u32 localRamDataAutoIncr; @@ -999,7 +963,6 @@ struct eeprom_data { #define QL3XXX_VENDOR_ID 0x1077 #define QL3022_DEVICE_ID 0x3022 -#define QL3032_DEVICE_ID 0x3032 /* MTU & Frame Size stuff */ #define NORMAL_MTU_SIZE ETH_DATA_LEN @@ -1075,41 +1038,11 @@ struct ql_rcv_buf_cb { int index; }; -/* - * Original IOCB has 3 sg entries: - * first points to skb-data area - * second points to first frag - * third points to next oal. - * OAL has 5 entries: - * 1 thru 4 point to frags - * fifth points to next oal. - */ -#define MAX_OAL_CNT ((MAX_SKB_FRAGS-1)/4 + 1) - -struct oal_entry { - u32 dma_lo; - u32 dma_hi; - u32 len; -#define OAL_LAST_ENTRY 0x80000000 /* Last valid buffer in list. */ -#define OAL_CONT_ENTRY 0x40000000 /* points to an OAL. (continuation) */ - u32 reserved; -}; - -struct oal { - struct oal_entry oal_entry[5]; -}; - -struct map_list { - DECLARE_PCI_UNMAP_ADDR(mapaddr); - DECLARE_PCI_UNMAP_LEN(maplen); -}; - struct ql_tx_buf_cb { struct sk_buff *skb; struct ob_mac_iocb_req *queue_entry ; - int seg_count; - struct oal *oal; - struct map_list map[MAX_SKB_FRAGS+1]; + DECLARE_PCI_UNMAP_ADDR(mapaddr); + DECLARE_PCI_UNMAP_LEN(maplen); }; /* definitions for type field */ @@ -1256,7 +1189,6 @@ struct ql3_adapter { struct delayed_work reset_work; struct delayed_work tx_timeout_work; u32 max_frame_size; - u32 device_id; }; #endif /* _QLA3XXX_H_ */ diff --git a/trunk/drivers/net/s2io-regs.h b/trunk/drivers/net/s2io-regs.h index 0e345cbc2bf9..a914fef44309 100644 --- a/trunk/drivers/net/s2io-regs.h +++ b/trunk/drivers/net/s2io-regs.h @@ -15,7 +15,7 @@ #define TBD 0 -struct XENA_dev_config { +typedef struct _XENA_dev_config { /* Convention: mHAL_XXX is mask, vHAL_XXX is value */ /* General Control-Status Registers */ @@ -300,7 +300,6 @@ struct XENA_dev_config { u64 gpio_control; #define GPIO_CTRL_GPIO_0 BIT(8) u64 misc_control; -#define FAULT_BEHAVIOUR BIT(0) #define EXT_REQ_EN BIT(1) #define MISC_LINK_STABILITY_PRD(val) vBIT(val,29,3) @@ -852,9 +851,9 @@ struct XENA_dev_config { #define SPI_CONTROL_DONE BIT(6) u64 spi_data; #define SPI_DATA_WRITE(data,len) vBIT(data,0,len) -}; +} XENA_dev_config_t; -#define XENA_REG_SPACE sizeof(struct XENA_dev_config) +#define XENA_REG_SPACE sizeof(XENA_dev_config_t) #define XENA_EEPROM_SPACE (0x01 << 11) #endif /* _REGS_H */ diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 639fbc0f16f3..1dd66b8ea0fa 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -77,7 +77,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.16.1" +#define DRV_VERSION "2.0.15.2" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; @@ -86,7 +86,7 @@ static char s2io_driver_version[] = DRV_VERSION; static int rxd_size[4] = {32,48,48,64}; static int rxd_count[4] = {127,85,85,63}; -static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) +static inline int RXD_IS_UP2DT(RxD_t *rxdp) { int ret; @@ -111,9 +111,9 @@ static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) #define TASKLET_IN_USE test_and_set_bit(0, (&sp->tasklet_status)) #define PANIC 1 #define LOW 2 -static inline int rx_buffer_level(struct s2io_nic * sp, int rxb_size, int ring) +static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) { - struct mac_info *mac_control; + mac_info_t *mac_control; mac_control = &sp->mac_control; if (rxb_size <= rxd_count[sp->rxd_mode]) @@ -286,7 +286,7 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { static void s2io_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) { - struct s2io_nic *nic = dev->priv; + nic_t *nic = dev->priv; unsigned long flags; spin_lock_irqsave(&nic->tx_lock, flags); @@ -297,7 +297,7 @@ static void s2io_vlan_rx_register(struct net_device *dev, /* Unregister the vlan */ static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) { - struct s2io_nic *nic = dev->priv; + nic_t *nic = dev->priv; unsigned long flags; spin_lock_irqsave(&nic->tx_lock, flags); @@ -401,10 +401,9 @@ S2IO_PARM_INT(lro, 0); * aggregation happens until we hit max IP pkt size(64K) */ S2IO_PARM_INT(lro_max_pkts, 0xFFFF); +#ifndef CONFIG_S2IO_NAPI S2IO_PARM_INT(indicate_max_pkts, 0); - -S2IO_PARM_INT(napi, 1); -S2IO_PARM_INT(ufo, 0); +#endif static unsigned int tx_fifo_len[MAX_TX_FIFOS] = {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; @@ -458,14 +457,14 @@ static int init_shared_mem(struct s2io_nic *nic) u32 size; void *tmp_v_addr, *tmp_v_addr_next; dma_addr_t tmp_p_addr, tmp_p_addr_next; - struct RxD_block *pre_rxd_blk = NULL; - int i, j, blk_cnt; + RxD_block_t *pre_rxd_blk = NULL; + int i, j, blk_cnt, rx_sz, tx_sz; int lst_size, lst_per_page; struct net_device *dev = nic->dev; unsigned long tmp; - struct buffAdd *ba; + buffAdd_t *ba; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; mac_control = &nic->mac_control; @@ -483,12 +482,13 @@ static int init_shared_mem(struct s2io_nic *nic) return -EINVAL; } - lst_size = (sizeof(struct TxD) * config->max_txds); + lst_size = (sizeof(TxD_t) * config->max_txds); + tx_sz = lst_size * size; lst_per_page = PAGE_SIZE / lst_size; for (i = 0; i < config->tx_fifo_num; i++) { int fifo_len = config->tx_cfg[i].fifo_len; - int list_holder_size = fifo_len * sizeof(struct list_info_hold); + int list_holder_size = fifo_len * sizeof(list_info_hold_t); mac_control->fifos[i].list_info = kmalloc(list_holder_size, GFP_KERNEL); if (!mac_control->fifos[i].list_info) { @@ -579,9 +579,10 @@ static int init_shared_mem(struct s2io_nic *nic) mac_control->rings[i].block_count; } if (nic->rxd_mode == RXD_MODE_1) - size = (size * (sizeof(struct RxD1))); + size = (size * (sizeof(RxD1_t))); else - size = (size * (sizeof(struct RxD3))); + size = (size * (sizeof(RxD3_t))); + rx_sz = size; for (i = 0; i < config->rx_ring_num; i++) { mac_control->rings[i].rx_curr_get_info.block_index = 0; @@ -599,7 +600,7 @@ static int init_shared_mem(struct s2io_nic *nic) (rxd_count[nic->rxd_mode] + 1); /* Allocating all the Rx blocks */ for (j = 0; j < blk_cnt; j++) { - struct rx_block_info *rx_blocks; + rx_block_info_t *rx_blocks; int l; rx_blocks = &mac_control->rings[i].rx_blocks[j]; @@ -619,11 +620,9 @@ static int init_shared_mem(struct s2io_nic *nic) memset(tmp_v_addr, 0, size); rx_blocks->block_virt_addr = tmp_v_addr; rx_blocks->block_dma_addr = tmp_p_addr; - rx_blocks->rxds = kmalloc(sizeof(struct rxd_info)* + rx_blocks->rxds = kmalloc(sizeof(rxd_info_t)* rxd_count[nic->rxd_mode], GFP_KERNEL); - if (!rx_blocks->rxds) - return -ENOMEM; for (l=0; lrxd_mode];l++) { rx_blocks->rxds[l].virt_addr = rx_blocks->block_virt_addr + @@ -646,7 +645,7 @@ static int init_shared_mem(struct s2io_nic *nic) mac_control->rings[i].rx_blocks[(j + 1) % blk_cnt].block_dma_addr; - pre_rxd_blk = (struct RxD_block *) tmp_v_addr; + pre_rxd_blk = (RxD_block_t *) tmp_v_addr; pre_rxd_blk->reserved_2_pNext_RxD_block = (unsigned long) tmp_v_addr_next; pre_rxd_blk->pNext_RxD_Blk_physical = @@ -662,14 +661,14 @@ static int init_shared_mem(struct s2io_nic *nic) blk_cnt = config->rx_cfg[i].num_rxd / (rxd_count[nic->rxd_mode]+ 1); mac_control->rings[i].ba = - kmalloc((sizeof(struct buffAdd *) * blk_cnt), + kmalloc((sizeof(buffAdd_t *) * blk_cnt), GFP_KERNEL); if (!mac_control->rings[i].ba) return -ENOMEM; for (j = 0; j < blk_cnt; j++) { int k = 0; mac_control->rings[i].ba[j] = - kmalloc((sizeof(struct buffAdd) * + kmalloc((sizeof(buffAdd_t) * (rxd_count[nic->rxd_mode] + 1)), GFP_KERNEL); if (!mac_control->rings[i].ba[j]) @@ -701,7 +700,7 @@ static int init_shared_mem(struct s2io_nic *nic) } /* Allocation and initialization of Statistics block */ - size = sizeof(struct stat_block); + size = sizeof(StatInfo_t); mac_control->stats_mem = pci_alloc_consistent (nic->pdev, size, &mac_control->stats_mem_phy); @@ -716,7 +715,7 @@ static int init_shared_mem(struct s2io_nic *nic) mac_control->stats_mem_sz = size; tmp_v_addr = mac_control->stats_mem; - mac_control->stats_info = (struct stat_block *) tmp_v_addr; + mac_control->stats_info = (StatInfo_t *) tmp_v_addr; memset(tmp_v_addr, 0, size); DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name, (unsigned long long) tmp_p_addr); @@ -736,7 +735,7 @@ static void free_shared_mem(struct s2io_nic *nic) int i, j, blk_cnt, size; void *tmp_v_addr; dma_addr_t tmp_p_addr; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; int lst_size, lst_per_page; struct net_device *dev = nic->dev; @@ -747,7 +746,7 @@ static void free_shared_mem(struct s2io_nic *nic) mac_control = &nic->mac_control; config = &nic->config; - lst_size = (sizeof(struct TxD) * config->max_txds); + lst_size = (sizeof(TxD_t) * config->max_txds); lst_per_page = PAGE_SIZE / lst_size; for (i = 0; i < config->tx_fifo_num; i++) { @@ -810,7 +809,7 @@ static void free_shared_mem(struct s2io_nic *nic) if (!mac_control->rings[i].ba[j]) continue; while (k != rxd_count[nic->rxd_mode]) { - struct buffAdd *ba = + buffAdd_t *ba = &mac_control->rings[i].ba[j][k]; kfree(ba->ba_0_org); kfree(ba->ba_1_org); @@ -836,9 +835,9 @@ static void free_shared_mem(struct s2io_nic *nic) * s2io_verify_pci_mode - */ -static int s2io_verify_pci_mode(struct s2io_nic *nic) +static int s2io_verify_pci_mode(nic_t *nic) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; register u64 val64 = 0; int mode; @@ -869,9 +868,9 @@ static int bus_speed[8] = {33, 133, 133, 200, 266, 133, 200, 266}; /** * s2io_print_pci_mode - */ -static int s2io_print_pci_mode(struct s2io_nic *nic) +static int s2io_print_pci_mode(nic_t *nic) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; register u64 val64 = 0; int mode; struct config_param *config = &nic->config; @@ -939,13 +938,13 @@ static int s2io_print_pci_mode(struct s2io_nic *nic) static int init_nic(struct s2io_nic *nic) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; struct net_device *dev = nic->dev; register u64 val64 = 0; void __iomem *add; u32 time; int i, j; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; int dtx_cnt = 0; unsigned long long mem_share; @@ -1415,7 +1414,7 @@ static int init_nic(struct s2io_nic *nic) val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | TTI_DATA2_MEM_TX_UFC_B(0x20) | - TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80); + TTI_DATA2_MEM_TX_UFC_C(0x70) | TTI_DATA2_MEM_TX_UFC_D(0x80); writeq(val64, &bar0->tti_data2_mem); val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; @@ -1611,8 +1610,7 @@ static int init_nic(struct s2io_nic *nic) * that does not start on an ADB to reduce disconnects. */ if (nic->device_type == XFRAME_II_DEVICE) { - val64 = FAULT_BEHAVIOUR | EXT_REQ_EN | - MISC_LINK_STABILITY_PRD(3); + val64 = EXT_REQ_EN | MISC_LINK_STABILITY_PRD(3); writeq(val64, &bar0->misc_control); val64 = readq(&bar0->pic_control2); val64 &= ~(BIT(13)|BIT(14)|BIT(15)); @@ -1628,7 +1626,7 @@ static int init_nic(struct s2io_nic *nic) #define LINK_UP_DOWN_INTERRUPT 1 #define MAC_RMAC_ERR_TIMER 2 -static int s2io_link_fault_indication(struct s2io_nic *nic) +static int s2io_link_fault_indication(nic_t *nic) { if (nic->intr_type != INTA) return MAC_RMAC_ERR_TIMER; @@ -1651,14 +1649,14 @@ static int s2io_link_fault_indication(struct s2io_nic *nic) static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; register u64 val64 = 0, temp64 = 0; /* Top level interrupt classification */ /* PIC Interrupts */ if ((mask & (TX_PIC_INTR | RX_PIC_INTR))) { /* Enable PIC Intrs in the general intr mask register */ - val64 = TXPIC_INT_M; + val64 = TXPIC_INT_M | PIC_RX_INT_M; if (flag == ENABLE_INTRS) { temp64 = readq(&bar0->general_int_mask); temp64 &= ~((u64) val64); @@ -1696,6 +1694,70 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) } } + /* DMA Interrupts */ + /* Enabling/Disabling Tx DMA interrupts */ + if (mask & TX_DMA_INTR) { + /* Enable TxDMA Intrs in the general intr mask register */ + val64 = TXDMA_INT_M; + if (flag == ENABLE_INTRS) { + temp64 = readq(&bar0->general_int_mask); + temp64 &= ~((u64) val64); + writeq(temp64, &bar0->general_int_mask); + /* + * Keep all interrupts other than PFC interrupt + * and PCC interrupt disabled in DMA level. + */ + val64 = DISABLE_ALL_INTRS & ~(TXDMA_PFC_INT_M | + TXDMA_PCC_INT_M); + writeq(val64, &bar0->txdma_int_mask); + /* + * Enable only the MISC error 1 interrupt in PFC block + */ + val64 = DISABLE_ALL_INTRS & (~PFC_MISC_ERR_1); + writeq(val64, &bar0->pfc_err_mask); + /* + * Enable only the FB_ECC error interrupt in PCC block + */ + val64 = DISABLE_ALL_INTRS & (~PCC_FB_ECC_ERR); + writeq(val64, &bar0->pcc_err_mask); + } else if (flag == DISABLE_INTRS) { + /* + * Disable TxDMA Intrs in the general intr mask + * register + */ + writeq(DISABLE_ALL_INTRS, &bar0->txdma_int_mask); + writeq(DISABLE_ALL_INTRS, &bar0->pfc_err_mask); + temp64 = readq(&bar0->general_int_mask); + val64 |= temp64; + writeq(val64, &bar0->general_int_mask); + } + } + + /* Enabling/Disabling Rx DMA interrupts */ + if (mask & RX_DMA_INTR) { + /* Enable RxDMA Intrs in the general intr mask register */ + val64 = RXDMA_INT_M; + if (flag == ENABLE_INTRS) { + temp64 = readq(&bar0->general_int_mask); + temp64 &= ~((u64) val64); + writeq(temp64, &bar0->general_int_mask); + /* + * All RxDMA block interrupts are disabled for now + * TODO + */ + writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); + } else if (flag == DISABLE_INTRS) { + /* + * Disable RxDMA Intrs in the general intr mask + * register + */ + writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); + temp64 = readq(&bar0->general_int_mask); + val64 |= temp64; + writeq(val64, &bar0->general_int_mask); + } + } + /* MAC Interrupts */ /* Enabling/Disabling MAC interrupts */ if (mask & (TX_MAC_INTR | RX_MAC_INTR)) { @@ -1722,6 +1784,53 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) } } + /* XGXS Interrupts */ + if (mask & (TX_XGXS_INTR | RX_XGXS_INTR)) { + val64 = TXXGXS_INT_M | RXXGXS_INT_M; + if (flag == ENABLE_INTRS) { + temp64 = readq(&bar0->general_int_mask); + temp64 &= ~((u64) val64); + writeq(temp64, &bar0->general_int_mask); + /* + * All XGXS block error interrupts are disabled for now + * TODO + */ + writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); + } else if (flag == DISABLE_INTRS) { + /* + * Disable MC Intrs in the general intr mask register + */ + writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); + temp64 = readq(&bar0->general_int_mask); + val64 |= temp64; + writeq(val64, &bar0->general_int_mask); + } + } + + /* Memory Controller(MC) interrupts */ + if (mask & MC_INTR) { + val64 = MC_INT_M; + if (flag == ENABLE_INTRS) { + temp64 = readq(&bar0->general_int_mask); + temp64 &= ~((u64) val64); + writeq(temp64, &bar0->general_int_mask); + /* + * Enable all MC Intrs. + */ + writeq(0x0, &bar0->mc_int_mask); + writeq(0x0, &bar0->mc_err_mask); + } else if (flag == DISABLE_INTRS) { + /* + * Disable MC Intrs in the general intr mask register + */ + writeq(DISABLE_ALL_INTRS, &bar0->mc_int_mask); + temp64 = readq(&bar0->general_int_mask); + val64 |= temp64; + writeq(val64, &bar0->general_int_mask); + } + } + + /* Tx traffic interrupts */ if (mask & TX_TRAFFIC_INTR) { val64 = TXTRAFFIC_INT_M; @@ -1768,36 +1877,41 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) } } -/** - * verify_pcc_quiescent- Checks for PCC quiescent state - * Return: 1 If PCC is quiescence - * 0 If PCC is not quiescence - */ -static int verify_pcc_quiescent(struct s2io_nic *sp, int flag) +static int check_prc_pcc_state(u64 val64, int flag, int rev_id, int herc) { - int ret = 0, herc; - struct XENA_dev_config __iomem *bar0 = sp->bar0; - u64 val64 = readq(&bar0->adapter_status); - - herc = (sp->device_type == XFRAME_II_DEVICE); + int ret = 0; if (flag == FALSE) { - if ((!herc && (get_xena_rev_id(sp->pdev) >= 4)) || herc) { - if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE)) + if ((!herc && (rev_id >= 4)) || herc) { + if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) && + ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == + ADAPTER_STATUS_RC_PRC_QUIESCENT)) { ret = 1; - } else { - if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE)) + } + }else { + if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) && + ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == + ADAPTER_STATUS_RC_PRC_QUIESCENT)) { ret = 1; + } } } else { - if ((!herc && (get_xena_rev_id(sp->pdev) >= 4)) || herc) { + if ((!herc && (rev_id >= 4)) || herc) { if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) == - ADAPTER_STATUS_RMAC_PCC_IDLE)) + ADAPTER_STATUS_RMAC_PCC_IDLE) && + (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || + ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == + ADAPTER_STATUS_RC_PRC_QUIESCENT))) { ret = 1; + } } else { if (((val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) == - ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE)) + ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) && + (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || + ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == + ADAPTER_STATUS_RC_PRC_QUIESCENT))) { ret = 1; + } } } @@ -1805,6 +1919,9 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag) } /** * verify_xena_quiescence - Checks whether the H/W is ready + * @val64 : Value read from adapter status register. + * @flag : indicates if the adapter enable bit was ever written once + * before. * Description: Returns whether the H/W is ready to go or not. Depending * on whether adapter enable bit was written or not the comparison * differs and the calling function passes the input argument flag to @@ -1813,63 +1930,24 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag) * 0 If Xena is not quiescence */ -static int verify_xena_quiescence(struct s2io_nic *sp) +static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag) { - int mode; - struct XENA_dev_config __iomem *bar0 = sp->bar0; - u64 val64 = readq(&bar0->adapter_status); - mode = s2io_verify_pci_mode(sp); + int ret = 0, herc; + u64 tmp64 = ~((u64) val64); + int rev_id = get_xena_rev_id(sp->pdev); - if (!(val64 & ADAPTER_STATUS_TDMA_READY)) { - DBG_PRINT(ERR_DBG, "%s", "TDMA is not ready!"); - return 0; - } - if (!(val64 & ADAPTER_STATUS_RDMA_READY)) { - DBG_PRINT(ERR_DBG, "%s", "RDMA is not ready!"); - return 0; - } - if (!(val64 & ADAPTER_STATUS_PFC_READY)) { - DBG_PRINT(ERR_DBG, "%s", "PFC is not ready!"); - return 0; - } - if (!(val64 & ADAPTER_STATUS_TMAC_BUF_EMPTY)) { - DBG_PRINT(ERR_DBG, "%s", "TMAC BUF is not empty!"); - return 0; - } - if (!(val64 & ADAPTER_STATUS_PIC_QUIESCENT)) { - DBG_PRINT(ERR_DBG, "%s", "PIC is not QUIESCENT!"); - return 0; - } - if (!(val64 & ADAPTER_STATUS_MC_DRAM_READY)) { - DBG_PRINT(ERR_DBG, "%s", "MC_DRAM is not ready!"); - return 0; - } - if (!(val64 & ADAPTER_STATUS_MC_QUEUES_READY)) { - DBG_PRINT(ERR_DBG, "%s", "MC_QUEUES is not ready!"); - return 0; - } - if (!(val64 & ADAPTER_STATUS_M_PLL_LOCK)) { - DBG_PRINT(ERR_DBG, "%s", "M_PLL is not locked!"); - return 0; + herc = (sp->device_type == XFRAME_II_DEVICE); + if (! + (tmp64 & + (ADAPTER_STATUS_TDMA_READY | ADAPTER_STATUS_RDMA_READY | + ADAPTER_STATUS_PFC_READY | ADAPTER_STATUS_TMAC_BUF_EMPTY | + ADAPTER_STATUS_PIC_QUIESCENT | ADAPTER_STATUS_MC_DRAM_READY | + ADAPTER_STATUS_MC_QUEUES_READY | ADAPTER_STATUS_M_PLL_LOCK | + ADAPTER_STATUS_P_PLL_LOCK))) { + ret = check_prc_pcc_state(val64, flag, rev_id, herc); } - /* - * In PCI 33 mode, the P_PLL is not used, and therefore, - * the the P_PLL_LOCK bit in the adapter_status register will - * not be asserted. - */ - if (!(val64 & ADAPTER_STATUS_P_PLL_LOCK) && - sp->device_type == XFRAME_II_DEVICE && mode != - PCI_MODE_PCI_33) { - DBG_PRINT(ERR_DBG, "%s", "P_PLL is not locked!"); - return 0; - } - if (!((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == - ADAPTER_STATUS_RC_PRC_QUIESCENT)) { - DBG_PRINT(ERR_DBG, "%s", "RC_PRC is not QUIESCENT!"); - return 0; - } - return 1; + return ret; } /** @@ -1880,9 +1958,9 @@ static int verify_xena_quiescence(struct s2io_nic *sp) * */ -static void fix_mac_address(struct s2io_nic * sp) +static void fix_mac_address(nic_t * sp) { - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64; int i = 0; @@ -1908,11 +1986,11 @@ static void fix_mac_address(struct s2io_nic * sp) static int start_nic(struct s2io_nic *nic) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; struct net_device *dev = nic->dev; register u64 val64 = 0; u16 subid, i; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; mac_control = &nic->mac_control; @@ -1974,7 +2052,7 @@ static int start_nic(struct s2io_nic *nic) * it. */ val64 = readq(&bar0->adapter_status); - if (!verify_xena_quiescence(nic)) { + if (!verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { DBG_PRINT(ERR_DBG, "%s: device is not ready, ", dev->name); DBG_PRINT(ERR_DBG, "Adapter status reads: 0x%llx\n", (unsigned long long) val64); @@ -2017,12 +2095,11 @@ static int start_nic(struct s2io_nic *nic) /** * s2io_txdl_getskb - Get the skb from txdl, unmap and return skb */ -static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \ - TxD *txdlp, int get_off) +static struct sk_buff *s2io_txdl_getskb(fifo_info_t *fifo_data, TxD_t *txdlp, int get_off) { - struct s2io_nic *nic = fifo_data->nic; + nic_t *nic = fifo_data->nic; struct sk_buff *skb; - struct TxD *txds; + TxD_t *txds; u16 j, frg_cnt; txds = txdlp; @@ -2036,7 +2113,7 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \ skb = (struct sk_buff *) ((unsigned long) txds->Host_Control); if (!skb) { - memset(txdlp, 0, (sizeof(struct TxD) * fifo_data->max_txds)); + memset(txdlp, 0, (sizeof(TxD_t) * fifo_data->max_txds)); return NULL; } pci_unmap_single(nic->pdev, (dma_addr_t) @@ -2055,7 +2132,7 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \ frag->size, PCI_DMA_TODEVICE); } } - memset(txdlp,0, (sizeof(struct TxD) * fifo_data->max_txds)); + memset(txdlp,0, (sizeof(TxD_t) * fifo_data->max_txds)); return(skb); } @@ -2071,9 +2148,9 @@ static void free_tx_buffers(struct s2io_nic *nic) { struct net_device *dev = nic->dev; struct sk_buff *skb; - struct TxD *txdp; + TxD_t *txdp; int i, j; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; int cnt = 0; @@ -2082,7 +2159,7 @@ static void free_tx_buffers(struct s2io_nic *nic) for (i = 0; i < config->tx_fifo_num; i++) { for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { - txdp = (struct TxD *) mac_control->fifos[i].list_info[j]. + txdp = (TxD_t *) mac_control->fifos[i].list_info[j]. list_virt_addr; skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j); if (skb) { @@ -2110,10 +2187,10 @@ static void free_tx_buffers(struct s2io_nic *nic) static void stop_nic(struct s2io_nic *nic) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; register u64 val64 = 0; u16 interruptible; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; mac_control = &nic->mac_control; @@ -2131,15 +2208,14 @@ static void stop_nic(struct s2io_nic *nic) writeq(val64, &bar0->adapter_control); } -static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \ - sk_buff *skb) +static int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) { struct net_device *dev = nic->dev; struct sk_buff *frag_list; void *tmp; /* Buffer-1 receives L3/L4 headers */ - ((struct RxD3*)rxdp)->Buffer1_ptr = pci_map_single + ((RxD3_t*)rxdp)->Buffer1_ptr = pci_map_single (nic->pdev, skb->data, l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); @@ -2150,14 +2226,13 @@ static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \ return -ENOMEM ; } frag_list = skb_shinfo(skb)->frag_list; - skb->truesize += frag_list->truesize; frag_list->next = NULL; tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1); frag_list->data = tmp; frag_list->tail = tmp; /* Buffer-2 receives L4 data payload */ - ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev, + ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev, frag_list->data, dev->mtu, PCI_DMA_FROMDEVICE); rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); @@ -2191,16 +2266,18 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) { struct net_device *dev = nic->dev; struct sk_buff *skb; - struct RxD_t *rxdp; + RxD_t *rxdp; int off, off1, size, block_no, block_no1; u32 alloc_tab = 0; u32 alloc_cnt; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; u64 tmp; - struct buffAdd *ba; + buffAdd_t *ba; +#ifndef CONFIG_S2IO_NAPI unsigned long flags; - struct RxD_t *first_rxdp = NULL; +#endif + RxD_t *first_rxdp = NULL; mac_control = &nic->mac_control; config = &nic->config; @@ -2243,15 +2320,12 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", dev->name, rxdp); } - if(!napi) { - spin_lock_irqsave(&nic->put_lock, flags); - mac_control->rings[ring_no].put_pos = - (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; - spin_unlock_irqrestore(&nic->put_lock, flags); - } else { - mac_control->rings[ring_no].put_pos = - (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; - } +#ifndef CONFIG_S2IO_NAPI + spin_lock_irqsave(&nic->put_lock, flags); + mac_control->rings[ring_no].put_pos = + (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; + spin_unlock_irqrestore(&nic->put_lock, flags); +#endif if ((rxdp->Control_1 & RXD_OWN_XENA) && ((nic->rxd_mode >= RXD_MODE_3A) && (rxdp->Control_2 & BIT(0)))) { @@ -2282,9 +2356,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) } if (nic->rxd_mode == RXD_MODE_1) { /* 1 buffer mode - normal operation mode */ - memset(rxdp, 0, sizeof(struct RxD1)); + memset(rxdp, 0, sizeof(RxD1_t)); skb_reserve(skb, NET_IP_ALIGN); - ((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single + ((RxD1_t*)rxdp)->Buffer0_ptr = pci_map_single (nic->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN); @@ -2301,7 +2375,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) * payload */ - memset(rxdp, 0, sizeof(struct RxD3)); + memset(rxdp, 0, sizeof(RxD3_t)); ba = &mac_control->rings[ring_no].ba[block_no][off]; skb_reserve(skb, BUF0_LEN); tmp = (u64)(unsigned long) skb->data; @@ -2310,13 +2384,13 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) skb->data = (void *) (unsigned long)tmp; skb->tail = (void *) (unsigned long)tmp; - if (!(((struct RxD3*)rxdp)->Buffer0_ptr)) - ((struct RxD3*)rxdp)->Buffer0_ptr = + if (!(((RxD3_t*)rxdp)->Buffer0_ptr)) + ((RxD3_t*)rxdp)->Buffer0_ptr = pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); else pci_dma_sync_single_for_device(nic->pdev, - (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr, + (dma_addr_t) ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); if (nic->rxd_mode == RXD_MODE_3B) { @@ -2326,13 +2400,13 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) * Buffer2 will have L3/L4 header plus * L4 payload */ - ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single + ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single (nic->pdev, skb->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); /* Buffer-1 will be dummy buffer. Not used */ - if (!(((struct RxD3*)rxdp)->Buffer1_ptr)) { - ((struct RxD3*)rxdp)->Buffer1_ptr = + if (!(((RxD3_t*)rxdp)->Buffer1_ptr)) { + ((RxD3_t*)rxdp)->Buffer1_ptr = pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); @@ -2392,9 +2466,9 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) struct net_device *dev = sp->dev; int j; struct sk_buff *skb; - struct RxD_t *rxdp; - struct mac_info *mac_control; - struct buffAdd *ba; + RxD_t *rxdp; + mac_info_t *mac_control; + buffAdd_t *ba; mac_control = &sp->mac_control; for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) { @@ -2407,41 +2481,41 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) } if (sp->rxd_mode == RXD_MODE_1) { pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD1*)rxdp)->Buffer0_ptr, + ((RxD1_t*)rxdp)->Buffer0_ptr, dev->mtu + HEADER_ETHERNET_II_802_3_SIZE + HEADER_802_2_SIZE + HEADER_SNAP_SIZE, PCI_DMA_FROMDEVICE); - memset(rxdp, 0, sizeof(struct RxD1)); + memset(rxdp, 0, sizeof(RxD1_t)); } else if(sp->rxd_mode == RXD_MODE_3B) { ba = &mac_control->rings[ring_no]. ba[blk][j]; pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, + ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, + ((RxD3_t*)rxdp)->Buffer1_ptr, BUF1_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, + ((RxD3_t*)rxdp)->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); - memset(rxdp, 0, sizeof(struct RxD3)); + memset(rxdp, 0, sizeof(RxD3_t)); } else { pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, + ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, + ((RxD3_t*)rxdp)->Buffer1_ptr, l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, dev->mtu, + ((RxD3_t*)rxdp)->Buffer2_ptr, dev->mtu, PCI_DMA_FROMDEVICE); - memset(rxdp, 0, sizeof(struct RxD3)); + memset(rxdp, 0, sizeof(RxD3_t)); } dev_kfree_skb(skb); atomic_dec(&sp->rx_bufs_left[ring_no]); @@ -2461,7 +2535,7 @@ static void free_rx_buffers(struct s2io_nic *sp) { struct net_device *dev = sp->dev; int i, blk = 0, buf_cnt = 0; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; mac_control = &sp->mac_control; @@ -2494,13 +2568,15 @@ static void free_rx_buffers(struct s2io_nic *sp) * 0 on success and 1 if there are No Rx packets to be processed. */ +#if defined(CONFIG_S2IO_NAPI) static int s2io_poll(struct net_device *dev, int *budget) { - struct s2io_nic *nic = dev->priv; + nic_t *nic = dev->priv; int pkt_cnt = 0, org_pkts_to_process; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; + u64 val64 = 0xFFFFFFFFFFFFFFFFULL; int i; atomic_inc(&nic->isr_cnt); @@ -2512,8 +2588,8 @@ static int s2io_poll(struct net_device *dev, int *budget) nic->pkts_to_process = dev->quota; org_pkts_to_process = nic->pkts_to_process; - writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); - readl(&bar0->rx_traffic_int); + writeq(val64, &bar0->rx_traffic_int); + val64 = readl(&bar0->rx_traffic_int); for (i = 0; i < config->rx_ring_num; i++) { rx_intr_handler(&mac_control->rings[i]); @@ -2539,7 +2615,7 @@ static int s2io_poll(struct net_device *dev, int *budget) } /* Re enable the Rx interrupts. */ writeq(0x0, &bar0->rx_traffic_mask); - readl(&bar0->rx_traffic_mask); + val64 = readl(&bar0->rx_traffic_mask); atomic_dec(&nic->isr_cnt); return 0; @@ -2557,6 +2633,7 @@ static int s2io_poll(struct net_device *dev, int *budget) atomic_dec(&nic->isr_cnt); return 1; } +#endif #ifdef CONFIG_NET_POLL_CONTROLLER /** @@ -2570,10 +2647,10 @@ static int s2io_poll(struct net_device *dev, int *budget) */ static void s2io_netpoll(struct net_device *dev) { - struct s2io_nic *nic = dev->priv; - struct mac_info *mac_control; + nic_t *nic = dev->priv; + mac_info_t *mac_control; struct config_param *config; - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64 = 0xFFFFFFFFFFFFFFFFULL; int i; @@ -2622,15 +2699,17 @@ static void s2io_netpoll(struct net_device *dev) * Return Value: * NONE. */ -static void rx_intr_handler(struct ring_info *ring_data) +static void rx_intr_handler(ring_info_t *ring_data) { - struct s2io_nic *nic = ring_data->nic; + nic_t *nic = ring_data->nic; struct net_device *dev = (struct net_device *) nic->dev; int get_block, put_block, put_offset; - struct rx_curr_get_info get_info, put_info; - struct RxD_t *rxdp; + rx_curr_get_info_t get_info, put_info; + RxD_t *rxdp; struct sk_buff *skb; +#ifndef CONFIG_S2IO_NAPI int pkt_cnt = 0; +#endif int i; spin_lock(&nic->rx_lock); @@ -2643,21 +2722,19 @@ static void rx_intr_handler(struct ring_info *ring_data) get_info = ring_data->rx_curr_get_info; get_block = get_info.block_index; - memcpy(&put_info, &ring_data->rx_curr_put_info, sizeof(put_info)); + put_info = ring_data->rx_curr_put_info; put_block = put_info.block_index; rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr; - if (!napi) { - spin_lock(&nic->put_lock); - put_offset = ring_data->put_pos; - spin_unlock(&nic->put_lock); - } else - put_offset = ring_data->put_pos; - +#ifndef CONFIG_S2IO_NAPI + spin_lock(&nic->put_lock); + put_offset = ring_data->put_pos; + spin_unlock(&nic->put_lock); +#else + put_offset = (put_block * (rxd_count[nic->rxd_mode] + 1)) + + put_info.offset; +#endif while (RXD_IS_UP2DT(rxdp)) { - /* - * If your are next to put index then it's - * FIFO full condition - */ + /* If your are next to put index then it's FIFO full condition */ if ((get_block == put_block) && (get_info.offset + 1) == put_info.offset) { DBG_PRINT(INTR_DBG, "%s: Ring Full\n",dev->name); @@ -2673,7 +2750,7 @@ static void rx_intr_handler(struct ring_info *ring_data) } if (nic->rxd_mode == RXD_MODE_1) { pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD1*)rxdp)->Buffer0_ptr, + ((RxD1_t*)rxdp)->Buffer0_ptr, dev->mtu + HEADER_ETHERNET_II_802_3_SIZE + HEADER_802_2_SIZE + @@ -2681,22 +2758,22 @@ static void rx_intr_handler(struct ring_info *ring_data) PCI_DMA_FROMDEVICE); } else if (nic->rxd_mode == RXD_MODE_3B) { pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, + ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, + ((RxD3_t*)rxdp)->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); } else { pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, + ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, + ((RxD3_t*)rxdp)->Buffer1_ptr, l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, + ((RxD3_t*)rxdp)->Buffer2_ptr, dev->mtu, PCI_DMA_FROMDEVICE); } prefetch(skb->data); @@ -2715,17 +2792,20 @@ static void rx_intr_handler(struct ring_info *ring_data) rxdp = ring_data->rx_blocks[get_block].block_virt_addr; } +#ifdef CONFIG_S2IO_NAPI nic->pkts_to_process -= 1; - if ((napi) && (!nic->pkts_to_process)) + if (!nic->pkts_to_process) break; +#else pkt_cnt++; if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts)) break; +#endif } if (nic->lro) { /* Clear all LRO sessions before exiting */ for (i=0; ilro0_n[i]; + lro_t *lro = &nic->lro0_n[i]; if (lro->in_use) { update_L3L4_header(nic, lro); queue_rx_frame(lro->parent); @@ -2749,17 +2829,17 @@ static void rx_intr_handler(struct ring_info *ring_data) * NONE */ -static void tx_intr_handler(struct fifo_info *fifo_data) +static void tx_intr_handler(fifo_info_t *fifo_data) { - struct s2io_nic *nic = fifo_data->nic; + nic_t *nic = fifo_data->nic; struct net_device *dev = (struct net_device *) nic->dev; - struct tx_curr_get_info get_info, put_info; + tx_curr_get_info_t get_info, put_info; struct sk_buff *skb; - struct TxD *txdlp; + TxD_t *txdlp; get_info = fifo_data->tx_curr_get_info; - memcpy(&put_info, &fifo_data->tx_curr_put_info, sizeof(put_info)); - txdlp = (struct TxD *) fifo_data->list_info[get_info.offset]. + put_info = fifo_data->tx_curr_put_info; + txdlp = (TxD_t *) fifo_data->list_info[get_info.offset]. list_virt_addr; while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) && (get_info.offset != put_info.offset) && @@ -2774,10 +2854,11 @@ static void tx_intr_handler(struct fifo_info *fifo_data) } if ((err >> 48) == 0xA) { DBG_PRINT(TX_DBG, "TxD returned due \ - to loss of link\n"); +to loss of link\n"); } else { - DBG_PRINT(ERR_DBG, "***TxD error %llx\n", err); + DBG_PRINT(ERR_DBG, "***TxD error \ +%llx\n", err); } } @@ -2796,7 +2877,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data) get_info.offset++; if (get_info.offset == get_info.fifo_len + 1) get_info.offset = 0; - txdlp = (struct TxD *) fifo_data->list_info + txdlp = (TxD_t *) fifo_data->list_info [get_info.offset].list_virt_addr; fifo_data->tx_curr_get_info.offset = get_info.offset; @@ -2821,8 +2902,8 @@ static void tx_intr_handler(struct fifo_info *fifo_data) static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device *dev) { u64 val64 = 0x0; - struct s2io_nic *sp = dev->priv; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + nic_t *sp = dev->priv; + XENA_dev_config_t __iomem *bar0 = sp->bar0; //address transaction val64 = val64 | MDIO_MMD_INDX_ADDR(addr) @@ -2870,8 +2951,8 @@ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev) { u64 val64 = 0x0; u64 rval64 = 0x0; - struct s2io_nic *sp = dev->priv; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + nic_t *sp = dev->priv; + XENA_dev_config_t __iomem *bar0 = sp->bar0; /* address transaction */ val64 = val64 | MDIO_MMD_INDX_ADDR(addr) @@ -2974,8 +3055,8 @@ static void s2io_updt_xpak_counter(struct net_device *dev) u64 val64 = 0x0; u64 addr = 0x0; - struct s2io_nic *sp = dev->priv; - struct stat_block *stat_info = sp->mac_control.stats_info; + nic_t *sp = dev->priv; + StatInfo_t *stat_info = sp->mac_control.stats_info; /* Check the communication with the MDIO slave */ addr = 0x0000; @@ -3073,12 +3154,10 @@ static void s2io_updt_xpak_counter(struct net_device *dev) static void alarm_intr_handler(struct s2io_nic *nic) { struct net_device *dev = (struct net_device *) nic->dev; - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; register u64 val64 = 0, err_reg = 0; u64 cnt; int i; - if (atomic_read(&nic->card_state) == CARD_DOWN) - return; nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0; /* Handling the XPAK counters update */ if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) { @@ -3218,25 +3297,6 @@ static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit) } return ret; } -/* - * check_pci_device_id - Checks if the device id is supported - * @id : device id - * Description: Function to check if the pci device id is supported by driver. - * Return value: Actual device id if supported else PCI_ANY_ID - */ -static u16 check_pci_device_id(u16 id) -{ - switch (id) { - case PCI_DEVICE_ID_HERC_WIN: - case PCI_DEVICE_ID_HERC_UNI: - return XFRAME_II_DEVICE; - case PCI_DEVICE_ID_S2IO_UNI: - case PCI_DEVICE_ID_S2IO_WIN: - return XFRAME_I_DEVICE; - default: - return PCI_ANY_ID; - } -} /** * s2io_reset - Resets the card. @@ -3248,58 +3308,43 @@ static u16 check_pci_device_id(u16 id) * void. */ -static void s2io_reset(struct s2io_nic * sp) +static void s2io_reset(nic_t * sp) { - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64; u16 subid, pci_cmd; - int i; - u16 val16; - DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n", - __FUNCTION__, sp->dev->name); /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); - if (sp->device_type == XFRAME_II_DEVICE) { - int ret; - ret = pci_set_power_state(sp->pdev, 3); - if (!ret) - ret = pci_set_power_state(sp->pdev, 0); - else { - DBG_PRINT(ERR_DBG,"%s PME based SW_Reset failed!\n", - __FUNCTION__); - goto old_way; - } - msleep(20); - goto new_way; - } -old_way: val64 = SW_RESET_ALL; writeq(val64, &bar0->sw_reset); -new_way: + + /* + * At this stage, if the PCI write is indeed completed, the + * card is reset and so is the PCI Config space of the device. + * So a read cannot be issued at this stage on any of the + * registers to ensure the write into "sw_reset" register + * has gone through. + * Question: Is there any system call that will explicitly force + * all the write commands still pending on the bus to be pushed + * through? + * As of now I'am just giving a 250ms delay and hoping that the + * PCI write to sw_reset register is done by this time. + */ + msleep(250); if (strstr(sp->product_name, "CX4")) { msleep(750); } - msleep(250); - for (i = 0; i < S2IO_MAX_PCI_CONFIG_SPACE_REINIT; i++) { - - /* Restore the PCI state saved during initialization. */ - pci_restore_state(sp->pdev); - pci_read_config_word(sp->pdev, 0x2, &val16); - if (check_pci_device_id(val16) != (u16)PCI_ANY_ID) - break; - msleep(200); - } - - if (check_pci_device_id(val16) == (u16)PCI_ANY_ID) { - DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __FUNCTION__); - } - - pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, pci_cmd); + /* Restore the PCI state saved during initialization. */ + pci_restore_state(sp->pdev); + pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, + pci_cmd); s2io_init_pci(sp); + msleep(250); + /* Set swapper to enable I/O register access */ s2io_set_swapper(sp); @@ -3354,10 +3399,10 @@ static void s2io_reset(struct s2io_nic * sp) * SUCCESS on success and FAILURE on failure. */ -static int s2io_set_swapper(struct s2io_nic * sp) +static int s2io_set_swapper(nic_t * sp) { struct net_device *dev = sp->dev; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64, valt, valr; /* @@ -3482,9 +3527,9 @@ static int s2io_set_swapper(struct s2io_nic * sp) return SUCCESS; } -static int wait_for_msix_trans(struct s2io_nic *nic, int i) +static int wait_for_msix_trans(nic_t *nic, int i) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64; int ret = 0, cnt = 0; @@ -3503,9 +3548,9 @@ static int wait_for_msix_trans(struct s2io_nic *nic, int i) return ret; } -static void restore_xmsi_data(struct s2io_nic *nic) +static void restore_xmsi_data(nic_t *nic) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64; int i; @@ -3521,9 +3566,9 @@ static void restore_xmsi_data(struct s2io_nic *nic) } } -static void store_xmsi_data(struct s2io_nic *nic) +static void store_xmsi_data(nic_t *nic) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64, addr, data; int i; @@ -3544,9 +3589,9 @@ static void store_xmsi_data(struct s2io_nic *nic) } } -int s2io_enable_msi(struct s2io_nic *nic) +int s2io_enable_msi(nic_t *nic) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u16 msi_ctrl, msg_val; struct config_param *config = &nic->config; struct net_device *dev = nic->dev; @@ -3594,9 +3639,9 @@ int s2io_enable_msi(struct s2io_nic *nic) return 0; } -static int s2io_enable_msi_x(struct s2io_nic *nic) +static int s2io_enable_msi_x(nic_t *nic) { - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 tx_mat, rx_mat; u16 msi_control; /* Temp variable */ int ret, i, j, msix_indx = 1; @@ -3704,7 +3749,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) static int s2io_open(struct net_device *dev) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; int err = 0; /* @@ -3757,7 +3802,7 @@ static int s2io_open(struct net_device *dev) static int s2io_close(struct net_device *dev) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; flush_scheduled_work(); netif_stop_queue(dev); @@ -3783,15 +3828,15 @@ static int s2io_close(struct net_device *dev) static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; register u64 val64; - struct TxD *txdp; - struct TxFIFO_element __iomem *tx_fifo; + TxD_t *txdp; + TxFIFO_element_t __iomem *tx_fifo; unsigned long flags; u16 vlan_tag = 0; int vlan_priority = 0; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; int offload_type; @@ -3819,7 +3864,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset; get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset; - txdp = (struct TxD *) mac_control->fifos[queue].list_info[put_off]. + txdp = (TxD_t *) mac_control->fifos[queue].list_info[put_off]. list_virt_addr; queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; @@ -3842,10 +3887,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) } offload_type = s2io_offload_type(skb); +#ifdef NETIF_F_TSO if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { txdp->Control_1 |= TXD_TCP_LSO_EN; txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb)); } +#endif if (skb->ip_summed == CHECKSUM_PARTIAL) { txdp->Control_2 |= (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | @@ -3946,13 +3993,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) static void s2io_alarm_handle(unsigned long data) { - struct s2io_nic *sp = (struct s2io_nic *)data; + nic_t *sp = (nic_t *)data; alarm_intr_handler(sp); mod_timer(&sp->alarm_timer, jiffies + HZ / 2); } -static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n) +static int s2io_chk_rx_buffers(nic_t *sp, int rng_n) { int rxb_size, level; @@ -3984,9 +4031,9 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n) static irqreturn_t s2io_msi_handle(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; int i; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; atomic_inc(&sp->isr_cnt); @@ -4016,8 +4063,8 @@ static irqreturn_t s2io_msi_handle(int irq, void *dev_id) static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) { - struct ring_info *ring = (struct ring_info *)dev_id; - struct s2io_nic *sp = ring->nic; + ring_info_t *ring = (ring_info_t *)dev_id; + nic_t *sp = ring->nic; atomic_inc(&sp->isr_cnt); @@ -4030,17 +4077,17 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) { - struct fifo_info *fifo = (struct fifo_info *)dev_id; - struct s2io_nic *sp = fifo->nic; + fifo_info_t *fifo = (fifo_info_t *)dev_id; + nic_t *sp = fifo->nic; atomic_inc(&sp->isr_cnt); tx_intr_handler(fifo); atomic_dec(&sp->isr_cnt); return IRQ_HANDLED; } -static void s2io_txpic_intr_handle(struct s2io_nic *sp) +static void s2io_txpic_intr_handle(nic_t *sp) { - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64; val64 = readq(&bar0->pic_int_status); @@ -4062,33 +4109,39 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp) } else if (val64 & GPIO_INT_REG_LINK_UP) { val64 = readq(&bar0->adapter_status); + if (verify_xena_quiescence(sp, val64, + sp->device_enabled_once)) { /* Enable Adapter */ - val64 = readq(&bar0->adapter_control); - val64 |= ADAPTER_CNTL_EN; - writeq(val64, &bar0->adapter_control); - val64 |= ADAPTER_LED_ON; - writeq(val64, &bar0->adapter_control); - if (!sp->device_enabled_once) - sp->device_enabled_once = 1; + val64 = readq(&bar0->adapter_control); + val64 |= ADAPTER_CNTL_EN; + writeq(val64, &bar0->adapter_control); + val64 |= ADAPTER_LED_ON; + writeq(val64, &bar0->adapter_control); + if (!sp->device_enabled_once) + sp->device_enabled_once = 1; - s2io_link(sp, LINK_UP); - /* - * unmask link down interrupt and mask link-up - * intr - */ - val64 = readq(&bar0->gpio_int_mask); - val64 &= ~GPIO_INT_MASK_LINK_DOWN; - val64 |= GPIO_INT_MASK_LINK_UP; - writeq(val64, &bar0->gpio_int_mask); + s2io_link(sp, LINK_UP); + /* + * unmask link down interrupt and mask link-up + * intr + */ + val64 = readq(&bar0->gpio_int_mask); + val64 &= ~GPIO_INT_MASK_LINK_DOWN; + val64 |= GPIO_INT_MASK_LINK_UP; + writeq(val64, &bar0->gpio_int_mask); + } }else if (val64 & GPIO_INT_REG_LINK_DOWN) { val64 = readq(&bar0->adapter_status); - s2io_link(sp, LINK_DOWN); - /* Link is down so unmaks link up interrupt */ - val64 = readq(&bar0->gpio_int_mask); - val64 &= ~GPIO_INT_MASK_LINK_UP; - val64 |= GPIO_INT_MASK_LINK_DOWN; - writeq(val64, &bar0->gpio_int_mask); + if (verify_xena_quiescence(sp, val64, + sp->device_enabled_once)) { + s2io_link(sp, LINK_DOWN); + /* Link is down so unmaks link up interrupt */ + val64 = readq(&bar0->gpio_int_mask); + val64 &= ~GPIO_INT_MASK_LINK_UP; + val64 |= GPIO_INT_MASK_LINK_DOWN; + writeq(val64, &bar0->gpio_int_mask); + } } } val64 = readq(&bar0->gpio_int_mask); @@ -4110,11 +4163,11 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp) static irqreturn_t s2io_isr(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; - struct s2io_nic *sp = dev->priv; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + nic_t *sp = dev->priv; + XENA_dev_config_t __iomem *bar0 = sp->bar0; int i; - u64 reason = 0; - struct mac_info *mac_control; + u64 reason = 0, val64, org_mask; + mac_info_t *mac_control; struct config_param *config; atomic_inc(&sp->isr_cnt); @@ -4132,48 +4185,43 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) reason = readq(&bar0->general_int_status); if (!reason) { - /* The interrupt was not raised by us. */ - atomic_dec(&sp->isr_cnt); - return IRQ_NONE; - } - else if (unlikely(reason == S2IO_MINUS_ONE) ) { - /* Disable device and get out */ + /* The interrupt was not raised by Xena. */ atomic_dec(&sp->isr_cnt); return IRQ_NONE; } - if (napi) { - if (reason & GEN_INTR_RXTRAFFIC) { - if ( likely ( netif_rx_schedule_prep(dev)) ) { - __netif_rx_schedule(dev); - writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask); - } - else - writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); - } - } else { - /* - * Rx handler is called by default, without checking for the - * cause of interrupt. - * rx_traffic_int reg is an R1 register, writing all 1's - * will ensure that the actual interrupt causing bit get's - * cleared and hence a read can be avoided. - */ - if (reason & GEN_INTR_RXTRAFFIC) - writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); + val64 = 0xFFFFFFFFFFFFFFFFULL; + /* Store current mask before masking all interrupts */ + org_mask = readq(&bar0->general_int_mask); + writeq(val64, &bar0->general_int_mask); - for (i = 0; i < config->rx_ring_num; i++) { - rx_intr_handler(&mac_control->rings[i]); +#ifdef CONFIG_S2IO_NAPI + if (reason & GEN_INTR_RXTRAFFIC) { + if (netif_rx_schedule_prep(dev)) { + writeq(val64, &bar0->rx_traffic_mask); + __netif_rx_schedule(dev); } } +#else + /* + * Rx handler is called by default, without checking for the + * cause of interrupt. + * rx_traffic_int reg is an R1 register, writing all 1's + * will ensure that the actual interrupt causing bit get's + * cleared and hence a read can be avoided. + */ + writeq(val64, &bar0->rx_traffic_int); + for (i = 0; i < config->rx_ring_num; i++) { + rx_intr_handler(&mac_control->rings[i]); + } +#endif /* * tx_traffic_int reg is an R1 register, writing all 1's * will ensure that the actual interrupt causing bit get's * cleared and hence a read can be avoided. */ - if (reason & GEN_INTR_TXTRAFFIC) - writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); + writeq(val64, &bar0->tx_traffic_int); for (i = 0; i < config->tx_fifo_num; i++) tx_intr_handler(&mac_control->fifos[i]); @@ -4185,14 +4233,11 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) * reallocate the buffers from the interrupt handler itself, * else schedule a tasklet to reallocate the buffers. */ - if (!napi) { - for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(sp, i); - } - - writeq(0, &bar0->general_int_mask); - readl(&bar0->general_int_status); - +#ifndef CONFIG_S2IO_NAPI + for (i = 0; i < config->rx_ring_num; i++) + s2io_chk_rx_buffers(sp, i); +#endif + writeq(org_mask, &bar0->general_int_mask); atomic_dec(&sp->isr_cnt); return IRQ_HANDLED; } @@ -4200,9 +4245,9 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) /** * s2io_updt_stats - */ -static void s2io_updt_stats(struct s2io_nic *sp) +static void s2io_updt_stats(nic_t *sp) { - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64; int cnt = 0; @@ -4221,7 +4266,7 @@ static void s2io_updt_stats(struct s2io_nic *sp) break; /* Updt failed */ } while(1); } else { - memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block)); + memset(sp->mac_control.stats_info, 0, sizeof(StatInfo_t)); } } @@ -4237,8 +4282,8 @@ static void s2io_updt_stats(struct s2io_nic *sp) static struct net_device_stats *s2io_get_stats(struct net_device *dev) { - struct s2io_nic *sp = dev->priv; - struct mac_info *mac_control; + nic_t *sp = dev->priv; + mac_info_t *mac_control; struct config_param *config; @@ -4279,8 +4324,8 @@ static void s2io_set_multicast(struct net_device *dev) { int i, j, prev_cnt; struct dev_mc_list *mclist; - struct s2io_nic *sp = dev->priv; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + nic_t *sp = dev->priv; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64 = 0, multi_mac = 0x010203040506ULL, mask = 0xfeffffffffffULL; u64 dis_addr = 0xffffffffffffULL, mac_addr = 0; @@ -4433,8 +4478,8 @@ static void s2io_set_multicast(struct net_device *dev) static int s2io_set_mac_addr(struct net_device *dev, u8 * addr) { - struct s2io_nic *sp = dev->priv; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + nic_t *sp = dev->priv; + XENA_dev_config_t __iomem *bar0 = sp->bar0; register u64 val64, mac_addr = 0; int i; @@ -4480,7 +4525,7 @@ static int s2io_set_mac_addr(struct net_device *dev, u8 * addr) static int s2io_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; if ((info->autoneg == AUTONEG_ENABLE) || (info->speed != SPEED_10000) || (info->duplex != DUPLEX_FULL)) return -EINVAL; @@ -4506,7 +4551,7 @@ static int s2io_ethtool_sset(struct net_device *dev, static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; info->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); info->advertising = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); info->port = PORT_FIBRE; @@ -4539,7 +4584,7 @@ static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) static void s2io_ethtool_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; strncpy(info->driver, s2io_driver_name, sizeof(info->driver)); strncpy(info->version, s2io_driver_version, sizeof(info->version)); @@ -4571,7 +4616,7 @@ static void s2io_ethtool_gregs(struct net_device *dev, int i; u64 reg; u8 *reg_space = (u8 *) space; - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; regs->len = XENA_REG_SPACE; regs->version = sp->pdev->subsystem_device; @@ -4593,8 +4638,8 @@ static void s2io_ethtool_gregs(struct net_device *dev, */ static void s2io_phy_id(unsigned long data) { - struct s2io_nic *sp = (struct s2io_nic *) data; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + nic_t *sp = (nic_t *) data; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64 = 0; u16 subid; @@ -4631,8 +4676,8 @@ static void s2io_phy_id(unsigned long data) static int s2io_ethtool_idnic(struct net_device *dev, u32 data) { u64 val64 = 0, last_gpio_ctrl_val; - struct s2io_nic *sp = dev->priv; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + nic_t *sp = dev->priv; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u16 subid; subid = sp->pdev->subsystem_device; @@ -4680,8 +4725,8 @@ static void s2io_ethtool_getpause_data(struct net_device *dev, struct ethtool_pauseparam *ep) { u64 val64; - struct s2io_nic *sp = dev->priv; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + nic_t *sp = dev->priv; + XENA_dev_config_t __iomem *bar0 = sp->bar0; val64 = readq(&bar0->rmac_pause_cfg); if (val64 & RMAC_PAUSE_GEN_ENABLE) @@ -4707,8 +4752,8 @@ static int s2io_ethtool_setpause_data(struct net_device *dev, struct ethtool_pauseparam *ep) { u64 val64; - struct s2io_nic *sp = dev->priv; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + nic_t *sp = dev->priv; + XENA_dev_config_t __iomem *bar0 = sp->bar0; val64 = readq(&bar0->rmac_pause_cfg); if (ep->tx_pause) @@ -4740,12 +4785,12 @@ static int s2io_ethtool_setpause_data(struct net_device *dev, */ #define S2IO_DEV_ID 5 -static int read_eeprom(struct s2io_nic * sp, int off, u64 * data) +static int read_eeprom(nic_t * sp, int off, u64 * data) { int ret = -1; u32 exit_cnt = 0; u64 val64; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; if (sp->device_type == XFRAME_I_DEVICE) { val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | @@ -4805,11 +4850,11 @@ static int read_eeprom(struct s2io_nic * sp, int off, u64 * data) * 0 on success, -1 on failure. */ -static int write_eeprom(struct s2io_nic * sp, int off, u64 data, int cnt) +static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) { int exit_cnt = 0, ret = -1; u64 val64; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; if (sp->device_type == XFRAME_I_DEVICE) { val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | @@ -4854,7 +4899,7 @@ static int write_eeprom(struct s2io_nic * sp, int off, u64 data, int cnt) } return ret; } -static void s2io_vpd_read(struct s2io_nic *nic) +static void s2io_vpd_read(nic_t *nic) { u8 *vpd_data; u8 data; @@ -4869,7 +4914,6 @@ static void s2io_vpd_read(struct s2io_nic *nic) strcpy(nic->product_name, "Xframe I 10GbE network adapter"); vpd_addr = 0x50; } - strcpy(nic->serial_num, "NOT AVAILABLE"); vpd_data = kmalloc(256, GFP_KERNEL); if (!vpd_data) @@ -4893,22 +4937,7 @@ static void s2io_vpd_read(struct s2io_nic *nic) pci_read_config_dword(nic->pdev, (vpd_addr + 4), (u32 *)&vpd_data[i]); } - - if(!fail) { - /* read serial number of adapter */ - for (cnt = 0; cnt < 256; cnt++) { - if ((vpd_data[cnt] == 'S') && - (vpd_data[cnt+1] == 'N') && - (vpd_data[cnt+2] < VPD_STRING_LEN)) { - memset(nic->serial_num, 0, VPD_STRING_LEN); - memcpy(nic->serial_num, &vpd_data[cnt + 3], - vpd_data[cnt+2]); - break; - } - } - } - - if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) { + if ((!fail) && (vpd_data[1] < VPD_PRODUCT_NAME_LEN)) { memset(nic->product_name, 0, vpd_data[1]); memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); } @@ -4933,7 +4962,7 @@ static int s2io_ethtool_geeprom(struct net_device *dev, { u32 i, valid; u64 data; - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16); @@ -4971,7 +5000,7 @@ static int s2io_ethtool_seeprom(struct net_device *dev, { int len = eeprom->len, cnt = 0; u64 valid = 0, data; - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) { DBG_PRINT(ERR_DBG, @@ -5015,9 +5044,9 @@ static int s2io_ethtool_seeprom(struct net_device *dev, * 0 on success. */ -static int s2io_register_test(struct s2io_nic * sp, uint64_t * data) +static int s2io_register_test(nic_t * sp, uint64_t * data) { - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64 = 0, exp_val; int fail = 0; @@ -5082,7 +5111,7 @@ static int s2io_register_test(struct s2io_nic * sp, uint64_t * data) * 0 on success. */ -static int s2io_eeprom_test(struct s2io_nic * sp, uint64_t * data) +static int s2io_eeprom_test(nic_t * sp, uint64_t * data) { int fail = 0; u64 ret_data, org_4F0, org_7F0; @@ -5184,7 +5213,7 @@ static int s2io_eeprom_test(struct s2io_nic * sp, uint64_t * data) * 0 on success and -1 on failure. */ -static int s2io_bist_test(struct s2io_nic * sp, uint64_t * data) +static int s2io_bist_test(nic_t * sp, uint64_t * data) { u8 bist = 0; int cnt = 0, ret = -1; @@ -5220,9 +5249,9 @@ static int s2io_bist_test(struct s2io_nic * sp, uint64_t * data) * 0 on success. */ -static int s2io_link_test(struct s2io_nic * sp, uint64_t * data) +static int s2io_link_test(nic_t * sp, uint64_t * data) { - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64; val64 = readq(&bar0->adapter_status); @@ -5247,9 +5276,9 @@ static int s2io_link_test(struct s2io_nic * sp, uint64_t * data) * 0 on success. */ -static int s2io_rldram_test(struct s2io_nic * sp, uint64_t * data) +static int s2io_rldram_test(nic_t * sp, uint64_t * data) { - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64; int cnt, iteration = 0, test_fail = 0; @@ -5351,7 +5380,7 @@ static void s2io_ethtool_test(struct net_device *dev, struct ethtool_test *ethtest, uint64_t * data) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; int orig_state = netif_running(sp->dev); if (ethtest->flags == ETH_TEST_FL_OFFLINE) { @@ -5407,8 +5436,8 @@ static void s2io_get_ethtool_stats(struct net_device *dev, u64 * tmp_stats) { int i = 0; - struct s2io_nic *sp = dev->priv; - struct stat_block *stat_info = sp->mac_control.stats_info; + nic_t *sp = dev->priv; + StatInfo_t *stat_info = sp->mac_control.stats_info; s2io_updt_stats(sp); tmp_stats[i++] = @@ -5635,14 +5664,14 @@ static int s2io_ethtool_get_regs_len(struct net_device *dev) static u32 s2io_ethtool_get_rx_csum(struct net_device * dev) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; return (sp->rx_csum); } static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; if (data) sp->rx_csum = 1; @@ -5721,8 +5750,10 @@ static const struct ethtool_ops netdev_ethtool_ops = { .set_tx_csum = s2io_ethtool_op_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, +#ifdef NETIF_F_TSO .get_tso = s2io_ethtool_op_get_tso, .set_tso = s2io_ethtool_op_set_tso, +#endif .get_ufo = ethtool_op_get_ufo, .set_ufo = ethtool_op_set_ufo, .self_test_count = s2io_ethtool_self_test_count, @@ -5763,7 +5794,7 @@ static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) static int s2io_change_mtu(struct net_device *dev, int new_mtu) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) { DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n", @@ -5782,7 +5813,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) if (netif_queue_stopped(dev)) netif_wake_queue(dev); } else { /* Device is down */ - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64 = new_mtu; writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); @@ -5807,9 +5838,9 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) static void s2io_tasklet(unsigned long dev_addr) { struct net_device *dev = (struct net_device *) dev_addr; - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; int i, ret; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; mac_control = &sp->mac_control; @@ -5842,9 +5873,9 @@ static void s2io_tasklet(unsigned long dev_addr) static void s2io_set_link(struct work_struct *work) { - struct s2io_nic *nic = container_of(work, struct s2io_nic, set_link_task); + nic_t *nic = container_of(work, nic_t, set_link_task); struct net_device *dev = nic->dev; - struct XENA_dev_config __iomem *bar0 = nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; register u64 val64; u16 subid; @@ -5863,53 +5894,57 @@ static void s2io_set_link(struct work_struct *work) } val64 = readq(&bar0->adapter_status); - if (LINK_IS_UP(val64)) { - if (!(readq(&bar0->adapter_control) & ADAPTER_CNTL_EN)) { - if (verify_xena_quiescence(nic)) { - val64 = readq(&bar0->adapter_control); - val64 |= ADAPTER_CNTL_EN; + if (verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { + if (LINK_IS_UP(val64)) { + val64 = readq(&bar0->adapter_control); + val64 |= ADAPTER_CNTL_EN; + writeq(val64, &bar0->adapter_control); + if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, + subid)) { + val64 = readq(&bar0->gpio_control); + val64 |= GPIO_CTRL_GPIO_0; + writeq(val64, &bar0->gpio_control); + val64 = readq(&bar0->gpio_control); + } else { + val64 |= ADAPTER_LED_ON; writeq(val64, &bar0->adapter_control); - if (CARDS_WITH_FAULTY_LINK_INDICATORS( - nic->device_type, subid)) { - val64 = readq(&bar0->gpio_control); - val64 |= GPIO_CTRL_GPIO_0; - writeq(val64, &bar0->gpio_control); - val64 = readq(&bar0->gpio_control); - } else { - val64 |= ADAPTER_LED_ON; - writeq(val64, &bar0->adapter_control); + } + if (s2io_link_fault_indication(nic) == + MAC_RMAC_ERR_TIMER) { + val64 = readq(&bar0->adapter_status); + if (!LINK_IS_UP(val64)) { + DBG_PRINT(ERR_DBG, "%s:", dev->name); + DBG_PRINT(ERR_DBG, " Link down"); + DBG_PRINT(ERR_DBG, "after "); + DBG_PRINT(ERR_DBG, "enabling "); + DBG_PRINT(ERR_DBG, "device \n"); } + } + if (nic->device_enabled_once == FALSE) { nic->device_enabled_once = TRUE; - } else { - DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); - DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); - netif_stop_queue(dev); } - } - val64 = readq(&bar0->adapter_status); - if (!LINK_IS_UP(val64)) { - DBG_PRINT(ERR_DBG, "%s:", dev->name); - DBG_PRINT(ERR_DBG, " Link down after enabling "); - DBG_PRINT(ERR_DBG, "device \n"); - } else s2io_link(nic, LINK_UP); - } else { - if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, - subid)) { - val64 = readq(&bar0->gpio_control); - val64 &= ~GPIO_CTRL_GPIO_0; - writeq(val64, &bar0->gpio_control); - val64 = readq(&bar0->gpio_control); + } else { + if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, + subid)) { + val64 = readq(&bar0->gpio_control); + val64 &= ~GPIO_CTRL_GPIO_0; + writeq(val64, &bar0->gpio_control); + val64 = readq(&bar0->gpio_control); + } + s2io_link(nic, LINK_DOWN); } - s2io_link(nic, LINK_DOWN); + } else { /* NIC is not Quiescent. */ + DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); + DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); + netif_stop_queue(dev); } clear_bit(0, &(nic->link_state)); } -static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, - struct buffAdd *ba, - struct sk_buff **skb, u64 *temp0, u64 *temp1, - u64 *temp2, int size) +static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba, + struct sk_buff **skb, u64 *temp0, u64 *temp1, + u64 *temp2, int size) { struct net_device *dev = sp->dev; struct sk_buff *frag_list; @@ -5923,7 +5958,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, * using same mapped address for the Rxd * buffer pointer */ - ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0; + ((RxD1_t*)rxdp)->Buffer0_ptr = *temp0; } else { *skb = dev_alloc_skb(size); if (!(*skb)) { @@ -5935,7 +5970,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, * such it will be used for next rxd whose * Host Control is NULL */ - ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0 = + ((RxD1_t*)rxdp)->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); @@ -5944,36 +5979,36 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { /* Two buffer Mode */ if (*skb) { - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2; - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0; - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1; + ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; + ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0; + ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; } else { *skb = dev_alloc_skb(size); if (!(*skb)) { DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n", - dev->name); + dev->name); return -ENOMEM; } - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 = + ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 = + ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); rxdp->Host_Control = (unsigned long) (*skb); /* Buffer-1 will be dummy buffer not used */ - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 = + ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); } } else if ((rxdp->Host_Control == 0)) { /* Three buffer mode */ if (*skb) { - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0; - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1; - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2; + ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0; + ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; + ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; } else { *skb = dev_alloc_skb(size); if (!(*skb)) { @@ -5981,11 +6016,11 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, dev->name); return -ENOMEM; } - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 = + ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); /* Buffer-1 receives L3/L4 headers */ - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 = + ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1 = pci_map_single( sp->pdev, (*skb)->data, l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); @@ -6005,15 +6040,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, /* * Buffer-2 receives L4 data payload */ - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 = + ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = pci_map_single( sp->pdev, frag_list->data, dev->mtu, PCI_DMA_FROMDEVICE); } } return 0; } -static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp, - int size) +static void set_rxd_buffer_size(nic_t *sp, RxD_t *rxdp, int size) { struct net_device *dev = sp->dev; if (sp->rxd_mode == RXD_MODE_1) { @@ -6029,15 +6063,15 @@ static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp, } } -static int rxd_owner_bit_reset(struct s2io_nic *sp) +static int rxd_owner_bit_reset(nic_t *sp) { int i, j, k, blk_cnt = 0, size; - struct mac_info * mac_control = &sp->mac_control; + mac_info_t * mac_control = &sp->mac_control; struct config_param *config = &sp->config; struct net_device *dev = sp->dev; - struct RxD_t *rxdp = NULL; + RxD_t *rxdp = NULL; struct sk_buff *skb = NULL; - struct buffAdd *ba = NULL; + buffAdd_t *ba = NULL; u64 temp0_64 = 0, temp1_64 = 0, temp2_64 = 0; /* Calculate the size based on ring mode */ @@ -6076,7 +6110,7 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp) } -static int s2io_add_isr(struct s2io_nic * sp) +static int s2io_add_isr(nic_t * sp) { int ret = 0; struct net_device *dev = sp->dev; @@ -6091,7 +6125,7 @@ static int s2io_add_isr(struct s2io_nic * sp) sp->intr_type = INTA; } - /* Store the values of the MSIX table in the struct s2io_nic structure */ + /* Store the values of the MSIX table in the nic_t structure */ store_xmsi_data(sp); /* After proper initialization of H/W, register ISR */ @@ -6146,7 +6180,7 @@ static int s2io_add_isr(struct s2io_nic * sp) } return 0; } -static void s2io_rem_isr(struct s2io_nic * sp) +static void s2io_rem_isr(nic_t * sp) { int cnt = 0; struct net_device *dev = sp->dev; @@ -6188,10 +6222,10 @@ static void s2io_rem_isr(struct s2io_nic * sp) } while(cnt < 5); } -static void s2io_card_down(struct s2io_nic * sp) +static void s2io_card_down(nic_t * sp) { int cnt = 0; - struct XENA_dev_config __iomem *bar0 = sp->bar0; + XENA_dev_config_t __iomem *bar0 = sp->bar0; unsigned long flags; register u64 val64 = 0; @@ -6222,8 +6256,7 @@ static void s2io_card_down(struct s2io_nic * sp) rxd_owner_bit_reset(sp); val64 = readq(&bar0->adapter_status); - if (verify_xena_quiescence(sp)) { - if(verify_pcc_quiescent(sp, sp->device_enabled_once)) + if (verify_xena_quiescence(sp, val64, sp->device_enabled_once)) { break; } @@ -6252,10 +6285,10 @@ static void s2io_card_down(struct s2io_nic * sp) clear_bit(0, &(sp->link_state)); } -static int s2io_card_up(struct s2io_nic * sp) +static int s2io_card_up(nic_t * sp) { int i, ret = 0; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; struct net_device *dev = (struct net_device *) sp->dev; u16 interruptible; @@ -6286,13 +6319,6 @@ static int s2io_card_up(struct s2io_nic * sp) DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i, atomic_read(&sp->rx_bufs_left[i])); } - /* Maintain the state prior to the open */ - if (sp->promisc_flg) - sp->promisc_flg = 0; - if (sp->m_cast_flg) { - sp->m_cast_flg = 0; - sp->all_multi_pos= 0; - } /* Setting its receive mode */ s2io_set_multicast(dev); @@ -6354,7 +6380,7 @@ static int s2io_card_up(struct s2io_nic * sp) static void s2io_restart_nic(struct work_struct *work) { - struct s2io_nic *sp = container_of(work, struct s2io_nic, rst_timer_task); + nic_t *sp = container_of(work, nic_t, rst_timer_task); struct net_device *dev = sp->dev; s2io_card_down(sp); @@ -6383,7 +6409,7 @@ static void s2io_restart_nic(struct work_struct *work) static void s2io_tx_watchdog(struct net_device *dev) { - struct s2io_nic *sp = dev->priv; + nic_t *sp = dev->priv; if (netif_carrier_ok(dev)) { schedule_work(&sp->rst_timer_task); @@ -6408,16 +6434,16 @@ static void s2io_tx_watchdog(struct net_device *dev) * Return value: * SUCCESS on success and -1 on failure. */ -static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) +static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) { - struct s2io_nic *sp = ring_data->nic; + nic_t *sp = ring_data->nic; struct net_device *dev = (struct net_device *) sp->dev; struct sk_buff *skb = (struct sk_buff *) ((unsigned long) rxdp->Host_Control); int ring_no = ring_data->ring_no; u16 l3_csum, l4_csum; unsigned long long err = rxdp->Control_1 & RXD_T_CODE; - struct lro *lro; + lro_t *lro; skb->dev = dev; @@ -6462,7 +6488,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) int buf2_len = RXD_GET_BUFFER2_SIZE_3(rxdp->Control_2); unsigned char *buff = skb_push(skb, buf0_len); - struct buffAdd *ba = &ring_data->ba[get_block][get_off]; + buffAdd_t *ba = &ring_data->ba[get_block][get_off]; sp->stats.rx_bytes += buf0_len + buf2_len; memcpy(buff, ba->ba_0, buf0_len); @@ -6472,6 +6498,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) skb_put(skb, buf1_len); skb->len += buf2_len; skb->data_len += buf2_len; + skb->truesize += buf2_len; skb_put(skb_shinfo(skb)->frag_list, buf2_len); sp->stats.rx_bytes += buf1_len; @@ -6555,20 +6582,23 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) if (!sp->lro) { skb->protocol = eth_type_trans(skb, dev); +#ifdef CONFIG_S2IO_NAPI if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { /* Queueing the vlan frame to the upper layer */ - if (napi) - vlan_hwaccel_receive_skb(skb, sp->vlgrp, - RXD_GET_VLAN_TAG(rxdp->Control_2)); - else - vlan_hwaccel_rx(skb, sp->vlgrp, - RXD_GET_VLAN_TAG(rxdp->Control_2)); + vlan_hwaccel_receive_skb(skb, sp->vlgrp, + RXD_GET_VLAN_TAG(rxdp->Control_2)); } else { - if (napi) - netif_receive_skb(skb); - else - netif_rx(skb); + netif_receive_skb(skb); } +#else + if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { + /* Queueing the vlan frame to the upper layer */ + vlan_hwaccel_rx(skb, sp->vlgrp, + RXD_GET_VLAN_TAG(rxdp->Control_2)); + } else { + netif_rx(skb); + } +#endif } else { send_up: queue_rx_frame(skb); @@ -6592,7 +6622,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) * void. */ -static void s2io_link(struct s2io_nic * sp, int link) +static void s2io_link(nic_t * sp, int link) { struct net_device *dev = (struct net_device *) sp->dev; @@ -6636,7 +6666,7 @@ static int get_xena_rev_id(struct pci_dev *pdev) * void */ -static void s2io_init_pci(struct s2io_nic * sp) +static void s2io_init_pci(nic_t * sp) { u16 pci_cmd = 0, pcix_cmd = 0; @@ -6669,9 +6699,13 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) DBG_PRINT(ERR_DBG, "s2io: Default to 8 Rx rings\n"); rx_ring_num = 8; } - if (*dev_intr_type != INTA) - napi = 0; - +#ifdef CONFIG_S2IO_NAPI + if (*dev_intr_type != INTA) { + DBG_PRINT(ERR_DBG, "s2io: NAPI cannot be enabled when " + "MSI/MSI-X is enabled. Defaulting to INTA\n"); + *dev_intr_type = INTA; + } +#endif #ifndef CONFIG_PCI_MSI if (*dev_intr_type != INTA) { DBG_PRINT(ERR_DBG, "s2io: This kernel does not support" @@ -6692,8 +6726,6 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) "Defaulting to INTA\n"); *dev_intr_type = INTA; } - if ( (rx_ring_num > 1) && (*dev_intr_type != INTA) ) - napi = 0; if (rx_ring_mode > 3) { DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n"); DBG_PRINT(ERR_DBG, "s2io: Defaulting to 3-buffer mode\n"); @@ -6719,15 +6751,15 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) static int __devinit s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) { - struct s2io_nic *sp; + nic_t *sp; struct net_device *dev; int i, j, ret; int dma_flag = FALSE; u32 mac_up, mac_down; u64 val64 = 0, tmp64 = 0; - struct XENA_dev_config __iomem *bar0 = NULL; + XENA_dev_config_t __iomem *bar0 = NULL; u16 subid; - struct mac_info *mac_control; + mac_info_t *mac_control; struct config_param *config; int mode; u8 dev_intr_type = intr_type; @@ -6782,7 +6814,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) } } - dev = alloc_etherdev(sizeof(struct s2io_nic)); + dev = alloc_etherdev(sizeof(nic_t)); if (dev == NULL) { DBG_PRINT(ERR_DBG, "Device allocation failed\n"); pci_disable_device(pdev); @@ -6797,7 +6829,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* Private member variable initialized to s2io NIC structure */ sp = dev->priv; - memset(sp, 0, sizeof(struct s2io_nic)); + memset(sp, 0, sizeof(nic_t)); sp->dev = dev; sp->pdev = pdev; sp->high_dma_flag = dma_flag; @@ -6893,7 +6925,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) sp->bar0 = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (!sp->bar0) { - DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem1\n", + DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem1\n", dev->name); ret = -ENOMEM; goto bar0_remap_failed; @@ -6902,7 +6934,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) sp->bar1 = ioremap(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2)); if (!sp->bar1) { - DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem2\n", + DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem2\n", dev->name); ret = -ENOMEM; goto bar1_remap_failed; @@ -6913,7 +6945,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* Initializing the BAR1 address as the start of the FIFO pointer. */ for (j = 0; j < MAX_TX_FIFOS; j++) { - mac_control->tx_FIFO_start[j] = (struct TxFIFO_element __iomem *) + mac_control->tx_FIFO_start[j] = (TxFIFO_element_t __iomem *) (sp->bar1 + (j * 0x00020000)); } @@ -6934,8 +6966,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) * will use eth_mac_addr() for dev->set_mac_address * mac address will be set every time dev->open() is called */ +#if defined(CONFIG_S2IO_NAPI) dev->poll = s2io_poll; dev->weight = 32; +#endif #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = s2io_netpoll; @@ -6944,9 +6978,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; if (sp->high_dma_flag == TRUE) dev->features |= NETIF_F_HIGHDMA; +#ifdef NETIF_F_TSO dev->features |= NETIF_F_TSO; +#endif +#ifdef NETIF_F_TSO6 dev->features |= NETIF_F_TSO6; - if ((sp->device_type & XFRAME_II_DEVICE) && (ufo)) { +#endif + if (sp->device_type & XFRAME_II_DEVICE) { dev->features |= NETIF_F_UFO; dev->features |= NETIF_F_HW_CSUM; } @@ -7027,9 +7065,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* Initialize spinlocks */ spin_lock_init(&sp->tx_lock); - - if (!napi) - spin_lock_init(&sp->put_lock); +#ifndef CONFIG_S2IO_NAPI + spin_lock_init(&sp->put_lock); +#endif spin_lock_init(&sp->rx_lock); /* @@ -7060,14 +7098,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name, s2io_driver_version); DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " - "%02x:%02x:%02x:%02x:%02x:%02x", dev->name, + "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, sp->def_mac_addr[0].mac_addr[0], sp->def_mac_addr[0].mac_addr[1], sp->def_mac_addr[0].mac_addr[2], sp->def_mac_addr[0].mac_addr[3], sp->def_mac_addr[0].mac_addr[4], sp->def_mac_addr[0].mac_addr[5]); - DBG_PRINT(ERR_DBG, "SERIAL NUMBER: %s\n", sp->serial_num); if (sp->device_type & XFRAME_II_DEVICE) { mode = s2io_print_pci_mode(sp); if (mode < 0) { @@ -7091,9 +7128,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->name); break; } - - if (napi) - DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); +#ifdef CONFIG_S2IO_NAPI + DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); +#endif switch(sp->intr_type) { case INTA: DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); @@ -7108,9 +7145,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) if (sp->lro) DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", dev->name); - if (ufo) - DBG_PRINT(ERR_DBG, "%s: UDP Fragmentation Offload(UFO)" - " enabled\n", dev->name); + /* Initialize device name */ sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name); @@ -7167,7 +7202,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) { struct net_device *dev = (struct net_device *) pci_get_drvdata(pdev); - struct s2io_nic *sp; + nic_t *sp; if (dev == NULL) { DBG_PRINT(ERR_DBG, "Driver Data is NULL!!\n"); @@ -7180,6 +7215,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) free_shared_mem(sp); iounmap(sp->bar0); iounmap(sp->bar1); + pci_disable_device(pdev); if (sp->intr_type != MSI_X) pci_release_regions(pdev); else { @@ -7190,7 +7226,6 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) } pci_set_drvdata(pdev, NULL); free_netdev(dev); - pci_disable_device(pdev); } /** @@ -7209,7 +7244,7 @@ int __init s2io_starter(void) * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. */ -static __exit void s2io_closer(void) +static void s2io_closer(void) { pci_unregister_driver(&s2io_driver); DBG_PRINT(INIT_DBG, "cleanup done\n"); @@ -7219,7 +7254,7 @@ module_init(s2io_starter); module_exit(s2io_closer); static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, - struct tcphdr **tcp, struct RxD_t *rxdp) + struct tcphdr **tcp, RxD_t *rxdp) { int ip_off; u8 l2_type = (u8)((rxdp->Control_1 >> 37) & 0x7), ip_len; @@ -7253,7 +7288,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, return 0; } -static int check_for_socket_match(struct lro *lro, struct iphdr *ip, +static int check_for_socket_match(lro_t *lro, struct iphdr *ip, struct tcphdr *tcp) { DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); @@ -7268,7 +7303,7 @@ static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp) return(ntohs(ip->tot_len) - (ip->ihl << 2) - (tcp->doff << 2)); } -static void initiate_new_session(struct lro *lro, u8 *l2h, +static void initiate_new_session(lro_t *lro, u8 *l2h, struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len) { DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); @@ -7294,12 +7329,12 @@ static void initiate_new_session(struct lro *lro, u8 *l2h, lro->in_use = 1; } -static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) +static void update_L3L4_header(nic_t *sp, lro_t *lro) { struct iphdr *ip = lro->iph; struct tcphdr *tcp = lro->tcph; u16 nchk; - struct stat_block *statinfo = sp->mac_control.stats_info; + StatInfo_t *statinfo = sp->mac_control.stats_info; DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); /* Update L3 header */ @@ -7325,7 +7360,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) statinfo->sw_stat.num_aggregations++; } -static void aggregate_new_rx(struct lro *lro, struct iphdr *ip, +static void aggregate_new_rx(lro_t *lro, struct iphdr *ip, struct tcphdr *tcp, u32 l4_pyld) { DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); @@ -7347,7 +7382,7 @@ static void aggregate_new_rx(struct lro *lro, struct iphdr *ip, } } -static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip, +static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len) { u8 *ptr; @@ -7405,8 +7440,8 @@ static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip, } static int -s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, - struct RxD_t *rxdp, struct s2io_nic *sp) +s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, lro_t **lro, + RxD_t *rxdp, nic_t *sp) { struct iphdr *ip; struct tcphdr *tcph; @@ -7423,7 +7458,7 @@ s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, tcph = (struct tcphdr *)*tcp; *tcp_len = get_l4_pyld_length(ip, tcph); for (i=0; ilro0_n[i]; + lro_t *l_lro = &sp->lro0_n[i]; if (l_lro->in_use) { if (check_for_socket_match(l_lro, ip, tcph)) continue; @@ -7461,7 +7496,7 @@ s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, } for (i=0; ilro0_n[i]; + lro_t *l_lro = &sp->lro0_n[i]; if (!(l_lro->in_use)) { *lro = l_lro; ret = 3; /* Begin anew */ @@ -7500,9 +7535,9 @@ s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, return ret; } -static void clear_lro_session(struct lro *lro) +static void clear_lro_session(lro_t *lro) { - static u16 lro_struct_size = sizeof(struct lro); + static u16 lro_struct_size = sizeof(lro_t); memset(lro, 0, lro_struct_size); } @@ -7512,14 +7547,14 @@ static void queue_rx_frame(struct sk_buff *skb) struct net_device *dev = skb->dev; skb->protocol = eth_type_trans(skb, dev); - if (napi) - netif_receive_skb(skb); - else - netif_rx(skb); +#ifdef CONFIG_S2IO_NAPI + netif_receive_skb(skb); +#else + netif_rx(skb); +#endif } -static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, - struct sk_buff *skb, +static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, u32 tcp_len) { struct sk_buff *first = lro->parent; @@ -7531,7 +7566,6 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, lro->last_frag->next = skb; else skb_shinfo(first)->frag_list = skb; - first->truesize += skb->truesize; lro->last_frag = skb; sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; return; diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index a5e1a513deb5..3b0bafd273c8 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -30,8 +30,6 @@ #undef SUCCESS #define SUCCESS 0 #define FAILURE -1 -#define S2IO_MINUS_ONE 0xFFFFFFFFFFFFFFFFULL -#define S2IO_MAX_PCI_CONFIG_SPACE_REINIT 100 #define CHECKBIT(value, nbit) (value & (1 << nbit)) @@ -39,7 +37,7 @@ #define MAX_FLICKER_TIME 60000 /* 60 Secs */ /* Maximum outstanding splits to be configured into xena. */ -enum { +typedef enum xena_max_outstanding_splits { XENA_ONE_SPLIT_TRANSACTION = 0, XENA_TWO_SPLIT_TRANSACTION = 1, XENA_THREE_SPLIT_TRANSACTION = 2, @@ -48,7 +46,7 @@ enum { XENA_TWELVE_SPLIT_TRANSACTION = 5, XENA_SIXTEEN_SPLIT_TRANSACTION = 6, XENA_THIRTYTWO_SPLIT_TRANSACTION = 7 -}; +} xena_max_outstanding_splits; #define XENA_MAX_OUTSTANDING_SPLITS(n) (n << 4) /* OS concerned variables and constants */ @@ -79,7 +77,7 @@ static int debug_level = ERR_DBG; #define S2IO_JUMBO_SIZE 9600 /* Driver statistics maintained by driver */ -struct swStat { +typedef struct { unsigned long long single_ecc_errs; unsigned long long double_ecc_errs; unsigned long long parity_err_cnt; @@ -94,10 +92,10 @@ struct swStat { unsigned long long flush_max_pkts; unsigned long long sum_avg_pkts_aggregated; unsigned long long num_aggregations; -}; +} swStat_t; /* Xpak releated alarm and warnings */ -struct xpakStat { +typedef struct { u64 alarm_transceiver_temp_high; u64 alarm_transceiver_temp_low; u64 alarm_laser_bias_current_high; @@ -112,11 +110,11 @@ struct xpakStat { u64 warn_laser_output_power_low; u64 xpak_regs_stat; u32 xpak_timer_count; -}; +} xpakStat_t; /* The statistics block of Xena */ -struct stat_block { +typedef struct stat_block { /* Tx MAC statistics counters. */ __le32 tmac_data_octets; __le32 tmac_frms; @@ -292,9 +290,9 @@ struct stat_block { __le32 reserved_14; __le32 link_fault_cnt; u8 buffer[20]; - struct swStat sw_stat; - struct xpakStat xpak_stat; -}; + swStat_t sw_stat; + xpakStat_t xpak_stat; +} StatInfo_t; /* * Structures representing different init time configuration @@ -317,7 +315,7 @@ static int fifo_map[][MAX_TX_FIFOS] = { }; /* Maintains Per FIFO related information. */ -struct tx_fifo_config { +typedef struct tx_fifo_config { #define MAX_AVAILABLE_TXDS 8192 u32 fifo_len; /* specifies len of FIFO upto 8192, ie no of TxDLs */ /* Priority definition */ @@ -334,11 +332,11 @@ struct tx_fifo_config { u8 f_no_snoop; #define NO_SNOOP_TXD 0x01 #define NO_SNOOP_TXD_BUFFER 0x02 -}; +} tx_fifo_config_t; /* Maintains per Ring related information */ -struct rx_ring_config { +typedef struct rx_ring_config { u32 num_rxd; /*No of RxDs per Rx Ring */ #define RX_RING_PRI_0 0 /* highest */ #define RX_RING_PRI_1 1 @@ -359,7 +357,7 @@ struct rx_ring_config { u8 f_no_snoop; #define NO_SNOOP_RXD 0x01 #define NO_SNOOP_RXD_BUFFER 0x02 -}; +} rx_ring_config_t; /* This structure provides contains values of the tunable parameters * of the H/W @@ -369,7 +367,7 @@ struct config_param { u32 tx_fifo_num; /*Number of Tx FIFOs */ u8 fifo_mapping[MAX_TX_FIFOS]; - struct tx_fifo_config tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ + tx_fifo_config_t tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */ u64 tx_intr_type; /* Specifies if Tx Intr is UTILZ or PER_LIST type. */ @@ -378,7 +376,7 @@ struct config_param { u32 rx_ring_num; /*Number of receive rings */ #define MAX_RX_BLOCKS_PER_RING 150 - struct rx_ring_config rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ + rx_ring_config_t rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ u8 bimodal; /*Flag for setting bimodal interrupts*/ #define HEADER_ETHERNET_II_802_3_SIZE 14 @@ -397,14 +395,14 @@ struct config_param { }; /* Structure representing MAC Addrs */ -struct mac_addr { +typedef struct mac_addr { u8 mac_addr[ETH_ALEN]; -}; +} macaddr_t; /* Structure that represent every FIFO element in the BAR1 * Address location. */ -struct TxFIFO_element { +typedef struct _TxFIFO_element { u64 TxDL_Pointer; u64 List_Control; @@ -415,10 +413,10 @@ struct TxFIFO_element { #define TX_FIFO_SPECIAL_FUNC BIT(23) #define TX_FIFO_DS_NO_SNOOP BIT(31) #define TX_FIFO_BUFF_NO_SNOOP BIT(30) -}; +} TxFIFO_element_t; /* Tx descriptor structure */ -struct TxD { +typedef struct _TxD { u64 Control_1; /* bit mask */ #define TXD_LIST_OWN_XENA BIT(7) @@ -449,16 +447,16 @@ struct TxD { u64 Buffer_Pointer; u64 Host_Control; /* reserved for host */ -}; +} TxD_t; /* Structure to hold the phy and virt addr of every TxDL. */ -struct list_info_hold { +typedef struct list_info_hold { dma_addr_t list_phy_addr; void *list_virt_addr; -}; +} list_info_hold_t; /* Rx descriptor structure for 1 buffer mode */ -struct RxD_t { +typedef struct _RxD_t { u64 Host_Control; /* reserved for host */ u64 Control_1; #define RXD_OWN_XENA BIT(7) @@ -483,21 +481,21 @@ struct RxD_t { #define SET_NUM_TAG(val) vBIT(val,16,32) -}; +} RxD_t; /* Rx descriptor structure for 1 buffer mode */ -struct RxD1 { - struct RxD_t h; +typedef struct _RxD1_t { + struct _RxD_t h; #define MASK_BUFFER0_SIZE_1 vBIT(0x3FFF,2,14) #define SET_BUFFER0_SIZE_1(val) vBIT(val,2,14) #define RXD_GET_BUFFER0_SIZE_1(_Control_2) \ (u16)((_Control_2 & MASK_BUFFER0_SIZE_1) >> 48) u64 Buffer0_ptr; -}; +} RxD1_t; /* Rx descriptor structure for 3 or 2 buffer mode */ -struct RxD3 { - struct RxD_t h; +typedef struct _RxD3_t { + struct _RxD_t h; #define MASK_BUFFER0_SIZE_3 vBIT(0xFF,2,14) #define MASK_BUFFER1_SIZE_3 vBIT(0xFFFF,16,16) @@ -517,15 +515,15 @@ struct RxD3 { u64 Buffer0_ptr; u64 Buffer1_ptr; u64 Buffer2_ptr; -}; +} RxD3_t; /* Structure that represents the Rx descriptor block which contains * 128 Rx descriptors. */ -struct RxD_block { +typedef struct _RxD_block { #define MAX_RXDS_PER_BLOCK_1 127 - struct RxD1 rxd[MAX_RXDS_PER_BLOCK_1]; + RxD1_t rxd[MAX_RXDS_PER_BLOCK_1]; u64 reserved_0; #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL @@ -535,22 +533,22 @@ struct RxD_block { u64 pNext_RxD_Blk_physical; /* Buff0_ptr.In a 32 bit arch * the upper 32 bits should * be 0 */ -}; +} RxD_block_t; #define SIZE_OF_BLOCK 4096 -#define RXD_MODE_1 0 /* One Buffer mode */ -#define RXD_MODE_3A 1 /* Three Buffer mode */ -#define RXD_MODE_3B 2 /* Two Buffer mode */ +#define RXD_MODE_1 0 +#define RXD_MODE_3A 1 +#define RXD_MODE_3B 2 /* Structure to hold virtual addresses of Buf0 and Buf1 in * 2buf mode. */ -struct buffAdd { +typedef struct bufAdd { void *ba_0_org; void *ba_1_org; void *ba_0; void *ba_1; -}; +} buffAdd_t; /* Structure which stores all the MAC control parameters */ @@ -558,46 +556,43 @@ struct buffAdd { * from which the Rx Interrupt processor can start picking * up the RxDs for processing. */ -struct rx_curr_get_info { +typedef struct _rx_curr_get_info_t { u32 block_index; u32 offset; u32 ring_len; -}; +} rx_curr_get_info_t; -struct rx_curr_put_info { - u32 block_index; - u32 offset; - u32 ring_len; -}; +typedef rx_curr_get_info_t rx_curr_put_info_t; /* This structure stores the offset of the TxDl in the FIFO * from which the Tx Interrupt processor can start picking * up the TxDLs for send complete interrupt processing. */ -struct tx_curr_get_info { +typedef struct { u32 offset; u32 fifo_len; -}; +} tx_curr_get_info_t; -struct tx_curr_put_info { - u32 offset; - u32 fifo_len; -}; +typedef tx_curr_get_info_t tx_curr_put_info_t; -struct rxd_info { + +typedef struct rxd_info { void *virt_addr; dma_addr_t dma_addr; -}; +}rxd_info_t; /* Structure that holds the Phy and virt addresses of the Blocks */ -struct rx_block_info { +typedef struct rx_block_info { void *block_virt_addr; dma_addr_t block_dma_addr; - struct rxd_info *rxds; -}; + rxd_info_t *rxds; +} rx_block_info_t; + +/* pre declaration of the nic structure */ +typedef struct s2io_nic nic_t; /* Ring specific structure */ -struct ring_info { +typedef struct ring_info { /* The ring number */ int ring_no; @@ -605,7 +600,7 @@ struct ring_info { * Place holders for the virtual and physical addresses of * all the Rx Blocks */ - struct rx_block_info rx_blocks[MAX_RX_BLOCKS_PER_RING]; + rx_block_info_t rx_blocks[MAX_RX_BLOCKS_PER_RING]; int block_count; int pkt_cnt; @@ -613,24 +608,26 @@ struct ring_info { * Put pointer info which indictes which RxD has to be replenished * with a new buffer. */ - struct rx_curr_put_info rx_curr_put_info; + rx_curr_put_info_t rx_curr_put_info; /* * Get pointer info which indictes which is the last RxD that was * processed by the driver. */ - struct rx_curr_get_info rx_curr_get_info; + rx_curr_get_info_t rx_curr_get_info; +#ifndef CONFIG_S2IO_NAPI /* Index to the absolute position of the put pointer of Rx ring */ int put_pos; +#endif /* Buffer Address store. */ - struct buffAdd **ba; - struct s2io_nic *nic; -}; + buffAdd_t **ba; + nic_t *nic; +} ring_info_t; /* Fifo specific structure */ -struct fifo_info { +typedef struct fifo_info { /* FIFO number */ int fifo_no; @@ -638,40 +635,40 @@ struct fifo_info { int max_txds; /* Place holder of all the TX List's Phy and Virt addresses. */ - struct list_info_hold *list_info; + list_info_hold_t *list_info; /* * Current offset within the tx FIFO where driver would write * new Tx frame */ - struct tx_curr_put_info tx_curr_put_info; + tx_curr_put_info_t tx_curr_put_info; /* * Current offset within tx FIFO from where the driver would start freeing * the buffers */ - struct tx_curr_get_info tx_curr_get_info; + tx_curr_get_info_t tx_curr_get_info; - struct s2io_nic *nic; -}; + nic_t *nic; +}fifo_info_t; /* Information related to the Tx and Rx FIFOs and Rings of Xena * is maintained in this structure. */ -struct mac_info { +typedef struct mac_info { /* tx side stuff */ /* logical pointer of start of each Tx FIFO */ - struct TxFIFO_element __iomem *tx_FIFO_start[MAX_TX_FIFOS]; + TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS]; /* Fifo specific structure */ - struct fifo_info fifos[MAX_TX_FIFOS]; + fifo_info_t fifos[MAX_TX_FIFOS]; /* Save virtual address of TxD page with zero DMA addr(if any) */ void *zerodma_virt_addr; /* rx side stuff */ /* Ring specific structure */ - struct ring_info rings[MAX_RX_RINGS]; + ring_info_t rings[MAX_RX_RINGS]; u16 rmac_pause_time; u16 mc_pause_threshold_q0q3; @@ -680,14 +677,14 @@ struct mac_info { void *stats_mem; /* orignal pointer to allocated mem */ dma_addr_t stats_mem_phy; /* Physical address of the stat block */ u32 stats_mem_sz; - struct stat_block *stats_info; /* Logical address of the stat block */ -}; + StatInfo_t *stats_info; /* Logical address of the stat block */ +} mac_info_t; /* structure representing the user defined MAC addresses */ -struct usr_addr { +typedef struct { char addr[ETH_ALEN]; int usage_cnt; -}; +} usr_addr_t; /* Default Tunable parameters of the NIC. */ #define DEFAULT_FIFO_0_LEN 4096 @@ -720,7 +717,7 @@ struct msix_info_st { }; /* Data structure to represent a LRO session */ -struct lro { +typedef struct lro { struct sk_buff *parent; struct sk_buff *last_frag; u8 *l2h; @@ -736,18 +733,20 @@ struct lro { u32 cur_tsval; u32 cur_tsecr; u8 saw_ts; -}; +}lro_t; /* Structure representing one instance of the NIC */ struct s2io_nic { int rxd_mode; +#ifdef CONFIG_S2IO_NAPI /* * Count of packets to be processed in a given iteration, it will be indicated * by the quota field of the device structure when NAPI is enabled. */ int pkts_to_process; +#endif struct net_device *dev; - struct mac_info mac_control; + mac_info_t mac_control; struct config_param config; struct pci_dev *pdev; void __iomem *bar0; @@ -755,8 +754,8 @@ struct s2io_nic { #define MAX_MAC_SUPPORTED 16 #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED - struct mac_addr def_mac_addr[MAX_MAC_SUPPORTED]; - struct mac_addr pre_mac_addr[MAX_MAC_SUPPORTED]; + macaddr_t def_mac_addr[MAX_MAC_SUPPORTED]; + macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED]; struct net_device_stats stats; int high_dma_flag; @@ -776,7 +775,9 @@ struct s2io_nic { atomic_t rx_bufs_left[MAX_RX_RINGS]; spinlock_t tx_lock; +#ifndef CONFIG_S2IO_NAPI spinlock_t put_lock; +#endif #define PROMISC 1 #define ALL_MULTI 2 @@ -784,7 +785,7 @@ struct s2io_nic { #define MAX_ADDRS_SUPPORTED 64 u16 usr_addr_count; u16 mc_addr_count; - struct usr_addr usr_addrs[MAX_ADDRS_SUPPORTED]; + usr_addr_t usr_addrs[MAX_ADDRS_SUPPORTED]; u16 m_cast_flg; u16 all_multi_pos; @@ -840,7 +841,7 @@ struct s2io_nic { u8 device_type; #define MAX_LRO_SESSIONS 32 - struct lro lro0_n[MAX_LRO_SESSIONS]; + lro_t lro0_n[MAX_LRO_SESSIONS]; unsigned long clubbed_frms_cnt; unsigned long sending_both; u8 lro; @@ -854,9 +855,8 @@ struct s2io_nic { spinlock_t rx_lock; atomic_t isr_cnt; u64 *ufo_in_band_v; -#define VPD_STRING_LEN 80 - u8 product_name[VPD_STRING_LEN]; - u8 serial_num[VPD_STRING_LEN]; +#define VPD_PRODUCT_NAME_LEN 50 + u8 product_name[VPD_PRODUCT_NAME_LEN]; }; #define RESET_ERROR 1; @@ -975,50 +975,43 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev); static int init_shared_mem(struct s2io_nic *sp); static void free_shared_mem(struct s2io_nic *sp); static int init_nic(struct s2io_nic *nic); -static void rx_intr_handler(struct ring_info *ring_data); -static void tx_intr_handler(struct fifo_info *fifo_data); +static void rx_intr_handler(ring_info_t *ring_data); +static void tx_intr_handler(fifo_info_t *fifo_data); static void alarm_intr_handler(struct s2io_nic *sp); static int s2io_starter(void); -static void s2io_closer(void); static void s2io_tx_watchdog(struct net_device *dev); static void s2io_tasklet(unsigned long dev_addr); static void s2io_set_multicast(struct net_device *dev); -static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); -static void s2io_link(struct s2io_nic * sp, int link); -static void s2io_reset(struct s2io_nic * sp); +static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp); +static void s2io_link(nic_t * sp, int link); +#if defined(CONFIG_S2IO_NAPI) static int s2io_poll(struct net_device *dev, int *budget); -static void s2io_init_pci(struct s2io_nic * sp); +#endif +static void s2io_init_pci(nic_t * sp); static int s2io_set_mac_addr(struct net_device *dev, u8 * addr); static void s2io_alarm_handle(unsigned long data); -static int s2io_enable_msi(struct s2io_nic *nic); +static int s2io_enable_msi(nic_t *nic); static irqreturn_t s2io_msi_handle(int irq, void *dev_id); static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id); static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id); static irqreturn_t s2io_isr(int irq, void *dev_id); -static int verify_xena_quiescence(struct s2io_nic *sp); +static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag); static const struct ethtool_ops netdev_ethtool_ops; static void s2io_set_link(struct work_struct *work); -static int s2io_set_swapper(struct s2io_nic * sp); -static void s2io_card_down(struct s2io_nic *nic); -static int s2io_card_up(struct s2io_nic *nic); +static int s2io_set_swapper(nic_t * sp); +static void s2io_card_down(nic_t *nic); +static int s2io_card_up(nic_t *nic); static int get_xena_rev_id(struct pci_dev *pdev); -static int wait_for_cmd_complete(void *addr, u64 busy_bit); -static int s2io_add_isr(struct s2io_nic * sp); -static void s2io_rem_isr(struct s2io_nic * sp); - -static void restore_xmsi_data(struct s2io_nic *nic); +static void restore_xmsi_data(nic_t *nic); -static int -s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, - struct RxD_t *rxdp, struct s2io_nic *sp); -static void clear_lro_session(struct lro *lro); +static int s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, lro_t **lro, RxD_t *rxdp, nic_t *sp); +static void clear_lro_session(lro_t *lro); static void queue_rx_frame(struct sk_buff *skb); -static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro); -static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, - struct sk_buff *skb, u32 tcp_len); +static void update_L3L4_header(nic_t *sp, lro_t *lro); +static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, u32 tcp_len); #define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size #define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size diff --git a/trunk/drivers/net/sc92031.c b/trunk/drivers/net/sc92031.c deleted file mode 100644 index 7f800feaa9a2..000000000000 --- a/trunk/drivers/net/sc92031.c +++ /dev/null @@ -1,1620 +0,0 @@ -/* Silan SC92031 PCI Fast Ethernet Adapter driver - * - * Based on vendor drivers: - * Silan Fast Ethernet Netcard Driver: - * MODULE_AUTHOR ("gaoyonghong"); - * MODULE_DESCRIPTION ("SILAN Fast Ethernet driver"); - * MODULE_LICENSE("GPL"); - * 8139D Fast Ethernet driver: - * (C) 2002 by gaoyonghong - * MODULE_AUTHOR ("gaoyonghong"); - * MODULE_DESCRIPTION ("Rsltek 8139D PCI Fast Ethernet Adapter driver"); - * MODULE_LICENSE("GPL"); - * Both are almost identical and seem to be based on pci-skeleton.c - * - * Rewritten for 2.6 by Cesar Eduardo Barros - */ - -/* Note about set_mac_address: I don't know how to change the hardware - * matching, so you need to enable IFF_PROMISC when using it. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define PCI_VENDOR_ID_SILAN 0x1904 -#define PCI_DEVICE_ID_SILAN_SC92031 0x2031 -#define PCI_DEVICE_ID_SILAN_8139D 0x8139 - -#define SC92031_NAME "sc92031" -#define SC92031_DESCRIPTION "Silan SC92031 PCI Fast Ethernet Adapter driver" -#define SC92031_VERSION "2.0c" - -/* BAR 0 is MMIO, BAR 1 is PIO */ -#ifndef SC92031_USE_BAR -#define SC92031_USE_BAR 0 -#endif - -/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). */ -static int multicast_filter_limit = 64; -module_param(multicast_filter_limit, int, 0); -MODULE_PARM_DESC(multicast_filter_limit, - "Maximum number of filtered multicast addresses"); - -static int media; -module_param(media, int, 0); -MODULE_PARM_DESC(media, "Media type (0x00 = autodetect," - " 0x01 = 10M half, 0x02 = 10M full," - " 0x04 = 100M half, 0x08 = 100M full)"); - -/* Size of the in-memory receive ring. */ -#define RX_BUF_LEN_IDX 3 /* 0==8K, 1==16K, 2==32K, 3==64K ,4==128K*/ -#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX) - -/* Number of Tx descriptor registers. */ -#define NUM_TX_DESC 4 - -/* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/ -#define MAX_ETH_FRAME_SIZE 1536 - -/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */ -#define TX_BUF_SIZE MAX_ETH_FRAME_SIZE -#define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC) - -/* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024, 7==end of packet. */ -#define RX_FIFO_THRESH 7 /* Rx buffer level before first PCI xfer. */ - -/* Time in jiffies before concluding the transmitter is hung. */ -#define TX_TIMEOUT (4*HZ) - -#define SILAN_STATS_NUM 2 /* number of ETHTOOL_GSTATS */ - -/* media options */ -#define AUTOSELECT 0x00 -#define M10_HALF 0x01 -#define M10_FULL 0x02 -#define M100_HALF 0x04 -#define M100_FULL 0x08 - - /* Symbolic offsets to registers. */ -enum silan_registers { - Config0 = 0x00, // Config0 - Config1 = 0x04, // Config1 - RxBufWPtr = 0x08, // Rx buffer writer poiter - IntrStatus = 0x0C, // Interrupt status - IntrMask = 0x10, // Interrupt mask - RxbufAddr = 0x14, // Rx buffer start address - RxBufRPtr = 0x18, // Rx buffer read pointer - Txstatusall = 0x1C, // Transmit status of all descriptors - TxStatus0 = 0x20, // Transmit status (Four 32bit registers). - TxAddr0 = 0x30, // Tx descriptors (also four 32bit). - RxConfig = 0x40, // Rx configuration - MAC0 = 0x44, // Ethernet hardware address. - MAR0 = 0x4C, // Multicast filter. - RxStatus0 = 0x54, // Rx status - TxConfig = 0x5C, // Tx configuration - PhyCtrl = 0x60, // physical control - FlowCtrlConfig = 0x64, // flow control - Miicmd0 = 0x68, // Mii command0 register - Miicmd1 = 0x6C, // Mii command1 register - Miistatus = 0x70, // Mii status register - Timercnt = 0x74, // Timer counter register - TimerIntr = 0x78, // Timer interrupt register - PMConfig = 0x7C, // Power Manager configuration - CRC0 = 0x80, // Power Manager CRC ( Two 32bit regisers) - Wakeup0 = 0x88, // power Manager wakeup( Eight 64bit regiser) - LSBCRC0 = 0xC8, // power Manager LSBCRC(Two 32bit regiser) - TestD0 = 0xD0, - TestD4 = 0xD4, - TestD8 = 0xD8, -}; - -#define MII_BMCR 0 // Basic mode control register -#define MII_BMSR 1 // Basic mode status register -#define MII_JAB 16 -#define MII_OutputStatus 24 - -#define BMCR_FULLDPLX 0x0100 // Full duplex -#define BMCR_ANRESTART 0x0200 // Auto negotiation restart -#define BMCR_ANENABLE 0x1000 // Enable auto negotiation -#define BMCR_SPEED100 0x2000 // Select 100Mbps -#define BMSR_LSTATUS 0x0004 // Link status -#define PHY_16_JAB_ENB 0x1000 -#define PHY_16_PORT_ENB 0x1 - -enum IntrStatusBits { - LinkFail = 0x80000000, - LinkOK = 0x40000000, - TimeOut = 0x20000000, - RxOverflow = 0x0040, - RxOK = 0x0020, - TxOK = 0x0001, - IntrBits = LinkFail|LinkOK|TimeOut|RxOverflow|RxOK|TxOK, -}; - -enum TxStatusBits { - TxCarrierLost = 0x20000000, - TxAborted = 0x10000000, - TxOutOfWindow = 0x08000000, - TxNccShift = 22, - EarlyTxThresShift = 16, - TxStatOK = 0x8000, - TxUnderrun = 0x4000, - TxOwn = 0x2000, -}; - -enum RxStatusBits { - RxStatesOK = 0x80000, - RxBadAlign = 0x40000, - RxHugeFrame = 0x20000, - RxSmallFrame = 0x10000, - RxCRCOK = 0x8000, - RxCrlFrame = 0x4000, - Rx_Broadcast = 0x2000, - Rx_Multicast = 0x1000, - RxAddrMatch = 0x0800, - MiiErr = 0x0400, -}; - -enum RxConfigBits { - RxFullDx = 0x80000000, - RxEnb = 0x40000000, - RxSmall = 0x20000000, - RxHuge = 0x10000000, - RxErr = 0x08000000, - RxAllphys = 0x04000000, - RxMulticast = 0x02000000, - RxBroadcast = 0x01000000, - RxLoopBack = (1 << 23) | (1 << 22), - LowThresholdShift = 12, - HighThresholdShift = 2, -}; - -enum TxConfigBits { - TxFullDx = 0x80000000, - TxEnb = 0x40000000, - TxEnbPad = 0x20000000, - TxEnbHuge = 0x10000000, - TxEnbFCS = 0x08000000, - TxNoBackOff = 0x04000000, - TxEnbPrem = 0x02000000, - TxCareLostCrs = 0x1000000, - TxExdCollNum = 0xf00000, - TxDataRate = 0x80000, -}; - -enum PhyCtrlconfigbits { - PhyCtrlAne = 0x80000000, - PhyCtrlSpd100 = 0x40000000, - PhyCtrlSpd10 = 0x20000000, - PhyCtrlPhyBaseAddr = 0x1f000000, - PhyCtrlDux = 0x800000, - PhyCtrlReset = 0x400000, -}; - -enum FlowCtrlConfigBits { - FlowCtrlFullDX = 0x80000000, - FlowCtrlEnb = 0x40000000, -}; - -enum Config0Bits { - Cfg0_Reset = 0x80000000, - Cfg0_Anaoff = 0x40000000, - Cfg0_LDPS = 0x20000000, -}; - -enum Config1Bits { - Cfg1_EarlyRx = 1 << 31, - Cfg1_EarlyTx = 1 << 30, - - //rx buffer size - Cfg1_Rcv8K = 0x0, - Cfg1_Rcv16K = 0x1, - Cfg1_Rcv32K = 0x3, - Cfg1_Rcv64K = 0x7, - Cfg1_Rcv128K = 0xf, -}; - -enum MiiCmd0Bits { - Mii_Divider = 0x20000000, - Mii_WRITE = 0x400000, - Mii_READ = 0x200000, - Mii_SCAN = 0x100000, - Mii_Tamod = 0x80000, - Mii_Drvmod = 0x40000, - Mii_mdc = 0x20000, - Mii_mdoen = 0x10000, - Mii_mdo = 0x8000, - Mii_mdi = 0x4000, -}; - -enum MiiStatusBits { - Mii_StatusBusy = 0x80000000, -}; - -enum PMConfigBits { - PM_Enable = 1 << 31, - PM_LongWF = 1 << 30, - PM_Magic = 1 << 29, - PM_LANWake = 1 << 28, - PM_LWPTN = (1 << 27 | 1<< 26), - PM_LinkUp = 1 << 25, - PM_WakeUp = 1 << 24, -}; - -/* Locking rules: - * priv->lock protects most of the fields of priv and most of the - * hardware registers. It does not have to protect against softirqs - * between sc92031_disable_interrupts and sc92031_enable_interrupts; - * it also does not need to be used in ->open and ->stop while the - * device interrupts are off. - * Not having to protect against softirqs is very useful due to heavy - * use of mdelay() at _sc92031_reset. - * Functions prefixed with _sc92031_ must be called with the lock held; - * functions prefixed with sc92031_ must be called without the lock held. - * Use mmiowb() before unlocking if the hardware was written to. - */ - -/* Locking rules for the interrupt: - * - the interrupt and the tasklet never run at the same time - * - neither run between sc92031_disable_interrupts and - * sc92031_enable_interrupt - */ - -struct sc92031_priv { - spinlock_t lock; - /* iomap.h cookie */ - void __iomem *port_base; - /* pci device structure */ - struct pci_dev *pdev; - /* tasklet */ - struct tasklet_struct tasklet; - - /* CPU address of rx ring */ - void *rx_ring; - /* PCI address of rx ring */ - dma_addr_t rx_ring_dma_addr; - /* PCI address of rx ring read pointer */ - dma_addr_t rx_ring_tail; - - /* tx ring write index */ - unsigned tx_head; - /* tx ring read index */ - unsigned tx_tail; - /* CPU address of tx bounce buffer */ - void *tx_bufs; - /* PCI address of tx bounce buffer */ - dma_addr_t tx_bufs_dma_addr; - - /* copies of some hardware registers */ - u32 intr_status; - atomic_t intr_mask; - u32 rx_config; - u32 tx_config; - u32 pm_config; - - /* copy of some flags from dev->flags */ - unsigned int mc_flags; - - /* for ETHTOOL_GSTATS */ - u64 tx_timeouts; - u64 rx_loss; - - /* for dev->get_stats */ - long rx_value; - struct net_device_stats stats; -}; - -/* I don't know which registers can be safely read; however, I can guess - * MAC0 is one of them. */ -static inline void _sc92031_dummy_read(void __iomem *port_base) -{ - ioread32(port_base + MAC0); -} - -static u32 _sc92031_mii_wait(void __iomem *port_base) -{ - u32 mii_status; - - do { - udelay(10); - mii_status = ioread32(port_base + Miistatus); - } while (mii_status & Mii_StatusBusy); - - return mii_status; -} - -static u32 _sc92031_mii_cmd(void __iomem *port_base, u32 cmd0, u32 cmd1) -{ - iowrite32(Mii_Divider, port_base + Miicmd0); - - _sc92031_mii_wait(port_base); - - iowrite32(cmd1, port_base + Miicmd1); - iowrite32(Mii_Divider | cmd0, port_base + Miicmd0); - - return _sc92031_mii_wait(port_base); -} - -static void _sc92031_mii_scan(void __iomem *port_base) -{ - _sc92031_mii_cmd(port_base, Mii_SCAN, 0x1 << 6); -} - -static u16 _sc92031_mii_read(void __iomem *port_base, unsigned reg) -{ - return _sc92031_mii_cmd(port_base, Mii_READ, reg << 6) >> 13; -} - -static void _sc92031_mii_write(void __iomem *port_base, unsigned reg, u16 val) -{ - _sc92031_mii_cmd(port_base, Mii_WRITE, (reg << 6) | ((u32)val << 11)); -} - -static void sc92031_disable_interrupts(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - - /* tell the tasklet/interrupt not to enable interrupts */ - atomic_set(&priv->intr_mask, 0); - wmb(); - - /* stop interrupts */ - iowrite32(0, port_base + IntrMask); - _sc92031_dummy_read(port_base); - mmiowb(); - - /* wait for any concurrent interrupt/tasklet to finish */ - synchronize_irq(dev->irq); - tasklet_disable(&priv->tasklet); -} - -static void sc92031_enable_interrupts(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - - tasklet_enable(&priv->tasklet); - - atomic_set(&priv->intr_mask, IntrBits); - wmb(); - - iowrite32(IntrBits, port_base + IntrMask); - mmiowb(); -} - -static void _sc92031_disable_tx_rx(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - - priv->rx_config &= ~RxEnb; - priv->tx_config &= ~TxEnb; - iowrite32(priv->rx_config, port_base + RxConfig); - iowrite32(priv->tx_config, port_base + TxConfig); -} - -static void _sc92031_enable_tx_rx(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - - priv->rx_config |= RxEnb; - priv->tx_config |= TxEnb; - iowrite32(priv->rx_config, port_base + RxConfig); - iowrite32(priv->tx_config, port_base + TxConfig); -} - -static void _sc92031_tx_clear(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - - while (priv->tx_head - priv->tx_tail > 0) { - priv->tx_tail++; - priv->stats.tx_dropped++; - } - priv->tx_head = priv->tx_tail = 0; -} - -static void _sc92031_set_mar(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u32 mar0 = 0, mar1 = 0; - - if ((dev->flags & IFF_PROMISC) - || dev->mc_count > multicast_filter_limit - || (dev->flags & IFF_ALLMULTI)) - mar0 = mar1 = 0xffffffff; - else if (dev->flags & IFF_MULTICAST) { - struct dev_mc_list *mc_list; - - for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) { - u32 crc; - unsigned bit = 0; - - crc = ~ether_crc(ETH_ALEN, mc_list->dmi_addr); - crc >>= 24; - - if (crc & 0x01) bit |= 0x02; - if (crc & 0x02) bit |= 0x01; - if (crc & 0x10) bit |= 0x20; - if (crc & 0x20) bit |= 0x10; - if (crc & 0x40) bit |= 0x08; - if (crc & 0x80) bit |= 0x04; - - if (bit > 31) - mar0 |= 0x1 << (bit - 32); - else - mar1 |= 0x1 << bit; - } - } - - iowrite32(mar0, port_base + MAR0); - iowrite32(mar1, port_base + MAR0 + 4); -} - -static void _sc92031_set_rx_config(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - unsigned int old_mc_flags; - u32 rx_config_bits = 0; - - old_mc_flags = priv->mc_flags; - - if (dev->flags & IFF_PROMISC) - rx_config_bits |= RxSmall | RxHuge | RxErr | RxBroadcast - | RxMulticast | RxAllphys; - - if (dev->flags & (IFF_ALLMULTI | IFF_MULTICAST)) - rx_config_bits |= RxMulticast; - - if (dev->flags & IFF_BROADCAST) - rx_config_bits |= RxBroadcast; - - priv->rx_config &= ~(RxSmall | RxHuge | RxErr | RxBroadcast - | RxMulticast | RxAllphys); - priv->rx_config |= rx_config_bits; - - priv->mc_flags = dev->flags & (IFF_PROMISC | IFF_ALLMULTI - | IFF_MULTICAST | IFF_BROADCAST); - - if (netif_carrier_ok(dev) && priv->mc_flags != old_mc_flags) - iowrite32(priv->rx_config, port_base + RxConfig); -} - -static bool _sc92031_check_media(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u16 bmsr; - - bmsr = _sc92031_mii_read(port_base, MII_BMSR); - rmb(); - if (bmsr & BMSR_LSTATUS) { - bool speed_100, duplex_full; - u32 flow_ctrl_config = 0; - u16 output_status = _sc92031_mii_read(port_base, - MII_OutputStatus); - _sc92031_mii_scan(port_base); - - speed_100 = output_status & 0x2; - duplex_full = output_status & 0x4; - - /* Initial Tx/Rx configuration */ - priv->rx_config = (0x40 << LowThresholdShift) | (0x1c0 << HighThresholdShift); - priv->tx_config = 0x48800000; - - /* NOTE: vendor driver had dead code here to enable tx padding */ - - if (!speed_100) - priv->tx_config |= 0x80000; - - // configure rx mode - _sc92031_set_rx_config(dev); - - if (duplex_full) { - priv->rx_config |= RxFullDx; - priv->tx_config |= TxFullDx; - flow_ctrl_config = FlowCtrlFullDX | FlowCtrlEnb; - } else { - priv->rx_config &= ~RxFullDx; - priv->tx_config &= ~TxFullDx; - } - - _sc92031_set_mar(dev); - _sc92031_set_rx_config(dev); - _sc92031_enable_tx_rx(dev); - iowrite32(flow_ctrl_config, port_base + FlowCtrlConfig); - - netif_carrier_on(dev); - - if (printk_ratelimit()) - printk(KERN_INFO "%s: link up, %sMbps, %s-duplex\n", - dev->name, - speed_100 ? "100" : "10", - duplex_full ? "full" : "half"); - return true; - } else { - _sc92031_mii_scan(port_base); - - netif_carrier_off(dev); - - _sc92031_disable_tx_rx(dev); - - if (printk_ratelimit()) - printk(KERN_INFO "%s: link down\n", dev->name); - return false; - } -} - -static void _sc92031_phy_reset(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u32 phy_ctrl; - - phy_ctrl = ioread32(port_base + PhyCtrl); - phy_ctrl &= ~(PhyCtrlDux | PhyCtrlSpd100 | PhyCtrlSpd10); - phy_ctrl |= PhyCtrlAne | PhyCtrlReset; - - switch (media) { - default: - case AUTOSELECT: - phy_ctrl |= PhyCtrlDux | PhyCtrlSpd100 | PhyCtrlSpd10; - break; - case M10_HALF: - phy_ctrl |= PhyCtrlSpd10; - break; - case M10_FULL: - phy_ctrl |= PhyCtrlDux | PhyCtrlSpd10; - break; - case M100_HALF: - phy_ctrl |= PhyCtrlSpd100; - break; - case M100_FULL: - phy_ctrl |= PhyCtrlDux | PhyCtrlSpd100; - break; - } - - iowrite32(phy_ctrl, port_base + PhyCtrl); - mdelay(10); - - phy_ctrl &= ~PhyCtrlReset; - iowrite32(phy_ctrl, port_base + PhyCtrl); - mdelay(1); - - _sc92031_mii_write(port_base, MII_JAB, - PHY_16_JAB_ENB | PHY_16_PORT_ENB); - _sc92031_mii_scan(port_base); - - netif_carrier_off(dev); - netif_stop_queue(dev); -} - -static void _sc92031_reset(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - - /* disable PM */ - iowrite32(0, port_base + PMConfig); - - /* soft reset the chip */ - iowrite32(Cfg0_Reset, port_base + Config0); - mdelay(200); - - iowrite32(0, port_base + Config0); - mdelay(10); - - /* disable interrupts */ - iowrite32(0, port_base + IntrMask); - - /* clear multicast address */ - iowrite32(0, port_base + MAR0); - iowrite32(0, port_base + MAR0 + 4); - - /* init rx ring */ - iowrite32(priv->rx_ring_dma_addr, port_base + RxbufAddr); - priv->rx_ring_tail = priv->rx_ring_dma_addr; - - /* init tx ring */ - _sc92031_tx_clear(dev); - - /* clear old register values */ - priv->intr_status = 0; - atomic_set(&priv->intr_mask, 0); - priv->rx_config = 0; - priv->tx_config = 0; - priv->mc_flags = 0; - - /* configure rx buffer size */ - /* NOTE: vendor driver had dead code here to enable early tx/rx */ - iowrite32(Cfg1_Rcv64K, port_base + Config1); - - _sc92031_phy_reset(dev); - _sc92031_check_media(dev); - - /* calculate rx fifo overflow */ - priv->rx_value = 0; - - /* enable PM */ - iowrite32(priv->pm_config, port_base + PMConfig); - - /* clear intr register */ - ioread32(port_base + IntrStatus); -} - -static void _sc92031_tx_tasklet(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - - unsigned old_tx_tail; - unsigned entry; - u32 tx_status; - - old_tx_tail = priv->tx_tail; - while (priv->tx_head - priv->tx_tail > 0) { - entry = priv->tx_tail % NUM_TX_DESC; - tx_status = ioread32(port_base + TxStatus0 + entry * 4); - - if (!(tx_status & (TxStatOK | TxUnderrun | TxAborted))) - break; - - priv->tx_tail++; - - if (tx_status & TxStatOK) { - priv->stats.tx_bytes += tx_status & 0x1fff; - priv->stats.tx_packets++; - /* Note: TxCarrierLost is always asserted at 100mbps. */ - priv->stats.collisions += (tx_status >> 22) & 0xf; - } - - if (tx_status & (TxOutOfWindow | TxAborted)) { - priv->stats.tx_errors++; - - if (tx_status & TxAborted) - priv->stats.tx_aborted_errors++; - - if (tx_status & TxCarrierLost) - priv->stats.tx_carrier_errors++; - - if (tx_status & TxOutOfWindow) - priv->stats.tx_window_errors++; - } - - if (tx_status & TxUnderrun) - priv->stats.tx_fifo_errors++; - } - - if (priv->tx_tail != old_tx_tail) - if (netif_queue_stopped(dev)) - netif_wake_queue(dev); -} - -static void _sc92031_rx_tasklet_error(u32 rx_status, - struct sc92031_priv *priv, unsigned rx_size) -{ - if(rx_size > (MAX_ETH_FRAME_SIZE + 4) || rx_size < 16) { - priv->stats.rx_errors++; - priv->stats.rx_length_errors++; - } - - if (!(rx_status & RxStatesOK)) { - priv->stats.rx_errors++; - - if (rx_status & (RxHugeFrame | RxSmallFrame)) - priv->stats.rx_length_errors++; - - if (rx_status & RxBadAlign) - priv->stats.rx_frame_errors++; - - if (!(rx_status & RxCRCOK)) - priv->stats.rx_crc_errors++; - } else - priv->rx_loss++; -} - -static void _sc92031_rx_tasklet(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - - dma_addr_t rx_ring_head; - unsigned rx_len; - unsigned rx_ring_offset; - void *rx_ring = priv->rx_ring; - - rx_ring_head = ioread32(port_base + RxBufWPtr); - rmb(); - - /* rx_ring_head is only 17 bits in the RxBufWPtr register. - * we need to change it to 32 bits physical address - */ - rx_ring_head &= (dma_addr_t)(RX_BUF_LEN - 1); - rx_ring_head |= priv->rx_ring_dma_addr & ~(dma_addr_t)(RX_BUF_LEN - 1); - if (rx_ring_head < priv->rx_ring_dma_addr) - rx_ring_head += RX_BUF_LEN; - - if (rx_ring_head >= priv->rx_ring_tail) - rx_len = rx_ring_head - priv->rx_ring_tail; - else - rx_len = RX_BUF_LEN - (priv->rx_ring_tail - rx_ring_head); - - if (!rx_len) - return; - - if (unlikely(rx_len > RX_BUF_LEN)) { - if (printk_ratelimit()) - printk(KERN_ERR "%s: rx packets length > rx buffer\n", - dev->name); - return; - } - - rx_ring_offset = (priv->rx_ring_tail - priv->rx_ring_dma_addr) % RX_BUF_LEN; - - while (rx_len) { - u32 rx_status; - unsigned rx_size, rx_size_align, pkt_size; - struct sk_buff *skb; - - rx_status = le32_to_cpup((__le32 *)(rx_ring + rx_ring_offset)); - rmb(); - - rx_size = rx_status >> 20; - rx_size_align = (rx_size + 3) & ~3; // for 4 bytes aligned - pkt_size = rx_size - 4; // Omit the four octet CRC from the length. - - rx_ring_offset = (rx_ring_offset + 4) % RX_BUF_LEN; - - if (unlikely(rx_status == 0 - || rx_size > (MAX_ETH_FRAME_SIZE + 4) - || rx_size < 16 - || !(rx_status & RxStatesOK))) { - _sc92031_rx_tasklet_error(rx_status, priv, rx_size); - break; - } - - if (unlikely(rx_size_align + 4 > rx_len)) { - if (printk_ratelimit()) - printk(KERN_ERR "%s: rx_len is too small\n", dev->name); - break; - } - - rx_len -= rx_size_align + 4; - - skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); - if (unlikely(!skb)) { - if (printk_ratelimit()) - printk(KERN_ERR "%s: Couldn't allocate a skb_buff for a packet of size %u\n", - dev->name, pkt_size); - goto next; - } - - skb_reserve(skb, NET_IP_ALIGN); - - if ((rx_ring_offset + pkt_size) > RX_BUF_LEN) { - memcpy(skb_put(skb, RX_BUF_LEN - rx_ring_offset), - rx_ring + rx_ring_offset, RX_BUF_LEN - rx_ring_offset); - memcpy(skb_put(skb, pkt_size - (RX_BUF_LEN - rx_ring_offset)), - rx_ring, pkt_size - (RX_BUF_LEN - rx_ring_offset)); - } else { - memcpy(skb_put(skb, pkt_size), rx_ring + rx_ring_offset, pkt_size); - } - - skb->dev = dev; - skb->protocol = eth_type_trans(skb, dev); - dev->last_rx = jiffies; - netif_rx(skb); - - priv->stats.rx_bytes += pkt_size; - priv->stats.rx_packets++; - - if (rx_status & Rx_Multicast) - priv->stats.multicast++; - - next: - rx_ring_offset = (rx_ring_offset + rx_size_align) % RX_BUF_LEN; - } - mb(); - - priv->rx_ring_tail = rx_ring_head; - iowrite32(priv->rx_ring_tail, port_base + RxBufRPtr); -} - -static void _sc92031_link_tasklet(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - - if (_sc92031_check_media(dev)) - netif_wake_queue(dev); - else { - netif_stop_queue(dev); - priv->stats.tx_carrier_errors++; - } -} - -static void sc92031_tasklet(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u32 intr_status, intr_mask; - - intr_status = priv->intr_status; - - spin_lock(&priv->lock); - - if (unlikely(!netif_running(dev))) - goto out; - - if (intr_status & TxOK) - _sc92031_tx_tasklet(dev); - - if (intr_status & RxOK) - _sc92031_rx_tasklet(dev); - - if (intr_status & RxOverflow) - priv->stats.rx_errors++; - - if (intr_status & TimeOut) { - priv->stats.rx_errors++; - priv->stats.rx_length_errors++; - } - - if (intr_status & (LinkFail | LinkOK)) - _sc92031_link_tasklet(dev); - -out: - intr_mask = atomic_read(&priv->intr_mask); - rmb(); - - iowrite32(intr_mask, port_base + IntrMask); - mmiowb(); - - spin_unlock(&priv->lock); -} - -static irqreturn_t sc92031_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u32 intr_status, intr_mask; - - /* mask interrupts before clearing IntrStatus */ - iowrite32(0, port_base + IntrMask); - _sc92031_dummy_read(port_base); - - intr_status = ioread32(port_base + IntrStatus); - if (unlikely(intr_status == 0xffffffff)) - return IRQ_NONE; // hardware has gone missing - - intr_status &= IntrBits; - if (!intr_status) - goto out_none; - - priv->intr_status = intr_status; - tasklet_schedule(&priv->tasklet); - - return IRQ_HANDLED; - -out_none: - intr_mask = atomic_read(&priv->intr_mask); - rmb(); - - iowrite32(intr_mask, port_base + IntrMask); - mmiowb(); - - return IRQ_NONE; -} - -static struct net_device_stats *sc92031_get_stats(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - - // FIXME I do not understand what is this trying to do. - if (netif_running(dev)) { - int temp; - - spin_lock_bh(&priv->lock); - - /* Update the error count. */ - temp = (ioread32(port_base + RxStatus0) >> 16) & 0xffff; - - if (temp == 0xffff) { - priv->rx_value += temp; - priv->stats.rx_fifo_errors = priv->rx_value; - } else { - priv->stats.rx_fifo_errors = temp + priv->rx_value; - } - - spin_unlock_bh(&priv->lock); - } - - return &priv->stats; -} - -static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - int err = 0; - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - - unsigned len; - unsigned entry; - u32 tx_status; - - if (unlikely(skb->len > TX_BUF_SIZE)) { - err = -EMSGSIZE; - priv->stats.tx_dropped++; - goto out; - } - - spin_lock_bh(&priv->lock); - - if (unlikely(!netif_carrier_ok(dev))) { - err = -ENOLINK; - priv->stats.tx_dropped++; - goto out_unlock; - } - - BUG_ON(priv->tx_head - priv->tx_tail >= NUM_TX_DESC); - - entry = priv->tx_head++ % NUM_TX_DESC; - - skb_copy_and_csum_dev(skb, priv->tx_bufs + entry * TX_BUF_SIZE); - - len = skb->len; - if (unlikely(len < ETH_ZLEN)) { - memset(priv->tx_bufs + entry * TX_BUF_SIZE + len, - 0, ETH_ZLEN - len); - len = ETH_ZLEN; - } - - wmb(); - - if (len < 100) - tx_status = len; - else if (len < 300) - tx_status = 0x30000 | len; - else - tx_status = 0x50000 | len; - - iowrite32(priv->tx_bufs_dma_addr + entry * TX_BUF_SIZE, - port_base + TxAddr0 + entry * 4); - iowrite32(tx_status, port_base + TxStatus0 + entry * 4); - mmiowb(); - - dev->trans_start = jiffies; - - if (priv->tx_head - priv->tx_tail >= NUM_TX_DESC) - netif_stop_queue(dev); - -out_unlock: - spin_unlock_bh(&priv->lock); - -out: - dev_kfree_skb(skb); - - return err; -} - -static int sc92031_open(struct net_device *dev) -{ - int err; - struct sc92031_priv *priv = netdev_priv(dev); - struct pci_dev *pdev = priv->pdev; - - priv->rx_ring = pci_alloc_consistent(pdev, RX_BUF_LEN, - &priv->rx_ring_dma_addr); - if (unlikely(!priv->rx_ring)) { - err = -ENOMEM; - goto out_alloc_rx_ring; - } - - priv->tx_bufs = pci_alloc_consistent(pdev, TX_BUF_TOT_LEN, - &priv->tx_bufs_dma_addr); - if (unlikely(!priv->tx_bufs)) { - err = -ENOMEM; - goto out_alloc_tx_bufs; - } - priv->tx_head = priv->tx_tail = 0; - - err = request_irq(pdev->irq, sc92031_interrupt, - SA_SHIRQ, dev->name, dev); - if (unlikely(err < 0)) - goto out_request_irq; - - priv->pm_config = 0; - - /* Interrupts already disabled by sc92031_stop or sc92031_probe */ - spin_lock(&priv->lock); - - _sc92031_reset(dev); - mmiowb(); - - spin_unlock(&priv->lock); - sc92031_enable_interrupts(dev); - - if (netif_carrier_ok(dev)) - netif_start_queue(dev); - else - netif_tx_disable(dev); - - return 0; - -out_request_irq: - pci_free_consistent(pdev, TX_BUF_TOT_LEN, priv->tx_bufs, - priv->tx_bufs_dma_addr); -out_alloc_tx_bufs: - pci_free_consistent(pdev, RX_BUF_LEN, priv->rx_ring, - priv->rx_ring_dma_addr); -out_alloc_rx_ring: - return err; -} - -static int sc92031_stop(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - struct pci_dev *pdev = priv->pdev; - - netif_tx_disable(dev); - - /* Disable interrupts, stop Tx and Rx. */ - sc92031_disable_interrupts(dev); - - spin_lock(&priv->lock); - - _sc92031_disable_tx_rx(dev); - _sc92031_tx_clear(dev); - mmiowb(); - - spin_unlock(&priv->lock); - - free_irq(pdev->irq, dev); - pci_free_consistent(pdev, TX_BUF_TOT_LEN, priv->tx_bufs, - priv->tx_bufs_dma_addr); - pci_free_consistent(pdev, RX_BUF_LEN, priv->rx_ring, - priv->rx_ring_dma_addr); - - return 0; -} - -static void sc92031_set_multicast_list(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - - spin_lock_bh(&priv->lock); - - _sc92031_set_mar(dev); - _sc92031_set_rx_config(dev); - mmiowb(); - - spin_unlock_bh(&priv->lock); -} - -static void sc92031_tx_timeout(struct net_device *dev) -{ - struct sc92031_priv *priv = netdev_priv(dev); - - /* Disable interrupts by clearing the interrupt mask.*/ - sc92031_disable_interrupts(dev); - - spin_lock(&priv->lock); - - priv->tx_timeouts++; - - _sc92031_reset(dev); - mmiowb(); - - spin_unlock(&priv->lock); - - /* enable interrupts */ - sc92031_enable_interrupts(dev); - - if (netif_carrier_ok(dev)) - netif_wake_queue(dev); -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void sc92031_poll_controller(struct net_device *dev) -{ - disable_irq(dev->irq); - if (sc92031_interrupt(dev->irq, dev) != IRQ_NONE) - sc92031_tasklet((unsigned long)dev); - enable_irq(dev->irq); -} -#endif - -static int sc92031_ethtool_get_settings(struct net_device *dev, - struct ethtool_cmd *cmd) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u8 phy_address; - u32 phy_ctrl; - u16 output_status; - - spin_lock_bh(&priv->lock); - - phy_address = ioread32(port_base + Miicmd1) >> 27; - phy_ctrl = ioread32(port_base + PhyCtrl); - - output_status = _sc92031_mii_read(port_base, MII_OutputStatus); - _sc92031_mii_scan(port_base); - mmiowb(); - - spin_unlock_bh(&priv->lock); - - cmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full - | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full - | SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII; - - cmd->advertising = ADVERTISED_TP | ADVERTISED_MII; - - if ((phy_ctrl & (PhyCtrlDux | PhyCtrlSpd100 | PhyCtrlSpd10)) - == (PhyCtrlDux | PhyCtrlSpd100 | PhyCtrlSpd10)) - cmd->advertising |= ADVERTISED_Autoneg; - - if ((phy_ctrl & PhyCtrlSpd10) == PhyCtrlSpd10) - cmd->advertising |= ADVERTISED_10baseT_Half; - - if ((phy_ctrl & (PhyCtrlSpd10 | PhyCtrlDux)) - == (PhyCtrlSpd10 | PhyCtrlDux)) - cmd->advertising |= ADVERTISED_10baseT_Full; - - if ((phy_ctrl & PhyCtrlSpd100) == PhyCtrlSpd100) - cmd->advertising |= ADVERTISED_100baseT_Half; - - if ((phy_ctrl & (PhyCtrlSpd100 | PhyCtrlDux)) - == (PhyCtrlSpd100 | PhyCtrlDux)) - cmd->advertising |= ADVERTISED_100baseT_Full; - - if (phy_ctrl & PhyCtrlAne) - cmd->advertising |= ADVERTISED_Autoneg; - - cmd->speed = (output_status & 0x2) ? SPEED_100 : SPEED_10; - cmd->duplex = (output_status & 0x4) ? DUPLEX_FULL : DUPLEX_HALF; - cmd->port = PORT_MII; - cmd->phy_address = phy_address; - cmd->transceiver = XCVR_INTERNAL; - cmd->autoneg = (phy_ctrl & PhyCtrlAne) ? AUTONEG_ENABLE : AUTONEG_DISABLE; - - return 0; -} - -static int sc92031_ethtool_set_settings(struct net_device *dev, - struct ethtool_cmd *cmd) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u32 phy_ctrl; - u32 old_phy_ctrl; - - if (!(cmd->speed == SPEED_10 || cmd->speed == SPEED_100)) - return -EINVAL; - if (!(cmd->duplex == DUPLEX_HALF || cmd->duplex == DUPLEX_FULL)) - return -EINVAL; - if (!(cmd->port == PORT_MII)) - return -EINVAL; - if (!(cmd->phy_address == 0x1f)) - return -EINVAL; - if (!(cmd->transceiver == XCVR_INTERNAL)) - return -EINVAL; - if (!(cmd->autoneg == AUTONEG_DISABLE || cmd->autoneg == AUTONEG_ENABLE)) - return -EINVAL; - - if (cmd->autoneg == AUTONEG_ENABLE) { - if (!(cmd->advertising & (ADVERTISED_Autoneg - | ADVERTISED_100baseT_Full - | ADVERTISED_100baseT_Half - | ADVERTISED_10baseT_Full - | ADVERTISED_10baseT_Half))) - return -EINVAL; - - phy_ctrl = PhyCtrlAne; - - // FIXME: I'm not sure what the original code was trying to do - if (cmd->advertising & ADVERTISED_Autoneg) - phy_ctrl |= PhyCtrlDux | PhyCtrlSpd100 | PhyCtrlSpd10; - if (cmd->advertising & ADVERTISED_100baseT_Full) - phy_ctrl |= PhyCtrlDux | PhyCtrlSpd100; - if (cmd->advertising & ADVERTISED_100baseT_Half) - phy_ctrl |= PhyCtrlSpd100; - if (cmd->advertising & ADVERTISED_10baseT_Full) - phy_ctrl |= PhyCtrlSpd10 | PhyCtrlDux; - if (cmd->advertising & ADVERTISED_10baseT_Half) - phy_ctrl |= PhyCtrlSpd10; - } else { - // FIXME: Whole branch guessed - phy_ctrl = 0; - - if (cmd->speed == SPEED_10) - phy_ctrl |= PhyCtrlSpd10; - else /* cmd->speed == SPEED_100 */ - phy_ctrl |= PhyCtrlSpd100; - - if (cmd->duplex == DUPLEX_FULL) - phy_ctrl |= PhyCtrlDux; - } - - spin_lock_bh(&priv->lock); - - old_phy_ctrl = ioread32(port_base + PhyCtrl); - phy_ctrl |= old_phy_ctrl & ~(PhyCtrlAne | PhyCtrlDux - | PhyCtrlSpd100 | PhyCtrlSpd10); - if (phy_ctrl != old_phy_ctrl) - iowrite32(phy_ctrl, port_base + PhyCtrl); - - spin_unlock_bh(&priv->lock); - - return 0; -} - -static void sc92031_ethtool_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *drvinfo) -{ - struct sc92031_priv *priv = netdev_priv(dev); - struct pci_dev *pdev = priv->pdev; - - strcpy(drvinfo->driver, SC92031_NAME); - strcpy(drvinfo->version, SC92031_VERSION); - strcpy(drvinfo->bus_info, pci_name(pdev)); -} - -static void sc92031_ethtool_get_wol(struct net_device *dev, - struct ethtool_wolinfo *wolinfo) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u32 pm_config; - - spin_lock_bh(&priv->lock); - pm_config = ioread32(port_base + PMConfig); - spin_unlock_bh(&priv->lock); - - // FIXME: Guessed - wolinfo->supported = WAKE_PHY | WAKE_MAGIC - | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST; - wolinfo->wolopts = 0; - - if (pm_config & PM_LinkUp) - wolinfo->wolopts |= WAKE_PHY; - - if (pm_config & PM_Magic) - wolinfo->wolopts |= WAKE_MAGIC; - - if (pm_config & PM_WakeUp) - // FIXME: Guessed - wolinfo->wolopts |= WAKE_UCAST | WAKE_MCAST | WAKE_BCAST; -} - -static int sc92031_ethtool_set_wol(struct net_device *dev, - struct ethtool_wolinfo *wolinfo) -{ - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u32 pm_config; - - spin_lock_bh(&priv->lock); - - pm_config = ioread32(port_base + PMConfig) - & ~(PM_LinkUp | PM_Magic | PM_WakeUp); - - if (wolinfo->wolopts & WAKE_PHY) - pm_config |= PM_LinkUp; - - if (wolinfo->wolopts & WAKE_MAGIC) - pm_config |= PM_Magic; - - // FIXME: Guessed - if (wolinfo->wolopts & (WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)) - pm_config |= PM_WakeUp; - - priv->pm_config = pm_config; - iowrite32(pm_config, port_base + PMConfig); - mmiowb(); - - spin_unlock_bh(&priv->lock); - - return 0; -} - -static int sc92031_ethtool_nway_reset(struct net_device *dev) -{ - int err = 0; - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem *port_base = priv->port_base; - u16 bmcr; - - spin_lock_bh(&priv->lock); - - bmcr = _sc92031_mii_read(port_base, MII_BMCR); - if (!(bmcr & BMCR_ANENABLE)) { - err = -EINVAL; - goto out; - } - - _sc92031_mii_write(port_base, MII_BMCR, bmcr | BMCR_ANRESTART); - -out: - _sc92031_mii_scan(port_base); - mmiowb(); - - spin_unlock_bh(&priv->lock); - - return err; -} - -static const char sc92031_ethtool_stats_strings[SILAN_STATS_NUM][ETH_GSTRING_LEN] = { - "tx_timeout", - "rx_loss", -}; - -static void sc92031_ethtool_get_strings(struct net_device *dev, - u32 stringset, u8 *data) -{ - if (stringset == ETH_SS_STATS) - memcpy(data, sc92031_ethtool_stats_strings, - SILAN_STATS_NUM * ETH_GSTRING_LEN); -} - -static int sc92031_ethtool_get_stats_count(struct net_device *dev) -{ - return SILAN_STATS_NUM; -} - -static void sc92031_ethtool_get_ethtool_stats(struct net_device *dev, - struct ethtool_stats *stats, u64 *data) -{ - struct sc92031_priv *priv = netdev_priv(dev); - - spin_lock_bh(&priv->lock); - data[0] = priv->tx_timeouts; - data[1] = priv->rx_loss; - spin_unlock_bh(&priv->lock); -} - -static struct ethtool_ops sc92031_ethtool_ops = { - .get_settings = sc92031_ethtool_get_settings, - .set_settings = sc92031_ethtool_set_settings, - .get_drvinfo = sc92031_ethtool_get_drvinfo, - .get_wol = sc92031_ethtool_get_wol, - .set_wol = sc92031_ethtool_set_wol, - .nway_reset = sc92031_ethtool_nway_reset, - .get_link = ethtool_op_get_link, - .get_tx_csum = ethtool_op_get_tx_csum, - .get_sg = ethtool_op_get_sg, - .get_tso = ethtool_op_get_tso, - .get_strings = sc92031_ethtool_get_strings, - .get_stats_count = sc92031_ethtool_get_stats_count, - .get_ethtool_stats = sc92031_ethtool_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, - .get_ufo = ethtool_op_get_ufo, -}; - -static int __devinit sc92031_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int err; - void __iomem* port_base; - struct net_device *dev; - struct sc92031_priv *priv; - u32 mac0, mac1; - - err = pci_enable_device(pdev); - if (unlikely(err < 0)) - goto out_enable_device; - - pci_set_master(pdev); - - err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (unlikely(err < 0)) - goto out_set_dma_mask; - - err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); - if (unlikely(err < 0)) - goto out_set_dma_mask; - - err = pci_request_regions(pdev, SC92031_NAME); - if (unlikely(err < 0)) - goto out_request_regions; - - port_base = pci_iomap(pdev, SC92031_USE_BAR, 0); - if (unlikely(!port_base)) { - err = -EIO; - goto out_iomap; - } - - dev = alloc_etherdev(sizeof(struct sc92031_priv)); - if (unlikely(!dev)) { - err = -ENOMEM; - goto out_alloc_etherdev; - } - - pci_set_drvdata(pdev, dev); - -#if SC92031_USE_BAR == 0 - dev->mem_start = pci_resource_start(pdev, SC92031_USE_BAR); - dev->mem_end = pci_resource_end(pdev, SC92031_USE_BAR); -#elif SC92031_USE_BAR == 1 - dev->base_addr = pci_resource_start(pdev, SC92031_USE_BAR); -#endif - dev->irq = pdev->irq; - - /* faked with skb_copy_and_csum_dev */ - dev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA; - - dev->get_stats = sc92031_get_stats; - dev->ethtool_ops = &sc92031_ethtool_ops; - dev->hard_start_xmit = sc92031_start_xmit; - dev->watchdog_timeo = TX_TIMEOUT; - dev->open = sc92031_open; - dev->stop = sc92031_stop; - dev->set_multicast_list = sc92031_set_multicast_list; - dev->tx_timeout = sc92031_tx_timeout; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = sc92031_poll_controller; -#endif - - priv = netdev_priv(dev); - spin_lock_init(&priv->lock); - priv->port_base = port_base; - priv->pdev = pdev; - tasklet_init(&priv->tasklet, sc92031_tasklet, (unsigned long)dev); - /* Fudge tasklet count so the call to sc92031_enable_interrupts at - * sc92031_open will work correctly */ - tasklet_disable_nosync(&priv->tasklet); - - /* PCI PM Wakeup */ - iowrite32((~PM_LongWF & ~PM_LWPTN) | PM_Enable, port_base + PMConfig); - - mac0 = ioread32(port_base + MAC0); - mac1 = ioread32(port_base + MAC0 + 4); - dev->dev_addr[0] = dev->perm_addr[0] = mac0 >> 24; - dev->dev_addr[1] = dev->perm_addr[1] = mac0 >> 16; - dev->dev_addr[2] = dev->perm_addr[2] = mac0 >> 8; - dev->dev_addr[3] = dev->perm_addr[3] = mac0; - dev->dev_addr[4] = dev->perm_addr[4] = mac1 >> 8; - dev->dev_addr[5] = dev->perm_addr[5] = mac1; - - err = register_netdev(dev); - if (err < 0) - goto out_register_netdev; - - return 0; - -out_register_netdev: - free_netdev(dev); -out_alloc_etherdev: - pci_iounmap(pdev, port_base); -out_iomap: - pci_release_regions(pdev); -out_request_regions: -out_set_dma_mask: - pci_disable_device(pdev); -out_enable_device: - return err; -} - -static void __devexit sc92031_remove(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct sc92031_priv *priv = netdev_priv(dev); - void __iomem* port_base = priv->port_base; - - unregister_netdev(dev); - free_netdev(dev); - pci_iounmap(pdev, port_base); - pci_release_regions(pdev); - pci_disable_device(pdev); -} - -static int sc92031_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct sc92031_priv *priv = netdev_priv(dev); - - pci_save_state(pdev); - - if (!netif_running(dev)) - goto out; - - netif_device_detach(dev); - - /* Disable interrupts, stop Tx and Rx. */ - sc92031_disable_interrupts(dev); - - spin_lock(&priv->lock); - - _sc92031_disable_tx_rx(dev); - _sc92031_tx_clear(dev); - mmiowb(); - - spin_unlock(&priv->lock); - -out: - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - - return 0; -} - -static int sc92031_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct sc92031_priv *priv = netdev_priv(dev); - - pci_restore_state(pdev); - pci_set_power_state(pdev, PCI_D0); - - if (!netif_running(dev)) - goto out; - - /* Interrupts already disabled by sc92031_suspend */ - spin_lock(&priv->lock); - - _sc92031_reset(dev); - mmiowb(); - - spin_unlock(&priv->lock); - sc92031_enable_interrupts(dev); - - netif_device_attach(dev); - - if (netif_carrier_ok(dev)) - netif_wake_queue(dev); - else - netif_tx_disable(dev); - -out: - return 0; -} - -static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = { - { PCI_DEVICE(PCI_VENDOR_ID_SILAN, PCI_DEVICE_ID_SILAN_SC92031) }, - { PCI_DEVICE(PCI_VENDOR_ID_SILAN, PCI_DEVICE_ID_SILAN_8139D) }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table); - -static struct pci_driver sc92031_pci_driver = { - .name = SC92031_NAME, - .id_table = sc92031_pci_device_id_table, - .probe = sc92031_probe, - .remove = __devexit_p(sc92031_remove), - .suspend = sc92031_suspend, - .resume = sc92031_resume, -}; - -static int __init sc92031_init(void) -{ - printk(KERN_INFO SC92031_DESCRIPTION " " SC92031_VERSION "\n"); - return pci_register_driver(&sc92031_pci_driver); -} - -static void __exit sc92031_exit(void) -{ - pci_unregister_driver(&sc92031_pci_driver); -} - -module_init(sc92031_init); -module_exit(sc92031_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Cesar Eduardo Barros "); -MODULE_DESCRIPTION(SC92031_DESCRIPTION); -MODULE_VERSION(SC92031_VERSION); diff --git a/trunk/drivers/net/sk_mca.c b/trunk/drivers/net/sk_mca.c new file mode 100644 index 000000000000..96e06c51b75d --- /dev/null +++ b/trunk/drivers/net/sk_mca.c @@ -0,0 +1,1216 @@ +/* +net-3-driver for the SKNET MCA-based cards + +This is an extension to the Linux operating system, and is covered by the +same GNU General Public License that covers that work. + +Copyright 1999 by Alfred Arnold (alfred@ccac.rwth-aachen.de, + alfred.arnold@lancom.de) + +This driver is based both on the 3C523 driver and the SK_G16 driver. + +paper sources: + 'PC Hardware: Aufbau, Funktionsweise, Programmierung' by + Hans-Peter Messmer for the basic Microchannel stuff + + 'Linux Geraetetreiber' by Allesandro Rubini, Kalle Dalheimer + for help on Ethernet driver programming + + 'Ethernet/IEEE 802.3 Family 1992 World Network Data Book/Handbook' by AMD + for documentation on the AM7990 LANCE + + 'SKNET Personal Technisches Manual', Version 1.2 by Schneider&Koch + for documentation on the Junior board + + 'SK-NET MC2+ Technical Manual", Version 1.1 by Schneider&Koch for + documentation on the MC2 bord + + A big thank you to the S&K support for providing me so quickly with + documentation! + + Also see http://www.syskonnect.com/ + + Missing things: + + -> set debug level via ioctl instead of compile-time switches + -> I didn't follow the development of the 2.1.x kernels, so my + assumptions about which things changed with which kernel version + are probably nonsense + +History: + May 16th, 1999 + startup + May 22st, 1999 + added private structure, methods + begun building data structures in RAM + May 23nd, 1999 + can receive frames, send frames + May 24th, 1999 + modularized initialization of LANCE + loadable as module + still Tx problem :-( + May 26th, 1999 + MC2 works + support for multiple devices + display media type for MC2+ + May 28th, 1999 + fixed problem in GetLANCE leaving interrupts turned off + increase TX queue to 4 packets to improve send performance + May 29th, 1999 + a few corrections in statistics, caught rcvr overruns + reinitialization of LANCE/board in critical situations + MCA info implemented + implemented LANCE multicast filter + Jun 6th, 1999 + additions for Linux 2.2 + Dec 25th, 1999 + unfortunately there seem to be newer MC2+ boards that react + on IRQ 3/5/9/10 instead of 3/5/10/11, so we have to autoprobe + in questionable cases... + Dec 28th, 1999 + integrated patches from David Weinehall & Bill Wendling for 2.3 + kernels (isa_...functions). Things are defined in a way that + it still works with 2.0.x 8-) + Dec 30th, 1999 + added handling of the remaining interrupt conditions. That + should cure the spurious hangs. + Jan 30th, 2000 + newer kernels automatically probe more than one board, so the + 'startslot' as a variable is also needed here + June 1st, 2000 + added changes for recent 2.3 kernels + + *************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define _SK_MCA_DRIVER_ +#include "sk_mca.h" + +/* ------------------------------------------------------------------------ + * global static data - not more since we can handle multiple boards and + * have to pack all state info into the device struct! + * ------------------------------------------------------------------------ */ + +static char *MediaNames[Media_Count] = + { "10Base2", "10BaseT", "10Base5", "Unknown" }; + +static unsigned char poly[] = + { 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0 +}; + +/* ------------------------------------------------------------------------ + * private subfunctions + * ------------------------------------------------------------------------ */ + +/* dump parts of shared memory - only needed during debugging */ + +#ifdef DEBUG +static void dumpmem(struct net_device *dev, u32 start, u32 len) +{ + skmca_priv *priv = netdev_priv(dev); + int z; + + for (z = 0; z < len; z++) { + if ((z & 15) == 0) + printk("%04x:", z); + printk(" %02x", readb(priv->base + start + z)); + if ((z & 15) == 15) + printk("\n"); + } +} + +/* print exact time - ditto */ + +static void PrTime(void) +{ + struct timeval tv; + + do_gettimeofday(&tv); + printk("%9d:%06d: ", tv.tv_sec, tv.tv_usec); +} +#endif + +/* deduce resources out of POS registers */ + +static void __init getaddrs(int slot, int junior, int *base, int *irq, + skmca_medium * medium) +{ + u_char pos0, pos1, pos2; + + if (junior) { + pos0 = mca_read_stored_pos(slot, 2); + *base = ((pos0 & 0x0e) << 13) + 0xc0000; + *irq = ((pos0 & 0x10) >> 4) + 10; + *medium = Media_Unknown; + } else { + /* reset POS 104 Bits 0+1 so the shared memory region goes to the + configured area between 640K and 1M. Afterwards, enable the MC2. + I really don't know what rode SK to do this... */ + + mca_write_pos(slot, 4, + mca_read_stored_pos(slot, 4) & 0xfc); + mca_write_pos(slot, 2, + mca_read_stored_pos(slot, 2) | 0x01); + + pos1 = mca_read_stored_pos(slot, 3); + pos2 = mca_read_stored_pos(slot, 4); + *base = ((pos1 & 0x07) << 14) + 0xc0000; + switch (pos2 & 0x0c) { + case 0: + *irq = 3; + break; + case 4: + *irq = 5; + break; + case 8: + *irq = -10; + break; + case 12: + *irq = -11; + break; + } + *medium = (pos2 >> 6) & 3; + } +} + +/* check for both cards: + When the MC2 is turned off, it was configured for more than 15MB RAM, + is disabled and won't get detected using the standard probe. We + therefore have to scan the slots manually :-( */ + +static int __init dofind(int *junior, int firstslot) +{ + int slot; + unsigned int id; + + for (slot = firstslot; slot < MCA_MAX_SLOT_NR; slot++) { + id = mca_read_stored_pos(slot, 0) + + (((unsigned int) mca_read_stored_pos(slot, 1)) << 8); + + *junior = 0; + if (id == SKNET_MCA_ID) + return slot; + *junior = 1; + if (id == SKNET_JUNIOR_MCA_ID) + return slot; + } + return MCA_NOTFOUND; +} + +/* reset the whole board */ + +static void ResetBoard(struct net_device *dev) +{ + skmca_priv *priv = netdev_priv(dev); + + writeb(CTRL_RESET_ON, priv->ctrladdr); + udelay(10); + writeb(CTRL_RESET_OFF, priv->ctrladdr); +} + +/* wait for LANCE interface to become not busy */ + +static int WaitLANCE(struct net_device *dev) +{ + skmca_priv *priv = netdev_priv(dev); + int t = 0; + + while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == + STAT_IO_BUSY) { + udelay(1); + if (++t > 1000) { + printk("%s: LANCE access timeout", dev->name); + return 0; + } + } + + return 1; +} + +/* set LANCE register - must be atomic */ + +static void SetLANCE(struct net_device *dev, u16 addr, u16 value) +{ + skmca_priv *priv = netdev_priv(dev); + unsigned long flags; + + /* disable interrupts */ + + spin_lock_irqsave(&priv->lock, flags); + + /* wait until no transfer is pending */ + + WaitLANCE(dev); + + /* transfer register address to RAP */ + + writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr); + writew(addr, priv->ioregaddr); + writeb(IOCMD_GO, priv->cmdaddr); + udelay(1); + WaitLANCE(dev); + + /* transfer data to register */ + + writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA, priv->ctrladdr); + writew(value, priv->ioregaddr); + writeb(IOCMD_GO, priv->cmdaddr); + udelay(1); + WaitLANCE(dev); + + /* reenable interrupts */ + + spin_unlock_irqrestore(&priv->lock, flags); +} + +/* get LANCE register */ + +static u16 GetLANCE(struct net_device *dev, u16 addr) +{ + skmca_priv *priv = netdev_priv(dev); + unsigned long flags; + unsigned int res; + + /* disable interrupts */ + + spin_lock_irqsave(&priv->lock, flags); + + /* wait until no transfer is pending */ + + WaitLANCE(dev); + + /* transfer register address to RAP */ + + writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr); + writew(addr, priv->ioregaddr); + writeb(IOCMD_GO, priv->cmdaddr); + udelay(1); + WaitLANCE(dev); + + /* transfer data from register */ + + writeb(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA, priv->ctrladdr); + writeb(IOCMD_GO, priv->cmdaddr); + udelay(1); + WaitLANCE(dev); + res = readw(priv->ioregaddr); + + /* reenable interrupts */ + + spin_unlock_irqrestore(&priv->lock, flags); + + return res; +} + +/* build up descriptors in shared RAM */ + +static void InitDscrs(struct net_device *dev) +{ + skmca_priv *priv = netdev_priv(dev); + u32 bufaddr; + + /* Set up Tx descriptors. The board has only 16K RAM so bits 16..23 + are always 0. */ + + bufaddr = RAM_DATABASE; + { + LANCE_TxDescr descr; + int z; + + for (z = 0; z < TXCOUNT; z++) { + descr.LowAddr = bufaddr; + descr.Flags = 0; + descr.Len = 0xf000; + descr.Status = 0; + memcpy_toio(priv->base + RAM_TXBASE + + (z * sizeof(LANCE_TxDescr)), &descr, + sizeof(LANCE_TxDescr)); + memset_io(priv->base + bufaddr, 0, RAM_BUFSIZE); + bufaddr += RAM_BUFSIZE; + } + } + + /* do the same for the Rx descriptors */ + + { + LANCE_RxDescr descr; + int z; + + for (z = 0; z < RXCOUNT; z++) { + descr.LowAddr = bufaddr; + descr.Flags = RXDSCR_FLAGS_OWN; + descr.MaxLen = -RAM_BUFSIZE; + descr.Len = 0; + memcpy_toio(priv->base + RAM_RXBASE + + (z * sizeof(LANCE_RxDescr)), &descr, + sizeof(LANCE_RxDescr)); + memset_io(priv->base + bufaddr, 0, RAM_BUFSIZE); + bufaddr += RAM_BUFSIZE; + } + } +} + +/* calculate the hash bit position for a given multicast address + taken more or less directly from the AMD datasheet... */ + +static void UpdateCRC(unsigned char *CRC, int bit) +{ + int j; + + /* shift CRC one bit */ + + memmove(CRC + 1, CRC, 32 * sizeof(unsigned char)); + CRC[0] = 0; + + /* if bit XOR controlbit = 1, set CRC = CRC XOR polynomial */ + + if (bit ^ CRC[32]) + for (j = 0; j < 32; j++) + CRC[j] ^= poly[j]; +} + +static unsigned int GetHash(char *address) +{ + unsigned char CRC[33]; + int i, byte, hashcode; + + /* a multicast address has bit 0 in the first byte set */ + + if ((address[0] & 1) == 0) + return -1; + + /* initialize CRC */ + + memset(CRC, 1, sizeof(CRC)); + + /* loop through address bits */ + + for (byte = 0; byte < 6; byte++) + for (i = 0; i < 8; i++) + UpdateCRC(CRC, (address[byte] >> i) & 1); + + /* hashcode is the 6 least significant bits of the CRC */ + + hashcode = 0; + for (i = 0; i < 6; i++) + hashcode = (hashcode << 1) + CRC[i]; + return hashcode; +} + +/* feed ready-built initialization block into LANCE */ + +static void InitLANCE(struct net_device *dev) +{ + skmca_priv *priv = netdev_priv(dev); + + /* build up descriptors. */ + + InitDscrs(dev); + + /* next RX descriptor to be read is the first one. Since the LANCE + will start from the beginning after initialization, we have to + reset out pointers too. */ + + priv->nextrx = 0; + + /* no TX descriptors active */ + + priv->nexttxput = priv->nexttxdone = priv->txbusy = 0; + + /* set up the LANCE bus control register - constant for SKnet boards */ + + SetLANCE(dev, LANCE_CSR3, + CSR3_BSWAP_OFF | CSR3_ALE_LOW | CSR3_BCON_HOLD); + + /* write address of initialization block into LANCE */ + + SetLANCE(dev, LANCE_CSR1, RAM_INITBASE & 0xffff); + SetLANCE(dev, LANCE_CSR2, (RAM_INITBASE >> 16) & 0xff); + + /* we don't get ready until the LANCE has read the init block */ + + netif_stop_queue(dev); + + /* let LANCE read the initialization block. LANCE is ready + when we receive the corresponding interrupt. */ + + SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_INIT); +} + +/* stop the LANCE so we can reinitialize it */ + +static void StopLANCE(struct net_device *dev) +{ + /* can't take frames any more */ + + netif_stop_queue(dev); + + /* disable interrupts, stop it */ + + SetLANCE(dev, LANCE_CSR0, CSR0_STOP); +} + +/* initialize card and LANCE for proper operation */ + +static void InitBoard(struct net_device *dev) +{ + skmca_priv *priv = netdev_priv(dev); + LANCE_InitBlock block; + + /* Lay out the shared RAM - first we create the init block for the LANCE. + We do not overwrite it later because we need it again when we switch + promiscous mode on/off. */ + + block.Mode = 0; + if (dev->flags & IFF_PROMISC) + block.Mode |= LANCE_INIT_PROM; + memcpy(block.PAdr, dev->dev_addr, 6); + memset(block.LAdrF, 0, sizeof(block.LAdrF)); + block.RdrP = (RAM_RXBASE & 0xffffff) | (LRXCOUNT << 29); + block.TdrP = (RAM_TXBASE & 0xffffff) | (LTXCOUNT << 29); + + memcpy_toio(priv->base + RAM_INITBASE, &block, sizeof(block)); + + /* initialize LANCE. Implicitly sets up other structures in RAM. */ + + InitLANCE(dev); +} + +/* deinitialize card and LANCE */ + +static void DeinitBoard(struct net_device *dev) +{ + /* stop LANCE */ + + StopLANCE(dev); + + /* reset board */ + + ResetBoard(dev); +} + +/* probe for device's irq */ + +static int __init ProbeIRQ(struct net_device *dev) +{ + unsigned long imaskval, njiffies, irq; + u16 csr0val; + + /* enable all interrupts */ + + imaskval = probe_irq_on(); + + /* initialize the board. Wait for interrupt 'Initialization done'. */ + + ResetBoard(dev); + InitBoard(dev); + + njiffies = jiffies + HZ; + do { + csr0val = GetLANCE(dev, LANCE_CSR0); + } + while (((csr0val & CSR0_IDON) == 0) && (jiffies != njiffies)); + + /* turn of interrupts again */ + + irq = probe_irq_off(imaskval); + + /* if we found something, ack the interrupt */ + + if (irq) + SetLANCE(dev, LANCE_CSR0, csr0val | CSR0_IDON); + + /* back to idle state */ + + DeinitBoard(dev); + + return irq; +} + +/* ------------------------------------------------------------------------ + * interrupt handler(s) + * ------------------------------------------------------------------------ */ + +/* LANCE has read initialization block -> start it */ + +static u16 irqstart_handler(struct net_device *dev, u16 oldcsr0) +{ + /* now we're ready to transmit */ + + netif_wake_queue(dev); + + /* reset IDON bit, start LANCE */ + + SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_IDON | CSR0_STRT); + return GetLANCE(dev, LANCE_CSR0); +} + +/* did we lose blocks due to a FIFO overrun ? */ + +static u16 irqmiss_handler(struct net_device *dev, u16 oldcsr0) +{ + skmca_priv *priv = netdev_priv(dev); + + /* update statistics */ + + priv->stat.rx_fifo_errors++; + + /* reset MISS bit */ + + SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_MISS); + return GetLANCE(dev, LANCE_CSR0); +} + +/* receive interrupt */ + +static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0) +{ + skmca_priv *priv = netdev_priv(dev); + LANCE_RxDescr descr; + unsigned int descraddr; + + /* run through queue until we reach a descriptor we do not own */ + + descraddr = RAM_RXBASE + (priv->nextrx * sizeof(LANCE_RxDescr)); + while (1) { + /* read descriptor */ + memcpy_fromio(&descr, priv->base + descraddr, + sizeof(LANCE_RxDescr)); + + /* if we reach a descriptor we do not own, we're done */ + if ((descr.Flags & RXDSCR_FLAGS_OWN) != 0) + break; + +#ifdef DEBUG + PrTime(); + printk("Receive packet on descr %d len %d\n", priv->nextrx, + descr.Len); +#endif + + /* erroneous packet ? */ + if ((descr.Flags & RXDSCR_FLAGS_ERR) != 0) { + priv->stat.rx_errors++; + if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0) + priv->stat.rx_crc_errors++; + else if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0) + priv->stat.rx_frame_errors++; + else if ((descr.Flags & RXDSCR_FLAGS_OFLO) != 0) + priv->stat.rx_fifo_errors++; + } + + /* good packet ? */ + else { + struct sk_buff *skb; + + skb = dev_alloc_skb(descr.Len + 2); + if (skb == NULL) + priv->stat.rx_dropped++; + else { + memcpy_fromio(skb_put(skb, descr.Len), + priv->base + + descr.LowAddr, descr.Len); + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + skb->ip_summed = CHECKSUM_NONE; + priv->stat.rx_packets++; + priv->stat.rx_bytes += descr.Len; + netif_rx(skb); + dev->last_rx = jiffies; + } + } + + /* give descriptor back to LANCE */ + descr.Len = 0; + descr.Flags |= RXDSCR_FLAGS_OWN; + + /* update descriptor in shared RAM */ + memcpy_toio(priv->base + descraddr, &descr, + sizeof(LANCE_RxDescr)); + + /* go to next descriptor */ + priv->nextrx++; + descraddr += sizeof(LANCE_RxDescr); + if (priv->nextrx >= RXCOUNT) { + priv->nextrx = 0; + descraddr = RAM_RXBASE; + } + } + + /* reset RINT bit */ + + SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_RINT); + return GetLANCE(dev, LANCE_CSR0); +} + +/* transmit interrupt */ + +static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0) +{ + skmca_priv *priv = netdev_priv(dev); + LANCE_TxDescr descr; + unsigned int descraddr; + + /* check descriptors at most until no busy one is left */ + + descraddr = + RAM_TXBASE + (priv->nexttxdone * sizeof(LANCE_TxDescr)); + while (priv->txbusy > 0) { + /* read descriptor */ + memcpy_fromio(&descr, priv->base + descraddr, + sizeof(LANCE_TxDescr)); + + /* if the LANCE still owns this one, we've worked out all sent packets */ + if ((descr.Flags & TXDSCR_FLAGS_OWN) != 0) + break; + +#ifdef DEBUG + PrTime(); + printk("Send packet done on descr %d\n", priv->nexttxdone); +#endif + + /* update statistics */ + if ((descr.Flags & TXDSCR_FLAGS_ERR) == 0) { + priv->stat.tx_packets++; + priv->stat.tx_bytes++; + } else { + priv->stat.tx_errors++; + if ((descr.Status & TXDSCR_STATUS_UFLO) != 0) { + priv->stat.tx_fifo_errors++; + InitLANCE(dev); + } + else + if ((descr.Status & TXDSCR_STATUS_LCOL) != + 0) priv->stat.tx_window_errors++; + else if ((descr.Status & TXDSCR_STATUS_LCAR) != 0) + priv->stat.tx_carrier_errors++; + else if ((descr.Status & TXDSCR_STATUS_RTRY) != 0) + priv->stat.tx_aborted_errors++; + } + + /* go to next descriptor */ + priv->nexttxdone++; + descraddr += sizeof(LANCE_TxDescr); + if (priv->nexttxdone >= TXCOUNT) { + priv->nexttxdone = 0; + descraddr = RAM_TXBASE; + } + priv->txbusy--; + } + + /* reset TX interrupt bit */ + + SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_TINT); + oldcsr0 = GetLANCE(dev, LANCE_CSR0); + + /* at least one descriptor is freed. Therefore we can accept + a new one */ + /* inform upper layers we're in business again */ + + netif_wake_queue(dev); + + return oldcsr0; +} + +/* general interrupt entry */ + +static irqreturn_t irq_handler(int irq, void *device) +{ + struct net_device *dev = (struct net_device *) device; + u16 csr0val; + + /* read CSR0 to get interrupt cause */ + + csr0val = GetLANCE(dev, LANCE_CSR0); + + /* in case we're not meant... */ + + if ((csr0val & CSR0_INTR) == 0) + return IRQ_NONE; + +#if 0 + set_bit(LINK_STATE_RXSEM, &dev->state); +#endif + + /* loop through the interrupt bits until everything is clear */ + + do { + if ((csr0val & CSR0_IDON) != 0) + csr0val = irqstart_handler(dev, csr0val); + if ((csr0val & CSR0_RINT) != 0) + csr0val = irqrx_handler(dev, csr0val); + if ((csr0val & CSR0_MISS) != 0) + csr0val = irqmiss_handler(dev, csr0val); + if ((csr0val & CSR0_TINT) != 0) + csr0val = irqtx_handler(dev, csr0val); + if ((csr0val & CSR0_MERR) != 0) { + SetLANCE(dev, LANCE_CSR0, csr0val | CSR0_MERR); + csr0val = GetLANCE(dev, LANCE_CSR0); + } + if ((csr0val & CSR0_BABL) != 0) { + SetLANCE(dev, LANCE_CSR0, csr0val | CSR0_BABL); + csr0val = GetLANCE(dev, LANCE_CSR0); + } + } + while ((csr0val & CSR0_INTR) != 0); + +#if 0 + clear_bit(LINK_STATE_RXSEM, &dev->state); +#endif + return IRQ_HANDLED; +} + +/* ------------------------------------------------------------------------ + * driver methods + * ------------------------------------------------------------------------ */ + +/* MCA info */ + +static int skmca_getinfo(char *buf, int slot, void *d) +{ + int len = 0, i; + struct net_device *dev = (struct net_device *) d; + skmca_priv *priv; + + /* can't say anything about an uninitialized device... */ + + if (dev == NULL) + return len; + priv = netdev_priv(dev); + + /* print info */ + + len += sprintf(buf + len, "IRQ: %d\n", priv->realirq); + len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start, + dev->mem_end - 1); + len += + sprintf(buf + len, "Transceiver: %s\n", + MediaNames[priv->medium]); + len += sprintf(buf + len, "Device: %s\n", dev->name); + len += sprintf(buf + len, "MAC address:"); + for (i = 0; i < 6; i++) + len += sprintf(buf + len, " %02x", dev->dev_addr[i]); + buf[len++] = '\n'; + buf[len] = 0; + + return len; +} + +/* open driver. Means also initialization and start of LANCE */ + +static int skmca_open(struct net_device *dev) +{ + int result; + skmca_priv *priv = netdev_priv(dev); + + /* register resources - only necessary for IRQ */ + result = + request_irq(priv->realirq, irq_handler, + IRQF_SHARED | IRQF_SAMPLE_RANDOM, "sk_mca", dev); + if (result != 0) { + printk("%s: failed to register irq %d\n", dev->name, + dev->irq); + return result; + } + dev->irq = priv->realirq; + + /* set up the card and LANCE */ + + InitBoard(dev); + + /* set up flags */ + + netif_start_queue(dev); + + return 0; +} + +/* close driver. Shut down board and free allocated resources */ + +static int skmca_close(struct net_device *dev) +{ + /* turn off board */ + DeinitBoard(dev); + + /* release resources */ + if (dev->irq != 0) + free_irq(dev->irq, dev); + dev->irq = 0; + + return 0; +} + +/* transmit a block. */ + +static int skmca_tx(struct sk_buff *skb, struct net_device *dev) +{ + skmca_priv *priv = netdev_priv(dev); + LANCE_TxDescr descr; + unsigned int address; + int tmplen, retval = 0; + unsigned long flags; + + /* if we get called with a NULL descriptor, the Ethernet layer thinks + our card is stuck an we should reset it. We'll do this completely: */ + + if (skb == NULL) { + DeinitBoard(dev); + InitBoard(dev); + return 0; /* don't try to free the block here ;-) */ + } + + /* is there space in the Tx queue ? If no, the upper layer gave us a + packet in spite of us not being ready and is really in trouble. + We'll do the dropping for him: */ + if (priv->txbusy >= TXCOUNT) { + priv->stat.tx_dropped++; + retval = -EIO; + goto tx_done; + } + + /* get TX descriptor */ + address = RAM_TXBASE + (priv->nexttxput * sizeof(LANCE_TxDescr)); + memcpy_fromio(&descr, priv->base + address, sizeof(LANCE_TxDescr)); + + /* enter packet length as 2s complement - assure minimum length */ + tmplen = skb->len; + if (tmplen < 60) + tmplen = 60; + descr.Len = 65536 - tmplen; + + /* copy filler into RAM - in case we're filling up... + we're filling a bit more than necessary, but that doesn't harm + since the buffer is far larger... */ + if (tmplen > skb->len) { + char *fill = "NetBSD is a nice OS too! "; + unsigned int destoffs = 0, l = strlen(fill); + + while (destoffs < tmplen) { + memcpy_toio(priv->base + descr.LowAddr + + destoffs, fill, l); + destoffs += l; + } + } + + /* do the real data copying */ + memcpy_toio(priv->base + descr.LowAddr, skb->data, skb->len); + + /* hand descriptor over to LANCE - this is the first and last chunk */ + descr.Flags = + TXDSCR_FLAGS_OWN | TXDSCR_FLAGS_STP | TXDSCR_FLAGS_ENP; + +#ifdef DEBUG + PrTime(); + printk("Send packet on descr %d len %d\n", priv->nexttxput, + skb->len); +#endif + + /* one more descriptor busy */ + + spin_lock_irqsave(&priv->lock, flags); + + priv->nexttxput++; + if (priv->nexttxput >= TXCOUNT) + priv->nexttxput = 0; + priv->txbusy++; + + /* are we saturated ? */ + + if (priv->txbusy >= TXCOUNT) + netif_stop_queue(dev); + + /* write descriptor back to RAM */ + memcpy_toio(priv->base + address, &descr, sizeof(LANCE_TxDescr)); + + /* if no descriptors were active, give the LANCE a hint to read it + immediately */ + + if (priv->txbusy == 0) + SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_TDMD); + + spin_unlock_irqrestore(&priv->lock, flags); + + tx_done: + + dev_kfree_skb(skb); + + return retval; +} + +/* return pointer to Ethernet statistics */ + +static struct net_device_stats *skmca_stats(struct net_device *dev) +{ + skmca_priv *priv = netdev_priv(dev); + + return &(priv->stat); +} + +/* switch receiver mode. We use the LANCE's multicast filter to prefilter + multicast addresses. */ + +static void skmca_set_multicast_list(struct net_device *dev) +{ + skmca_priv *priv = netdev_priv(dev); + LANCE_InitBlock block; + + /* first stop the LANCE... */ + StopLANCE(dev); + + /* ...then modify the initialization block... */ + memcpy_fromio(&block, priv->base + RAM_INITBASE, sizeof(block)); + if (dev->flags & IFF_PROMISC) + block.Mode |= LANCE_INIT_PROM; + else + block.Mode &= ~LANCE_INIT_PROM; + + if (dev->flags & IFF_ALLMULTI) { /* get all multicasts */ + memset(block.LAdrF, 0xff, sizeof(block.LAdrF)); + } else { /* get selected/no multicasts */ + + struct dev_mc_list *mptr; + int code; + + memset(block.LAdrF, 0, sizeof(block.LAdrF)); + for (mptr = dev->mc_list; mptr != NULL; mptr = mptr->next) { + code = GetHash(mptr->dmi_addr); + block.LAdrF[(code >> 3) & 7] |= 1 << (code & 7); + } + } + + memcpy_toio(priv->base + RAM_INITBASE, &block, sizeof(block)); + + /* ...then reinit LANCE with the correct flags */ + InitLANCE(dev); +} + +/* ------------------------------------------------------------------------ + * hardware check + * ------------------------------------------------------------------------ */ + +static int startslot; /* counts through slots when probing multiple devices */ + +static void cleanup_card(struct net_device *dev) +{ + skmca_priv *priv = netdev_priv(dev); + DeinitBoard(dev); + if (dev->irq != 0) + free_irq(dev->irq, dev); + iounmap(priv->base); + mca_mark_as_unused(priv->slot); + mca_set_adapter_procfn(priv->slot, NULL, NULL); +} + +struct net_device * __init skmca_probe(int unit) +{ + struct net_device *dev; + int force_detect = 0; + int junior, slot, i; + int base = 0, irq = 0; + skmca_priv *priv; + skmca_medium medium; + int err; + + /* can't work without an MCA bus ;-) */ + + if (MCA_bus == 0) + return ERR_PTR(-ENODEV); + + dev = alloc_etherdev(sizeof(skmca_priv)); + if (!dev) + return ERR_PTR(-ENOMEM); + + if (unit >= 0) { + sprintf(dev->name, "eth%d", unit); + netdev_boot_setup_check(dev); + } + + SET_MODULE_OWNER(dev); + + /* start address of 1 --> forced detection */ + + if (dev->mem_start == 1) + force_detect = 1; + + /* search through slots */ + + base = dev->mem_start; + irq = dev->base_addr; + for (slot = startslot; (slot = dofind(&junior, slot)) != -1; slot++) { + /* deduce card addresses */ + + getaddrs(slot, junior, &base, &irq, &medium); + + /* slot already in use ? */ + + if (mca_is_adapter_used(slot)) + continue; + + /* were we looking for something different ? */ + + if (dev->irq && dev->irq != irq) + continue; + if (dev->mem_start && dev->mem_start != base) + continue; + + /* found something that matches */ + + break; + } + + /* nothing found ? */ + + if (slot == -1) { + free_netdev(dev); + return (base || irq) ? ERR_PTR(-ENXIO) : ERR_PTR(-ENODEV); + } + + /* make procfs entries */ + + if (junior) + mca_set_adapter_name(slot, + "SKNET junior MC2 Ethernet Adapter"); + else + mca_set_adapter_name(slot, "SKNET MC2+ Ethernet Adapter"); + mca_set_adapter_procfn(slot, (MCA_ProcFn) skmca_getinfo, dev); + + mca_mark_as_used(slot); + + /* announce success */ + printk("%s: SKNet %s adapter found in slot %d\n", dev->name, + junior ? "Junior MC2" : "MC2+", slot + 1); + + priv = netdev_priv(dev); + priv->base = ioremap(base, 0x4000); + if (!priv->base) { + mca_set_adapter_procfn(slot, NULL, NULL); + mca_mark_as_unused(slot); + free_netdev(dev); + return ERR_PTR(-ENOMEM); + } + + priv->slot = slot; + priv->macbase = priv->base + 0x3fc0; + priv->ioregaddr = priv->base + 0x3ff0; + priv->ctrladdr = priv->base + 0x3ff2; + priv->cmdaddr = priv->base + 0x3ff3; + priv->medium = medium; + memset(&priv->stat, 0, sizeof(struct net_device_stats)); + spin_lock_init(&priv->lock); + + /* set base + irq for this device (irq not allocated so far) */ + dev->irq = 0; + dev->mem_start = base; + dev->mem_end = base + 0x4000; + + /* autoprobe ? */ + if (irq < 0) { + int nirq; + + printk + ("%s: ambigous POS bit combination, must probe for IRQ...\n", + dev->name); + nirq = ProbeIRQ(dev); + if (nirq <= 0) + printk("%s: IRQ probe failed, assuming IRQ %d", + dev->name, priv->realirq = -irq); + else + priv->realirq = nirq; + } else + priv->realirq = irq; + + /* set methods */ + dev->open = skmca_open; + dev->stop = skmca_close; + dev->hard_start_xmit = skmca_tx; + dev->do_ioctl = NULL; + dev->get_stats = skmca_stats; + dev->set_multicast_list = skmca_set_multicast_list; + dev->flags |= IFF_MULTICAST; + + /* copy out MAC address */ + for (i = 0; i < 6; i++) + dev->dev_addr[i] = readb(priv->macbase + (i << 1)); + + /* print config */ + printk("%s: IRQ %d, memory %#lx-%#lx, " + "MAC address %02x:%02x:%02x:%02x:%02x:%02x.\n", + dev->name, priv->realirq, dev->mem_start, dev->mem_end - 1, + dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk("%s: %s medium\n", dev->name, MediaNames[priv->medium]); + + /* reset board */ + + ResetBoard(dev); + + startslot = slot + 1; + + err = register_netdev(dev); + if (err) { + cleanup_card(dev); + free_netdev(dev); + dev = ERR_PTR(err); + } + return dev; +} + +/* ------------------------------------------------------------------------ + * modularization support + * ------------------------------------------------------------------------ */ + +#ifdef MODULE +MODULE_LICENSE("GPL"); + +#define DEVMAX 5 + +static struct net_device *moddevs[DEVMAX]; + +int init_module(void) +{ + int z; + + startslot = 0; + for (z = 0; z < DEVMAX; z++) { + struct net_device *dev = skmca_probe(-1); + if (IS_ERR(dev)) + break; + moddevs[z] = dev; + } + if (!z) + return -EIO; + return 0; +} + +void cleanup_module(void) +{ + int z; + + for (z = 0; z < DEVMAX; z++) { + struct net_device *dev = moddevs[z]; + if (dev) { + unregister_netdev(dev); + cleanup_card(dev); + free_netdev(dev); + } + } +} +#endif /* MODULE */ diff --git a/trunk/drivers/net/sk_mca.h b/trunk/drivers/net/sk_mca.h new file mode 100644 index 000000000000..0dae056fed99 --- /dev/null +++ b/trunk/drivers/net/sk_mca.h @@ -0,0 +1,170 @@ +#ifndef _SK_MCA_INCLUDE_ +#define _SK_MCA_INCLUDE_ + +#ifdef _SK_MCA_DRIVER_ + +/* Adapter ID's */ +#define SKNET_MCA_ID 0x6afd +#define SKNET_JUNIOR_MCA_ID 0x6be9 + +/* media enumeration - defined in a way that it fits onto the MC2+'s + POS registers... */ + +typedef enum { Media_10Base2, Media_10BaseT, + Media_10Base5, Media_Unknown, Media_Count +} skmca_medium; + +/* private structure */ +typedef struct { + unsigned int slot; /* MCA-Slot-# */ + void __iomem *base; + void __iomem *macbase; /* base address of MAC address PROM */ + void __iomem *ioregaddr;/* address of I/O-register (Lo) */ + void __iomem *ctrladdr; /* address of control/stat register */ + void __iomem *cmdaddr; /* address of I/O-command register */ + int nextrx; /* index of next RX descriptor to + be read */ + int nexttxput; /* index of next free TX descriptor */ + int nexttxdone; /* index of next TX descriptor to + be finished */ + int txbusy; /* # of busy TX descriptors */ + struct net_device_stats stat; /* packet statistics */ + int realirq; /* memorizes actual IRQ, even when + currently not allocated */ + skmca_medium medium; /* physical cannector */ + spinlock_t lock; +} skmca_priv; + +/* card registers: control/status register bits */ + +#define CTRL_ADR_DATA 0 /* Bit 0 = 0 ->access data register */ +#define CTRL_ADR_RAP 1 /* Bit 0 = 1 ->access RAP register */ +#define CTRL_RW_WRITE 0 /* Bit 1 = 0 ->write register */ +#define CTRL_RW_READ 2 /* Bit 1 = 1 ->read register */ +#define CTRL_RESET_ON 0 /* Bit 3 = 0 ->reset board */ +#define CTRL_RESET_OFF 8 /* Bit 3 = 1 ->no reset of board */ + +#define STAT_ADR_DATA 0 /* Bit 0 of ctrl register read back */ +#define STAT_ADR_RAP 1 +#define STAT_RW_WRITE 0 /* Bit 1 of ctrl register read back */ +#define STAT_RW_READ 2 +#define STAT_RESET_ON 0 /* Bit 3 of ctrl register read back */ +#define STAT_RESET_OFF 8 +#define STAT_IRQ_ACT 0 /* interrupt pending */ +#define STAT_IRQ_NOACT 16 /* no interrupt pending */ +#define STAT_IO_NOBUSY 0 /* no transfer busy */ +#define STAT_IO_BUSY 32 /* transfer busy */ + +/* I/O command register bits */ + +#define IOCMD_GO 128 /* Bit 7 = 1 -> start register xfer */ + +/* LANCE registers */ + +#define LANCE_CSR0 0 /* Status/Control */ + +#define CSR0_ERR 0x8000 /* general error flag */ +#define CSR0_BABL 0x4000 /* transmitter timeout */ +#define CSR0_CERR 0x2000 /* collision error */ +#define CSR0_MISS 0x1000 /* lost Rx block */ +#define CSR0_MERR 0x0800 /* memory access error */ +#define CSR0_RINT 0x0400 /* receiver interrupt */ +#define CSR0_TINT 0x0200 /* transmitter interrupt */ +#define CSR0_IDON 0x0100 /* initialization done */ +#define CSR0_INTR 0x0080 /* general interrupt flag */ +#define CSR0_INEA 0x0040 /* interrupt enable */ +#define CSR0_RXON 0x0020 /* receiver enabled */ +#define CSR0_TXON 0x0010 /* transmitter enabled */ +#define CSR0_TDMD 0x0008 /* force transmission now */ +#define CSR0_STOP 0x0004 /* stop LANCE */ +#define CSR0_STRT 0x0002 /* start LANCE */ +#define CSR0_INIT 0x0001 /* read initialization block */ + +#define LANCE_CSR1 1 /* addr bit 0..15 of initialization */ +#define LANCE_CSR2 2 /* 16..23 block */ + +#define LANCE_CSR3 3 /* Bus control */ +#define CSR3_BCON_HOLD 0 /* Bit 0 = 0 -> BM1,BM0,HOLD */ +#define CSR3_BCON_BUSRQ 1 /* Bit 0 = 1 -> BUSAK0,BYTE,BUSRQ */ +#define CSR3_ALE_HIGH 0 /* Bit 1 = 0 -> ALE asserted high */ +#define CSR3_ALE_LOW 2 /* Bit 1 = 1 -> ALE asserted low */ +#define CSR3_BSWAP_OFF 0 /* Bit 2 = 0 -> no byte swap */ +#define CSR3_BSWAP_ON 4 /* Bit 2 = 1 -> byte swap */ + +/* LANCE structures */ + +typedef struct { /* LANCE initialization block */ + u16 Mode; /* mode flags */ + u8 PAdr[6]; /* MAC address */ + u8 LAdrF[8]; /* Multicast filter */ + u32 RdrP; /* Receive descriptor */ + u32 TdrP; /* Transmit descriptor */ +} LANCE_InitBlock; + +/* Mode flags init block */ + +#define LANCE_INIT_PROM 0x8000 /* enable promiscous mode */ +#define LANCE_INIT_INTL 0x0040 /* internal loopback */ +#define LANCE_INIT_DRTY 0x0020 /* disable retry */ +#define LANCE_INIT_COLL 0x0010 /* force collision */ +#define LANCE_INIT_DTCR 0x0008 /* disable transmit CRC */ +#define LANCE_INIT_LOOP 0x0004 /* loopback */ +#define LANCE_INIT_DTX 0x0002 /* disable transmitter */ +#define LANCE_INIT_DRX 0x0001 /* disable receiver */ + +typedef struct { /* LANCE Tx descriptor */ + u16 LowAddr; /* bit 0..15 of address */ + u16 Flags; /* bit 16..23 of address + Flags */ + u16 Len; /* 2s complement of packet length */ + u16 Status; /* Result of transmission */ +} LANCE_TxDescr; + +#define TXDSCR_FLAGS_OWN 0x8000 /* LANCE owns descriptor */ +#define TXDSCR_FLAGS_ERR 0x4000 /* summary error flag */ +#define TXDSCR_FLAGS_MORE 0x1000 /* more than one retry needed? */ +#define TXDSCR_FLAGS_ONE 0x0800 /* one retry? */ +#define TXDSCR_FLAGS_DEF 0x0400 /* transmission deferred? */ +#define TXDSCR_FLAGS_STP 0x0200 /* first packet in chain? */ +#define TXDSCR_FLAGS_ENP 0x0100 /* last packet in chain? */ + +#define TXDSCR_STATUS_BUFF 0x8000 /* buffer error? */ +#define TXDSCR_STATUS_UFLO 0x4000 /* silo underflow during transmit? */ +#define TXDSCR_STATUS_LCOL 0x1000 /* late collision? */ +#define TXDSCR_STATUS_LCAR 0x0800 /* loss of carrier? */ +#define TXDSCR_STATUS_RTRY 0x0400 /* retry error? */ + +typedef struct { /* LANCE Rx descriptor */ + u16 LowAddr; /* bit 0..15 of address */ + u16 Flags; /* bit 16..23 of address + Flags */ + u16 MaxLen; /* 2s complement of buffer length */ + u16 Len; /* packet length */ +} LANCE_RxDescr; + +#define RXDSCR_FLAGS_OWN 0x8000 /* LANCE owns descriptor */ +#define RXDSCR_FLAGS_ERR 0x4000 /* summary error flag */ +#define RXDSCR_FLAGS_FRAM 0x2000 /* framing error flag */ +#define RXDSCR_FLAGS_OFLO 0x1000 /* FIFO overflow? */ +#define RXDSCR_FLAGS_CRC 0x0800 /* CRC error? */ +#define RXDSCR_FLAGS_BUFF 0x0400 /* buffer error? */ +#define RXDSCR_FLAGS_STP 0x0200 /* first packet in chain? */ +#define RXDCSR_FLAGS_ENP 0x0100 /* last packet in chain? */ + +/* RAM layout */ + +#define TXCOUNT 4 /* length of TX descriptor queue */ +#define LTXCOUNT 2 /* log2 of it */ +#define RXCOUNT 4 /* length of RX descriptor queue */ +#define LRXCOUNT 2 /* log2 of it */ + +#define RAM_INITBASE 0 /* LANCE init block */ +#define RAM_TXBASE 24 /* Start of TX descriptor queue */ +#define RAM_RXBASE \ +(RAM_TXBASE + (TXCOUNT * 8)) /* Start of RX descriptor queue */ +#define RAM_DATABASE \ +(RAM_RXBASE + (RXCOUNT * 8)) /* Start of data area for frames */ +#define RAM_BUFSIZE 1580 /* max. frame size - should never be + reached */ + +#endif /* _SK_MCA_DRIVER_ */ + +#endif /* _SK_MCA_INCLUDE_ */ diff --git a/trunk/drivers/net/skfp/can.c b/trunk/drivers/net/skfp/can.c new file mode 100644 index 000000000000..8a49abce7961 --- /dev/null +++ b/trunk/drivers/net/skfp/can.c @@ -0,0 +1,83 @@ +/****************************************************************************** + * + * (C)Copyright 1998,1999 SysKonnect, + * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * + * See the file "skfddi.c" for further information. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +#ifndef lint +static const char xID_sccs[] = "@(#)can.c 1.5 97/04/07 (C) SK " ; +#endif + +/* + * canonical bit order + */ +const u_char canonical[256] = { + 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0, + 0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0, + 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8, + 0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8, + 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4, + 0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4, + 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec, + 0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc, + 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2, + 0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2, + 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea, + 0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa, + 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6, + 0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6, + 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee, + 0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe, + 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1, + 0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1, + 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9, + 0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9, + 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5, + 0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5, + 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed, + 0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd, + 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3, + 0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3, + 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb, + 0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb, + 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7, + 0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7, + 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef, + 0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff +} ; + +#ifdef MAKE_TABLE +int byte_reverse(x) +int x ; +{ + int y = 0 ; + + if (x & 0x01) + y |= 0x80 ; + if (x & 0x02) + y |= 0x40 ; + if (x & 0x04) + y |= 0x20 ; + if (x & 0x08) + y |= 0x10 ; + if (x & 0x10) + y |= 0x08 ; + if (x & 0x20) + y |= 0x04 ; + if (x & 0x40) + y |= 0x02 ; + if (x & 0x80) + y |= 0x01 ; + return(y) ; +} +#endif diff --git a/trunk/drivers/net/skfp/drvfbi.c b/trunk/drivers/net/skfp/drvfbi.c index 4fe624b0dd25..5b475833f645 100644 --- a/trunk/drivers/net/skfp/drvfbi.c +++ b/trunk/drivers/net/skfp/drvfbi.c @@ -23,7 +23,6 @@ #include "h/smc.h" #include "h/supern_2.h" #include "h/skfbiinc.h" -#include #ifndef lint static const char ID_sccs[] = "@(#)drvfbi.c 1.63 99/02/11 (C) SK " ; @@ -446,14 +445,16 @@ void read_address(struct s_smc *smc, u_char *mac_addr) char PmdType ; int i ; + extern const u_char canonical[256] ; + #if (defined(ISA) || defined(MCA)) for (i = 0; i < 4 ;i++) { /* read mac address from board */ smc->hw.fddi_phys_addr.a[i] = - bitrev8(inpw(PR_A(i+SA_MAC))); + canonical[(inpw(PR_A(i+SA_MAC))&0xff)] ; } for (i = 4; i < 6; i++) { smc->hw.fddi_phys_addr.a[i] = - bitrev8(inpw(PR_A(i+SA_MAC+PRA_OFF))); + canonical[(inpw(PR_A(i+SA_MAC+PRA_OFF))&0xff)] ; } #endif #ifdef EISA @@ -463,17 +464,17 @@ void read_address(struct s_smc *smc, u_char *mac_addr) */ for (i = 0; i < 4 ;i++) { /* read mac address from board */ smc->hw.fddi_phys_addr.a[i] = - bitrev8(inp(PR_A(i+SA_MAC))); + canonical[inp(PR_A(i+SA_MAC))] ; } for (i = 4; i < 6; i++) { smc->hw.fddi_phys_addr.a[i] = - bitrev8(inp(PR_A(i+SA_MAC+PRA_OFF))); + canonical[inp(PR_A(i+SA_MAC+PRA_OFF))] ; } #endif #ifdef PCI for (i = 0; i < 6; i++) { /* read mac address from board */ smc->hw.fddi_phys_addr.a[i] = - bitrev8(inp(ADDR(B2_MAC_0+i))); + canonical[inp(ADDR(B2_MAC_0+i))] ; } #endif #ifndef PCI @@ -492,7 +493,7 @@ void read_address(struct s_smc *smc, u_char *mac_addr) if (mac_addr) { for (i = 0; i < 6 ;i++) { smc->hw.fddi_canon_addr.a[i] = mac_addr[i] ; - smc->hw.fddi_home_addr.a[i] = bitrev8(mac_addr[i]); + smc->hw.fddi_home_addr.a[i] = canonical[mac_addr[i]] ; } return ; } @@ -500,7 +501,7 @@ void read_address(struct s_smc *smc, u_char *mac_addr) for (i = 0; i < 6 ;i++) { smc->hw.fddi_canon_addr.a[i] = - bitrev8(smc->hw.fddi_phys_addr.a[i]); + canonical[smc->hw.fddi_phys_addr.a[i]] ; } } @@ -1268,8 +1269,11 @@ void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr) { int i ; - for (i = 0 ; i < 6 ; i++) - bia_addr->a[i] = bitrev8(smc->hw.fddi_phys_addr.a[i]); + extern const u_char canonical[256] ; + + for (i = 0 ; i < 6 ; i++) { + bia_addr->a[i] = canonical[smc->hw.fddi_phys_addr.a[i]] ; + } } void smt_start_watchdog(struct s_smc *smc) diff --git a/trunk/drivers/net/skfp/fplustm.c b/trunk/drivers/net/skfp/fplustm.c index a45205da8033..0784f558ca9a 100644 --- a/trunk/drivers/net/skfp/fplustm.c +++ b/trunk/drivers/net/skfp/fplustm.c @@ -22,7 +22,7 @@ #include "h/fddi.h" #include "h/smc.h" #include "h/supern_2.h" -#include +#include "can.c" #ifndef lint static const char ID_sccs[] = "@(#)fplustm.c 1.32 99/02/23 (C) SK " ; @@ -1073,7 +1073,7 @@ static struct s_fpmc* mac_get_mc_table(struct s_smc *smc, if (can) { p = own->a ; for (i = 0 ; i < 6 ; i++, p++) - *p = bitrev8(*p); + *p = canonical[*p] ; } slot = NULL; for (i = 0, tb = smc->hw.fp.mc.table ; i < FPMAX_MULTICAST ; i++, tb++){ diff --git a/trunk/drivers/net/skfp/smt.c b/trunk/drivers/net/skfp/smt.c index fe847800acdc..99a776a51fb5 100644 --- a/trunk/drivers/net/skfp/smt.c +++ b/trunk/drivers/net/skfp/smt.c @@ -18,7 +18,6 @@ #include "h/fddi.h" #include "h/smc.h" #include "h/smt_p.h" -#include #define KERNEL #include "h/smtstate.h" @@ -27,6 +26,8 @@ static const char ID_sccs[] = "@(#)smt.c 2.43 98/11/23 (C) SK " ; #endif +extern const u_char canonical[256] ; + /* * FC in SMbuf */ @@ -179,7 +180,7 @@ void smt_agent_init(struct s_smc *smc) driver_get_bia(smc,&smc->mib.fddiSMTStationId.sid_node) ; for (i = 0 ; i < 6 ; i ++) { smc->mib.fddiSMTStationId.sid_node.a[i] = - bitrev8(smc->mib.fddiSMTStationId.sid_node.a[i]); + canonical[smc->mib.fddiSMTStationId.sid_node.a[i]] ; } smc->mib.fddiSMTManufacturerData[0] = smc->mib.fddiSMTStationId.sid_node.a[0] ; @@ -2048,8 +2049,9 @@ static void hwm_conv_can(struct s_smc *smc, char *data, int len) SK_UNUSED(smc) ; - for (i = len; i ; i--, data++) - *data = bitrev8(*data); + for (i = len; i ; i--, data++) { + *data = canonical[*(u_char *)data] ; + } } #endif diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index e482e7fcbb2b..45283f3f95e4 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -42,7 +42,7 @@ #include "skge.h" #define DRV_NAME "skge" -#define DRV_VERSION "1.10" +#define DRV_VERSION "1.9" #define PFX DRV_NAME " " #define DEFAULT_TX_RING_SIZE 128 @@ -132,93 +132,18 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, } /* Wake on Lan only supported on Yukon chips with rev 1 or above */ -static u32 wol_supported(const struct skge_hw *hw) +static int wol_supported(const struct skge_hw *hw) { - if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0) - return WAKE_MAGIC | WAKE_PHY; - else - return 0; -} - -static u32 pci_wake_enabled(struct pci_dev *dev) -{ - int pm = pci_find_capability(dev, PCI_CAP_ID_PM); - u16 value; - - /* If device doesn't support PM Capabilities, but request is to disable - * wake events, it's a nop; otherwise fail */ - if (!pm) - return 0; - - pci_read_config_word(dev, pm + PCI_PM_PMC, &value); - - value &= PCI_PM_CAP_PME_MASK; - value >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */ - - return value != 0; -} - -static void skge_wol_init(struct skge_port *skge) -{ - struct skge_hw *hw = skge->hw; - int port = skge->port; - enum pause_control save_mode; - u32 ctrl; - - /* Bring hardware out of reset */ - skge_write16(hw, B0_CTST, CS_RST_CLR); - skge_write16(hw, SK_REG(port, GMAC_LINK_CTRL), GMLC_RST_CLR); - - skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); - skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); - - /* Force to 10/100 skge_reset will re-enable on resume */ - save_mode = skge->flow_control; - skge->flow_control = FLOW_MODE_SYMMETRIC; - - ctrl = skge->advertising; - skge->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full); - - skge_phy_reset(skge); - - skge->flow_control = save_mode; - skge->advertising = ctrl; - - /* Set GMAC to no flow control and auto update for speed/duplex */ - gma_write16(hw, port, GM_GP_CTRL, - GM_GPCR_FC_TX_DIS|GM_GPCR_TX_ENA|GM_GPCR_RX_ENA| - GM_GPCR_DUP_FULL|GM_GPCR_FC_RX_DIS|GM_GPCR_AU_FCT_DIS); - - /* Set WOL address */ - memcpy_toio(hw->regs + WOL_REGS(port, WOL_MAC_ADDR), - skge->netdev->dev_addr, ETH_ALEN); - - /* Turn on appropriate WOL control bits */ - skge_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), WOL_CTL_CLEAR_RESULT); - ctrl = 0; - if (skge->wol & WAKE_PHY) - ctrl |= WOL_CTL_ENA_PME_ON_LINK_CHG|WOL_CTL_ENA_LINK_CHG_UNIT; - else - ctrl |= WOL_CTL_DIS_PME_ON_LINK_CHG|WOL_CTL_DIS_LINK_CHG_UNIT; - - if (skge->wol & WAKE_MAGIC) - ctrl |= WOL_CTL_ENA_PME_ON_MAGIC_PKT|WOL_CTL_ENA_MAGIC_PKT_UNIT; - else - ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;; - - ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT; - skge_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl); - - /* block receiver */ - skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); + return !((hw->chip_id == CHIP_ID_GENESIS || + (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0))); } static void skge_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct skge_port *skge = netdev_priv(dev); - wol->supported = wol_supported(skge->hw); - wol->wolopts = skge->wol; + wol->supported = wol_supported(skge->hw) ? WAKE_MAGIC : 0; + wol->wolopts = skge->wol ? WAKE_MAGIC : 0; } static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) @@ -226,12 +151,23 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct skge_port *skge = netdev_priv(dev); struct skge_hw *hw = skge->hw; - if (wol->wolopts & wol_supported(hw)) + if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) return -EOPNOTSUPP; - skge->wol = wol->wolopts; - if (!netif_running(dev)) - skge_wol_init(skge); + if (wol->wolopts == WAKE_MAGIC && !wol_supported(hw)) + return -EOPNOTSUPP; + + skge->wol = wol->wolopts == WAKE_MAGIC; + + if (skge->wol) { + memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN); + + skge_write16(hw, WOL_CTRL_STAT, + WOL_CTL_ENA_PME_ON_MAGIC_PKT | + WOL_CTL_ENA_MAGIC_PKT_UNIT); + } else + skge_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT); + return 0; } @@ -2437,9 +2373,6 @@ static int skge_up(struct net_device *dev) size_t rx_size, tx_size; int err; - if (!is_valid_ether_addr(dev->dev_addr)) - return -EINVAL; - if (netif_msg_ifup(skge)) printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); @@ -2459,7 +2392,7 @@ static int skge_up(struct net_device *dev) BUG_ON(skge->dma & 7); if ((u64)skge->dma >> 32 != ((u64) skge->dma + skge->mem_size) >> 32) { - dev_err(&hw->pdev->dev, "pci_alloc_consistent region crosses 4G boundary\n"); + printk(KERN_ERR PFX "pci_alloc_consistent region crosses 4G boundary\n"); err = -EINVAL; goto free_pci_mem; } @@ -3068,7 +3001,6 @@ static void skge_mac_intr(struct skge_hw *hw, int port) /* Handle device specific framing and timeout interrupts */ static void skge_error_irq(struct skge_hw *hw) { - struct pci_dev *pdev = hw->pdev; u32 hwstatus = skge_read32(hw, B0_HWE_ISRC); if (hw->chip_id == CHIP_ID_GENESIS) { @@ -3084,12 +3016,12 @@ static void skge_error_irq(struct skge_hw *hw) } if (hwstatus & IS_RAM_RD_PAR) { - dev_err(&pdev->dev, "Ram read data parity error\n"); + printk(KERN_ERR PFX "Ram read data parity error\n"); skge_write16(hw, B3_RI_CTRL, RI_CLR_RD_PERR); } if (hwstatus & IS_RAM_WR_PAR) { - dev_err(&pdev->dev, "Ram write data parity error\n"); + printk(KERN_ERR PFX "Ram write data parity error\n"); skge_write16(hw, B3_RI_CTRL, RI_CLR_WR_PERR); } @@ -3100,38 +3032,38 @@ static void skge_error_irq(struct skge_hw *hw) skge_mac_parity(hw, 1); if (hwstatus & IS_R1_PAR_ERR) { - dev_err(&pdev->dev, "%s: receive queue parity error\n", - hw->dev[0]->name); + printk(KERN_ERR PFX "%s: receive queue parity error\n", + hw->dev[0]->name); skge_write32(hw, B0_R1_CSR, CSR_IRQ_CL_P); } if (hwstatus & IS_R2_PAR_ERR) { - dev_err(&pdev->dev, "%s: receive queue parity error\n", - hw->dev[1]->name); + printk(KERN_ERR PFX "%s: receive queue parity error\n", + hw->dev[1]->name); skge_write32(hw, B0_R2_CSR, CSR_IRQ_CL_P); } if (hwstatus & (IS_IRQ_MST_ERR|IS_IRQ_STAT)) { u16 pci_status, pci_cmd; - pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); - pci_read_config_word(pdev, PCI_STATUS, &pci_status); + pci_read_config_word(hw->pdev, PCI_COMMAND, &pci_cmd); + pci_read_config_word(hw->pdev, PCI_STATUS, &pci_status); - dev_err(&pdev->dev, "PCI error cmd=%#x status=%#x\n", - pci_cmd, pci_status); + printk(KERN_ERR PFX "%s: PCI error cmd=%#x status=%#x\n", + pci_name(hw->pdev), pci_cmd, pci_status); /* Write the error bits back to clear them. */ pci_status &= PCI_STATUS_ERROR_BITS; skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); - pci_write_config_word(pdev, PCI_COMMAND, + pci_write_config_word(hw->pdev, PCI_COMMAND, pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY); - pci_write_config_word(pdev, PCI_STATUS, pci_status); + pci_write_config_word(hw->pdev, PCI_STATUS, pci_status); skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); /* if error still set then just ignore it */ hwstatus = skge_read32(hw, B0_HWE_ISRC); if (hwstatus & IS_IRQ_STAT) { - dev_warn(&hw->pdev->dev, "unable to clear error (so ignoring them)\n"); + printk(KERN_INFO PFX "unable to clear error (so ignoring them)\n"); hw->intr_mask &= ~IS_HW_ERR; } } @@ -3345,8 +3277,8 @@ static int skge_reset(struct skge_hw *hw) hw->phy_addr = PHY_ADDR_BCOM; break; default: - dev_err(&hw->pdev->dev, "unsupported phy type 0x%x\n", - hw->phy_type); + printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n", + pci_name(hw->pdev), hw->phy_type); return -EOPNOTSUPP; } break; @@ -3361,8 +3293,8 @@ static int skge_reset(struct skge_hw *hw) break; default: - dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", - hw->chip_id); + printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", + pci_name(hw->pdev), hw->chip_id); return -EOPNOTSUPP; } @@ -3402,7 +3334,7 @@ static int skge_reset(struct skge_hw *hw) /* avoid boards with stuck Hardware error bits */ if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { - dev_warn(&hw->pdev->dev, "stuck hardware sensor bit\n"); + printk(KERN_WARNING PFX "stuck hardware sensor bit\n"); hw->intr_mask &= ~IS_HW_ERR; } @@ -3476,7 +3408,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, struct net_device *dev = alloc_etherdev(sizeof(*skge)); if (!dev) { - dev_err(&hw->pdev->dev, "etherdev alloc failed\n"); + printk(KERN_ERR "skge etherdev alloc failed"); return NULL; } @@ -3520,7 +3452,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, skge->duplex = -1; skge->speed = -1; skge->advertising = skge_supported_modes(hw); - skge->wol = pci_wake_enabled(hw->pdev) ? wol_supported(hw) : 0; hw->dev[port] = dev; @@ -3565,13 +3496,15 @@ static int __devinit skge_probe(struct pci_dev *pdev, err = pci_enable_device(pdev); if (err) { - dev_err(&pdev->dev, "cannot enable PCI device\n"); + printk(KERN_ERR PFX "%s cannot enable PCI device\n", + pci_name(pdev)); goto err_out; } err = pci_request_regions(pdev, DRV_NAME); if (err) { - dev_err(&pdev->dev, "cannot obtain PCI resources\n"); + printk(KERN_ERR PFX "%s cannot obtain PCI resources\n", + pci_name(pdev)); goto err_out_disable_pdev; } @@ -3586,7 +3519,8 @@ static int __devinit skge_probe(struct pci_dev *pdev, } if (err) { - dev_err(&pdev->dev, "no usable DMA configuration\n"); + printk(KERN_ERR PFX "%s no usable DMA configuration\n", + pci_name(pdev)); goto err_out_free_regions; } @@ -3604,7 +3538,8 @@ static int __devinit skge_probe(struct pci_dev *pdev, err = -ENOMEM; hw = kzalloc(sizeof(*hw), GFP_KERNEL); if (!hw) { - dev_err(&pdev->dev, "cannot allocate hardware struct\n"); + printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", + pci_name(pdev)); goto err_out_free_regions; } @@ -3615,7 +3550,8 @@ static int __devinit skge_probe(struct pci_dev *pdev, hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); if (!hw->regs) { - dev_err(&pdev->dev, "cannot map device registers\n"); + printk(KERN_ERR PFX "%s: cannot map device registers\n", + pci_name(pdev)); goto err_out_free_hw; } @@ -3631,19 +3567,23 @@ static int __devinit skge_probe(struct pci_dev *pdev, if (!dev) goto err_out_led_off; - /* Some motherboards are broken and has zero in ROM. */ - if (!is_valid_ether_addr(dev->dev_addr)) - dev_warn(&pdev->dev, "bad (zero?) ethernet address in rom\n"); + if (!is_valid_ether_addr(dev->dev_addr)) { + printk(KERN_ERR PFX "%s: bad (zero?) ethernet address in rom\n", + pci_name(pdev)); + err = -EIO; + goto err_out_free_netdev; + } err = register_netdev(dev); if (err) { - dev_err(&pdev->dev, "cannot register net device\n"); + printk(KERN_ERR PFX "%s: cannot register net device\n", + pci_name(pdev)); goto err_out_free_netdev; } err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, dev->name, hw); if (err) { - dev_err(&pdev->dev, "%s: cannot assign irq %d\n", + printk(KERN_ERR PFX "%s: cannot assign irq %d\n", dev->name, pdev->irq); goto err_out_unregister; } @@ -3654,7 +3594,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, skge_show_addr(dev1); else { /* Failure to register second port need not be fatal */ - dev_warn(&pdev->dev, "register of second port failed\n"); + printk(KERN_WARNING PFX "register of second port failed\n"); hw->dev[1] = NULL; free_netdev(dev1); } @@ -3719,46 +3659,28 @@ static void __devexit skge_remove(struct pci_dev *pdev) } #ifdef CONFIG_PM -static int vaux_avail(struct pci_dev *pdev) -{ - int pm_cap; - - pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pm_cap) { - u16 ctl; - pci_read_config_word(pdev, pm_cap + PCI_PM_PMC, &ctl); - if (ctl & PCI_PM_CAP_AUX_POWER) - return 1; - } - return 0; -} - - static int skge_suspend(struct pci_dev *pdev, pm_message_t state) { struct skge_hw *hw = pci_get_drvdata(pdev); - int i, err, wol = 0; - - err = pci_save_state(pdev); - if (err) - return err; + int i, wol = 0; + pci_save_state(pdev); for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; - struct skge_port *skge = netdev_priv(dev); - if (netif_running(dev)) - skge_down(dev); - if (skge->wol) - skge_wol_init(skge); + if (netif_running(dev)) { + struct skge_port *skge = netdev_priv(dev); - wol |= skge->wol; + netif_carrier_off(dev); + if (skge->wol) + netif_stop_queue(dev); + else + skge_down(dev); + wol |= skge->wol; + } + netif_device_detach(dev); } - if (wol && vaux_avail(pdev)) - skge_write8(hw, B0_POWER_CTRL, - PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF); - skge_write32(hw, B0_IMSK, 0); pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); pci_set_power_state(pdev, pci_choose_state(pdev, state)); @@ -3771,14 +3693,8 @@ static int skge_resume(struct pci_dev *pdev) struct skge_hw *hw = pci_get_drvdata(pdev); int i, err; - err = pci_set_power_state(pdev, PCI_D0); - if (err) - goto out; - - err = pci_restore_state(pdev); - if (err) - goto out; - + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D0, 0); err = skge_reset(hw); @@ -3788,6 +3704,7 @@ static int skge_resume(struct pci_dev *pdev) for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; + netif_device_attach(dev); if (netif_running(dev)) { err = skge_up(dev); diff --git a/trunk/drivers/net/skge.h b/trunk/drivers/net/skge.h index 17b1b479dff5..f6223c533c01 100644 --- a/trunk/drivers/net/skge.h +++ b/trunk/drivers/net/skge.h @@ -876,13 +876,11 @@ enum { WOL_PATT_CNT_0 = 0x0f38,/* 32 bit WOL Pattern Counter 3..0 */ WOL_PATT_CNT_4 = 0x0f3c,/* 24 bit WOL Pattern Counter 6..4 */ }; -#define WOL_REGS(port, x) (x + (port)*0x80) enum { WOL_PATT_RAM_1 = 0x1000,/* WOL Pattern RAM Link 1 */ WOL_PATT_RAM_2 = 0x1400,/* WOL Pattern RAM Link 2 */ }; -#define WOL_PATT_RAM_BASE(port) (WOL_PATT_RAM_1 + (port)*0x400) enum { BASE_XMAC_1 = 0x2000,/* XMAC 1 registers */ diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index f2ab3d56e565..822dd0b13133 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -49,7 +49,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.12" +#define DRV_VERSION "1.10" #define PFX DRV_NAME " " /* @@ -105,7 +105,6 @@ static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) }, /* DGE-550SX */ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B02) }, /* DGE-560SX */ - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B03) }, /* DGE-550T */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, /* 88E8021 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, /* 88E8022 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, /* 88E8061 */ @@ -127,9 +126,6 @@ static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ { 0 } }; @@ -144,7 +140,7 @@ static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 }; static const char *yukon2_name[] = { "XL", /* 0xb3 */ "EC Ultra", /* 0xb4 */ - "Extreme", /* 0xb5 */ + "UNKNOWN", /* 0xb5 */ "EC", /* 0xb6 */ "FE", /* 0xb7 */ }; @@ -196,52 +192,76 @@ static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) return v; } - -static void sky2_power_on(struct sky2_hw *hw) +static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) { - /* switch power to VCC (WA for VAUX problem) */ - sky2_write8(hw, B0_POWER_CTRL, - PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); + u16 power_control; + int vaux; - /* disable Core Clock Division, */ - sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); + pr_debug("sky2_set_power_state %d\n", state); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); - if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) - /* enable bits are inverted */ - sky2_write8(hw, B2_Y2_CLK_GATE, - Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | - Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | - Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); - else - sky2_write8(hw, B2_Y2_CLK_GATE, 0); + power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_PMC); + vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) && + (power_control & PCI_PM_CAP_PME_D3cold); - if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { - u32 reg1; + power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL); - sky2_pci_write32(hw, PCI_DEV_REG3, 0); - reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); - reg1 &= P_ASPM_CONTROL_MSK; - sky2_pci_write32(hw, PCI_DEV_REG4, reg1); - sky2_pci_write32(hw, PCI_DEV_REG5, 0); - } -} + power_control |= PCI_PM_CTRL_PME_STATUS; + power_control &= ~(PCI_PM_CTRL_STATE_MASK); -static void sky2_power_aux(struct sky2_hw *hw) -{ - if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) - sky2_write8(hw, B2_Y2_CLK_GATE, 0); - else - /* enable bits are inverted */ - sky2_write8(hw, B2_Y2_CLK_GATE, - Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | - Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | - Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); - - /* switch power to VAUX */ - if (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) + switch (state) { + case PCI_D0: + /* switch power to VCC (WA for VAUX problem) */ sky2_write8(hw, B0_POWER_CTRL, - (PC_VAUX_ENA | PC_VCC_ENA | - PC_VAUX_ON | PC_VCC_OFF)); + PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); + + /* disable Core Clock Division, */ + sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); + + if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) + /* enable bits are inverted */ + sky2_write8(hw, B2_Y2_CLK_GATE, + Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | + Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | + Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); + else + sky2_write8(hw, B2_Y2_CLK_GATE, 0); + + if (hw->chip_id == CHIP_ID_YUKON_EC_U) { + u32 reg1; + + sky2_pci_write32(hw, PCI_DEV_REG3, 0); + reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); + reg1 &= P_ASPM_CONTROL_MSK; + sky2_pci_write32(hw, PCI_DEV_REG4, reg1); + sky2_pci_write32(hw, PCI_DEV_REG5, 0); + } + + break; + + case PCI_D3hot: + case PCI_D3cold: + if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) + sky2_write8(hw, B2_Y2_CLK_GATE, 0); + else + /* enable bits are inverted */ + sky2_write8(hw, B2_Y2_CLK_GATE, + Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | + Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | + Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); + + /* switch power to VAUX */ + if (vaux && state != PCI_D3cold) + sky2_write8(hw, B0_POWER_CTRL, + (PC_VAUX_ENA | PC_VCC_ENA | + PC_VAUX_ON | PC_VCC_OFF)); + break; + default: + printk(KERN_ERR PFX "Unknown power state %d\n", state); + } + + sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) @@ -293,10 +313,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) struct sky2_port *sky2 = netdev_priv(hw->dev[port]); u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg; - if (sky2->autoneg == AUTONEG_ENABLE - && !(hw->chip_id == CHIP_ID_YUKON_XL - || hw->chip_id == CHIP_ID_YUKON_EC_U - || hw->chip_id == CHIP_ID_YUKON_EX)) { + if (sky2->autoneg == AUTONEG_ENABLE && + !(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | @@ -323,10 +341,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* enable automatic crossover */ ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); - if (sky2->autoneg == AUTONEG_ENABLE - && (hw->chip_id == CHIP_ID_YUKON_XL - || hw->chip_id == CHIP_ID_YUKON_EC_U - || hw->chip_id == CHIP_ID_YUKON_EX)) { + if (sky2->autoneg == AUTONEG_ENABLE && + (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { ctrl &= ~PHY_M_PC_DSC_MSK; ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; } @@ -481,9 +497,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* restore page register */ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); break; - case CHIP_ID_YUKON_EC_U: - case CHIP_ID_YUKON_EX: pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); /* select page 3 to access LED control register */ @@ -525,7 +539,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* set page register to 0 */ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); - } else if (hw->chip_id != CHIP_ID_YUKON_EX) { + } else { gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { @@ -577,73 +591,6 @@ static void sky2_phy_reinit(struct sky2_port *sky2) spin_unlock_bh(&sky2->phy_lock); } -/* Put device in state to listen for Wake On Lan */ -static void sky2_wol_init(struct sky2_port *sky2) -{ - struct sky2_hw *hw = sky2->hw; - unsigned port = sky2->port; - enum flow_control save_mode; - u16 ctrl; - u32 reg1; - - /* Bring hardware out of reset */ - sky2_write16(hw, B0_CTST, CS_RST_CLR); - sky2_write16(hw, SK_REG(port, GMAC_LINK_CTRL), GMLC_RST_CLR); - - sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); - sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); - - /* Force to 10/100 - * sky2_reset will re-enable on resume - */ - save_mode = sky2->flow_mode; - ctrl = sky2->advertising; - - sky2->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full); - sky2->flow_mode = FC_NONE; - sky2_phy_power(hw, port, 1); - sky2_phy_reinit(sky2); - - sky2->flow_mode = save_mode; - sky2->advertising = ctrl; - - /* Set GMAC to no flow control and auto update for speed/duplex */ - gma_write16(hw, port, GM_GP_CTRL, - GM_GPCR_FC_TX_DIS|GM_GPCR_TX_ENA|GM_GPCR_RX_ENA| - GM_GPCR_DUP_FULL|GM_GPCR_FC_RX_DIS|GM_GPCR_AU_FCT_DIS); - - /* Set WOL address */ - memcpy_toio(hw->regs + WOL_REGS(port, WOL_MAC_ADDR), - sky2->netdev->dev_addr, ETH_ALEN); - - /* Turn on appropriate WOL control bits */ - sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), WOL_CTL_CLEAR_RESULT); - ctrl = 0; - if (sky2->wol & WAKE_PHY) - ctrl |= WOL_CTL_ENA_PME_ON_LINK_CHG|WOL_CTL_ENA_LINK_CHG_UNIT; - else - ctrl |= WOL_CTL_DIS_PME_ON_LINK_CHG|WOL_CTL_DIS_LINK_CHG_UNIT; - - if (sky2->wol & WAKE_MAGIC) - ctrl |= WOL_CTL_ENA_PME_ON_MAGIC_PKT|WOL_CTL_ENA_MAGIC_PKT_UNIT; - else - ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;; - - ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT; - sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl); - - /* Turn on legacy PCI-Express PME mode */ - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); - reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); - reg1 |= PCI_Y2_PME_LEGACY; - sky2_pci_write32(hw, PCI_DEV_REG1, reg1); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - - /* block receiver */ - sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); - -} - static void sky2_mac_init(struct sky2_hw *hw, unsigned port) { struct sky2_port *sky2 = netdev_priv(hw->dev[port]); @@ -737,7 +684,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); - if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { + if (hw->chip_id == CHIP_ID_YUKON_EC_U) { sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); if (hw->dev[port]->mtu > ETH_DATA_LEN) { @@ -1520,9 +1467,6 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) if (unlikely(netif_msg_tx_done(sky2))) printk(KERN_DEBUG "%s: tx done %u\n", dev->name, idx); - sky2->net_stats.tx_packets++; - sky2->net_stats.tx_bytes += re->skb->len; - dev_kfree_skb_any(re->skb); } @@ -1697,9 +1641,7 @@ static void sky2_link_up(struct sky2_port *sky2) sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); - if (hw->chip_id == CHIP_ID_YUKON_XL - || hw->chip_id == CHIP_ID_YUKON_EC_U - || hw->chip_id == CHIP_ID_YUKON_EX) { + if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) { u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ @@ -1792,16 +1734,14 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF; /* Pause bits are offset (9..8) */ - if (hw->chip_id == CHIP_ID_YUKON_XL - || hw->chip_id == CHIP_ID_YUKON_EC_U - || hw->chip_id == CHIP_ID_YUKON_EX) + if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) aux >>= 6; sky2->flow_status = sky2_flow(aux & PHY_M_PS_RX_P_EN, aux & PHY_M_PS_TX_P_EN); if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 - && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)) + && hw->chip_id != CHIP_ID_YUKON_EC_U) sky2->flow_status = FC_NONE; if (aux & PHY_M_PS_RX_P_EN) @@ -1854,37 +1794,48 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) } -/* Transmit timeout is only called if we are running, carrier is up +/* Transmit timeout is only called if we are running, carries is up * and tx queue is full (stopped). - * Called with netif_tx_lock held. */ static void sky2_tx_timeout(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; - u32 imask; + unsigned txq = txqaddr[sky2->port]; + u16 report, done; if (netif_msg_timer(sky2)) printk(KERN_ERR PFX "%s: tx timeout\n", dev->name); + report = sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX); + done = sky2_read16(hw, Q_ADDR(txq, Q_DONE)); + printk(KERN_DEBUG PFX "%s: transmit ring %u .. %u report=%u done=%u\n", - dev->name, sky2->tx_cons, sky2->tx_prod, - sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX), - sky2_read16(hw, Q_ADDR(txqaddr[sky2->port], Q_DONE))); + dev->name, + sky2->tx_cons, sky2->tx_prod, report, done); - imask = sky2_read32(hw, B0_IMSK); /* block IRQ in hw */ - sky2_write32(hw, B0_IMSK, 0); - sky2_read32(hw, B0_IMSK); + if (report != done) { + printk(KERN_INFO PFX "status burst pending (irq moderation?)\n"); - netif_poll_disable(hw->dev[0]); /* stop NAPI poll */ - synchronize_irq(hw->pdev->irq); + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); + } else if (report != sky2->tx_cons) { + printk(KERN_INFO PFX "status report lost?\n"); - netif_start_queue(dev); /* don't wakeup during flush */ - sky2_tx_complete(sky2, sky2->tx_prod); /* Flush transmit queue */ + netif_tx_lock_bh(dev); + sky2_tx_complete(sky2, report); + netif_tx_unlock_bh(dev); + } else { + printk(KERN_INFO PFX "hardware hung? flushing\n"); - sky2_write32(hw, B0_IMSK, imask); + sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP); + sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); + + sky2_tx_clean(dev); - sky2_phy_reinit(sky2); /* this clears flow control etc */ + sky2_qset(hw, txq); + sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1); + } } static int sky2_change_mtu(struct net_device *dev, int new_mtu) @@ -1898,9 +1849,8 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) return -EINVAL; - /* TSO on Yukon Ultra and MTU > 1500 not supported */ if (hw->chip_id == CHIP_ID_YUKON_EC_U && new_mtu > ETH_DATA_LEN) - dev->features &= ~NETIF_F_TSO; + return -EINVAL; if (!netif_running(dev)) { dev->mtu = new_mtu; @@ -2139,8 +2089,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) goto force_update; skb->protocol = eth_type_trans(skb, dev); - sky2->net_stats.rx_packets++; - sky2->net_stats.rx_bytes += skb->len; dev->last_rx = jiffies; #ifdef SKY2_VLAN_TAG_USED @@ -2270,8 +2218,8 @@ static void sky2_hw_intr(struct sky2_hw *hw) pci_err = sky2_pci_read16(hw, PCI_STATUS); if (net_ratelimit()) - dev_err(&hw->pdev->dev, "PCI hardware error (0x%x)\n", - pci_err); + printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n", + pci_name(hw->pdev), pci_err); sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); sky2_pci_write16(hw, PCI_STATUS, @@ -2286,8 +2234,8 @@ static void sky2_hw_intr(struct sky2_hw *hw) pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT); if (net_ratelimit()) - dev_err(&hw->pdev->dev, "PCI Express error (0x%x)\n", - pex_err); + printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", + pci_name(hw->pdev), pex_err); /* clear the interrupt */ sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); @@ -2456,7 +2404,6 @@ static inline u32 sky2_mhz(const struct sky2_hw *hw) switch (hw->chip_id) { case CHIP_ID_YUKON_EC: case CHIP_ID_YUKON_EC_U: - case CHIP_ID_YUKON_EX: return 125; /* 125 Mhz */ case CHIP_ID_YUKON_FE: return 100; /* 100 Mhz */ @@ -2476,62 +2423,34 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) } -static int __devinit sky2_init(struct sky2_hw *hw) +static int sky2_reset(struct sky2_hw *hw) { + u16 status; u8 t8; + int i; sky2_write8(hw, B0_CTST, CS_RST_CLR); hw->chip_id = sky2_read8(hw, B2_CHIP_ID); if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { - dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", - hw->chip_id); + printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", + pci_name(hw->pdev), hw->chip_id); return -EOPNOTSUPP; } - if (hw->chip_id == CHIP_ID_YUKON_EX) - dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n" - "Please report success or failure to \n"); - - /* Make sure and enable all clocks */ - if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U) - sky2_pci_write32(hw, PCI_DEV_REG3, 0); - hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; /* This rev is really old, and requires untested workarounds */ if (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == CHIP_REV_YU_EC_A1) { - dev_err(&hw->pdev->dev, "unsupported revision Yukon-%s (0x%x) rev %d\n", - yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], - hw->chip_id, hw->chip_rev); + printk(KERN_ERR PFX "%s: unsupported revision Yukon-%s (0x%x) rev %d\n", + pci_name(hw->pdev), yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], + hw->chip_id, hw->chip_rev); return -EOPNOTSUPP; } - hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); - hw->ports = 1; - t8 = sky2_read8(hw, B2_Y2_HW_RES); - if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { - if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC)) - ++hw->ports; - } - - return 0; -} - -static void sky2_reset(struct sky2_hw *hw) -{ - u16 status; - int i; - /* disable ASF */ if (hw->chip_id <= CHIP_ID_YUKON_EC) { - if (hw->chip_id == CHIP_ID_YUKON_EX) { - status = sky2_read16(hw, HCU_CCSR); - status &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE | - HCU_CCSR_UC_STATE_MSK); - sky2_write16(hw, HCU_CCSR, status); - } else - sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); + sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE); } @@ -2553,7 +2472,15 @@ static void sky2_reset(struct sky2_hw *hw) sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); - sky2_power_on(hw); + hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); + hw->ports = 1; + t8 = sky2_read8(hw, B2_Y2_HW_RES); + if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { + if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC)) + ++hw->ports; + } + + sky2_set_power_state(hw, PCI_D0); for (i = 0; i < hw->ports; i++) { sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); @@ -2636,37 +2563,7 @@ static void sky2_reset(struct sky2_hw *hw) sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START); sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); -} - -static inline u8 sky2_wol_supported(const struct sky2_hw *hw) -{ - return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0; -} - -static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - const struct sky2_port *sky2 = netdev_priv(dev); - - wol->supported = sky2_wol_supported(sky2->hw); - wol->wolopts = sky2->wol; -} - -static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - struct sky2_port *sky2 = netdev_priv(dev); - struct sky2_hw *hw = sky2->hw; - - if (wol->wolopts & ~sky2_wol_supported(sky2->hw)) - return -EOPNOTSUPP; - - sky2->wol = wol->wolopts; - - if (hw->chip_id == CHIP_ID_YUKON_EC_U) - sky2_write32(hw, B0_CTST, sky2->wol - ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); - if (!netif_running(dev)) - sky2_wol_init(sky2); return 0; } @@ -2917,9 +2814,25 @@ static void sky2_get_strings(struct net_device *dev, u32 stringset, u8 * data) } } +/* Use hardware MIB variables for critical path statistics and + * transmit feedback not reported at interrupt. + * Other errors are accounted for in interrupt handler. + */ static struct net_device_stats *sky2_get_stats(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); + u64 data[13]; + + sky2_phy_stats(sky2, data, ARRAY_SIZE(data)); + + sky2->net_stats.tx_bytes = data[0]; + sky2->net_stats.rx_bytes = data[1]; + sky2->net_stats.tx_packets = data[2] + data[4] + data[6]; + sky2->net_stats.rx_packets = data[3] + data[5] + data[7]; + sky2->net_stats.multicast = data[3] + data[5]; + sky2->net_stats.collisions = data[10]; + sky2->net_stats.tx_aborted_errors = data[12]; + return &sky2->net_stats; } @@ -3278,9 +3191,7 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, static const struct ethtool_ops sky2_ethtool_ops = { .get_settings = sky2_get_settings, .set_settings = sky2_set_settings, - .get_drvinfo = sky2_get_drvinfo, - .get_wol = sky2_get_wol, - .set_wol = sky2_set_wol, + .get_drvinfo = sky2_get_drvinfo, .get_msglevel = sky2_get_msglevel, .set_msglevel = sky2_set_msglevel, .nway_reset = sky2_nway_reset, @@ -3310,14 +3221,13 @@ static const struct ethtool_ops sky2_ethtool_ops = { /* Initialize network device */ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, - unsigned port, - int highmem, int wol) + unsigned port, int highmem) { struct sky2_port *sky2; struct net_device *dev = alloc_etherdev(sizeof(*sky2)); if (!dev) { - dev_err(&hw->pdev->dev, "etherdev alloc failed"); + printk(KERN_ERR "sky2 etherdev alloc failed"); return NULL; } @@ -3359,7 +3269,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->speed = -1; sky2->advertising = sky2_supported_modes(hw); sky2->rx_csum = 1; - sky2->wol = wol; spin_lock_init(&sky2->phy_lock); sky2->tx_pending = TX_DEF_PENDING; @@ -3369,9 +3278,11 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->port = port; - dev->features |= NETIF_F_TSO | NETIF_F_IP_CSUM | NETIF_F_SG; + if (hw->chip_id != CHIP_ID_YUKON_EC_U) + dev->features |= NETIF_F_TSO; if (highmem) dev->features |= NETIF_F_HIGHDMA; + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; #ifdef SKY2_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; @@ -3432,7 +3343,8 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) err = request_irq(pdev->irq, sky2_test_intr, 0, DRV_NAME, hw); if (err) { - dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); + printk(KERN_ERR PFX "%s: cannot assign irq %d\n", + pci_name(pdev), pdev->irq); return err; } @@ -3443,8 +3355,9 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) if (!hw->msi) { /* MSI test failed, go back to INTx mode */ - dev_info(&pdev->dev, "No interrupt generated using MSI, " - "switching to INTx mode.\n"); + printk(KERN_INFO PFX "%s: No interrupt generated using MSI, " + "switching to INTx mode.\n", + pci_name(pdev)); err = -EOPNOTSUPP; sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); @@ -3458,62 +3371,62 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) return err; } -static int __devinit pci_wake_enabled(struct pci_dev *dev) -{ - int pm = pci_find_capability(dev, PCI_CAP_ID_PM); - u16 value; - - if (!pm) - return 0; - if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value)) - return 0; - return value & PCI_PM_CTRL_PME_ENABLE; -} - static int __devinit sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - struct net_device *dev; + struct net_device *dev, *dev1 = NULL; struct sky2_hw *hw; - int err, using_dac = 0, wol_default; + int err, pm_cap, using_dac = 0; err = pci_enable_device(pdev); if (err) { - dev_err(&pdev->dev, "cannot enable PCI device\n"); + printk(KERN_ERR PFX "%s cannot enable PCI device\n", + pci_name(pdev)); goto err_out; } err = pci_request_regions(pdev, DRV_NAME); if (err) { - dev_err(&pdev->dev, "cannot obtain PCI resources\n"); + printk(KERN_ERR PFX "%s cannot obtain PCI resources\n", + pci_name(pdev)); goto err_out; } pci_set_master(pdev); + /* Find power-management capability. */ + pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (pm_cap == 0) { + printk(KERN_ERR PFX "Cannot find PowerManagement capability, " + "aborting.\n"); + err = -EIO; + goto err_out_free_regions; + } + if (sizeof(dma_addr_t) > sizeof(u32) && !(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { using_dac = 1; err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); if (err < 0) { - dev_err(&pdev->dev, "unable to obtain 64 bit DMA " - "for consistent allocations\n"); + printk(KERN_ERR PFX "%s unable to obtain 64 bit DMA " + "for consistent allocations\n", pci_name(pdev)); goto err_out_free_regions; } + } else { err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (err) { - dev_err(&pdev->dev, "no usable DMA configuration\n"); + printk(KERN_ERR PFX "%s no usable DMA configuration\n", + pci_name(pdev)); goto err_out_free_regions; } } - wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0; - err = -ENOMEM; hw = kzalloc(sizeof(*hw), GFP_KERNEL); if (!hw) { - dev_err(&pdev->dev, "cannot allocate hardware struct\n"); + printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", + pci_name(pdev)); goto err_out_free_regions; } @@ -3521,9 +3434,11 @@ static int __devinit sky2_probe(struct pci_dev *pdev, hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); if (!hw->regs) { - dev_err(&pdev->dev, "cannot map device registers\n"); + printk(KERN_ERR PFX "%s: cannot map device registers\n", + pci_name(pdev)); goto err_out_free_hw; } + hw->pm_cap = pm_cap; #ifdef __BIG_ENDIAN /* The sk98lin vendor driver uses hardware byte swapping but @@ -3543,22 +3458,18 @@ static int __devinit sky2_probe(struct pci_dev *pdev, if (!hw->st_le) goto err_out_iounmap; - err = sky2_init(hw); + err = sky2_reset(hw); if (err) goto err_out_iounmap; - dev_info(&pdev->dev, "v%s addr 0x%llx irq %d Yukon-%s (0x%x) rev %d\n", + printk(KERN_INFO PFX "v%s addr 0x%llx irq %d Yukon-%s (0x%x) rev %d\n", DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], hw->chip_id, hw->chip_rev); - sky2_reset(hw); - - dev = sky2_init_netdev(hw, 0, using_dac, wol_default); - if (!dev) { - err = -ENOMEM; + dev = sky2_init_netdev(hw, 0, using_dac); + if (!dev) goto err_out_free_pci; - } if (!disable_msi && pci_enable_msi(pdev) == 0) { err = sky2_test_msi(hw); @@ -3570,33 +3481,32 @@ static int __devinit sky2_probe(struct pci_dev *pdev, err = register_netdev(dev); if (err) { - dev_err(&pdev->dev, "cannot register net device\n"); + printk(KERN_ERR PFX "%s: cannot register net device\n", + pci_name(pdev)); goto err_out_free_netdev; } err = request_irq(pdev->irq, sky2_intr, hw->msi ? 0 : IRQF_SHARED, dev->name, hw); if (err) { - dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); + printk(KERN_ERR PFX "%s: cannot assign irq %d\n", + pci_name(pdev), pdev->irq); goto err_out_unregister; } sky2_write32(hw, B0_IMSK, Y2_IS_BASE); sky2_show_addr(dev); - if (hw->ports > 1) { - struct net_device *dev1; - - dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default); - if (!dev1) - dev_warn(&pdev->dev, "allocation for second device failed\n"); - else if ((err = register_netdev(dev1))) { - dev_warn(&pdev->dev, - "register of second port failed (%d)\n", err); + if (hw->ports > 1 && (dev1 = sky2_init_netdev(hw, 1, using_dac))) { + if (register_netdev(dev1) == 0) + sky2_show_addr(dev1); + else { + /* Failure to register second port need not be fatal */ + printk(KERN_WARNING PFX + "register of second port failed\n"); hw->dev[1] = NULL; free_netdev(dev1); - } else - sky2_show_addr(dev1); + } } setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); @@ -3645,8 +3555,7 @@ static void __devexit sky2_remove(struct pci_dev *pdev) unregister_netdev(dev1); unregister_netdev(dev0); - sky2_power_aux(hw); - + sky2_set_power_state(hw, PCI_D3hot); sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); sky2_write8(hw, B0_CTST, CS_RST_SET); sky2_read8(hw, B0_CTST); @@ -3671,31 +3580,27 @@ static void __devexit sky2_remove(struct pci_dev *pdev) static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) { struct sky2_hw *hw = pci_get_drvdata(pdev); - int i, wol = 0; + int i; + pci_power_t pstate = pci_choose_state(pdev, state); + + if (!(pstate == PCI_D3hot || pstate == PCI_D3cold)) + return -EINVAL; del_timer_sync(&hw->idle_timer); netif_poll_disable(hw->dev[0]); for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; - struct sky2_port *sky2 = netdev_priv(dev); - if (netif_running(dev)) + if (netif_running(dev)) { sky2_down(dev); - - if (sky2->wol) - sky2_wol_init(sky2); - - wol |= sky2->wol; + netif_device_detach(dev); + } } sky2_write32(hw, B0_IMSK, 0); - sky2_power_aux(hw); - pci_save_state(pdev); - pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - + sky2_set_power_state(hw, pstate); return 0; } @@ -3704,22 +3609,21 @@ static int sky2_resume(struct pci_dev *pdev) struct sky2_hw *hw = pci_get_drvdata(pdev); int i, err; - err = pci_set_power_state(pdev, PCI_D0); - if (err) - goto out; + pci_restore_state(pdev); + pci_enable_wake(pdev, PCI_D0, 0); + sky2_set_power_state(hw, PCI_D0); - err = pci_restore_state(pdev); + err = sky2_reset(hw); if (err) goto out; - pci_enable_wake(pdev, PCI_D0, 0); - sky2_reset(hw); - sky2_write32(hw, B0_IMSK, Y2_IS_BASE); for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; if (netif_running(dev)) { + netif_device_attach(dev); + err = sky2_up(dev); if (err) { printk(KERN_ERR PFX "%s: could not up: %d\n", @@ -3732,43 +3636,11 @@ static int sky2_resume(struct pci_dev *pdev) netif_poll_enable(hw->dev[0]); sky2_idle_start(hw); - return 0; out: - dev_err(&pdev->dev, "resume failed (%d)\n", err); - pci_disable_device(pdev); return err; } #endif -static void sky2_shutdown(struct pci_dev *pdev) -{ - struct sky2_hw *hw = pci_get_drvdata(pdev); - int i, wol = 0; - - del_timer_sync(&hw->idle_timer); - netif_poll_disable(hw->dev[0]); - - for (i = 0; i < hw->ports; i++) { - struct net_device *dev = hw->dev[i]; - struct sky2_port *sky2 = netdev_priv(dev); - - if (sky2->wol) { - wol = 1; - sky2_wol_init(sky2); - } - } - - if (wol) - sky2_power_aux(hw); - - pci_enable_wake(pdev, PCI_D3hot, wol); - pci_enable_wake(pdev, PCI_D3cold, wol); - - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - -} - static struct pci_driver sky2_driver = { .name = DRV_NAME, .id_table = sky2_id_table, @@ -3778,7 +3650,6 @@ static struct pci_driver sky2_driver = { .suspend = sky2_suspend, .resume = sky2_resume, #endif - .shutdown = sky2_shutdown, }; static int __init sky2_init_module(void) diff --git a/trunk/drivers/net/sky2.h b/trunk/drivers/net/sky2.h index 3b0189569d52..6ed1d47dbbd3 100644 --- a/trunk/drivers/net/sky2.h +++ b/trunk/drivers/net/sky2.h @@ -32,7 +32,6 @@ enum pci_dev_reg_1 { PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */ PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */ PCI_Y2_PHY1_POWD = 1<<26, /* Set PHY 1 to Power Down (YUKON-2) */ - PCI_Y2_PME_LEGACY= 1<<15, /* PCI Express legacy power management mode */ }; enum pci_dev_reg_2 { @@ -371,9 +370,12 @@ enum { /* B2_CHIP_ID 8 bit Chip Identification Number */ enum { + CHIP_ID_GENESIS = 0x0a, /* Chip ID for GENESIS */ + CHIP_ID_YUKON = 0xb0, /* Chip ID for YUKON */ + CHIP_ID_YUKON_LITE = 0xb1, /* Chip ID for YUKON-Lite (Rev. A1-A3) */ + CHIP_ID_YUKON_LP = 0xb2, /* Chip ID for YUKON-LP */ CHIP_ID_YUKON_XL = 0xb3, /* Chip ID for YUKON-2 XL */ CHIP_ID_YUKON_EC_U = 0xb4, /* Chip ID for YUKON-2 EC Ultra */ - CHIP_ID_YUKON_EX = 0xb5, /* Chip ID for YUKON-2 Extreme */ CHIP_ID_YUKON_EC = 0xb6, /* Chip ID for YUKON-2 EC */ CHIP_ID_YUKON_FE = 0xb7, /* Chip ID for YUKON-2 FE */ @@ -765,24 +767,6 @@ enum { POLL_LIST_ADDR_HI= 0x0e2c,/* 32 bit Poll. List Start Addr (high) */ }; -enum { - SMB_CFG = 0x0e40, /* 32 bit SMBus Config Register */ - SMB_CSR = 0x0e44, /* 32 bit SMBus Control/Status Register */ -}; - -enum { - CPU_WDOG = 0x0e48, /* 32 bit Watchdog Register */ - CPU_CNTR = 0x0e4C, /* 32 bit Counter Register */ - CPU_TIM = 0x0e50,/* 32 bit Timer Compare Register */ - CPU_AHB_ADDR = 0x0e54, /* 32 bit CPU AHB Debug Register */ - CPU_AHB_WDATA = 0x0e58, /* 32 bit CPU AHB Debug Register */ - CPU_AHB_RDATA = 0x0e5C, /* 32 bit CPU AHB Debug Register */ - HCU_MAP_BASE = 0x0e60, /* 32 bit Reset Mapping Base */ - CPU_AHB_CTRL = 0x0e64, /* 32 bit CPU AHB Debug Register */ - HCU_CCSR = 0x0e68, /* 32 bit CPU Control and Status Register */ - HCU_HCSR = 0x0e6C, /* 32 bit Host Control and Status Register */ -}; - /* ASF Subsystem Registers (Yukon-2 only) */ enum { B28_Y2_SMB_CONFIG = 0x0e40,/* 32 bit ASF SMBus Config Register */ @@ -853,27 +837,33 @@ enum { GMAC_LINK_CTRL = 0x0f10,/* 16 bit Link Control Reg */ /* Wake-up Frame Pattern Match Control Registers (YUKON only) */ + + WOL_REG_OFFS = 0x20,/* HW-Bug: Address is + 0x20 against spec. */ + WOL_CTRL_STAT = 0x0f20,/* 16 bit WOL Control/Status Reg */ WOL_MATCH_CTL = 0x0f22,/* 8 bit WOL Match Control Reg */ WOL_MATCH_RES = 0x0f23,/* 8 bit WOL Match Result Reg */ WOL_MAC_ADDR = 0x0f24,/* 32 bit WOL MAC Address */ + WOL_PATT_PME = 0x0f2a,/* 8 bit WOL PME Match Enable (Yukon-2) */ + WOL_PATT_ASFM = 0x0f2b,/* 8 bit WOL ASF Match Enable (Yukon-2) */ WOL_PATT_RPTR = 0x0f2c,/* 8 bit WOL Pattern Read Pointer */ /* WOL Pattern Length Registers (YUKON only) */ + WOL_PATT_LEN_LO = 0x0f30,/* 32 bit WOL Pattern Length 3..0 */ WOL_PATT_LEN_HI = 0x0f34,/* 24 bit WOL Pattern Length 6..4 */ /* WOL Pattern Counter Registers (YUKON only) */ + + WOL_PATT_CNT_0 = 0x0f38,/* 32 bit WOL Pattern Counter 3..0 */ WOL_PATT_CNT_4 = 0x0f3c,/* 24 bit WOL Pattern Counter 6..4 */ }; -#define WOL_REGS(port, x) (x + (port)*0x80) enum { WOL_PATT_RAM_1 = 0x1000,/* WOL Pattern RAM Link 1 */ WOL_PATT_RAM_2 = 0x1400,/* WOL Pattern RAM Link 2 */ }; -#define WOL_PATT_RAM_BASE(port) (WOL_PATT_RAM_1 + (port)*0x400) enum { BASE_GMAC_1 = 0x2800,/* GMAC 1 registers */ @@ -1664,39 +1654,6 @@ enum { Y2_ASF_CLR_ASFI = 1<<1, /* Clear host IRQ */ Y2_ASF_HOST_IRQ = 1<<0, /* Issue an IRQ to HOST system */ }; -/* HCU_CCSR CPU Control and Status Register */ -enum { - HCU_CCSR_SMBALERT_MONITOR= 1<<27, /* SMBALERT pin monitor */ - HCU_CCSR_CPU_SLEEP = 1<<26, /* CPU sleep status */ - /* Clock Stretching Timeout */ - HCU_CCSR_CS_TO = 1<<25, - HCU_CCSR_WDOG = 1<<24, /* Watchdog Reset */ - - HCU_CCSR_CLR_IRQ_HOST = 1<<17, /* Clear IRQ_HOST */ - HCU_CCSR_SET_IRQ_HCU = 1<<16, /* Set IRQ_HCU */ - - HCU_CCSR_AHB_RST = 1<<9, /* Reset AHB bridge */ - HCU_CCSR_CPU_RST_MODE = 1<<8, /* CPU Reset Mode */ - - HCU_CCSR_SET_SYNC_CPU = 1<<5, - HCU_CCSR_CPU_CLK_DIVIDE_MSK = 3<<3,/* CPU Clock Divide */ - HCU_CCSR_CPU_CLK_DIVIDE_BASE= 1<<3, - HCU_CCSR_OS_PRSNT = 1<<2, /* ASF OS Present */ -/* Microcontroller State */ - HCU_CCSR_UC_STATE_MSK = 3, - HCU_CCSR_UC_STATE_BASE = 1<<0, - HCU_CCSR_ASF_RESET = 0, - HCU_CCSR_ASF_HALTED = 1<<1, - HCU_CCSR_ASF_RUNNING = 1<<0, -}; - -/* HCU_HCSR Host Control and Status Register */ -enum { - HCU_HCSR_SET_IRQ_CPU = 1<<16, /* Set IRQ_CPU */ - - HCU_HCSR_CLR_IRQ_HCU = 1<<1, /* Clear IRQ_HCU */ - HCU_HCSR_SET_IRQ_HOST = 1<<0, /* Set IRQ_HOST */ -}; /* STAT_CTRL 32 bit Status BMU control register (Yukon-2 only) */ enum { @@ -1758,17 +1715,14 @@ enum { GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */ #define GMAC_DEF_MSK GM_IS_TX_FF_UR -}; /* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ -enum { /* Bits 15.. 2: reserved */ + /* Bits 15.. 2: reserved */ GMLC_RST_CLR = 1<<1, /* Clear GMAC Link Reset */ GMLC_RST_SET = 1<<0, /* Set GMAC Link Reset */ -}; /* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */ -enum { WOL_CTL_LINK_CHG_OCC = 1<<15, WOL_CTL_MAGIC_PKT_OCC = 1<<14, WOL_CTL_PATTERN_OCC = 1<<13, @@ -1787,6 +1741,17 @@ enum { WOL_CTL_DIS_PATTERN_UNIT = 1<<0, }; +#define WOL_CTL_DEFAULT \ + (WOL_CTL_DIS_PME_ON_LINK_CHG | \ + WOL_CTL_DIS_PME_ON_PATTERN | \ + WOL_CTL_DIS_PME_ON_MAGIC_PKT | \ + WOL_CTL_DIS_LINK_CHG_UNIT | \ + WOL_CTL_DIS_PATTERN_UNIT | \ + WOL_CTL_DIS_MAGIC_PKT_UNIT) + +/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */ +#define WOL_CTL_PATT_ENA(x) (1 << (x)) + /* Control flags */ enum { @@ -1910,7 +1875,6 @@ struct sky2_port { u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */ u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ u8 rx_csum; - u8 wol; enum flow_control flow_mode; enum flow_control flow_status; @@ -1923,6 +1887,7 @@ struct sky2_hw { struct pci_dev *pdev; struct net_device *dev[2]; + int pm_cap; u8 chip_id; u8 chip_rev; u8 pmd_type; diff --git a/trunk/drivers/net/smc911x.c b/trunk/drivers/net/smc911x.c index c95614131980..43af61438449 100644 --- a/trunk/drivers/net/smc911x.c +++ b/trunk/drivers/net/smc911x.c @@ -1659,7 +1659,7 @@ smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { strncpy(info->driver, CARDNAME, sizeof(info->driver)); strncpy(info->version, version, sizeof(info->version)); - strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info)); + strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info)); } static int smc911x_ethtool_nwayreset(struct net_device *dev) diff --git a/trunk/drivers/net/smc91x.c b/trunk/drivers/net/smc91x.c index 49f4b7712ebf..e62a9586fb95 100644 --- a/trunk/drivers/net/smc91x.c +++ b/trunk/drivers/net/smc91x.c @@ -1712,7 +1712,7 @@ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { strncpy(info->driver, CARDNAME, sizeof(info->driver)); strncpy(info->version, version, sizeof(info->version)); - strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info)); + strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info)); } static int smc_ethtool_nwayreset(struct net_device *dev) diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index bf6ff39e02bb..8ea2fc1b96cb 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -280,67 +280,72 @@ spider_net_free_chain(struct spider_net_card *card, { struct spider_net_descr *descr; - descr = chain->ring; - do { + for (descr = chain->tail; !descr->bus_addr; descr = descr->next) { + pci_unmap_single(card->pdev, descr->bus_addr, + SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL); descr->bus_addr = 0; - descr->next_descr_addr = 0; - descr = descr->next; - } while (descr != chain->ring); - - dma_free_coherent(&card->pdev->dev, chain->num_desc, - chain->ring, chain->dma_addr); + } } /** - * spider_net_init_chain - alloc and link descriptor chain + * spider_net_init_chain - links descriptor chain * @card: card structure * @chain: address of chain + * @start_descr: address of descriptor array + * @no: number of descriptors * - * We manage a circular list that mirrors the hardware structure, + * we manage a circular list that mirrors the hardware structure, * except that the hardware uses bus addresses. * - * Returns 0 on success, <0 on failure + * returns 0 on success, <0 on failure */ static int spider_net_init_chain(struct spider_net_card *card, - struct spider_net_descr_chain *chain) + struct spider_net_descr_chain *chain, + struct spider_net_descr *start_descr, + int no) { int i; struct spider_net_descr *descr; dma_addr_t buf; - size_t alloc_size; - - alloc_size = chain->num_desc * sizeof (struct spider_net_descr); - chain->ring = dma_alloc_coherent(&card->pdev->dev, alloc_size, - &chain->dma_addr, GFP_KERNEL); + descr = start_descr; + memset(descr, 0, sizeof(*descr) * no); - if (!chain->ring) - return -ENOMEM; + /* set up the hardware pointers in each descriptor */ + for (i=0; idmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; - descr = chain->ring; - memset(descr, 0, alloc_size); + buf = pci_map_single(card->pdev, descr, + SPIDER_NET_DESCR_SIZE, + PCI_DMA_BIDIRECTIONAL); - /* Set up the hardware pointers in each descriptor */ - buf = chain->dma_addr; - for (i=0; i < chain->num_desc; i++, descr++) { - descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; + if (pci_dma_mapping_error(buf)) + goto iommu_error; descr->bus_addr = buf; - descr->next_descr_addr = 0; descr->next = descr + 1; descr->prev = descr - 1; - buf += sizeof(struct spider_net_descr); } /* do actual circular list */ - (descr-1)->next = chain->ring; - chain->ring->prev = descr-1; + (descr-1)->next = start_descr; + start_descr->prev = descr-1; spin_lock_init(&chain->lock); - chain->head = chain->ring; - chain->tail = chain->ring; + chain->head = start_descr; + chain->tail = start_descr; + return 0; + +iommu_error: + descr = start_descr; + for (i=0; i < no; i++, descr++) + if (descr->bus_addr) + pci_unmap_single(card->pdev, descr->bus_addr, + SPIDER_NET_DESCR_SIZE, + PCI_DMA_BIDIRECTIONAL); + return -ENOMEM; } /** @@ -367,20 +372,21 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) } /** - * spider_net_prepare_rx_descr - Reinitialize RX descriptor + * spider_net_prepare_rx_descr - reinitializes a rx descriptor * @card: card structure * @descr: descriptor to re-init * - * Return 0 on succes, <0 on failure. + * return 0 on succes, <0 on failure * - * Allocates a new rx skb, iommu-maps it and attaches it to the - * descriptor. Mark the descriptor as activated, ready-to-use. + * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. + * Activate the descriptor state-wise */ static int spider_net_prepare_rx_descr(struct spider_net_card *card, struct spider_net_descr *descr) { dma_addr_t buf; + int error = 0; int offset; int bufsize; @@ -408,7 +414,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, (SPIDER_NET_RXBUF_ALIGN - 1); if (offset) skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); - /* iommu-map the skb */ + /* io-mmu-map the skb */ buf = pci_map_single(card->pdev, descr->skb->data, SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); descr->buf_addr = buf; @@ -419,16 +425,11 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, card->spider_stats.rx_iommu_map_error++; descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; } else { - descr->next_descr_addr = 0; - wmb(); descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOINTR_COMPLETE; - - wmb(); - descr->prev->next_descr_addr = descr->bus_addr; } - return 0; + return error; } /** @@ -492,10 +493,10 @@ spider_net_refill_rx_chain(struct spider_net_card *card) } /** - * spider_net_alloc_rx_skbs - Allocates rx skbs in rx descriptor chains + * spider_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains * @card: card structure * - * Returns 0 on success, <0 on failure. + * returns 0 on success, <0 on failure */ static int spider_net_alloc_rx_skbs(struct spider_net_card *card) @@ -506,16 +507,16 @@ spider_net_alloc_rx_skbs(struct spider_net_card *card) result = -ENOMEM; chain = &card->rx_chain; - /* Put at least one buffer into the chain. if this fails, - * we've got a problem. If not, spider_net_refill_rx_chain - * will do the rest at the end of this function. */ + /* put at least one buffer into the chain. if this fails, + * we've got a problem. if not, spider_net_refill_rx_chain + * will do the rest at the end of this function */ if (spider_net_prepare_rx_descr(card, chain->head)) goto error; else chain->head = chain->head->next; - /* This will allocate the rest of the rx buffers; - * if not, it's business as usual later on. */ + /* this will allocate the rest of the rx buffers; if not, it's + * business as usual later on */ spider_net_refill_rx_chain(card); spider_net_enable_rxdmac(card); return 0; @@ -706,7 +707,7 @@ spider_net_set_low_watermark(struct spider_net_card *card) } /* If TX queue is short, don't even bother with interrupts */ - if (cnt < card->tx_chain.num_desc/4) + if (cnt < card->num_tx_desc/4) return cnt; /* Set low-watermark 3/4th's of the way into the queue. */ @@ -914,13 +915,16 @@ spider_net_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) * spider_net_pass_skb_up - takes an skb from a descriptor and passes it on * @descr: descriptor to process * @card: card structure + * @napi: whether caller is in NAPI context + * + * returns 1 on success, 0 if no packet was passed to the stack * - * Fills out skb structure and passes the data to the stack. - * The descriptor state is not changed. + * iommu-unmaps the skb, fills out skb structure and passes the data to the + * stack. The descriptor state is not changed. */ -static void +static int spider_net_pass_skb_up(struct spider_net_descr *descr, - struct spider_net_card *card) + struct spider_net_card *card, int napi) { struct sk_buff *skb; struct net_device *netdev; @@ -928,8 +932,23 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, data_status = descr->data_status; data_error = descr->data_error; + netdev = card->netdev; + /* unmap descriptor */ + pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, + PCI_DMA_FROMDEVICE); + + /* the cases we'll throw away the packet immediately */ + if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { + if (netif_msg_rx_err(card)) + pr_err("error in received descriptor found, " + "data_status=x%08x, data_error=x%08x\n", + data_status, data_error); + card->spider_stats.rx_desc_error++; + return 0; + } + skb = descr->skb; skb->dev = netdev; skb_put(skb, descr->valid_size); @@ -958,72 +977,57 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, } /* pass skb up to stack */ - netif_receive_skb(skb); + if (napi) + netif_receive_skb(skb); + else + netif_rx_ni(skb); /* update netdevice statistics */ card->netdev_stats.rx_packets++; card->netdev_stats.rx_bytes += skb->len; -} - -#ifdef DEBUG -static void show_rx_chain(struct spider_net_card *card) -{ - struct spider_net_descr_chain *chain = &card->rx_chain; - struct spider_net_descr *start= chain->tail; - struct spider_net_descr *descr= start; - int status; - int cnt = 0; - int cstat = spider_net_get_descr_status(descr); - printk(KERN_INFO "RX chain tail at descr=%ld\n", - (start - card->descr) - card->tx_chain.num_desc); - status = cstat; - do - { - status = spider_net_get_descr_status(descr); - if (cstat != status) { - printk(KERN_INFO "Have %d descrs with stat=x%08x\n", cnt, cstat); - cstat = status; - cnt = 0; - } - cnt ++; - descr = descr->next; - } while (descr != start); - printk(KERN_INFO "Last %d descrs with stat=x%08x\n", cnt, cstat); + return 1; } -#endif /** * spider_net_decode_one_descr - processes an rx descriptor * @card: card structure + * @napi: whether caller is in NAPI context * - * Returns 1 if a packet has been sent to the stack, otherwise 0 + * returns 1 if a packet has been sent to the stack, otherwise 0 * - * Processes an rx descriptor by iommu-unmapping the data buffer and passing + * processes an rx descriptor by iommu-unmapping the data buffer and passing * the packet up to the stack. This function is called in softirq * context, e.g. either bottom half from interrupt or NAPI polling context */ static int -spider_net_decode_one_descr(struct spider_net_card *card) +spider_net_decode_one_descr(struct spider_net_card *card, int napi) { struct spider_net_descr_chain *chain = &card->rx_chain; struct spider_net_descr *descr = chain->tail; int status; + int result; status = spider_net_get_descr_status(descr); - /* Nothing in the descriptor, or ring must be empty */ - if ((status == SPIDER_NET_DESCR_CARDOWNED) || - (status == SPIDER_NET_DESCR_NOT_IN_USE)) - return 0; + if (status == SPIDER_NET_DESCR_CARDOWNED) { + /* nothing in the descriptor yet */ + result=0; + goto out; + } + + if (status == SPIDER_NET_DESCR_NOT_IN_USE) { + /* not initialized yet, the ring must be empty */ + spider_net_refill_rx_chain(card); + spider_net_enable_rxdmac(card); + result=0; + goto out; + } /* descriptor definitively used -- move on tail */ chain->tail = descr->next; - /* unmap descriptor */ - pci_unmap_single(card->pdev, descr->buf_addr, - SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); - + result = 0; if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || (status == SPIDER_NET_DESCR_PROTECTION_ERROR) || (status == SPIDER_NET_DESCR_FORCE_END) ) { @@ -1031,55 +1035,31 @@ spider_net_decode_one_descr(struct spider_net_card *card) pr_err("%s: dropping RX descriptor with state %d\n", card->netdev->name, status); card->netdev_stats.rx_dropped++; - goto bad_desc; + pci_unmap_single(card->pdev, descr->buf_addr, + SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); + dev_kfree_skb_irq(descr->skb); + goto refill; } if ( (status != SPIDER_NET_DESCR_COMPLETE) && (status != SPIDER_NET_DESCR_FRAME_END) ) { - if (netif_msg_rx_err(card)) - pr_err("%s: RX descriptor with unkown state %d\n", + if (netif_msg_rx_err(card)) { + pr_err("%s: RX descriptor with state %d\n", card->netdev->name, status); - card->spider_stats.rx_desc_unk_state++; - goto bad_desc; - } - - /* The cases we'll throw away the packet immediately */ - if (descr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) { - if (netif_msg_rx_err(card)) - pr_err("%s: error in received descriptor found, " - "data_status=x%08x, data_error=x%08x\n", - card->netdev->name, - descr->data_status, descr->data_error); - goto bad_desc; - } - - if (descr->dmac_cmd_status & 0xfefe) { - pr_err("%s: bad status, cmd_status=x%08x\n", - card->netdev->name, - descr->dmac_cmd_status); - pr_err("buf_addr=x%08x\n", descr->buf_addr); - pr_err("buf_size=x%08x\n", descr->buf_size); - pr_err("next_descr_addr=x%08x\n", descr->next_descr_addr); - pr_err("result_size=x%08x\n", descr->result_size); - pr_err("valid_size=x%08x\n", descr->valid_size); - pr_err("data_status=x%08x\n", descr->data_status); - pr_err("data_error=x%08x\n", descr->data_error); - pr_err("bus_addr=x%08x\n", descr->bus_addr); - pr_err("which=%ld\n", descr - card->rx_chain.ring); - - card->spider_stats.rx_desc_error++; - goto bad_desc; + card->spider_stats.rx_desc_unk_state++; + } + goto refill; } - /* Ok, we've got a packet in descr */ - spider_net_pass_skb_up(descr, card); + /* ok, we've got a packet in descr */ + result = spider_net_pass_skb_up(descr, card, napi); +refill: descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; - return 1; - -bad_desc: - dev_kfree_skb_irq(descr->skb); - descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; - return 0; + /* change the descriptor state: */ + if (!napi) + spider_net_refill_rx_chain(card); +out: + return result; } /** @@ -1105,7 +1085,7 @@ spider_net_poll(struct net_device *netdev, int *budget) packets_to_do = min(*budget, netdev->quota); while (packets_to_do) { - if (spider_net_decode_one_descr(card)) { + if (spider_net_decode_one_descr(card, 1)) { packets_done++; packets_to_do--; } else { @@ -1118,7 +1098,6 @@ spider_net_poll(struct net_device *netdev, int *budget) netdev->quota -= packets_done; *budget -= packets_done; spider_net_refill_rx_chain(card); - spider_net_enable_rxdmac(card); /* if all packets are in the stack, enable interrupts and return 0 */ /* if not, return 1 */ @@ -1247,6 +1226,24 @@ spider_net_set_mac(struct net_device *netdev, void *p) return 0; } +/** + * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt + * @card: card structure + * + * spider_net_handle_rxram_full empties the RX ring so that spider can put + * more packets in it and empty its RX RAM. This is called in bottom half + * context + */ +static void +spider_net_handle_rxram_full(struct spider_net_card *card) +{ + while (spider_net_decode_one_descr(card, 0)) + ; + spider_net_enable_rxchtails(card); + spider_net_enable_rxdmac(card); + netif_rx_schedule(card->netdev); +} + /** * spider_net_handle_error_irq - handles errors raised by an interrupt * @card: card structure @@ -1369,10 +1366,10 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) case SPIDER_NET_GRFAFLLINT: /* fallthrough */ case SPIDER_NET_GRMFLLINT: if (netif_msg_intr(card) && net_ratelimit()) - pr_err("Spider RX RAM full, incoming packets " + pr_debug("Spider RX RAM full, incoming packets " "might be discarded!\n"); spider_net_rx_irq_off(card); - netif_rx_schedule(card->netdev); + tasklet_schedule(&card->rxram_full_tl); show_error = 0; break; @@ -1387,7 +1384,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) case SPIDER_NET_GDCDCEINT: /* fallthrough */ case SPIDER_NET_GDBDCEINT: /* fallthrough */ case SPIDER_NET_GDADCEINT: - if (netif_msg_intr(card) && net_ratelimit()) + if (netif_msg_intr(card)) pr_err("got descriptor chain end interrupt, " "restarting DMAC %c.\n", 'D'-(i-SPIDER_NET_GDDDCEINT)/3); @@ -1458,7 +1455,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) break; } - if ((show_error) && (netif_msg_intr(card)) && net_ratelimit()) + if ((show_error) && (netif_msg_intr(card))) pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", card->netdev->name, @@ -1654,18 +1651,27 @@ int spider_net_open(struct net_device *netdev) { struct spider_net_card *card = netdev_priv(netdev); - int result; + struct spider_net_descr *descr; + int i, result; - result = spider_net_init_chain(card, &card->tx_chain); - if (result) + result = -ENOMEM; + if (spider_net_init_chain(card, &card->tx_chain, card->descr, + card->num_tx_desc)) goto alloc_tx_failed; + card->low_watermark = NULL; - result = spider_net_init_chain(card, &card->rx_chain); - if (result) + /* rx_chain is after tx_chain, so offset is descr + tx_count */ + if (spider_net_init_chain(card, &card->rx_chain, + card->descr + card->num_tx_desc, + card->num_rx_desc)) goto alloc_rx_failed; - /* Allocate rx skbs */ + descr = card->rx_chain.head; + for (i=0; i < card->num_rx_desc; i++, descr++) + descr->next_descr_addr = descr->next->bus_addr; + + /* allocate rx skbs */ if (spider_net_alloc_rx_skbs(card)) goto alloc_skbs_failed; @@ -1896,6 +1902,7 @@ spider_net_stop(struct net_device *netdev) { struct spider_net_card *card = netdev_priv(netdev); + tasklet_kill(&card->rxram_full_tl); netif_poll_disable(netdev); netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -1917,7 +1924,6 @@ spider_net_stop(struct net_device *netdev) /* release chains */ spider_net_release_tx_chain(card, 1); - spider_net_free_rx_chain_contents(card); spider_net_free_rx_chain_contents(card); @@ -2040,6 +2046,9 @@ spider_net_setup_netdev(struct spider_net_card *card) pci_set_drvdata(card->pdev, netdev); + card->rxram_full_tl.data = (unsigned long) card; + card->rxram_full_tl.func = + (void (*)(unsigned long)) spider_net_handle_rxram_full; init_timer(&card->tx_timer); card->tx_timer.function = (void (*)(unsigned long)) spider_net_cleanup_tx_ring; @@ -2048,8 +2057,8 @@ spider_net_setup_netdev(struct spider_net_card *card) card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; - card->tx_chain.num_desc = tx_descriptors; - card->rx_chain.num_desc = rx_descriptors; + card->num_tx_desc = tx_descriptors; + card->num_rx_desc = rx_descriptors; spider_net_setup_netdev_ops(netdev); @@ -2098,8 +2107,12 @@ spider_net_alloc_card(void) { struct net_device *netdev; struct spider_net_card *card; + size_t alloc_size; - netdev = alloc_etherdev(sizeof(struct spider_net_card)); + alloc_size = sizeof (*card) + + sizeof (struct spider_net_descr) * rx_descriptors + + sizeof (struct spider_net_descr) * tx_descriptors; + netdev = alloc_etherdev(alloc_size); if (!netdev) return NULL; diff --git a/trunk/drivers/net/spider_net.h b/trunk/drivers/net/spider_net.h index 2fec5cf76926..3e196df29790 100644 --- a/trunk/drivers/net/spider_net.h +++ b/trunk/drivers/net/spider_net.h @@ -24,7 +24,7 @@ #ifndef _SPIDER_NET_H #define _SPIDER_NET_H -#define VERSION "1.6 B" +#define VERSION "1.6 A" #include "sungem_phy.h" @@ -378,9 +378,6 @@ struct spider_net_descr_chain { spinlock_t lock; struct spider_net_descr *head; struct spider_net_descr *tail; - struct spider_net_descr *ring; - int num_desc; - dma_addr_t dma_addr; }; /* descriptor data_status bits */ @@ -400,6 +397,8 @@ struct spider_net_descr_chain { * 701b8000 would be correct, but every packets gets that flag */ #define SPIDER_NET_DESTROY_RX_FLAGS 0x700b8000 +#define SPIDER_NET_DESCR_SIZE 32 + /* this will be bigger some time */ struct spider_net_options { int rx_csum; /* for rx: if 0 ip_summed=NONE, @@ -442,16 +441,25 @@ struct spider_net_card { struct spider_net_descr_chain rx_chain; struct spider_net_descr *low_watermark; + struct net_device_stats netdev_stats; + + struct spider_net_options options; + + spinlock_t intmask_lock; + struct tasklet_struct rxram_full_tl; struct timer_list tx_timer; + struct work_struct tx_timeout_task; atomic_t tx_timeout_task_counter; wait_queue_head_t waitq; /* for ethtool */ int msg_enable; - struct net_device_stats netdev_stats; + int num_rx_desc; + int num_tx_desc; struct spider_net_extra_stats spider_stats; - struct spider_net_options options; + + struct spider_net_descr descr[0]; }; #define pr_err(fmt,arg...) \ diff --git a/trunk/drivers/net/spider_net_ethtool.c b/trunk/drivers/net/spider_net_ethtool.c index 6bcf03fc89be..91b995102915 100644 --- a/trunk/drivers/net/spider_net_ethtool.c +++ b/trunk/drivers/net/spider_net_ethtool.c @@ -158,9 +158,9 @@ spider_net_ethtool_get_ringparam(struct net_device *netdev, struct spider_net_card *card = netdev->priv; ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX; - ering->tx_pending = card->tx_chain.num_desc; + ering->tx_pending = card->num_tx_desc; ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX; - ering->rx_pending = card->rx_chain.num_desc; + ering->rx_pending = card->num_rx_desc; } static int spider_net_get_stats_count(struct net_device *netdev) diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 135c0987deae..f4bf62c2a7a5 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -58,7 +58,11 @@ #define TG3_VLAN_TAG_USED 0 #endif +#ifdef NETIF_F_TSO #define TG3_TSO_SUPPORT 1 +#else +#define TG3_TSO_SUPPORT 0 +#endif #include "tg3.h" @@ -3869,6 +3873,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) entry = tp->tx_prod; base_flags = 0; +#if TG3_TSO_SUPPORT != 0 mss = 0; if (skb->len > (tp->dev->mtu + ETH_HLEN) && (mss = skb_shinfo(skb)->gso_size) != 0) { @@ -3901,6 +3906,11 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) } else if (skb->ip_summed == CHECKSUM_PARTIAL) base_flags |= TXD_FLAG_TCPUDP_CSUM; +#else + mss = 0; + if (skb->ip_summed == CHECKSUM_PARTIAL) + base_flags |= TXD_FLAG_TCPUDP_CSUM; +#endif #if TG3_VLAN_TAG_USED if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | @@ -3960,6 +3970,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } +#if TG3_TSO_SUPPORT != 0 static int tg3_start_xmit_dma_bug(struct sk_buff *, struct net_device *); /* Use GSO to workaround a rare TSO bug that may be triggered when the @@ -3991,6 +4002,7 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb) return NETDEV_TX_OK; } +#endif /* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and * support TG3_FLG2_HW_TSO_1 or firmware TSO only. @@ -4024,6 +4036,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) base_flags = 0; if (skb->ip_summed == CHECKSUM_PARTIAL) base_flags |= TXD_FLAG_TCPUDP_CSUM; +#if TG3_TSO_SUPPORT != 0 mss = 0; if (skb->len > (tp->dev->mtu + ETH_HLEN) && (mss = skb_shinfo(skb)->gso_size) != 0) { @@ -4078,6 +4091,9 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) } } } +#else + mss = 0; +#endif #if TG3_VLAN_TAG_USED if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | @@ -5313,6 +5329,7 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) return 0; } +#if TG3_TSO_SUPPORT != 0 #define TG3_TSO_FW_RELEASE_MAJOR 0x1 #define TG3_TSO_FW_RELASE_MINOR 0x6 @@ -5889,6 +5906,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp) return 0; } +#endif /* TG3_TSO_SUPPORT != 0 */ /* tp->lock is held. */ static void __tg3_set_mac_addr(struct tg3 *tp) @@ -6102,6 +6120,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE); tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE); } +#if TG3_TSO_SUPPORT != 0 else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { int fw_len; @@ -6116,6 +6135,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE5705 - fw_len - 0xa00); } +#endif if (tp->dev->mtu <= ETH_DATA_LEN) { tw32(BUFMGR_MB_RDMA_LOW_WATER, @@ -6317,8 +6337,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST; +#if TG3_TSO_SUPPORT != 0 if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) rdmac_mode |= (1 << 27); +#endif /* Receive/send statistics. */ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { @@ -6489,8 +6511,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB); tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ); tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); +#if TG3_TSO_SUPPORT != 0 if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8); +#endif tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE); tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE); @@ -6500,11 +6524,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) return err; } +#if TG3_TSO_SUPPORT != 0 if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { err = tg3_load_tso_firmware(tp); if (err) return err; } +#endif tp->tx_mode = TX_MODE_ENABLE; tw32_f(MAC_TX_MODE, tp->tx_mode); @@ -8036,6 +8062,7 @@ static void tg3_set_msglevel(struct net_device *dev, u32 value) tp->msg_enable = value; } +#if TG3_TSO_SUPPORT != 0 static int tg3_set_tso(struct net_device *dev, u32 value) { struct tg3 *tp = netdev_priv(dev); @@ -8054,6 +8081,7 @@ static int tg3_set_tso(struct net_device *dev, u32 value) } return ethtool_op_set_tso(dev, value); } +#endif static int tg3_nway_reset(struct net_device *dev) { @@ -9184,8 +9212,10 @@ static const struct ethtool_ops tg3_ethtool_ops = { .set_tx_csum = tg3_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, +#if TG3_TSO_SUPPORT != 0 .get_tso = ethtool_op_get_tso, .set_tso = tg3_set_tso, +#endif .self_test_count = tg3_get_test_count, .self_test = tg3_self_test, .get_strings = tg3_get_strings, @@ -11826,6 +11856,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tg3_init_bufmgr_config(tp); +#if TG3_TSO_SUPPORT != 0 if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; } @@ -11850,6 +11881,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, dev->features |= NETIF_F_TSO6; } +#endif if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 && !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) && diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index abb8611c5a91..7e4b23c7c1ba 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -2865,8 +2865,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4) align = UCC_GETH_TX_BD_RING_ALIGNMENT; ugeth->tx_bd_ring_offset[j] = - kmalloc((u32) (length + align), GFP_KERNEL); - + (u32) (kmalloc((u32) (length + align), + GFP_KERNEL)); if (ugeth->tx_bd_ring_offset[j] != 0) ugeth->p_tx_bd_ring[j] = (void*)((ugeth->tx_bd_ring_offset[j] + @@ -2901,7 +2901,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) align = UCC_GETH_RX_BD_RING_ALIGNMENT; ugeth->rx_bd_ring_offset[j] = - kmalloc((u32) (length + align), GFP_KERNEL); + (u32) (kmalloc((u32) (length + align), GFP_KERNEL)); if (ugeth->rx_bd_ring_offset[j] != 0) ugeth->p_rx_bd_ring[j] = (void*)((ugeth->rx_bd_ring_offset[j] + @@ -2927,9 +2927,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Init Tx bds */ for (j = 0; j < ug_info->numQueuesTx; j++) { /* Setup the skbuff rings */ - ugeth->tx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) * - ugeth->ug_info->bdRingLenTx[j], - GFP_KERNEL); + ugeth->tx_skbuff[j] = + (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * + ugeth->ug_info->bdRingLenTx[j], + GFP_KERNEL); if (ugeth->tx_skbuff[j] == NULL) { ugeth_err("%s: Could not allocate tx_skbuff", @@ -2958,9 +2959,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Init Rx bds */ for (j = 0; j < ug_info->numQueuesRx; j++) { /* Setup the skbuff rings */ - ugeth->rx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) * - ugeth->ug_info->bdRingLenRx[j], - GFP_KERNEL); + ugeth->rx_skbuff[j] = + (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * + ugeth->ug_info->bdRingLenRx[j], + GFP_KERNEL); if (ugeth->rx_skbuff[j] == NULL) { ugeth_err("%s: Could not allocate rx_skbuff", @@ -3451,7 +3453,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) * allocated resources can be released when the channel is freed. */ if (!(ugeth->p_init_enet_param_shadow = - kmalloc(sizeof(struct ucc_geth_init_pram), GFP_KERNEL))) { + (struct ucc_geth_init_pram *) kmalloc(sizeof(struct ucc_geth_init_pram), + GFP_KERNEL))) { ugeth_err ("%s: Can not allocate memory for" " p_UccInitEnetParamShadows.", __FUNCTION__); diff --git a/trunk/drivers/net/wan/Kconfig b/trunk/drivers/net/wan/Kconfig index 61708cf4c85d..21f76f51c95e 100644 --- a/trunk/drivers/net/wan/Kconfig +++ b/trunk/drivers/net/wan/Kconfig @@ -235,19 +235,6 @@ comment "Cyclades-PC300 MLPPP support is disabled." comment "Refer to the file README.mlppp, provided by PC300 package." depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) -config PC300TOO - tristate "Cyclades PC300 RSV/X21 alternative support" - depends on HDLC && PCI - help - Alternative driver for PC300 RSV/X21 PCI cards made by - Cyclades, Inc. If you have such a card, say Y here and see - . - - To compile this as a module, choose M here: the module - will be called pc300too. - - If unsure, say N here. - config N2 tristate "SDL RISCom/N2 support" depends on HDLC && ISA @@ -357,6 +344,17 @@ config DLCI To compile this driver as a module, choose M here: the module will be called dlci. +config DLCI_COUNT + int "Max open DLCI" + depends on DLCI + default "24" + help + Maximal number of logical point-to-point frame relay connections + (the identifiers of which are called DCLIs) that the driver can + handle. + + The default is probably fine. + config DLCI_MAX int "Max DLCI per device" depends on DLCI diff --git a/trunk/drivers/net/wan/Makefile b/trunk/drivers/net/wan/Makefile index d61fef36afc9..83ec2c87ba3f 100644 --- a/trunk/drivers/net/wan/Makefile +++ b/trunk/drivers/net/wan/Makefile @@ -41,7 +41,6 @@ obj-$(CONFIG_N2) += n2.o obj-$(CONFIG_C101) += c101.o obj-$(CONFIG_WANXL) += wanxl.o obj-$(CONFIG_PCI200SYN) += pci200syn.o -obj-$(CONFIG_PC300TOO) += pc300too.o clean-files := wanxlfw.inc $(obj)/wanxl.o: $(obj)/wanxlfw.inc diff --git a/trunk/drivers/net/wan/hdlc.c b/trunk/drivers/net/wan/hdlc.c index 9040d7cf651e..db354e0edbe5 100644 --- a/trunk/drivers/net/wan/hdlc.c +++ b/trunk/drivers/net/wan/hdlc.c @@ -222,7 +222,7 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -EINVAL; } -static void hdlc_setup(struct net_device *dev) +void hdlc_setup(struct net_device *dev) { hdlc_device *hdlc = dev_to_hdlc(dev); @@ -325,6 +325,7 @@ MODULE_LICENSE("GPL v2"); EXPORT_SYMBOL(hdlc_open); EXPORT_SYMBOL(hdlc_close); EXPORT_SYMBOL(hdlc_ioctl); +EXPORT_SYMBOL(hdlc_setup); EXPORT_SYMBOL(alloc_hdlcdev); EXPORT_SYMBOL(unregister_hdlc_device); EXPORT_SYMBOL(register_hdlc_protocol); diff --git a/trunk/drivers/net/wan/pc300too.c b/trunk/drivers/net/wan/pc300too.c deleted file mode 100644 index 79b2d5454d6b..000000000000 --- a/trunk/drivers/net/wan/pc300too.c +++ /dev/null @@ -1,565 +0,0 @@ -/* - * Cyclades PC300 synchronous serial card driver for Linux - * - * Copyright (C) 2000-2007 Krzysztof Halasa - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * - * For information see . - * - * Sources of information: - * Hitachi HD64572 SCA-II User's Manual - * Cyclades PC300 Linux driver - * - * This driver currently supports only PC300/RSV (V.24/V.35) and - * PC300/X21 cards. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hd64572.h" - -static const char* version = "Cyclades PC300 driver version: 1.17"; -static const char* devname = "PC300"; - -#undef DEBUG_PKT -#define DEBUG_RINGS - -#define PC300_PLX_SIZE 0x80 /* PLX control window size (128 B) */ -#define PC300_SCA_SIZE 0x400 /* SCA window size (1 KB) */ -#define ALL_PAGES_ALWAYS_MAPPED -#define NEED_DETECT_RAM -#define NEED_SCA_MSCI_INTR -#define MAX_TX_BUFFERS 10 - -static int pci_clock_freq = 33000000; -static int use_crystal_clock = 0; -static unsigned int CLOCK_BASE; - -/* Masks to access the init_ctrl PLX register */ -#define PC300_CLKSEL_MASK (0x00000004UL) -#define PC300_CHMEDIA_MASK(port) (0x00000020UL << ((port) * 3)) -#define PC300_CTYPE_MASK (0x00000800UL) - - -enum { PC300_RSV = 1, PC300_X21, PC300_TE }; /* card types */ - -/* - * PLX PCI9050-1 local configuration and shared runtime registers. - * This structure can be used to access 9050 registers (memory mapped). - */ -typedef struct { - u32 loc_addr_range[4]; /* 00-0Ch : Local Address Ranges */ - u32 loc_rom_range; /* 10h : Local ROM Range */ - u32 loc_addr_base[4]; /* 14-20h : Local Address Base Addrs */ - u32 loc_rom_base; /* 24h : Local ROM Base */ - u32 loc_bus_descr[4]; /* 28-34h : Local Bus Descriptors */ - u32 rom_bus_descr; /* 38h : ROM Bus Descriptor */ - u32 cs_base[4]; /* 3C-48h : Chip Select Base Addrs */ - u32 intr_ctrl_stat; /* 4Ch : Interrupt Control/Status */ - u32 init_ctrl; /* 50h : EEPROM ctrl, Init Ctrl, etc */ -}plx9050; - - - -typedef struct port_s { - struct net_device *dev; - struct card_s *card; - spinlock_t lock; /* TX lock */ - sync_serial_settings settings; - int rxpart; /* partial frame received, next frame invalid*/ - unsigned short encoding; - unsigned short parity; - unsigned int iface; - u16 rxin; /* rx ring buffer 'in' pointer */ - u16 txin; /* tx ring buffer 'in' and 'last' pointers */ - u16 txlast; - u8 rxs, txs, tmc; /* SCA registers */ - u8 phy_node; /* physical port # - 0 or 1 */ -}port_t; - - - -typedef struct card_s { - int type; /* RSV, X21, etc. */ - int n_ports; /* 1 or 2 ports */ - u8* __iomem rambase; /* buffer memory base (virtual) */ - u8* __iomem scabase; /* SCA memory base (virtual) */ - plx9050 __iomem *plxbase; /* PLX registers memory base (virtual) */ - u32 init_ctrl_value; /* Saved value - 9050 bug workaround */ - u16 rx_ring_buffers; /* number of buffers in a ring */ - u16 tx_ring_buffers; - u16 buff_offset; /* offset of first buffer of first channel */ - u8 irq; /* interrupt request level */ - - port_t ports[2]; -}card_t; - - -#define sca_in(reg, card) readb(card->scabase + (reg)) -#define sca_out(value, reg, card) writeb(value, card->scabase + (reg)) -#define sca_inw(reg, card) readw(card->scabase + (reg)) -#define sca_outw(value, reg, card) writew(value, card->scabase + (reg)) -#define sca_inl(reg, card) readl(card->scabase + (reg)) -#define sca_outl(value, reg, card) writel(value, card->scabase + (reg)) - -#define port_to_card(port) (port->card) -#define log_node(port) (port->phy_node) -#define phy_node(port) (port->phy_node) -#define winbase(card) (card->rambase) -#define get_port(card, port) ((port) < (card)->n_ports ? \ - (&(card)->ports[port]) : (NULL)) - -#include "hd6457x.c" - - -static void pc300_set_iface(port_t *port) -{ - card_t *card = port->card; - u32* init_ctrl = &card->plxbase->init_ctrl; - u16 msci = get_msci(port); - u8 rxs = port->rxs & CLK_BRG_MASK; - u8 txs = port->txs & CLK_BRG_MASK; - - sca_out(EXS_TES1, (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) + EXS, - port_to_card(port)); - switch(port->settings.clock_type) { - case CLOCK_INT: - rxs |= CLK_BRG; /* BRG output */ - txs |= CLK_PIN_OUT | CLK_TX_RXCLK; /* RX clock */ - break; - - case CLOCK_TXINT: - rxs |= CLK_LINE; /* RXC input */ - txs |= CLK_PIN_OUT | CLK_BRG; /* BRG output */ - break; - - case CLOCK_TXFROMRX: - rxs |= CLK_LINE; /* RXC input */ - txs |= CLK_PIN_OUT | CLK_TX_RXCLK; /* RX clock */ - break; - - default: /* EXTernal clock */ - rxs |= CLK_LINE; /* RXC input */ - txs |= CLK_PIN_OUT | CLK_LINE; /* TXC input */ - break; - } - - port->rxs = rxs; - port->txs = txs; - sca_out(rxs, msci + RXS, card); - sca_out(txs, msci + TXS, card); - sca_set_port(port); - - if (port->card->type == PC300_RSV) { - if (port->iface == IF_IFACE_V35) - writel(card->init_ctrl_value | - PC300_CHMEDIA_MASK(port->phy_node), init_ctrl); - else - writel(card->init_ctrl_value & - ~PC300_CHMEDIA_MASK(port->phy_node), init_ctrl); - } -} - - - -static int pc300_open(struct net_device *dev) -{ - port_t *port = dev_to_port(dev); - - int result = hdlc_open(dev); - if (result) - return result; - - sca_open(dev); - pc300_set_iface(port); - return 0; -} - - - -static int pc300_close(struct net_device *dev) -{ - sca_close(dev); - hdlc_close(dev); - return 0; -} - - - -static int pc300_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - const size_t size = sizeof(sync_serial_settings); - sync_serial_settings new_line; - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; - int new_type; - port_t *port = dev_to_port(dev); - -#ifdef DEBUG_RINGS - if (cmd == SIOCDEVPRIVATE) { - sca_dump_rings(dev); - return 0; - } -#endif - if (cmd != SIOCWANDEV) - return hdlc_ioctl(dev, ifr, cmd); - - if (ifr->ifr_settings.type == IF_GET_IFACE) { - ifr->ifr_settings.type = port->iface; - if (ifr->ifr_settings.size < size) { - ifr->ifr_settings.size = size; /* data size wanted */ - return -ENOBUFS; - } - if (copy_to_user(line, &port->settings, size)) - return -EFAULT; - return 0; - - } - - if (port->card->type == PC300_X21 && - (ifr->ifr_settings.type == IF_IFACE_SYNC_SERIAL || - ifr->ifr_settings.type == IF_IFACE_X21)) - new_type = IF_IFACE_X21; - - else if (port->card->type == PC300_RSV && - (ifr->ifr_settings.type == IF_IFACE_SYNC_SERIAL || - ifr->ifr_settings.type == IF_IFACE_V35)) - new_type = IF_IFACE_V35; - - else if (port->card->type == PC300_RSV && - ifr->ifr_settings.type == IF_IFACE_V24) - new_type = IF_IFACE_V24; - - else - return hdlc_ioctl(dev, ifr, cmd); - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (copy_from_user(&new_line, line, size)) - return -EFAULT; - - if (new_line.clock_type != CLOCK_EXT && - new_line.clock_type != CLOCK_TXFROMRX && - new_line.clock_type != CLOCK_INT && - new_line.clock_type != CLOCK_TXINT) - return -EINVAL; /* No such clock setting */ - - if (new_line.loopback != 0 && new_line.loopback != 1) - return -EINVAL; - - memcpy(&port->settings, &new_line, size); /* Update settings */ - port->iface = new_type; - pc300_set_iface(port); - return 0; -} - - - -static void pc300_pci_remove_one(struct pci_dev *pdev) -{ - int i; - card_t *card = pci_get_drvdata(pdev); - - for (i = 0; i < 2; i++) - if (card->ports[i].card) { - struct net_device *dev = port_to_dev(&card->ports[i]); - unregister_hdlc_device(dev); - } - - if (card->irq) - free_irq(card->irq, card); - - if (card->rambase) - iounmap(card->rambase); - if (card->scabase) - iounmap(card->scabase); - if (card->plxbase) - iounmap(card->plxbase); - - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - if (card->ports[0].dev) - free_netdev(card->ports[0].dev); - if (card->ports[1].dev) - free_netdev(card->ports[1].dev); - kfree(card); -} - - - -static int __devinit pc300_pci_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - card_t *card; - u8 rev_id; - u32 __iomem *p; - int i; - u32 ramsize; - u32 ramphys; /* buffer memory base */ - u32 scaphys; /* SCA memory base */ - u32 plxphys; /* PLX registers memory base */ - -#ifndef MODULE - static int printed_version; - if (!printed_version++) - printk(KERN_INFO "%s\n", version); -#endif - - i = pci_enable_device(pdev); - if (i) - return i; - - i = pci_request_regions(pdev, "PC300"); - if (i) { - pci_disable_device(pdev); - return i; - } - - card = kmalloc(sizeof(card_t), GFP_KERNEL); - if (card == NULL) { - printk(KERN_ERR "pc300: unable to allocate memory\n"); - pci_release_regions(pdev); - pci_disable_device(pdev); - return -ENOBUFS; - } - memset(card, 0, sizeof(card_t)); - pci_set_drvdata(pdev, card); - - if (pdev->device == PCI_DEVICE_ID_PC300_TE_1 || - pdev->device == PCI_DEVICE_ID_PC300_TE_2) - card->type = PC300_TE; /* not fully supported */ - else if (card->init_ctrl_value & PC300_CTYPE_MASK) - card->type = PC300_X21; - else - card->type = PC300_RSV; - - if (pdev->device == PCI_DEVICE_ID_PC300_RX_1 || - pdev->device == PCI_DEVICE_ID_PC300_TE_1) - card->n_ports = 1; - else - card->n_ports = 2; - - for (i = 0; i < card->n_ports; i++) - if (!(card->ports[i].dev = alloc_hdlcdev(&card->ports[i]))) { - printk(KERN_ERR "pc300: unable to allocate memory\n"); - pc300_pci_remove_one(pdev); - return -ENOMEM; - } - - pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); - if (pci_resource_len(pdev, 0) != PC300_PLX_SIZE || - pci_resource_len(pdev, 2) != PC300_SCA_SIZE || - pci_resource_len(pdev, 3) < 16384) { - printk(KERN_ERR "pc300: invalid card EEPROM parameters\n"); - pc300_pci_remove_one(pdev); - return -EFAULT; - } - - plxphys = pci_resource_start(pdev,0) & PCI_BASE_ADDRESS_MEM_MASK; - card->plxbase = ioremap(plxphys, PC300_PLX_SIZE); - - scaphys = pci_resource_start(pdev,2) & PCI_BASE_ADDRESS_MEM_MASK; - card->scabase = ioremap(scaphys, PC300_SCA_SIZE); - - ramphys = pci_resource_start(pdev,3) & PCI_BASE_ADDRESS_MEM_MASK; - card->rambase = ioremap(ramphys, pci_resource_len(pdev,3)); - - if (card->plxbase == NULL || - card->scabase == NULL || - card->rambase == NULL) { - printk(KERN_ERR "pc300: ioremap() failed\n"); - pc300_pci_remove_one(pdev); - } - - /* PLX PCI 9050 workaround for local configuration register read bug */ - pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, scaphys); - card->init_ctrl_value = readl(&((plx9050*)card->scabase)->init_ctrl); - pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, plxphys); - - /* Reset PLX */ - p = &card->plxbase->init_ctrl; - writel(card->init_ctrl_value | 0x40000000, p); - readl(p); /* Flush the write - do not use sca_flush */ - udelay(1); - - writel(card->init_ctrl_value, p); - readl(p); /* Flush the write - do not use sca_flush */ - udelay(1); - - /* Reload Config. Registers from EEPROM */ - writel(card->init_ctrl_value | 0x20000000, p); - readl(p); /* Flush the write - do not use sca_flush */ - udelay(1); - - writel(card->init_ctrl_value, p); - readl(p); /* Flush the write - do not use sca_flush */ - udelay(1); - - ramsize = sca_detect_ram(card, card->rambase, - pci_resource_len(pdev, 3)); - - if (use_crystal_clock) - card->init_ctrl_value &= ~PC300_CLKSEL_MASK; - else - card->init_ctrl_value |= PC300_CLKSEL_MASK; - - writel(card->init_ctrl_value, &card->plxbase->init_ctrl); - /* number of TX + RX buffers for one port */ - i = ramsize / (card->n_ports * (sizeof(pkt_desc) + HDLC_MAX_MRU)); - card->tx_ring_buffers = min(i / 2, MAX_TX_BUFFERS); - card->rx_ring_buffers = i - card->tx_ring_buffers; - - card->buff_offset = card->n_ports * sizeof(pkt_desc) * - (card->tx_ring_buffers + card->rx_ring_buffers); - - printk(KERN_INFO "pc300: PC300/%s, %u KB RAM at 0x%x, IRQ%u, " - "using %u TX + %u RX packets rings\n", - card->type == PC300_X21 ? "X21" : - card->type == PC300_TE ? "TE" : "RSV", - ramsize / 1024, ramphys, pdev->irq, - card->tx_ring_buffers, card->rx_ring_buffers); - - if (card->tx_ring_buffers < 1) { - printk(KERN_ERR "pc300: RAM test failed\n"); - pc300_pci_remove_one(pdev); - return -EFAULT; - } - - /* Enable interrupts on the PCI bridge, LINTi1 active low */ - writew(0x0041, &card->plxbase->intr_ctrl_stat); - - /* Allocate IRQ */ - if (request_irq(pdev->irq, sca_intr, IRQF_SHARED, devname, card)) { - printk(KERN_WARNING "pc300: could not allocate IRQ%d.\n", - pdev->irq); - pc300_pci_remove_one(pdev); - return -EBUSY; - } - card->irq = pdev->irq; - - sca_init(card, 0); - - // COTE not set - allows better TX DMA settings - // sca_out(sca_in(PCR, card) | PCR_COTE, PCR, card); - - sca_out(0x10, BTCR, card); - - for (i = 0; i < card->n_ports; i++) { - port_t *port = &card->ports[i]; - struct net_device *dev = port_to_dev(port); - hdlc_device *hdlc = dev_to_hdlc(dev); - port->phy_node = i; - - spin_lock_init(&port->lock); - SET_MODULE_OWNER(dev); - dev->irq = card->irq; - dev->mem_start = ramphys; - dev->mem_end = ramphys + ramsize - 1; - dev->tx_queue_len = 50; - dev->do_ioctl = pc300_ioctl; - dev->open = pc300_open; - dev->stop = pc300_close; - hdlc->attach = sca_attach; - hdlc->xmit = sca_xmit; - port->settings.clock_type = CLOCK_EXT; - port->card = card; - if (card->type == PC300_X21) - port->iface = IF_IFACE_X21; - else - port->iface = IF_IFACE_V35; - - if (register_hdlc_device(dev)) { - printk(KERN_ERR "pc300: unable to register hdlc " - "device\n"); - port->card = NULL; - pc300_pci_remove_one(pdev); - return -ENOBUFS; - } - sca_init_sync_port(port); /* Set up SCA memory */ - - printk(KERN_INFO "%s: PC300 node %d\n", - dev->name, port->phy_node); - } - return 0; -} - - - -static struct pci_device_id pc300_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_PC300_RX_1, PCI_ANY_ID, - PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_PC300_RX_2, PCI_ANY_ID, - PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_PC300_TE_1, PCI_ANY_ID, - PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_PC300_TE_2, PCI_ANY_ID, - PCI_ANY_ID, 0, 0, 0 }, - { 0, } -}; - - -static struct pci_driver pc300_pci_driver = { - name: "PC300", - id_table: pc300_pci_tbl, - probe: pc300_pci_init_one, - remove: pc300_pci_remove_one, -}; - - -static int __init pc300_init_module(void) -{ -#ifdef MODULE - printk(KERN_INFO "%s\n", version); -#endif - if (pci_clock_freq < 1000000 || pci_clock_freq > 80000000) { - printk(KERN_ERR "pc300: Invalid PCI clock frequency\n"); - return -EINVAL; - } - if (use_crystal_clock != 0 && use_crystal_clock != 1) { - printk(KERN_ERR "pc300: Invalid 'use_crystal_clock' value\n"); - return -EINVAL; - } - - CLOCK_BASE = use_crystal_clock ? 24576000 : pci_clock_freq; - - return pci_module_init(&pc300_pci_driver); -} - - - -static void __exit pc300_cleanup_module(void) -{ - pci_unregister_driver(&pc300_pci_driver); -} - -MODULE_AUTHOR("Krzysztof Halasa "); -MODULE_DESCRIPTION("Cyclades PC300 serial port driver"); -MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(pci, pc300_pci_tbl); -module_param(pci_clock_freq, int, 0444); -MODULE_PARM_DESC(pci_clock_freq, "System PCI clock frequency in Hz"); -module_param(use_crystal_clock, int, 0444); -MODULE_PARM_DESC(use_crystal_clock, - "Use 24.576 MHz clock instead of PCI clock"); -module_init(pc300_init_module); -module_exit(pc300_cleanup_module); diff --git a/trunk/drivers/net/wan/z85230.c b/trunk/drivers/net/wan/z85230.c index 8dbcf83bb5f3..59ddd21c3958 100644 --- a/trunk/drivers/net/wan/z85230.c +++ b/trunk/drivers/net/wan/z85230.c @@ -331,7 +331,8 @@ static void z8530_rtsdtr(struct z8530_channel *c, int set) static void z8530_rx(struct z8530_channel *c) { u8 ch,stat; - + spin_lock(c->lock); + while(1) { /* FIFO empty ? */ @@ -389,6 +390,7 @@ static void z8530_rx(struct z8530_channel *c) */ write_zsctrl(c, ERR_RES); write_zsctrl(c, RES_H_IUS); + spin_unlock(c->lock); } @@ -404,6 +406,7 @@ static void z8530_rx(struct z8530_channel *c) static void z8530_tx(struct z8530_channel *c) { + spin_lock(c->lock); while(c->txcount) { /* FIFO full ? */ if(!(read_zsreg(c, R0)&4)) @@ -431,6 +434,7 @@ static void z8530_tx(struct z8530_channel *c) z8530_tx_done(c); write_zsctrl(c, RES_H_IUS); + spin_unlock(c->lock); } /** @@ -448,6 +452,7 @@ static void z8530_status(struct z8530_channel *chan) { u8 status, altered; + spin_lock(chan->lock); status=read_zsreg(chan, R0); altered=chan->status^status; @@ -482,6 +487,7 @@ static void z8530_status(struct z8530_channel *chan) } write_zsctrl(chan, RES_EXT_INT); write_zsctrl(chan, RES_H_IUS); + spin_unlock(chan->lock); } struct z8530_irqhandler z8530_sync= @@ -505,6 +511,7 @@ EXPORT_SYMBOL(z8530_sync); static void z8530_dma_rx(struct z8530_channel *chan) { + spin_lock(chan->lock); if(chan->rxdma_on) { /* Special condition check only */ @@ -527,6 +534,7 @@ static void z8530_dma_rx(struct z8530_channel *chan) /* DMA is off right now, drain the slow way */ z8530_rx(chan); } + spin_unlock(chan->lock); } /** @@ -539,6 +547,7 @@ static void z8530_dma_rx(struct z8530_channel *chan) static void z8530_dma_tx(struct z8530_channel *chan) { + spin_lock(chan->lock); if(!chan->dma_tx) { printk(KERN_WARNING "Hey who turned the DMA off?\n"); @@ -548,6 +557,7 @@ static void z8530_dma_tx(struct z8530_channel *chan) /* This shouldnt occur in DMA mode */ printk(KERN_ERR "DMA tx - bogus event!\n"); z8530_tx(chan); + spin_unlock(chan->lock); } /** @@ -586,6 +596,7 @@ static void z8530_dma_status(struct z8530_channel *chan) } } + spin_lock(chan->lock); if(altered&chan->dcdcheck) { if(status&chan->dcdcheck) @@ -607,6 +618,7 @@ static void z8530_dma_status(struct z8530_channel *chan) write_zsctrl(chan, RES_EXT_INT); write_zsctrl(chan, RES_H_IUS); + spin_unlock(chan->lock); } struct z8530_irqhandler z8530_dma_sync= diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h index 3a064def162e..8286678513b9 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h @@ -352,10 +352,6 @@ #define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040 #define BCM43xx_UCODEFLAG_JAPAN 0x0080 -/* Hardware Radio Enable masks */ -#define BCM43xx_MMIO_RADIO_HWENABLED_HI_MASK (1 << 16) -#define BCM43xx_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4) - /* Generic-Interrupt reasons. */ #define BCM43xx_IRQ_READY (1 << 0) #define BCM43xx_IRQ_BEACON (1 << 1) @@ -762,8 +758,7 @@ struct bcm43xx_private { bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ short_preamble:1, /* TRUE, if short preamble is enabled. */ - firmware_norelease:1, /* Do not release the firmware. Used on suspend. */ - radio_hw_enable:1; /* TRUE if radio is hardware enabled */ + firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ struct bcm43xx_stats stats; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index 8f198befba39..7d383a27b927 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c @@ -26,7 +26,6 @@ */ #include "bcm43xx_leds.h" -#include "bcm43xx_radio.h" #include "bcm43xx.h" #include @@ -109,7 +108,6 @@ static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm, switch (led_index) { case 0: led->behaviour = BCM43xx_LED_ACTIVITY; - led->activelow = 1; if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ) led->behaviour = BCM43xx_LED_RADIO_ALL; break; @@ -201,21 +199,20 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) turn_on = activity; break; case BCM43xx_LED_RADIO_ALL: - turn_on = radio->enabled && bcm43xx_is_hw_radio_enabled(bcm); + turn_on = radio->enabled; break; case BCM43xx_LED_RADIO_A: case BCM43xx_LED_BCM4303_2: - turn_on = (radio->enabled && bcm43xx_is_hw_radio_enabled(bcm) && - phy->type == BCM43xx_PHYTYPE_A); + turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A); break; case BCM43xx_LED_RADIO_B: case BCM43xx_LED_BCM4303_1: - turn_on = (radio->enabled && bcm43xx_is_hw_radio_enabled(bcm) && + turn_on = (radio->enabled && (phy->type == BCM43xx_PHYTYPE_B || phy->type == BCM43xx_PHYTYPE_G)); break; case BCM43xx_LED_MODE_BG: - if (phy->type == BCM43xx_PHYTYPE_G && bcm43xx_is_hw_radio_enabled(bcm) && + if (phy->type == BCM43xx_PHYTYPE_G && 1/*FIXME: using G rates.*/) turn_on = 1; break; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 23aaf1ed8541..91b752e3d07e 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -2441,9 +2441,6 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm) if (err) goto err_gpio_cleanup; bcm43xx_radio_turn_on(bcm); - bcm->radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm); - dprintk(KERN_INFO PFX "Radio %s by hardware\n", - (bcm->radio_hw_enable == 0) ? "disabled" : "enabled"); bcm43xx_write16(bcm, 0x03E6, 0x0000); err = bcm43xx_phy_init(bcm); @@ -3177,25 +3174,10 @@ static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm) } static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) -{ - bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning? - //TODO for APHY (temperature?) -} - -static void bcm43xx_periodic_every1sec(struct bcm43xx_private *bcm) { struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - int radio_hw_enable; - /* check if radio hardware enabled status changed */ - radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm); - if (unlikely(bcm->radio_hw_enable != radio_hw_enable)) { - bcm->radio_hw_enable = radio_hw_enable; - dprintk(KERN_INFO PFX "Radio hardware status changed to %s\n", - (radio_hw_enable == 0) ? "disabled" : "enabled"); - bcm43xx_leds_update(bcm, 0); - } if (phy->type == BCM43xx_PHYTYPE_G) { //TODO: update_aci_moving_average if (radio->aci_enable && radio->aci_wlan_automatic) { @@ -3219,21 +3201,21 @@ static void bcm43xx_periodic_every1sec(struct bcm43xx_private *bcm) //TODO: implement rev1 workaround } } + bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning? + //TODO for APHY (temperature?) } static void do_periodic_work(struct bcm43xx_private *bcm) { - if (bcm->periodic_state % 120 == 0) + if (bcm->periodic_state % 8 == 0) bcm43xx_periodic_every120sec(bcm); - if (bcm->periodic_state % 60 == 0) + if (bcm->periodic_state % 4 == 0) bcm43xx_periodic_every60sec(bcm); - if (bcm->periodic_state % 30 == 0) + if (bcm->periodic_state % 2 == 0) bcm43xx_periodic_every30sec(bcm); - if (bcm->periodic_state % 15 == 0) - bcm43xx_periodic_every15sec(bcm); - bcm43xx_periodic_every1sec(bcm); + bcm43xx_periodic_every15sec(bcm); - schedule_delayed_work(&bcm->periodic_work, HZ); + schedule_delayed_work(&bcm->periodic_work, HZ * 15); } static void bcm43xx_periodic_work_handler(struct work_struct *work) @@ -3246,7 +3228,7 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work) unsigned long orig_trans_start = 0; mutex_lock(&bcm->mutex); - if (unlikely(bcm->periodic_state % 60 == 0)) { + if (unlikely(bcm->periodic_state % 4 == 0)) { /* Periodic work will take a long time, so we want it to * be preemtible. */ @@ -3278,7 +3260,7 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work) do_periodic_work(bcm); - if (unlikely(bcm->periodic_state % 60 == 0)) { + if (unlikely(bcm->periodic_state % 4 == 0)) { spin_lock_irqsave(&bcm->irq_lock, flags); tasklet_enable(&bcm->isr_tasklet); bcm43xx_interrupt_enable(bcm, savedirqs); diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.c index af19a07032a3..bb9c484d7e19 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.c @@ -1981,7 +1981,6 @@ void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm) } radio->enabled = 1; dprintk(KERN_INFO PFX "Radio turned on\n"); - bcm43xx_leds_update(bcm, 0); } void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm) @@ -2002,7 +2001,6 @@ void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm) bcm43xx_phy_write(bcm, 0x0015, 0xAA00); radio->enabled = 0; dprintk(KERN_INFO PFX "Radio turned off\n"); - bcm43xx_leds_update(bcm, 0); } void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm) diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.h index 77a98a53a2e2..9ed18039fa3e 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.h +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.h @@ -65,22 +65,6 @@ void bcm43xx_radio_init2060(struct bcm43xx_private *bcm); void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm); void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm); -static inline -int bcm43xx_is_hw_radio_enabled(struct bcm43xx_private *bcm) -{ - /* function to return state of hardware enable of radio - * returns 0 if radio disabled, 1 if radio enabled - */ - if (bcm->current_core->rev >= 3) - return ((bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI) - & BCM43xx_MMIO_RADIO_HWENABLED_HI_MASK) - == 0) ? 1 : 0; - else - return ((bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO) - & BCM43xx_MMIO_RADIO_HWENABLED_LO_MASK) - == 0) ? 0 : 1; -} - int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm, u8 channel, int synthetic_pu_workaround); diff --git a/trunk/drivers/net/wireless/hostap/hostap_main.c b/trunk/drivers/net/wireless/hostap/hostap_main.c index 9077e6edde34..04c19cefa1da 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_main.c +++ b/trunk/drivers/net/wireless/hostap/hostap_main.c @@ -84,7 +84,7 @@ struct net_device * hostap_add_interface(struct local_info *local, if (strchr(dev->name, '%')) ret = dev_alloc_name(dev, dev->name); - SET_NETDEV_DEV(dev, mdev->dev.parent); + SET_NETDEV_DEV(dev, mdev->class_dev.dev); if (ret >= 0) ret = register_netdevice(dev); diff --git a/trunk/drivers/net/wireless/ipw2200.c b/trunk/drivers/net/wireless/ipw2200.c index c878a2f3239c..22cb3fb7502e 100644 --- a/trunk/drivers/net/wireless/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2200.c @@ -9166,7 +9166,7 @@ static int ipw_wx_set_rts(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); mutex_lock(&priv->mutex); - if (wrqu->rts.disabled || !wrqu->rts.fixed) + if (wrqu->rts.disabled) priv->rts_threshold = DEFAULT_RTS_THRESHOLD; else { if (wrqu->rts.value < MIN_RTS_THRESHOLD || @@ -9255,7 +9255,7 @@ static int ipw_wx_set_frag(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); mutex_lock(&priv->mutex); - if (wrqu->frag.disabled || !wrqu->frag.fixed) + if (wrqu->frag.disabled) priv->ieee->fts = DEFAULT_FTS; else { if (wrqu->frag.value < MIN_FRAG_THRESHOLD || diff --git a/trunk/drivers/net/wireless/orinoco.c b/trunk/drivers/net/wireless/orinoco.c index 4e7f6cf51436..936c888e03e1 100644 --- a/trunk/drivers/net/wireless/orinoco.c +++ b/trunk/drivers/net/wireless/orinoco.c @@ -2059,7 +2059,7 @@ static int determine_firmware(struct net_device *dev) int err; struct comp_id nic_id, sta_id; unsigned int firmver; - char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2))); + char tmp[SYMBOL_MAX_VER_LEN+1]; /* Get the hardware version */ err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id); @@ -4293,8 +4293,8 @@ static void orinoco_get_drvinfo(struct net_device *dev, strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1); strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1); strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1); - if (dev->dev.parent) - strncpy(info->bus_info, dev->dev.parent->bus_id, + if (dev->class_dev.dev) + strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info) - 1); else snprintf(info->bus_info, sizeof(info->bus_info) - 1, diff --git a/trunk/drivers/net/wireless/orinoco_cs.c b/trunk/drivers/net/wireless/orinoco_cs.c index d1e502236b2a..d08ae8d2726c 100644 --- a/trunk/drivers/net/wireless/orinoco_cs.c +++ b/trunk/drivers/net/wireless/orinoco_cs.c @@ -332,7 +332,7 @@ orinoco_cs_config(struct pcmcia_device *link) /* Finally, report what we've done */ printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io " - "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id, + "0x%04x-0x%04x\n", dev->name, dev->class_dev.dev->bus_id, link->irq.AssignedIRQ, link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); diff --git a/trunk/drivers/net/wireless/prism54/islpci_dev.c b/trunk/drivers/net/wireless/prism54/islpci_dev.c index a037b11dac9d..f057fd9fcd79 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_dev.c +++ b/trunk/drivers/net/wireless/prism54/islpci_dev.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -788,17 +787,6 @@ islpci_set_multicast_list(struct net_device *dev) } #endif -static void islpci_ethtool_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, DRV_NAME); - strcpy(info->version, DRV_VERSION); -} - -static struct ethtool_ops islpci_ethtool_ops = { - .get_drvinfo = islpci_ethtool_get_drvinfo, -}; - struct net_device * islpci_setup(struct pci_dev *pdev) { @@ -825,7 +813,6 @@ islpci_setup(struct pci_dev *pdev) ndev->do_ioctl = &prism54_ioctl; ndev->wireless_handlers = (struct iw_handler_def *) &prism54_handler_def; - ndev->ethtool_ops = &islpci_ethtool_ops; ndev->hard_start_xmit = &islpci_eth_transmit; /* ndev->set_multicast_list = &islpci_set_multicast_list; */ diff --git a/trunk/drivers/net/wireless/prism54/islpci_dev.h b/trunk/drivers/net/wireless/prism54/islpci_dev.h index 736666da6c24..a9aa1662eaa4 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_dev.h +++ b/trunk/drivers/net/wireless/prism54/islpci_dev.h @@ -211,8 +211,4 @@ islpci_trigger(islpci_private *priv) int islpci_free_memory(islpci_private *); struct net_device *islpci_setup(struct pci_dev *); - -#define DRV_NAME "prism54" -#define DRV_VERSION "1.2" - #endif /* _ISLPCI_DEV_H */ diff --git a/trunk/drivers/net/wireless/prism54/islpci_hotplug.c b/trunk/drivers/net/wireless/prism54/islpci_hotplug.c index 3dcb13bb7d57..58257b40c043 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_hotplug.c +++ b/trunk/drivers/net/wireless/prism54/islpci_hotplug.c @@ -28,6 +28,9 @@ #include "islpci_mgt.h" /* for pc_debug */ #include "isl_oid.h" +#define DRV_NAME "prism54" +#define DRV_VERSION "1.2" + MODULE_AUTHOR("[Intersil] R.Bastings and W.Termorshuizen, The prism54.org Development Team "); MODULE_DESCRIPTION("The Prism54 802.11 Wireless LAN adapter"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/wireless/spectrum_cs.c b/trunk/drivers/net/wireless/spectrum_cs.c index af70460f008a..cf2d1486b01d 100644 --- a/trunk/drivers/net/wireless/spectrum_cs.c +++ b/trunk/drivers/net/wireless/spectrum_cs.c @@ -806,7 +806,7 @@ spectrum_cs_config(struct pcmcia_device *link) /* Finally, report what we've done */ printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io " - "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id, + "0x%04x-0x%04x\n", dev->name, dev->class_dev.dev->bus_id, link->irq.AssignedIRQ, link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_chip.c b/trunk/drivers/net/wireless/zd1211rw/zd_chip.c index 12dfc0b6efe6..78ea72fb8f0c 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_chip.c @@ -84,18 +84,6 @@ static void print_id(struct zd_chip *chip) dev_info(zd_chip_dev(chip), "%s\n", buffer); } -static zd_addr_t inc_addr(zd_addr_t addr) -{ - u16 a = (u16)addr; - /* Control registers use byte addressing, but everything else uses word - * addressing. */ - if ((a & 0xf000) == CR_START) - a += 2; - else - a += 1; - return (zd_addr_t)a; -} - /* Read a variable number of 32-bit values. Parameter count is not allowed to * exceed USB_MAX_IOREAD32_COUNT. */ @@ -126,7 +114,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr for (i = 0; i < count; i++) { int j = 2*i; /* We read the high word always first. */ - a16[j] = inc_addr(addr[i]); + a16[j] = zd_inc_word(addr[i]); a16[j+1] = addr[i]; } @@ -175,7 +163,7 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, j = 2*i; /* We write the high word always first. */ ioreqs16[j].value = ioreqs[i].value >> 16; - ioreqs16[j].addr = inc_addr(ioreqs[i].addr); + ioreqs16[j].addr = zd_inc_word(ioreqs[i].addr); ioreqs16[j+1].value = ioreqs[i].value; ioreqs16[j+1].addr = ioreqs[i].addr; } @@ -478,8 +466,7 @@ static int read_values(struct zd_chip *chip, u8 *values, size_t count, ZD_ASSERT(mutex_is_locked(&chip->mutex)); for (i = 0;;) { - r = zd_ioread32_locked(chip, &v, - (zd_addr_t)((u16)e2p_addr+i/2)); + r = zd_ioread32_locked(chip, &v, e2p_addr+i/2); if (r) return r; v -= guard; @@ -811,18 +798,47 @@ static int hw_reset_phy(struct zd_chip *chip) static int zd1211_hw_init_hmac(struct zd_chip *chip) { static const struct zd_ioreq32 ioreqs[] = { + { CR_ACK_TIMEOUT_EXT, 0x20 }, + { CR_ADDA_MBIAS_WARMTIME, 0x30000808 }, { CR_ZD1211_RETRY_MAX, 0x2 }, + { CR_SNIFFER_ON, 0 }, + { CR_RX_FILTER, STA_RX_FILTER }, + { CR_GROUP_HASH_P1, 0x00 }, + { CR_GROUP_HASH_P2, 0x80000000 }, + { CR_REG1, 0xa4 }, + { CR_ADDA_PWR_DWN, 0x7f }, + { CR_BCN_PLCP_CFG, 0x00f00401 }, + { CR_PHY_DELAY, 0x00 }, + { CR_ACK_TIMEOUT_EXT, 0x80 }, + { CR_ADDA_PWR_DWN, 0x00 }, + { CR_ACK_TIME_80211, 0x100 }, + { CR_RX_PE_DELAY, 0x70 }, + { CR_PS_CTRL, 0x10000000 }, + { CR_RTS_CTS_RATE, 0x02030203 }, { CR_RX_THRESHOLD, 0x000c0640 }, + { CR_AFTER_PNP, 0x1 }, + { CR_WEP_PROTECT, 0x114 }, }; + int r; + dev_dbg_f(zd_chip_dev(chip), "\n"); ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); + r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); +#ifdef DEBUG + if (r) { + dev_err(zd_chip_dev(chip), + "error in zd_iowrite32a_locked. Error number %d\n", r); + } +#endif /* DEBUG */ + return r; } static int zd1211b_hw_init_hmac(struct zd_chip *chip) { static const struct zd_ioreq32 ioreqs[] = { + { CR_ACK_TIMEOUT_EXT, 0x20 }, + { CR_ADDA_MBIAS_WARMTIME, 0x30000808 }, { CR_ZD1211B_RETRY_MAX, 0x02020202 }, { CR_ZD1211B_TX_PWR_CTL4, 0x007f003f }, { CR_ZD1211B_TX_PWR_CTL3, 0x007f003f }, @@ -831,20 +847,6 @@ static int zd1211b_hw_init_hmac(struct zd_chip *chip) { CR_ZD1211B_AIFS_CTL1, 0x00280028 }, { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, { CR_ZD1211B_TXOP, 0x01800824 }, - { CR_RX_THRESHOLD, 0x000c0eff, }, - }; - - dev_dbg_f(zd_chip_dev(chip), "\n"); - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int hw_init_hmac(struct zd_chip *chip) -{ - int r; - static const struct zd_ioreq32 ioreqs[] = { - { CR_ACK_TIMEOUT_EXT, 0x20 }, - { CR_ADDA_MBIAS_WARMTIME, 0x30000808 }, { CR_SNIFFER_ON, 0 }, { CR_RX_FILTER, STA_RX_FILTER }, { CR_GROUP_HASH_P1, 0x00 }, @@ -859,16 +861,25 @@ static int hw_init_hmac(struct zd_chip *chip) { CR_RX_PE_DELAY, 0x70 }, { CR_PS_CTRL, 0x10000000 }, { CR_RTS_CTS_RATE, 0x02030203 }, + { CR_RX_THRESHOLD, 0x000c0eff, }, { CR_AFTER_PNP, 0x1 }, { CR_WEP_PROTECT, 0x114 }, - { CR_IFS_VALUE, IFS_VALUE_DEFAULT }, }; + int r; + + dev_dbg_f(zd_chip_dev(chip), "\n"); ZD_ASSERT(mutex_is_locked(&chip->mutex)); r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - return r; + if (r) { + dev_dbg_f(zd_chip_dev(chip), + "error in zd_iowrite32a_locked. Error number %d\n", r); + } + return r; +} +static int hw_init_hmac(struct zd_chip *chip) +{ return chip->is_zd1211b ? zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip); } @@ -963,12 +974,14 @@ static int hw_init(struct zd_chip *chip) if (r) return r; - return set_beacon_interval(chip, 100); -} + /* Although the vendor driver defaults to a different value during + * init, it overwrites the IFS value with the following every time + * the channel changes. We should aim to be more intelligent... */ + r = zd_iowrite32_locked(chip, IFS_VALUE_DEFAULT, CR_IFS_VALUE); + if (r) + return r; -static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset) -{ - return (zd_addr_t)((u16)chip->fw_regs_base + offset); + return set_beacon_interval(chip, 100); } #ifdef DEBUG @@ -1005,11 +1018,9 @@ static int test_init(struct zd_chip *chip) static void dump_fw_registers(struct zd_chip *chip) { - const zd_addr_t addr[4] = { - fw_reg_addr(chip, FW_REG_FIRMWARE_VER), - fw_reg_addr(chip, FW_REG_USB_SPEED), - fw_reg_addr(chip, FW_REG_FIX_TX_RATE), - fw_reg_addr(chip, FW_REG_LED_LINK_STATUS), + static const zd_addr_t addr[4] = { + FW_FIRMWARE_VER, FW_USB_SPEED, FW_FIX_TX_RATE, + FW_LINK_STATUS }; int r; @@ -1035,8 +1046,7 @@ static int print_fw_version(struct zd_chip *chip) int r; u16 version; - r = zd_ioread16_locked(chip, &version, - fw_reg_addr(chip, FW_REG_FIRMWARE_VER)); + r = zd_ioread16_locked(chip, &version, FW_FIRMWARE_VER); if (r) return r; @@ -1116,22 +1126,6 @@ int zd_chip_disable_hwint(struct zd_chip *chip) return r; } -static int read_fw_regs_offset(struct zd_chip *chip) -{ - int r; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_ioread16_locked(chip, (u16*)&chip->fw_regs_base, - FWRAW_REGS_ADDR); - if (r) - return r; - dev_dbg_f(zd_chip_dev(chip), "fw_regs_base: %#06hx\n", - (u16)chip->fw_regs_base); - - return 0; -} - - int zd_chip_init_hw(struct zd_chip *chip, u8 device_type) { int r; @@ -1151,7 +1145,7 @@ int zd_chip_init_hw(struct zd_chip *chip, u8 device_type) if (r) goto out; - r = read_fw_regs_offset(chip); + r = zd_usb_init_hw(&chip->usb); if (r) goto out; @@ -1331,15 +1325,15 @@ u8 zd_chip_get_channel(struct zd_chip *chip) int zd_chip_control_leds(struct zd_chip *chip, enum led_status status) { - const zd_addr_t a[] = { - fw_reg_addr(chip, FW_REG_LED_LINK_STATUS), + static const zd_addr_t a[] = { + FW_LINK_STATUS, CR_LED, }; int r; u16 v[ARRAY_SIZE(a)]; struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = { - [0] = { fw_reg_addr(chip, FW_REG_LED_LINK_STATUS) }, + [0] = { FW_LINK_STATUS }, [1] = { CR_LED }, }; u16 other_led; diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_chip.h b/trunk/drivers/net/wireless/zd1211rw/zd_chip.h index b07569e391ee..a4e3cee9b59d 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_chip.h @@ -18,6 +18,7 @@ #ifndef _ZD_CHIP_H #define _ZD_CHIP_H +#include "zd_types.h" #include "zd_rf.h" #include "zd_usb.h" @@ -26,37 +27,6 @@ * adds a processor for handling the USB protocol. */ -/* Address space */ -enum { - /* CONTROL REGISTERS */ - CR_START = 0x9000, - - - /* FIRMWARE */ - FW_START = 0xee00, - - - /* EEPROM */ - E2P_START = 0xf800, - E2P_LEN = 0x800, - - /* EEPROM layout */ - E2P_LOAD_CODE_LEN = 0xe, /* base 0xf800 */ - E2P_LOAD_VECT_LEN = 0x9, /* base 0xf80e */ - /* E2P_DATA indexes into this */ - E2P_DATA_LEN = 0x7e, /* base 0xf817 */ - E2P_BOOT_CODE_LEN = 0x760, /* base 0xf895 */ - E2P_INTR_VECT_LEN = 0xb, /* base 0xfff5 */ - - /* Some precomputed offsets into the EEPROM */ - E2P_DATA_OFFSET = E2P_LOAD_CODE_LEN + E2P_LOAD_VECT_LEN, - E2P_BOOT_CODE_OFFSET = E2P_DATA_OFFSET + E2P_DATA_LEN, -}; - -#define CTL_REG(offset) ((zd_addr_t)(CR_START + (offset))) -#define E2P_DATA(offset) ((zd_addr_t)(E2P_START + E2P_DATA_OFFSET + (offset))) -#define FWRAW_DATA(offset) ((zd_addr_t)(FW_START + (offset))) - /* 8-bit hardware registers */ #define CR0 CTL_REG(0x0000) #define CR1 CTL_REG(0x0004) @@ -332,7 +302,7 @@ enum { #define CR_MAX_PHY_REG 255 -/* Taken from the ZYDAS driver, not all of them are relevant for the ZD1211 +/* Taken from the ZYDAS driver, not all of them are relevant for the ZSD1211 * driver. */ @@ -624,70 +594,80 @@ enum { /* * Upper 16 bit contains the regulatory domain. */ -#define E2P_SUBID E2P_DATA(0x00) -#define E2P_POD E2P_DATA(0x02) -#define E2P_MAC_ADDR_P1 E2P_DATA(0x04) -#define E2P_MAC_ADDR_P2 E2P_DATA(0x06) -#define E2P_PWR_CAL_VALUE1 E2P_DATA(0x08) -#define E2P_PWR_CAL_VALUE2 E2P_DATA(0x0a) -#define E2P_PWR_CAL_VALUE3 E2P_DATA(0x0c) -#define E2P_PWR_CAL_VALUE4 E2P_DATA(0x0e) -#define E2P_PWR_INT_VALUE1 E2P_DATA(0x10) -#define E2P_PWR_INT_VALUE2 E2P_DATA(0x12) -#define E2P_PWR_INT_VALUE3 E2P_DATA(0x14) -#define E2P_PWR_INT_VALUE4 E2P_DATA(0x16) +#define E2P_SUBID E2P_REG(0x00) +#define E2P_POD E2P_REG(0x02) +#define E2P_MAC_ADDR_P1 E2P_REG(0x04) +#define E2P_MAC_ADDR_P2 E2P_REG(0x06) +#define E2P_PWR_CAL_VALUE1 E2P_REG(0x08) +#define E2P_PWR_CAL_VALUE2 E2P_REG(0x0a) +#define E2P_PWR_CAL_VALUE3 E2P_REG(0x0c) +#define E2P_PWR_CAL_VALUE4 E2P_REG(0x0e) +#define E2P_PWR_INT_VALUE1 E2P_REG(0x10) +#define E2P_PWR_INT_VALUE2 E2P_REG(0x12) +#define E2P_PWR_INT_VALUE3 E2P_REG(0x14) +#define E2P_PWR_INT_VALUE4 E2P_REG(0x16) /* Contains a bit for each allowed channel. It gives for Europe (ETSI 0x30) * also only 11 channels. */ -#define E2P_ALLOWED_CHANNEL E2P_DATA(0x18) - -#define E2P_PHY_REG E2P_DATA(0x1a) -#define E2P_DEVICE_VER E2P_DATA(0x20) -#define E2P_36M_CAL_VALUE1 E2P_DATA(0x28) -#define E2P_36M_CAL_VALUE2 E2P_DATA(0x2a) -#define E2P_36M_CAL_VALUE3 E2P_DATA(0x2c) -#define E2P_36M_CAL_VALUE4 E2P_DATA(0x2e) -#define E2P_11A_INT_VALUE1 E2P_DATA(0x30) -#define E2P_11A_INT_VALUE2 E2P_DATA(0x32) -#define E2P_11A_INT_VALUE3 E2P_DATA(0x34) -#define E2P_11A_INT_VALUE4 E2P_DATA(0x36) -#define E2P_48M_CAL_VALUE1 E2P_DATA(0x38) -#define E2P_48M_CAL_VALUE2 E2P_DATA(0x3a) -#define E2P_48M_CAL_VALUE3 E2P_DATA(0x3c) -#define E2P_48M_CAL_VALUE4 E2P_DATA(0x3e) -#define E2P_48M_INT_VALUE1 E2P_DATA(0x40) -#define E2P_48M_INT_VALUE2 E2P_DATA(0x42) -#define E2P_48M_INT_VALUE3 E2P_DATA(0x44) -#define E2P_48M_INT_VALUE4 E2P_DATA(0x46) -#define E2P_54M_CAL_VALUE1 E2P_DATA(0x48) /* ??? */ -#define E2P_54M_CAL_VALUE2 E2P_DATA(0x4a) -#define E2P_54M_CAL_VALUE3 E2P_DATA(0x4c) -#define E2P_54M_CAL_VALUE4 E2P_DATA(0x4e) -#define E2P_54M_INT_VALUE1 E2P_DATA(0x50) -#define E2P_54M_INT_VALUE2 E2P_DATA(0x52) -#define E2P_54M_INT_VALUE3 E2P_DATA(0x54) -#define E2P_54M_INT_VALUE4 E2P_DATA(0x56) - -/* This word contains the base address of the FW_REG_ registers below */ -#define FWRAW_REGS_ADDR FWRAW_DATA(0x1d) - -/* All 16 bit values, offset from the address in FWRAW_REGS_ADDR */ -enum { - FW_REG_FIRMWARE_VER = 0, - /* non-zero if USB high speed connection */ - FW_REG_USB_SPEED = 1, - FW_REG_FIX_TX_RATE = 2, - /* Seems to be able to control LEDs over the firmware */ - FW_REG_LED_LINK_STATUS = 3, - FW_REG_SOFT_RESET = 4, - FW_REG_FLASH_CHK = 5, -}; +#define E2P_ALLOWED_CHANNEL E2P_REG(0x18) + +#define E2P_PHY_REG E2P_REG(0x1a) +#define E2P_DEVICE_VER E2P_REG(0x20) +#define E2P_36M_CAL_VALUE1 E2P_REG(0x28) +#define E2P_36M_CAL_VALUE2 E2P_REG(0x2a) +#define E2P_36M_CAL_VALUE3 E2P_REG(0x2c) +#define E2P_36M_CAL_VALUE4 E2P_REG(0x2e) +#define E2P_11A_INT_VALUE1 E2P_REG(0x30) +#define E2P_11A_INT_VALUE2 E2P_REG(0x32) +#define E2P_11A_INT_VALUE3 E2P_REG(0x34) +#define E2P_11A_INT_VALUE4 E2P_REG(0x36) +#define E2P_48M_CAL_VALUE1 E2P_REG(0x38) +#define E2P_48M_CAL_VALUE2 E2P_REG(0x3a) +#define E2P_48M_CAL_VALUE3 E2P_REG(0x3c) +#define E2P_48M_CAL_VALUE4 E2P_REG(0x3e) +#define E2P_48M_INT_VALUE1 E2P_REG(0x40) +#define E2P_48M_INT_VALUE2 E2P_REG(0x42) +#define E2P_48M_INT_VALUE3 E2P_REG(0x44) +#define E2P_48M_INT_VALUE4 E2P_REG(0x46) +#define E2P_54M_CAL_VALUE1 E2P_REG(0x48) /* ??? */ +#define E2P_54M_CAL_VALUE2 E2P_REG(0x4a) +#define E2P_54M_CAL_VALUE3 E2P_REG(0x4c) +#define E2P_54M_CAL_VALUE4 E2P_REG(0x4e) +#define E2P_54M_INT_VALUE1 E2P_REG(0x50) +#define E2P_54M_INT_VALUE2 E2P_REG(0x52) +#define E2P_54M_INT_VALUE3 E2P_REG(0x54) +#define E2P_54M_INT_VALUE4 E2P_REG(0x56) + +/* All 16 bit values */ +#define FW_FIRMWARE_VER FW_REG(0) +/* non-zero if USB high speed connection */ +#define FW_USB_SPEED FW_REG(1) +#define FW_FIX_TX_RATE FW_REG(2) +/* Seems to be able to control LEDs over the firmware */ +#define FW_LINK_STATUS FW_REG(3) +#define FW_SOFT_RESET FW_REG(4) +#define FW_FLASH_CHK FW_REG(5) -/* Values for FW_LINK_STATUS */ #define FW_LINK_OFF 0x0 #define FW_LINK_TX 0x1 /* 0x2 - link led on? */ +enum { + CR_BASE_OFFSET = 0x9000, + FW_START_OFFSET = 0xee00, + FW_BASE_ADDR_OFFSET = FW_START_OFFSET + 0x1d, + EEPROM_START_OFFSET = 0xf800, + EEPROM_SIZE = 0x800, /* words */ + LOAD_CODE_SIZE = 0xe, /* words */ + LOAD_VECT_SIZE = 0x10000 - 0xfff7, /* words */ + EEPROM_REGS_OFFSET = LOAD_CODE_SIZE + LOAD_VECT_SIZE, + EEPROM_REGS_SIZE = 0x7e, /* words */ + E2P_BASE_OFFSET = EEPROM_START_OFFSET + + EEPROM_REGS_OFFSET, +}; + +#define FW_REG_TABLE_ADDR USB_ADDR(FW_START_OFFSET + 0x1d) + enum { /* indices for ofdm_cal_values */ OFDM_36M_INDEX = 0, @@ -699,8 +679,6 @@ struct zd_chip { struct zd_usb usb; struct zd_rf rf; struct mutex mutex; - /* Base address of FW_REG_ registers */ - zd_addr_t fw_regs_base; u8 e2p_mac[ETH_ALEN]; /* EepSetPoint in the vendor driver */ u8 pwr_cal_values[E2P_CHANNEL_COUNT]; diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_def.h b/trunk/drivers/net/wireless/zd1211rw/zd_def.h index deb99d1eaa77..fb22f62cf1f3 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_def.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_def.h @@ -23,8 +23,6 @@ #include #include -typedef u16 __nocast zd_addr_t; - #define dev_printk_f(level, dev, fmt, args...) \ dev_printk(level, dev, "%s() " fmt, __func__, ##args) diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_ieee80211.h b/trunk/drivers/net/wireless/zd1211rw/zd_ieee80211.h index c4f36d39642b..26b8298dff8c 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_ieee80211.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_ieee80211.h @@ -2,6 +2,7 @@ #define _ZD_IEEE80211_H #include +#include "zd_types.h" /* Additional definitions from the standards. */ diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_rf.h b/trunk/drivers/net/wireless/zd1211rw/zd_rf.h index a57732eb69e1..676b3734f1ed 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_rf.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_rf.h @@ -18,6 +18,8 @@ #ifndef _ZD_RF_H #define _ZD_RF_H +#include "zd_types.h" + #define UW2451_RF 0x2 #define UCHIP_RF 0x3 #define AL2230_RF 0x4 diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_types.h b/trunk/drivers/net/wireless/zd1211rw/zd_types.h new file mode 100644 index 000000000000..0155a1584ed3 --- /dev/null +++ b/trunk/drivers/net/wireless/zd1211rw/zd_types.h @@ -0,0 +1,71 @@ +/* zd_types.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ZD_TYPES_H +#define _ZD_TYPES_H + +#include + +/* We have three register spaces mapped into the overall USB address space of + * 64K words (16-bit values). There is the control register space of + * double-word registers, the eeprom register space and the firmware register + * space. The control register space is byte mapped, the others are word + * mapped. + * + * For that reason, we are using byte offsets for control registers and word + * offsets for everything else. + */ + +typedef u32 __nocast zd_addr_t; + +enum { + ADDR_BASE_MASK = 0xff000000, + ADDR_OFFSET_MASK = 0x0000ffff, + ADDR_ZERO_MASK = 0x00ff0000, + NULL_BASE = 0x00000000, + USB_BASE = 0x01000000, + CR_BASE = 0x02000000, + CR_MAX_OFFSET = 0x0b30, + E2P_BASE = 0x03000000, + E2P_MAX_OFFSET = 0x007e, + FW_BASE = 0x04000000, + FW_MAX_OFFSET = 0x0005, +}; + +#define ZD_ADDR_BASE(addr) ((u32)(addr) & ADDR_BASE_MASK) +#define ZD_OFFSET(addr) ((u32)(addr) & ADDR_OFFSET_MASK) + +#define ZD_ADDR(base, offset) \ + ((zd_addr_t)(((base) & ADDR_BASE_MASK) | ((offset) & ADDR_OFFSET_MASK))) + +#define ZD_NULL_ADDR ((zd_addr_t)0) +#define USB_REG(offset) ZD_ADDR(USB_BASE, offset) /* word addressing */ +#define CTL_REG(offset) ZD_ADDR(CR_BASE, offset) /* byte addressing */ +#define E2P_REG(offset) ZD_ADDR(E2P_BASE, offset) /* word addressing */ +#define FW_REG(offset) ZD_ADDR(FW_BASE, offset) /* word addressing */ + +static inline zd_addr_t zd_inc_word(zd_addr_t addr) +{ + u32 base = ZD_ADDR_BASE(addr); + u32 offset = ZD_OFFSET(addr); + + offset += base == CR_BASE ? 2 : 1; + + return base | offset; +} + +#endif /* _ZD_TYPES_H */ diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c index 75ef55624d7f..605e96e74057 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c @@ -58,10 +58,6 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x050d, 0x705c), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x13b1, 0x0024), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0586, 0x340f), .driver_info = DEVICE_ZD1211B }, /* "Driverless" devices that need ejecting */ { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, {} @@ -77,6 +73,96 @@ MODULE_DEVICE_TABLE(usb, usb_ids); #define FW_ZD1211_PREFIX "zd1211/zd1211_" #define FW_ZD1211B_PREFIX "zd1211/zd1211b_" +/* register address handling */ + +#ifdef DEBUG +static int check_addr(struct zd_usb *usb, zd_addr_t addr) +{ + u32 base = ZD_ADDR_BASE(addr); + u32 offset = ZD_OFFSET(addr); + + if ((u32)addr & ADDR_ZERO_MASK) + goto invalid_address; + switch (base) { + case USB_BASE: + break; + case CR_BASE: + if (offset > CR_MAX_OFFSET) { + dev_dbg(zd_usb_dev(usb), + "CR offset %#010x larger than" + " CR_MAX_OFFSET %#10x\n", + offset, CR_MAX_OFFSET); + goto invalid_address; + } + if (offset & 1) { + dev_dbg(zd_usb_dev(usb), + "CR offset %#010x is not a multiple of 2\n", + offset); + goto invalid_address; + } + break; + case E2P_BASE: + if (offset > E2P_MAX_OFFSET) { + dev_dbg(zd_usb_dev(usb), + "E2P offset %#010x larger than" + " E2P_MAX_OFFSET %#010x\n", + offset, E2P_MAX_OFFSET); + goto invalid_address; + } + break; + case FW_BASE: + if (!usb->fw_base_offset) { + dev_dbg(zd_usb_dev(usb), + "ERROR: fw base offset has not been set\n"); + return -EAGAIN; + } + if (offset > FW_MAX_OFFSET) { + dev_dbg(zd_usb_dev(usb), + "FW offset %#10x is larger than" + " FW_MAX_OFFSET %#010x\n", + offset, FW_MAX_OFFSET); + goto invalid_address; + } + break; + default: + dev_dbg(zd_usb_dev(usb), + "address has unsupported base %#010x\n", addr); + goto invalid_address; + } + + return 0; +invalid_address: + dev_dbg(zd_usb_dev(usb), + "ERROR: invalid address: %#010x\n", addr); + return -EINVAL; +} +#endif /* DEBUG */ + +static u16 usb_addr(struct zd_usb *usb, zd_addr_t addr) +{ + u32 base; + u16 offset; + + base = ZD_ADDR_BASE(addr); + offset = ZD_OFFSET(addr); + + ZD_ASSERT(check_addr(usb, addr) == 0); + + switch (base) { + case CR_BASE: + offset += CR_BASE_OFFSET; + break; + case E2P_BASE: + offset += E2P_BASE_OFFSET; + break; + case FW_BASE: + offset += usb->fw_base_offset; + break; + } + + return offset; +} + /* USB device initialization */ static int request_fw_file( @@ -209,13 +295,14 @@ static int handle_version_mismatch(struct usb_device *udev, u8 device_type, if (r) goto error; - r = upload_code(udev, ur_fw->data, ur_fw->size, FW_START, REBOOT); + r = upload_code(udev, ur_fw->data, ur_fw->size, FW_START_OFFSET, + REBOOT); if (r) goto error; - offset = (E2P_BOOT_CODE_OFFSET * sizeof(u16)); + offset = ((EEPROM_REGS_OFFSET + EEPROM_REGS_SIZE) * sizeof(u16)); r = upload_code(udev, ub_fw->data + offset, ub_fw->size - offset, - E2P_START + E2P_BOOT_CODE_OFFSET, REBOOT); + E2P_BASE_OFFSET + EEPROM_REGS_SIZE, REBOOT); /* At this point, the vendor driver downloads the whole firmware * image, hacks around with version IDs, and uploads it again, @@ -244,7 +331,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type) if (r) goto error; - fw_bcdDevice = get_word(ub_fw->data, E2P_DATA_OFFSET); + fw_bcdDevice = get_word(ub_fw->data, EEPROM_REGS_OFFSET); if (fw_bcdDevice != bcdDevice) { dev_info(&udev->dev, @@ -270,7 +357,8 @@ static int upload_firmware(struct usb_device *udev, u8 device_type) if (r) goto error; - r = upload_code(udev, uph_fw->data, uph_fw->size, FW_START, REBOOT); + r = upload_code(udev, uph_fw->data, uph_fw->size, FW_START_OFFSET, + REBOOT); if (r) { dev_err(&udev->dev, "Could not upload firmware code uph. Error number %d\n", @@ -770,7 +858,7 @@ static inline void init_usb_interrupt(struct zd_usb *usb) spin_lock_init(&intr->lock); intr->interval = int_urb_interval(zd_usb_to_usbdev(usb)); init_completion(&intr->read_regs.completion); - intr->read_regs.cr_int_addr = cpu_to_le16((u16)CR_INTERRUPT); + intr->read_regs.cr_int_addr = cpu_to_le16(usb_addr(usb, CR_INTERRUPT)); } static inline void init_usb_rx(struct zd_usb *usb) @@ -802,6 +890,22 @@ void zd_usb_init(struct zd_usb *usb, struct net_device *netdev, init_usb_rx(usb); } +int zd_usb_init_hw(struct zd_usb *usb) +{ + int r; + struct zd_chip *chip = zd_usb_to_chip(usb); + + ZD_ASSERT(mutex_is_locked(&chip->mutex)); + r = zd_ioread16_locked(chip, &usb->fw_base_offset, + USB_REG((u16)FW_BASE_ADDR_OFFSET)); + if (r) + return r; + dev_dbg_f(zd_usb_dev(usb), "fw_base_offset: %#06hx\n", + usb->fw_base_offset); + + return 0; +} + void zd_usb_clear(struct zd_usb *usb) { usb_set_intfdata(usb->intf, NULL); @@ -1149,7 +1253,7 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, return -ENOMEM; req->id = cpu_to_le16(USB_REQ_READ_REGS); for (i = 0; i < count; i++) - req->addr[i] = cpu_to_le16((u16)addresses[i]); + req->addr[i] = cpu_to_le16(usb_addr(usb, addresses[i])); udev = zd_usb_to_usbdev(usb); prepare_read_regs_int(usb); @@ -1214,7 +1318,7 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, req->id = cpu_to_le16(USB_REQ_WRITE_REGS); for (i = 0; i < count; i++) { struct reg_data *rw = &req->reg_writes[i]; - rw->addr = cpu_to_le16((u16)ioreqs[i].addr); + rw->addr = cpu_to_le16(usb_addr(usb, ioreqs[i].addr)); rw->value = cpu_to_le16(ioreqs[i].value); } diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_usb.h b/trunk/drivers/net/wireless/zd1211rw/zd_usb.h index 506ea6a74393..317d37c36679 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_usb.h @@ -25,6 +25,7 @@ #include #include "zd_def.h" +#include "zd_types.h" enum devicetype { DEVICE_ZD1211 = 0, @@ -180,14 +181,15 @@ struct zd_usb_tx { spinlock_t lock; }; -/* Contains the usb parts. The structure doesn't require a lock because intf - * will not be changed after initialization. +/* Contains the usb parts. The structure doesn't require a lock, because intf + * and fw_base_offset, will not be changed after initialization. */ struct zd_usb { struct zd_usb_interrupt intr; struct zd_usb_rx rx; struct zd_usb_tx tx; struct usb_interface *intf; + u16 fw_base_offset; }; #define zd_usb_dev(usb) (&usb->intf->dev) diff --git a/trunk/drivers/pci/hotplug/Kconfig b/trunk/drivers/pci/hotplug/Kconfig index be92695a7833..adce4204d87d 100644 --- a/trunk/drivers/pci/hotplug/Kconfig +++ b/trunk/drivers/pci/hotplug/Kconfig @@ -145,6 +145,15 @@ config HOTPLUG_PCI_SHPC When in doubt, say N. +config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE + bool "Use polling mechanism for hot-plug events (for testing purpose)" + depends on HOTPLUG_PCI_SHPC + help + Say Y here if you want to use the polling mechanism for hot-plug + events for early platform testing. + + When in doubt, say N. + config HOTPLUG_PCI_RPA tristate "RPA PCI Hotplug driver" depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index fca978fb158e..bd1faebf61a0 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -773,13 +773,13 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base) goto out; table = obj->buffer.pointer; - switch (((struct acpi_subtable_header *)table)->type) { - case ACPI_MADT_TYPE_IO_SAPIC: - *gsi_base = ((struct acpi_madt_io_sapic *)table)->global_irq_base; + switch (((acpi_table_entry_header *)table)->type) { + case ACPI_MADT_IOSAPIC: + *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base; result = 0; break; - case ACPI_MADT_TYPE_IO_APIC: - *gsi_base = ((struct acpi_madt_io_apic *)table)->global_irq_base; + case ACPI_MADT_IOAPIC: + *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base; result = 0; break; default: diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index d19fcae8a7c0..4fb12fcda563 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -44,20 +44,15 @@ extern int pciehp_poll_time; extern int pciehp_debug; extern int pciehp_force; -#define dbg(format, arg...) \ - do { \ - if (pciehp_debug) \ - printk("%s: " format, MY_NAME , ## arg); \ - } while (0) -#define err(format, arg...) \ - printk(KERN_ERR "%s: " format, MY_NAME , ## arg) -#define info(format, arg...) \ - printk(KERN_INFO "%s: " format, MY_NAME , ## arg) -#define warn(format, arg...) \ - printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) +/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ +#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) +#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) +#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) +#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) + -#define SLOT_NAME_SIZE 10 struct slot { + struct slot *next; u8 bus; u8 device; u32 number; @@ -68,8 +63,6 @@ struct slot { struct hpc_ops *hpc_ops; struct hotplug_slot *hotplug_slot; struct list_head slot_list; - char name[SLOT_NAME_SIZE]; - unsigned long last_emi_toggle; }; struct event_info { @@ -77,15 +70,34 @@ struct event_info { u8 hp_slot; }; +typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id); + +struct php_ctlr_state_s { + struct php_ctlr_state_s *pnext; + struct pci_dev *pci_dev; + unsigned int irq; + unsigned long flags; /* spinlock's */ + u32 slot_device_offset; + u32 num_slots; + struct timer_list int_poll_timer; /* Added for poll event */ + php_intr_callback_t attention_button_callback; + php_intr_callback_t switch_change_callback; + php_intr_callback_t presence_change_callback; + php_intr_callback_t power_fault_callback; + void *callback_instance_id; + struct ctrl_reg *creg; /* Ptr to controller register space */ +}; + #define MAX_EVENTS 10 struct controller { struct controller *next; struct mutex crit_sect; /* critical section mutex */ struct mutex ctrl_lock; /* controller lock */ + struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; - struct list_head slot_list; + struct pci_bus *pci_bus; struct event_info event_queue[MAX_EVENTS]; struct slot *slot; struct hpc_ops *hpc_ops; @@ -100,8 +112,6 @@ struct controller { u8 ctrlcap; u16 vendor_id; u8 cap_base; - struct timer_list poll_timer; - volatile int cmd_busy; }; #define INT_BUTTON_IGNORE 0 @@ -121,6 +131,8 @@ struct controller { #define POWERON_STATE 3 #define POWEROFF_STATE 4 +#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400 + /* Error messages */ #define INTERLOCK_OPEN 0x00000002 #define ADD_NOT_SUPPORTED 0x00000003 @@ -132,6 +144,10 @@ struct controller { #define WRONG_BUS_FREQUENCY 0x0000000D #define POWER_FAILURE 0x0000000E +#define REMOVE_NOT_SUPPORTED 0x00000003 + +#define DISABLE_CARD 1 + /* Field definitions in Slot Capabilities Register */ #define ATTN_BUTTN_PRSN 0x00000001 #define PWR_CTRL_PRSN 0x00000002 @@ -139,7 +155,6 @@ struct controller { #define ATTN_LED_PRSN 0x00000008 #define PWR_LED_PRSN 0x00000010 #define HP_SUPR_RM_SUP 0x00000020 -#define EMI_PRSN 0x00020000 #define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN) #define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN) @@ -147,65 +162,130 @@ struct controller { #define ATTN_LED(cap) (cap & ATTN_LED_PRSN) #define PWR_LED(cap) (cap & PWR_LED_PRSN) #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) -#define EMI(cap) (cap & EMI_PRSN) - -extern int pciehp_event_start_thread(void); -extern void pciehp_event_stop_thread(void); -extern int pciehp_enable_slot(struct slot *slot); -extern int pciehp_disable_slot(struct slot *slot); -extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl); -extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl); -extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl); -extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl); -extern int pciehp_configure_device(struct slot *p_slot); -extern int pciehp_unconfigure_device(struct slot *p_slot); -int pcie_init(struct controller *ctrl, struct pcie_device *dev); + +/* + * error Messages + */ +#define msg_initialization_err "Initialization failure, error=%d\n" +#define msg_button_on "PCI slot #%s - powering on due to button press.\n" +#define msg_button_off "PCI slot #%s - powering off due to button press.\n" +#define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" +#define msg_button_ignore "PCI slot #%s - button press ignored. (action in progress...)\n" + +/* controller functions */ +extern int pciehp_event_start_thread (void); +extern void pciehp_event_stop_thread (void); +extern int pciehp_enable_slot (struct slot *slot); +extern int pciehp_disable_slot (struct slot *slot); + +extern u8 pciehp_handle_attention_button (u8 hp_slot, void *inst_id); +extern u8 pciehp_handle_switch_change (u8 hp_slot, void *inst_id); +extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id); +extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id); +/* extern void long_delay (int delay); */ + +/* pci functions */ +extern int pciehp_configure_device (struct slot *p_slot); +extern int pciehp_unconfigure_device (struct slot *p_slot); + + /* Global variables */ extern struct controller *pciehp_ctrl_list; +/* Inline functions */ + static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) { - struct slot *slot; + struct slot *p_slot, *tmp_slot = NULL; + + p_slot = ctrl->slot; - list_for_each_entry(slot, &ctrl->slot_list, slot_list) { - if (slot->device == device) - return slot; + while (p_slot && (p_slot->device != device)) { + tmp_slot = p_slot; + p_slot = p_slot->next; } + if (p_slot == NULL) { + err("ERROR: pciehp_find_slot device=0x%x\n", device); + p_slot = tmp_slot; + } + + return p_slot; +} + +static inline int wait_for_ctrl_irq(struct controller *ctrl) +{ + int retval = 0; + + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&ctrl->queue, &wait); + if (!pciehp_poll_mode) + /* Sleep for up to 1 second */ + msleep_interruptible(1000); + else + msleep_interruptible(2500); + + remove_wait_queue(&ctrl->queue, &wait); + if (signal_pending(current)) + retval = -EINTR; + + return retval; +} + +#define SLOT_NAME_SIZE 10 - err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); - return NULL; +static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) +{ + snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number); } +enum php_ctlr_type { + PCI, + ISA, + ACPI +}; + +int pcie_init(struct controller *ctrl, struct pcie_device *dev); + +/* This has no meaning for PCI Express, as there is only 1 slot per port */ +int pcie_get_ctlr_slot_config(struct controller *ctrl, + int *num_ctlr_slots, + int *first_device_num, + int *physical_slot_num, + u8 *ctrlcap); + struct hpc_ops { - int (*power_on_slot)(struct slot *slot); - int (*power_off_slot)(struct slot *slot); - int (*get_power_status)(struct slot *slot, u8 *status); - int (*get_attention_status)(struct slot *slot, u8 *status); - int (*set_attention_status)(struct slot *slot, u8 status); - int (*get_latch_status)(struct slot *slot, u8 *status); - int (*get_adapter_status)(struct slot *slot, u8 *status); - int (*get_emi_status)(struct slot *slot, u8 *status); - int (*toggle_emi)(struct slot *slot); - int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); - int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); - int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val); - int (*get_cur_lnk_width)(struct slot *slot, enum pcie_link_width *val); - int (*query_power_fault)(struct slot *slot); - void (*green_led_on)(struct slot *slot); - void (*green_led_off)(struct slot *slot); - void (*green_led_blink)(struct slot *slot); - void (*release_ctlr)(struct controller *ctrl); - int (*check_lnk_status)(struct controller *ctrl); + int (*power_on_slot) (struct slot *slot); + int (*power_off_slot) (struct slot *slot); + int (*get_power_status) (struct slot *slot, u8 *status); + int (*get_attention_status) (struct slot *slot, u8 *status); + int (*set_attention_status) (struct slot *slot, u8 status); + int (*get_latch_status) (struct slot *slot, u8 *status); + int (*get_adapter_status) (struct slot *slot, u8 *status); + + int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); + int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); + + int (*get_max_lnk_width) (struct slot *slot, enum pcie_link_width *value); + int (*get_cur_lnk_width) (struct slot *slot, enum pcie_link_width *value); + + int (*query_power_fault) (struct slot *slot); + void (*green_led_on) (struct slot *slot); + void (*green_led_off) (struct slot *slot); + void (*green_led_blink) (struct slot *slot); + void (*release_ctlr) (struct controller *ctrl); + int (*check_lnk_status) (struct controller *ctrl); }; + #ifdef CONFIG_ACPI #include #include #include #include -#define pciehp_get_hp_hw_control_from_firmware(dev) \ +#define pciehp_get_hp_hw_control_from_firmware(dev) \ pciehp_acpi_get_hp_hw_control_from_firmware(dev) static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, struct hotplug_params *hpp) diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index a92eda6e02f6..f13f31323e85 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -34,7 +34,6 @@ #include #include "pciehp.h" #include -#include /* Global variables */ int pciehp_debug; @@ -88,95 +87,6 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { .get_cur_bus_speed = get_cur_bus_speed, }; -/* - * Check the status of the Electro Mechanical Interlock (EMI) - */ -static int get_lock_status(struct hotplug_slot *hotplug_slot, u8 *value) -{ - struct slot *slot = hotplug_slot->private; - return (slot->hpc_ops->get_emi_status(slot, value)); -} - -/* - * sysfs interface for the Electro Mechanical Interlock (EMI) - * 1 == locked, 0 == unlocked - */ -static ssize_t lock_read_file(struct hotplug_slot *slot, char *buf) -{ - int retval; - u8 value; - - retval = get_lock_status(slot, &value); - if (retval) - goto lock_read_exit; - retval = sprintf (buf, "%d\n", value); - -lock_read_exit: - return retval; -} - -/* - * Change the status of the Electro Mechanical Interlock (EMI) - * This is a toggle - in addition there must be at least 1 second - * in between toggles. - */ -static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status) -{ - struct slot *slot = hotplug_slot->private; - int retval; - u8 value; - - mutex_lock(&slot->ctrl->crit_sect); - - /* has it been >1 sec since our last toggle? */ - if ((get_seconds() - slot->last_emi_toggle) < 1) - return -EINVAL; - - /* see what our current state is */ - retval = get_lock_status(hotplug_slot, &value); - if (retval || (value == status)) - goto set_lock_exit; - - slot->hpc_ops->toggle_emi(slot); -set_lock_exit: - mutex_unlock(&slot->ctrl->crit_sect); - return 0; -} - -/* - * sysfs interface which allows the user to toggle the Electro Mechanical - * Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock - */ -static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf, - size_t count) -{ - unsigned long llock; - u8 lock; - int retval = 0; - - llock = simple_strtoul(buf, NULL, 10); - lock = (u8)(llock & 0xff); - - switch (lock) { - case 0: - case 1: - retval = set_lock_status(slot, lock); - break; - default: - err ("%d is an invalid lock value\n", lock); - retval = -EINVAL; - } - if (retval) - return retval; - return count; -} - -static struct hotplug_slot_attribute hotplug_slot_attr_lock = { - .attr = {.name = "lock", .mode = S_IFREG | S_IRUGO | S_IWUSR}, - .show = lock_read_file, - .store = lock_write_file -}; - /** * release_slot - free up the memory used by a slot * @hotplug_slot: slot to free @@ -188,108 +98,148 @@ static void release_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); kfree(slot); } -static void make_slot_name(struct slot *slot) -{ - snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d", - slot->bus, slot->number); -} - static int init_slots(struct controller *ctrl) { struct slot *slot; + struct hpc_ops *hpc_ops; struct hotplug_slot *hotplug_slot; - struct hotplug_slot_info *info; - int retval = -ENOMEM; - int i; + struct hotplug_slot_info *hotplug_slot_info; + u8 number_of_slots; + u8 slot_device; + u32 slot_number; + int result = -ENOMEM; - for (i = 0; i < ctrl->num_slots; i++) { + number_of_slots = ctrl->num_slots; + slot_device = ctrl->slot_device_offset; + slot_number = ctrl->first_slot; + + while (number_of_slots) { slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) goto error; - hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); - if (!hotplug_slot) + slot->hotplug_slot = + kzalloc(sizeof(*(slot->hotplug_slot)), + GFP_KERNEL); + if (!slot->hotplug_slot) goto error_slot; - slot->hotplug_slot = hotplug_slot; + hotplug_slot = slot->hotplug_slot; - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) + hotplug_slot->info = + kzalloc(sizeof(*(hotplug_slot->info)), + GFP_KERNEL); + if (!hotplug_slot->info) goto error_hpslot; - hotplug_slot->info = info; - - hotplug_slot->name = slot->name; + hotplug_slot_info = hotplug_slot->info; + hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); + if (!hotplug_slot->name) + goto error_info; - slot->hp_slot = i; slot->ctrl = ctrl; - slot->bus = ctrl->pci_dev->subordinate->number; - slot->device = ctrl->slot_device_offset + i; - slot->hpc_ops = ctrl->hpc_ops; + slot->bus = ctrl->slot_bus; + slot->device = slot_device; + slot->hpc_ops = hpc_ops = ctrl->hpc_ops; + slot->number = ctrl->first_slot; + slot->hp_slot = slot_device - ctrl->slot_device_offset; /* register this slot with the hotplug pci core */ hotplug_slot->private = slot; hotplug_slot->release = &release_slot; - make_slot_name(slot); + make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot); hotplug_slot->ops = &pciehp_hotplug_slot_ops; - get_power_status(hotplug_slot, &info->power_status); - get_attention_status(hotplug_slot, &info->attention_status); - get_latch_status(hotplug_slot, &info->latch_status); - get_adapter_status(hotplug_slot, &info->adapter_status); + hpc_ops->get_power_status(slot, + &(hotplug_slot_info->power_status)); + hpc_ops->get_attention_status(slot, + &(hotplug_slot_info->attention_status)); + hpc_ops->get_latch_status(slot, + &(hotplug_slot_info->latch_status)); + hpc_ops->get_adapter_status(slot, + &(hotplug_slot_info->adapter_status)); dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " - "slot_device_offset=%x\n", slot->bus, slot->device, - slot->hp_slot, slot->number, ctrl->slot_device_offset); - retval = pci_hp_register(hotplug_slot); - if (retval) { - err ("pci_hp_register failed with error %d\n", retval); - goto error_info; - } - /* create additional sysfs entries */ - if (EMI(ctrl->ctrlcap)) { - retval = sysfs_create_file(&hotplug_slot->kobj, - &hotplug_slot_attr_lock.attr); - if (retval) { - pci_hp_deregister(hotplug_slot); - err("cannot create additional sysfs entries\n"); - goto error_info; - } + "slot_device_offset=%x\n", + slot->bus, slot->device, slot->hp_slot, slot->number, + ctrl->slot_device_offset); + result = pci_hp_register(hotplug_slot); + if (result) { + err ("pci_hp_register failed with error %d\n", result); + goto error_name; } - list_add(&slot->slot_list, &ctrl->slot_list); + slot->next = ctrl->slot; + ctrl->slot = slot; + + number_of_slots--; + slot_device++; + slot_number += ctrl->slot_num_inc; } return 0; + +error_name: + kfree(hotplug_slot->name); error_info: - kfree(info); + kfree(hotplug_slot_info); error_hpslot: kfree(hotplug_slot); error_slot: kfree(slot); error: - return retval; + return result; } -static void cleanup_slots(struct controller *ctrl) + +static int cleanup_slots (struct controller * ctrl) { - struct list_head *tmp; - struct list_head *next; - struct slot *slot; + struct slot *old_slot, *next_slot; + + old_slot = ctrl->slot; + ctrl->slot = NULL; - list_for_each_safe(tmp, next, &ctrl->slot_list) { - slot = list_entry(tmp, struct slot, slot_list); - list_del(&slot->slot_list); - if (EMI(ctrl->ctrlcap)) - sysfs_remove_file(&slot->hotplug_slot->kobj, - &hotplug_slot_attr_lock.attr); - pci_hp_deregister(slot->hotplug_slot); + while (old_slot) { + next_slot = old_slot->next; + pci_hp_deregister (old_slot->hotplug_slot); + old_slot = next_slot; } + + + return(0); } +static int get_ctlr_slot_config(struct controller *ctrl) +{ + int num_ctlr_slots; /* Not needed; PCI Express has 1 slot per port*/ + int first_device_num; /* Not needed */ + int physical_slot_num; + u8 ctrlcap; + int rc; + + rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &ctrlcap); + if (rc) { + err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device); + return (-1); + } + + ctrl->num_slots = num_ctlr_slots; /* PCI Express has 1 slot per port */ + ctrl->slot_device_offset = first_device_num; + ctrl->first_slot = physical_slot_num; + ctrl->ctrlcap = ctrlcap; + + dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) ctrlcap(%x) for b:d (%x:%x)\n", + __FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, ctrlcap, + ctrl->bus, ctrl->device); + + return (0); +} + + /* * set_attention_status - Turns the Amber LED for a slot on, off or blink */ @@ -428,6 +378,8 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ int rc; struct controller *ctrl; struct slot *t_slot; + int first_device_num = 0 ; /* first PCI device number supported by this PCIE */ + int num_ctlr_slots; /* number of slots supported by this HPC */ u8 value; struct pci_dev *pdev; @@ -436,7 +388,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ err("%s : out of memory\n", __FUNCTION__); goto err_out_none; } - INIT_LIST_HEAD(&ctrl->slot_list); pdev = dev->port; ctrl->pci_dev = pdev; @@ -449,6 +400,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ pci_set_drvdata(pdev, ctrl); + ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); + if (!ctrl->pci_bus) { + err("%s: out of memory\n", __FUNCTION__); + rc = -ENOMEM; + goto err_out_unmap_mmio_region; + } + memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); ctrl->bus = pdev->bus->number; /* ctrl bus */ ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ @@ -457,14 +415,26 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__, ctrl->bus, ctrl->device, ctrl->function, pdev->irq); + /* + * Save configuration headers for this and subordinate PCI buses + */ + + rc = get_ctlr_slot_config(ctrl); + if (rc) { + err(msg_initialization_err, rc); + goto err_out_free_ctrl_bus; + } + first_device_num = ctrl->slot_device_offset; + num_ctlr_slots = ctrl->num_slots; + /* Setup the slot information structures */ rc = init_slots(ctrl); if (rc) { - err("%s: slot initialization failed\n", PCIE_MODULE_NAME); - goto err_out_release_ctlr; + err(msg_initialization_err, 6); + goto err_out_free_ctrl_slot; } - t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); + t_slot = pciehp_find_slot(ctrl, first_device_num); /* Finish setting up the hot plug ctrl device */ ctrl->next_event = 0; @@ -477,18 +447,32 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ pciehp_ctrl_list = ctrl; } + /* Wait for exclusive access to hardware */ + mutex_lock(&ctrl->ctrl_lock); + t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ + if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ - if (rc) + if (rc) { + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); goto err_out_free_ctrl_slot; + } else + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); } + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); + return 0; err_out_free_ctrl_slot: cleanup_slots(ctrl); -err_out_release_ctlr: +err_out_free_ctrl_bus: + kfree(ctrl->pci_bus); +err_out_unmap_mmio_region: ctrl->hpc_ops->release_ctlr(ctrl); err_out_free_ctrl: kfree(ctrl); @@ -522,6 +506,8 @@ static void __exit unload_pciehpd(void) while (ctrl) { cleanup_slots(ctrl); + kfree (ctrl->pci_bus); + ctrl->hpc_ops->release_ctlr(ctrl); tctrl = ctrl; diff --git a/trunk/drivers/pci/hotplug/pciehp_ctrl.c b/trunk/drivers/pci/hotplug/pciehp_ctrl.c index 4283ef56dbd9..372c63e35aa9 100644 --- a/trunk/drivers/pci/hotplug/pciehp_ctrl.c +++ b/trunk/drivers/pci/hotplug/pciehp_ctrl.c @@ -48,8 +48,9 @@ static inline char *slot_name(struct slot *p_slot) return p_slot->hotplug_slot->name; } -u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl) +u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) { + struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 rc = 0; u8 getstatus; @@ -100,8 +101,9 @@ u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl) } -u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) +u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id) { + struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 rc = 0; u8 getstatus; @@ -141,8 +143,9 @@ u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) return rc; } -u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) +u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id) { + struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 presence_save, rc = 0; struct event_info *taskInfo; @@ -184,8 +187,9 @@ u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) return rc; } -u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) +u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) { + struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 rc = 0; struct event_info *taskInfo; @@ -229,25 +233,35 @@ u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) static void set_slot_off(struct controller *ctrl, struct slot * pslot) { + /* Wait for exclusive access to hardware */ + mutex_lock(&ctrl->ctrl_lock); + /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ if (POWER_CTRL(ctrl->ctrlcap)) { if (pslot->hpc_ops->power_off_slot(pslot)) { - err("%s: Issue of Slot Power Off command failed\n", - __FUNCTION__); + err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); + mutex_unlock(&ctrl->ctrl_lock); return; } + wait_for_ctrl_irq (ctrl); } - if (PWR_LED(ctrl->ctrlcap)) + if (PWR_LED(ctrl->ctrlcap)) { pslot->hpc_ops->green_led_off(pslot); + wait_for_ctrl_irq (ctrl); + } - if (ATTN_LED(ctrl->ctrlcap)) { - if (pslot->hpc_ops->set_attention_status(pslot, 1)) { - err("%s: Issue of Set Attention Led command failed\n", - __FUNCTION__); + if (ATTN_LED(ctrl->ctrlcap)) { + if (pslot->hpc_ops->set_attention_status(pslot, 1)) { + err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); + mutex_unlock(&ctrl->ctrl_lock); return; } + wait_for_ctrl_irq (ctrl); } + + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); } /** @@ -260,7 +274,7 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) static int board_added(struct slot *p_slot) { u8 hp_slot; - int retval = 0; + int rc = 0; struct controller *ctrl = p_slot->ctrl; hp_slot = p_slot->device - ctrl->slot_device_offset; @@ -269,38 +283,53 @@ static int board_added(struct slot *p_slot) __FUNCTION__, p_slot->device, ctrl->slot_device_offset, hp_slot); + /* Wait for exclusive access to hardware */ + mutex_lock(&ctrl->ctrl_lock); + if (POWER_CTRL(ctrl->ctrlcap)) { /* Power on slot */ - retval = p_slot->hpc_ops->power_on_slot(p_slot); - if (retval) - return retval; + rc = p_slot->hpc_ops->power_on_slot(p_slot); + if (rc) { + mutex_unlock(&ctrl->ctrl_lock); + return -1; + } + + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); } - if (PWR_LED(ctrl->ctrlcap)) + if (PWR_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->green_led_blink(p_slot); + + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + } + + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); /* Wait for ~1 second */ - msleep(1000); + wait_for_ctrl_irq (ctrl); - /* Check link training status */ - retval = p_slot->hpc_ops->check_lnk_status(ctrl); - if (retval) { + /* Check link training status */ + rc = p_slot->hpc_ops->check_lnk_status(ctrl); + if (rc) { err("%s: Failed to check link status\n", __FUNCTION__); set_slot_off(ctrl, p_slot); - return retval; + return rc; } /* Check for a power fault */ if (p_slot->hpc_ops->query_power_fault(p_slot)) { dbg("%s: power fault detected\n", __FUNCTION__); - retval = POWER_FAILURE; + rc = POWER_FAILURE; goto err_exit; } - retval = pciehp_configure_device(p_slot); - if (retval) { + rc = pciehp_configure_device(p_slot); + if (rc) { err("Cannot add device 0x%x:%x\n", p_slot->bus, - p_slot->device); + p_slot->device); goto err_exit; } @@ -309,16 +338,26 @@ static int board_added(struct slot *p_slot) */ if (pcie_mch_quirk) pci_fixup_device(pci_fixup_final, ctrl->pci_dev); - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_on(p_slot); + if (PWR_LED(ctrl->ctrlcap)) { + /* Wait for exclusive access to hardware */ + mutex_lock(&ctrl->ctrl_lock); + p_slot->hpc_ops->green_led_on(p_slot); + + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); + } return 0; err_exit: set_slot_off(ctrl, p_slot); - return retval; + return -1; } + /** * remove_board - Turns off slot and LED's * @@ -327,32 +366,44 @@ static int remove_board(struct slot *p_slot) { u8 device; u8 hp_slot; - int retval = 0; + int rc; struct controller *ctrl = p_slot->ctrl; - retval = pciehp_unconfigure_device(p_slot); - if (retval) - return retval; + if (pciehp_unconfigure_device(p_slot)) + return 1; device = p_slot->device; + hp_slot = p_slot->device - ctrl->slot_device_offset; p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); + /* Wait for exclusive access to hardware */ + mutex_lock(&ctrl->ctrl_lock); + if (POWER_CTRL(ctrl->ctrlcap)) { /* power off slot */ - retval = p_slot->hpc_ops->power_off_slot(p_slot); - if (retval) { - err("%s: Issue of Slot Disable command failed\n", - __FUNCTION__); - return retval; + rc = p_slot->hpc_ops->power_off_slot(p_slot); + if (rc) { + err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); + mutex_unlock(&ctrl->ctrl_lock); + return rc; } + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); } - if (PWR_LED(ctrl->ctrlcap)) + if (PWR_LED(ctrl->ctrlcap)) { /* turn off Green LED */ p_slot->hpc_ops->green_led_off(p_slot); + + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + } + + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); return 0; } @@ -397,10 +448,18 @@ static void pciehp_pushbutton_thread(unsigned long slot) dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, p_slot->bus, p_slot->device); - if (pciehp_enable_slot(p_slot) && - PWR_LED(p_slot->ctrl->ctrlcap)) + if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { + /* Wait for exclusive access to hardware */ + mutex_lock(&p_slot->ctrl->ctrl_lock); + p_slot->hpc_ops->green_led_off(p_slot); + /* Wait for the command to complete */ + wait_for_ctrl_irq (p_slot->ctrl); + + /* Done with exclusive hardware access */ + mutex_unlock(&p_slot->ctrl->ctrl_lock); + } p_slot->state = STATIC_STATE; } @@ -439,10 +498,18 @@ static void pciehp_surprise_rm_thread(unsigned long slot) dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, p_slot->bus, p_slot->device); - if (pciehp_enable_slot(p_slot) && - PWR_LED(p_slot->ctrl->ctrlcap)) + if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { + /* Wait for exclusive access to hardware */ + mutex_lock(&p_slot->ctrl->ctrl_lock); + p_slot->hpc_ops->green_led_off(p_slot); + /* Wait for the command to complete */ + wait_for_ctrl_irq (p_slot->ctrl); + + /* Done with exclusive hardware access */ + mutex_unlock(&p_slot->ctrl->ctrl_lock); + } p_slot->state = STATIC_STATE; } @@ -553,24 +620,46 @@ static void interrupt_event_handler(struct controller *ctrl) switch (p_slot->state) { case BLINKINGOFF_STATE: - if (PWR_LED(ctrl->ctrlcap)) + /* Wait for exclusive access to hardware */ + mutex_lock(&ctrl->ctrl_lock); + + if (PWR_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->green_led_on(p_slot); - - if (ATTN_LED(ctrl->ctrlcap)) + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + } + if (ATTN_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->set_attention_status(p_slot, 0); + + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + } + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); break; case BLINKINGON_STATE: - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_off(p_slot); + /* Wait for exclusive access to hardware */ + mutex_lock(&ctrl->ctrl_lock); - if (ATTN_LED(ctrl->ctrlcap)) + if (PWR_LED(ctrl->ctrlcap)) { + p_slot->hpc_ops->green_led_off(p_slot); + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + } + if (ATTN_LED(ctrl->ctrlcap)){ p_slot->hpc_ops->set_attention_status(p_slot, 0); + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + } + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); + break; default: warn("Not a valid state\n"); return; } - info("PCI slot #%s - action canceled due to button press.\n", slot_name(p_slot)); + info(msg_button_cancel, slot_name(p_slot)); p_slot->state = STATIC_STATE; } /* ***********Button Pressed (No action on 1st press...) */ @@ -583,21 +672,34 @@ static void interrupt_event_handler(struct controller *ctrl) /* slot is on */ dbg("slot is on\n"); p_slot->state = BLINKINGOFF_STATE; - info("PCI slot #%s - powering off due to button press.\n", slot_name(p_slot)); + info(msg_button_off, slot_name(p_slot)); } else { /* slot is off */ dbg("slot is off\n"); p_slot->state = BLINKINGON_STATE; - info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot)); + info(msg_button_on, slot_name(p_slot)); } + /* Wait for exclusive access to hardware */ + mutex_lock(&ctrl->ctrl_lock); + /* blink green LED and turn off amber */ - if (PWR_LED(ctrl->ctrlcap)) + if (PWR_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->green_led_blink(p_slot); + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + } - if (ATTN_LED(ctrl->ctrlcap)) + if (ATTN_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->set_attention_status(p_slot, 0); + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + } + + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); + init_timer(&p_slot->task_event); p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; @@ -610,11 +712,21 @@ static void interrupt_event_handler(struct controller *ctrl) else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { if (POWER_CTRL(ctrl->ctrlcap)) { dbg("power fault\n"); - if (ATTN_LED(ctrl->ctrlcap)) + /* Wait for exclusive access to hardware */ + mutex_lock(&ctrl->ctrl_lock); + + if (ATTN_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->set_attention_status(p_slot, 1); + wait_for_ctrl_irq (ctrl); + } - if (PWR_LED(ctrl->ctrlcap)) + if (PWR_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->green_led_off(p_slot); + wait_for_ctrl_irq (ctrl); + } + + /* Done with exclusive hardware access */ + mutex_unlock(&ctrl->ctrl_lock); } } /***********SURPRISE REMOVAL********************/ @@ -642,6 +754,7 @@ static void interrupt_event_handler(struct controller *ctrl) } } + int pciehp_enable_slot(struct slot *p_slot) { u8 getstatus = 0; diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index fbc64aa2dd68..25d3aadfddbf 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -35,7 +35,6 @@ #include #include #include -#include #include "../pci.h" #include "pciehp.h" @@ -106,30 +105,34 @@ enum ctrl_offsets { ROOTCTRL = offsetof(struct ctrl_reg, root_ctrl), ROOTSTATUS = offsetof(struct ctrl_reg, root_status), }; - -static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) -{ - struct pci_dev *dev = ctrl->pci_dev; - return pci_read_config_word(dev, ctrl->cap_base + reg, value); -} - -static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) -{ - struct pci_dev *dev = ctrl->pci_dev; - return pci_read_config_dword(dev, ctrl->cap_base + reg, value); -} - -static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) -{ - struct pci_dev *dev = ctrl->pci_dev; - return pci_write_config_word(dev, ctrl->cap_base + reg, value); -} - -static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) -{ - struct pci_dev *dev = ctrl->pci_dev; - return pci_write_config_dword(dev, ctrl->cap_base + reg, value); -} +static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ + +#define PCIE_CAP_ID(cb) ( cb + PCIECAPID ) +#define NXT_CAP_PTR(cb) ( cb + NXTCAPPTR ) +#define CAP_REG(cb) ( cb + CAPREG ) +#define DEV_CAP(cb) ( cb + DEVCAP ) +#define DEV_CTRL(cb) ( cb + DEVCTRL ) +#define DEV_STATUS(cb) ( cb + DEVSTATUS ) +#define LNK_CAP(cb) ( cb + LNKCAP ) +#define LNK_CTRL(cb) ( cb + LNKCTRL ) +#define LNK_STATUS(cb) ( cb + LNKSTATUS ) +#define SLOT_CAP(cb) ( cb + SLOTCAP ) +#define SLOT_CTRL(cb) ( cb + SLOTCTRL ) +#define SLOT_STATUS(cb) ( cb + SLOTSTATUS ) +#define ROOT_CTRL(cb) ( cb + ROOTCTRL ) +#define ROOT_STATUS(cb) ( cb + ROOTSTATUS ) + +#define hp_register_read_word(pdev, reg , value) \ + pci_read_config_word(pdev, reg, &value) + +#define hp_register_read_dword(pdev, reg , value) \ + pci_read_config_dword(pdev, reg, &value) + +#define hp_register_write_word(pdev, reg , value) \ + pci_write_config_word(pdev, reg, value) + +#define hp_register_dwrite_word(pdev, reg , value) \ + pci_write_config_dword(pdev, reg, value) /* Field definitions in PCI Express Capabilities Register */ #define CAP_VER 0x000F @@ -193,7 +196,6 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) #define ATTN_LED_CTRL 0x00C0 #define PWR_LED_CTRL 0x0300 #define PWR_CTRL 0x0400 -#define EMI_CTRL 0x0800 /* Attention indicator and Power indicator states */ #define LED_ON 0x01 @@ -204,10 +206,6 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) #define POWER_ON 0 #define POWER_OFF 0x0400 -/* EMI Status defines */ -#define EMI_DISENGAGED 0 -#define EMI_ENGAGED 1 - /* Field definitions in Slot Status Register */ #define ATTN_BUTTN_PRESSED 0x0001 #define PWR_FAULT_DETECTED 0x0002 @@ -216,117 +214,114 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) #define CMD_COMPLETED 0x0010 #define MRL_STATE 0x0020 #define PRSN_STATE 0x0040 -#define EMI_STATE 0x0080 -#define EMI_STATUS_BIT 7 static spinlock_t hpc_event_lock; DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ +static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ static int ctlr_seq_num = 0; /* Controller sequence # */ +static spinlock_t list_lock; + +static irqreturn_t pcie_isr(int IRQ, void *dev_id); -static irqreturn_t pcie_isr(int irq, void *dev_id); -static void start_int_poll_timer(struct controller *ctrl, int sec); +static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); /* This is the interrupt polling timeout function. */ -static void int_poll_timeout(unsigned long data) +static void int_poll_timeout(unsigned long lphp_ctlr) { - struct controller *ctrl = (struct controller *)data; + struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr; DBG_ENTER_ROUTINE + if ( !php_ctlr ) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return; + } + /* Poll for interrupt events. regs == NULL => polling */ - pcie_isr(0, ctrl); + pcie_isr( 0, (void *)php_ctlr ); + + init_timer(&php_ctlr->int_poll_timer); - init_timer(&ctrl->poll_timer); if (!pciehp_poll_time) pciehp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/ - start_int_poll_timer(ctrl, pciehp_poll_time); + start_int_poll_timer(php_ctlr, pciehp_poll_time); + + return; } /* This function starts the interrupt polling timer. */ -static void start_int_poll_timer(struct controller *ctrl, int sec) +static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds) { - /* Clamp to sane value */ - if ((sec <= 0) || (sec > 60)) - sec = 2; - - ctrl->poll_timer.function = &int_poll_timeout; - ctrl->poll_timer.data = (unsigned long)ctrl; - ctrl->poll_timer.expires = jiffies + sec * HZ; - add_timer(&ctrl->poll_timer); -} + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return; + } -static inline int pcie_wait_cmd(struct controller *ctrl) -{ - int retval = 0; - unsigned int msecs = pciehp_poll_mode ? 2500 : 1000; - unsigned long timeout = msecs_to_jiffies(msecs); - int rc; + if ( ( seconds <= 0 ) || ( seconds > 60 ) ) + seconds = 2; /* Clamp to sane value */ - rc = wait_event_interruptible_timeout(ctrl->queue, - !ctrl->cmd_busy, timeout); - if (!rc) - dbg("Command not completed in 1000 msec\n"); - else if (rc < 0) { - retval = -EINTR; - info("Command was interrupted by a signal\n"); - } + php_ctlr->int_poll_timer.function = &int_poll_timeout; + php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */ + php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ; + add_timer(&php_ctlr->int_poll_timer); - return retval; + return; } static int pcie_write_cmd(struct slot *slot, u16 cmd) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; int retval = 0; u16 slot_status; DBG_ENTER_ROUTINE - - mutex_lock(&ctrl->ctrl_lock); - - retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); - if (retval) { - err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); - goto out; + + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; } + retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); + if (retval) { + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + return retval; + } + if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { - /* After 1 sec and CMD_COMPLETED still not set, just - proceed forward to issue the next command according - to spec. Just print out the error message */ - dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", - __FUNCTION__); + /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue + the next command according to spec. Just print out the error message */ + dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); } - ctrl->cmd_busy = 1; - retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); + retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); if (retval) { - err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); - goto out; + err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); + return retval; } - /* - * Wait for command completion. - */ - retval = pcie_wait_cmd(ctrl); - out: - mutex_unlock(&ctrl->ctrl_lock); DBG_LEAVE_ROUTINE return retval; } static int hpc_check_lnk_status(struct controller *ctrl) { + struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; u16 lnk_status; int retval = 0; DBG_ENTER_ROUTINE - retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); + if (retval) { - err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__); + err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); return retval; } @@ -345,21 +340,26 @@ static int hpc_check_lnk_status(struct controller *ctrl) static int hpc_get_attention_status(struct slot *slot, u8 *status) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_ctrl; u8 atten_led_state; int retval = 0; DBG_ENTER_ROUTINE - retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); + if (retval) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return retval; } - dbg("%s: SLOTCTRL %x, value read %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); + dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; @@ -385,22 +385,27 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) return 0; } -static int hpc_get_power_status(struct slot *slot, u8 *status) +static int hpc_get_power_status(struct slot * slot, u8 *status) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_ctrl; u8 pwr_state; int retval = 0; DBG_ENTER_ROUTINE - retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); + if (retval) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return retval; } - dbg("%s: SLOTCTRL %x value read %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); + dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); pwr_state = (slot_ctrl & PWR_CTRL) >> 10; @@ -423,15 +428,21 @@ static int hpc_get_power_status(struct slot *slot, u8 *status) static int hpc_get_latch_status(struct slot *slot, u8 *status) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_status; int retval = 0; DBG_ENTER_ROUTINE - retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); + if (retval) { - err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return retval; } @@ -443,16 +454,22 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) static int hpc_get_adapter_status(struct slot *slot, u8 *status) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_status; u8 card_state; int retval = 0; DBG_ENTER_ROUTINE - retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); + if (retval) { - err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return retval; } card_state = (u8)((slot_status & PRSN_STATE) >> 6); @@ -462,83 +479,54 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) return 0; } -static int hpc_query_power_fault(struct slot *slot) +static int hpc_query_power_fault(struct slot * slot) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_status; u8 pwr_fault; int retval = 0; DBG_ENTER_ROUTINE - retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); - if (retval) { - err("%s: Cannot check for power fault\n", __FUNCTION__); - return retval; + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; } - pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); - - DBG_LEAVE_ROUTINE - return pwr_fault; -} -static int hpc_get_emi_status(struct slot *slot, u8 *status) -{ - struct controller *ctrl = slot->ctrl; - u16 slot_status; - int retval = 0; + retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); - DBG_ENTER_ROUTINE - - retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s : Cannot check EMI status\n", __FUNCTION__); + err("%s : Cannot check for power fault\n", __FUNCTION__); return retval; } - *status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT; - + pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); + DBG_LEAVE_ROUTINE - return retval; + return pwr_fault; } -static int hpc_toggle_emi(struct slot *slot) +static int hpc_set_attention_status(struct slot *slot, u8 value) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_cmd = 0; u16 slot_ctrl; int rc = 0; DBG_ENTER_ROUTINE - rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); - if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", - __FUNCTION__); - return rc; + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; } - slot_cmd = (slot_ctrl | EMI_CTRL); - if (!pciehp_poll_mode) - slot_cmd = slot_cmd | HP_INTR_ENABLE; - - pcie_write_cmd(slot, slot_cmd); - slot->last_emi_toggle = get_seconds(); - DBG_LEAVE_ROUTINE - return rc; -} - -static int hpc_set_attention_status(struct slot *slot, u8 value) -{ - struct controller *ctrl = slot->ctrl; - u16 slot_cmd = 0; - u16 slot_ctrl; - int rc = 0; - - DBG_ENTER_ROUTINE + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); - rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (rc) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return rc; } @@ -559,8 +547,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) slot_cmd = slot_cmd | HP_INTR_ENABLE; pcie_write_cmd(slot, slot_cmd); - dbg("%s: SLOTCTRL %x write cmd %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); + dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); DBG_LEAVE_ROUTINE return rc; @@ -569,16 +556,27 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) static void hpc_set_green_led_on(struct slot *slot) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_cmd; u16 slot_ctrl; int rc = 0; DBG_ENTER_ROUTINE - rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return ; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return ; + } + + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); + if (rc) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return; } slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100; @@ -587,24 +585,34 @@ static void hpc_set_green_led_on(struct slot *slot) pcie_write_cmd(slot, slot_cmd); - dbg("%s: SLOTCTRL %x write cmd %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); + dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); DBG_LEAVE_ROUTINE return; } static void hpc_set_green_led_off(struct slot *slot) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_cmd; u16 slot_ctrl; int rc = 0; DBG_ENTER_ROUTINE - rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return ; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return ; + } + + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); + if (rc) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return; } @@ -613,8 +621,7 @@ static void hpc_set_green_led_off(struct slot *slot) if (!pciehp_poll_mode) slot_cmd = slot_cmd | HP_INTR_ENABLE; pcie_write_cmd(slot, slot_cmd); - dbg("%s: SLOTCTRL %x write cmd %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); + dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); DBG_LEAVE_ROUTINE return; @@ -622,16 +629,27 @@ static void hpc_set_green_led_off(struct slot *slot) static void hpc_set_green_led_blink(struct slot *slot) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_cmd; u16 slot_ctrl; int rc = 0; DBG_ENTER_ROUTINE - rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return ; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return ; + } + + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); + if (rc) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return; } @@ -641,54 +659,126 @@ static void hpc_set_green_led_blink(struct slot *slot) slot_cmd = slot_cmd | HP_INTR_ENABLE; pcie_write_cmd(slot, slot_cmd); - dbg("%s: SLOTCTRL %x write cmd %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); + dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); DBG_LEAVE_ROUTINE return; } +int pcie_get_ctlr_slot_config(struct controller *ctrl, + int *num_ctlr_slots, /* number of slots in this HPC; only 1 in PCIE */ + int *first_device_num, /* PCI dev num of the first slot in this PCIE */ + int *physical_slot_num, /* phy slot num of the first slot in this PCIE */ + u8 *ctrlcap) +{ + struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; + u32 slot_cap; + int rc = 0; + + DBG_ENTER_ROUTINE + + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + *first_device_num = 0; + *num_ctlr_slots = 1; + + rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); + + if (rc) { + err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__); + return -1; + } + + *physical_slot_num = slot_cap >> 19; + dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num); + + *ctrlcap = slot_cap & 0x0000007f; + + DBG_LEAVE_ROUTINE + return 0; +} + static void hpc_release_ctlr(struct controller *ctrl) { + struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *p, *p_prev; + DBG_ENTER_ROUTINE - if (pciehp_poll_mode) - del_timer(&ctrl->poll_timer); - else - free_irq(ctrl->pci_dev->irq, ctrl); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return ; + } + + if (pciehp_poll_mode) { + del_timer(&php_ctlr->int_poll_timer); + } else { + if (php_ctlr->irq) { + free_irq(php_ctlr->irq, ctrl); + php_ctlr->irq = 0; + } + } + if (php_ctlr->pci_dev) + php_ctlr->pci_dev = NULL; + + spin_lock(&list_lock); + p = php_ctlr_list_head; + p_prev = NULL; + while (p) { + if (p == php_ctlr) { + if (p_prev) + p_prev->pnext = p->pnext; + else + php_ctlr_list_head = p->pnext; + break; + } else { + p_prev = p; + p = p->pnext; + } + } + spin_unlock(&list_lock); + + kfree(php_ctlr); DBG_LEAVE_ROUTINE + } static int hpc_power_on_slot(struct slot * slot) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_cmd; u16 slot_ctrl, slot_status; + int retval = 0; DBG_ENTER_ROUTINE + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } /* Clear sticky power-fault bit from previous power failures */ - retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); - if (retval) { - err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); - return retval; - } + hp_register_read_word(php_ctlr->pci_dev, + SLOT_STATUS(slot->ctrl->cap_base), slot_status); slot_status &= PWR_FAULT_DETECTED; - if (slot_status) { - retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status); - if (retval) { - err("%s: Cannot write to SLOTSTATUS register\n", - __FUNCTION__); - return retval; - } - } + if (slot_status) + hp_register_write_word(php_ctlr->pci_dev, + SLOT_STATUS(slot->ctrl->cap_base), slot_status); + + retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); - retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (retval) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return retval; } @@ -708,8 +798,7 @@ static int hpc_power_on_slot(struct slot * slot) err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); return -1; } - dbg("%s: SLOTCTRL %x write cmd %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); + dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); DBG_LEAVE_ROUTINE @@ -718,18 +807,29 @@ static int hpc_power_on_slot(struct slot * slot) static int hpc_power_off_slot(struct slot * slot) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 slot_cmd; u16 slot_ctrl; + int retval = 0; DBG_ENTER_ROUTINE + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); + slot->hp_slot = 0; + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); - retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (retval) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return retval; } @@ -754,25 +854,47 @@ static int hpc_power_off_slot(struct slot * slot) err("%s: Write command failed!\n", __FUNCTION__); return -1; } - dbg("%s: SLOTCTRL %x write cmd %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); + dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); DBG_LEAVE_ROUTINE return retval; } -static irqreturn_t pcie_isr(int irq, void *dev_id) +static irqreturn_t pcie_isr(int IRQ, void *dev_id) { - struct controller *ctrl = (struct controller *)dev_id; + struct controller *ctrl = NULL; + struct php_ctlr_state_s *php_ctlr; + u8 schedule_flag = 0; u16 slot_status, intr_detect, intr_loc; u16 temp_word; int hp_slot = 0; /* only 1 slot per PCI Express port */ int rc = 0; - rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + if (!dev_id) + return IRQ_NONE; + + if (!pciehp_poll_mode) { + ctrl = dev_id; + php_ctlr = ctrl->hpc_ctlr_handle; + } else { + php_ctlr = dev_id; + ctrl = (struct controller *)php_ctlr->callback_instance_id; + } + + if (!ctrl) { + dbg("%s: dev_id %p ctlr == NULL\n", __FUNCTION__, (void*) dev_id); + return IRQ_NONE; + } + + if (!php_ctlr) { + dbg("%s: php_ctlr == NULL\n", __FUNCTION__); + return IRQ_NONE; + } + + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { - err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; } @@ -788,38 +910,33 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); /* Mask Hot-plug Interrupt Enable */ if (!pciehp_poll_mode) { - rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot read SLOT_CTRL register\n", - __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; } - dbg("%s: pciehp_readw(SLOTCTRL) with value %x\n", - __FUNCTION__, temp_word); + dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; - rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); + + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot write to SLOTCTRL register\n", - __FUNCTION__); + err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; } - - rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { - err("%s: Cannot read SLOT_STATUS register\n", - __FUNCTION__); + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; } - dbg("%s: pciehp_readw(SLOTSTATUS) with value %x\n", - __FUNCTION__, slot_status); + dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); /* Clear command complete interrupt caused by this write */ temp_word = 0x1f; - rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot write to SLOTSTATUS register\n", - __FUNCTION__); + err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; } } @@ -828,65 +945,60 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) /* * Command Complete Interrupt Pending */ - ctrl->cmd_busy = 0; wake_up_interruptible(&ctrl->queue); } - if (intr_loc & MRL_SENS_CHANGED) - pciehp_handle_switch_change(hp_slot, ctrl); - - if (intr_loc & ATTN_BUTTN_PRESSED) - pciehp_handle_attention_button(hp_slot, ctrl); - - if (intr_loc & PRSN_DETECT_CHANGED) - pciehp_handle_presence_change(hp_slot, ctrl); - - if (intr_loc & PWR_FAULT_DETECTED) - pciehp_handle_power_fault(hp_slot, ctrl); + if ((php_ctlr->switch_change_callback) && (intr_loc & MRL_SENS_CHANGED)) + schedule_flag += php_ctlr->switch_change_callback( + hp_slot, php_ctlr->callback_instance_id); + if ((php_ctlr->attention_button_callback) && (intr_loc & ATTN_BUTTN_PRESSED)) + schedule_flag += php_ctlr->attention_button_callback( + hp_slot, php_ctlr->callback_instance_id); + if ((php_ctlr->presence_change_callback) && (intr_loc & PRSN_DETECT_CHANGED)) + schedule_flag += php_ctlr->presence_change_callback( + hp_slot , php_ctlr->callback_instance_id); + if ((php_ctlr->power_fault_callback) && (intr_loc & PWR_FAULT_DETECTED)) + schedule_flag += php_ctlr->power_fault_callback( + hp_slot, php_ctlr->callback_instance_id); /* Clear all events after serving them */ temp_word = 0x1F; - rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); + err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; } /* Unmask Hot-plug Interrupt Enable */ if (!pciehp_poll_mode) { - rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot read SLOTCTRL register\n", - __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; } dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; - rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot write to SLOTCTRL register\n", - __FUNCTION__); + err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; } - - rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { - err("%s: Cannot read SLOT_STATUS register\n", - __FUNCTION__); + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; } /* Clear command complete interrupt caused by this write */ temp_word = 0x1F; - rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot write to SLOTSTATUS failed\n", - __FUNCTION__); + err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; } - dbg("%s: pciehp_writew(SLOTSTATUS) with value %x\n", - __FUNCTION__, temp_word); + dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word); } return IRQ_HANDLED; @@ -894,16 +1006,27 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pcie_link_speed lnk_speed; u32 lnk_cap; int retval = 0; DBG_ENTER_ROUTINE - retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + + retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); + if (retval) { - err("%s: Cannot read LNKCAP register\n", __FUNCTION__); + err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); return retval; } @@ -924,16 +1047,27 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pcie_link_width lnk_wdth; u32 lnk_cap; int retval = 0; DBG_ENTER_ROUTINE - retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + + retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); + if (retval) { - err("%s: Cannot read LNKCAP register\n", __FUNCTION__); + err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); return retval; } @@ -975,16 +1109,27 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN; int retval = 0; u16 lnk_status; DBG_ENTER_ROUTINE - retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + + retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); + if (retval) { - err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__); + err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); return retval; } @@ -1005,16 +1150,27 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN; int retval = 0; u16 lnk_status; DBG_ENTER_ROUTINE - retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + + retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); + if (retval) { - err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__); + err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); return retval; } @@ -1062,8 +1218,6 @@ static struct hpc_ops pciehp_hpc_ops = { .get_attention_status = hpc_get_attention_status, .get_latch_status = hpc_get_latch_status, .get_adapter_status = hpc_get_adapter_status, - .get_emi_status = hpc_get_emi_status, - .toggle_emi = hpc_toggle_emi, .get_max_bus_speed = hpc_get_max_lnk_speed, .get_cur_bus_speed = hpc_get_cur_lnk_speed, @@ -1151,24 +1305,38 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) int pcie_init(struct controller * ctrl, struct pcie_device *dev) { + struct php_ctlr_state_s *php_ctlr, *p; + void *instance_id = ctrl; int rc; static int first = 1; u16 temp_word; u16 cap_reg; u16 intr_enable = 0; u32 slot_cap; - int cap_base; + int cap_base, saved_cap_base; u16 slot_status, slot_ctrl; struct pci_dev *pdev; DBG_ENTER_ROUTINE + spin_lock_init(&list_lock); + php_ctlr = kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL); + + if (!php_ctlr) { /* allocate controller state data */ + err("%s: HPC controller memory allocation error!\n", __FUNCTION__); + goto abort; + } + + memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s)); + pdev = dev->port; - ctrl->pci_dev = pdev; /* save pci_dev in context */ + php_ctlr->pci_dev = pdev; /* save pci_dev in context */ dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n", __FUNCTION__, pdev->vendor, pdev->device); + saved_cap_base = pcie_cap_base; + if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) { dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__); goto abort_free_ctlr; @@ -1176,15 +1344,14 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) ctrl->cap_base = cap_base; - dbg("%s: pcie_cap_base %x\n", __FUNCTION__, cap_base); + dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base); - rc = pciehp_readw(ctrl, CAPREG, &cap_reg); + rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg); if (rc) { - err("%s: Cannot read CAPREG register\n", __FUNCTION__); + err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: CAPREG offset %x cap_reg %x\n", - __FUNCTION__, ctrl->cap_base + CAPREG, cap_reg); + dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg); if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040) && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) { @@ -1192,34 +1359,31 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) goto abort_free_ctlr; } - rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap); + rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); if (rc) { - err("%s: Cannot read SLOTCAP register\n", __FUNCTION__); + err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: SLOTCAP offset %x slot_cap %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap); + dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap); if (!(slot_cap & HP_CAP)) { dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); goto abort_free_ctlr; } /* For debugging purpose */ - rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { - err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: SLOTSTATUS offset %x slot_status %x\n", - __FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status); + dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status); - rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (rc) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); + dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (first) { spin_lock_init(&hpc_event_lock); @@ -1241,64 +1405,69 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) /* setup wait queue */ init_waitqueue_head(&ctrl->queue); + /* find the IRQ */ + php_ctlr->irq = dev->irq; + + /* Save interrupt callback info */ + php_ctlr->attention_button_callback = pciehp_handle_attention_button; + php_ctlr->switch_change_callback = pciehp_handle_switch_change; + php_ctlr->presence_change_callback = pciehp_handle_presence_change; + php_ctlr->power_fault_callback = pciehp_handle_power_fault; + php_ctlr->callback_instance_id = instance_id; + /* return PCI Controller Info */ - ctrl->slot_device_offset = 0; - ctrl->num_slots = 1; - ctrl->first_slot = slot_cap >> 19; - ctrl->ctrlcap = slot_cap & 0x0000007f; + php_ctlr->slot_device_offset = 0; + php_ctlr->num_slots = 1; /* Mask Hot-plug Interrupt Enable */ - rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); + rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: SLOTCTRL %x value read %x\n", - __FUNCTION__, ctrl->cap_base + SLOTCTRL, temp_word); + dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word); temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; - rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); + rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); goto abort_free_ctlr; } - rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { - err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_free_ctlr; } temp_word = 0x1F; /* Clear all events */ - rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); + err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_free_ctlr; } - if (pciehp_poll_mode) { - /* Install interrupt polling timer. Start with 10 sec delay */ - init_timer(&ctrl->poll_timer); - start_int_poll_timer(ctrl, 10); + if (pciehp_poll_mode) {/* Install interrupt polling code */ + /* Install and start the interrupt polling timer */ + init_timer(&php_ctlr->int_poll_timer); + start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ } else { /* Installs the interrupt handler */ - rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED, - MY_NAME, (void *)ctrl); - dbg("%s: request_irq %d for hpc%d (returns %d)\n", - __FUNCTION__, ctrl->pci_dev->irq, ctlr_seq_num, rc); + rc = request_irq(php_ctlr->irq, pcie_isr, IRQF_SHARED, MY_NAME, (void *) ctrl); + dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); if (rc) { - err("Can't get irq %d for the hotplug controller\n", - ctrl->pci_dev->irq); + err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); goto abort_free_ctlr; } } + dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq); - rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); + rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); goto abort_free_irq; } @@ -1322,21 +1491,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) } /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ - rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); + rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); + err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); goto abort_free_irq; } - rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { - err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_disable_intr; } temp_word = 0x1F; /* Clear all events */ - rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { - err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); + err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_disable_intr; } @@ -1349,7 +1518,24 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) goto abort_disable_intr; } + /* Add this HPC instance into the HPC list */ + spin_lock(&list_lock); + if (php_ctlr_list_head == 0) { + php_ctlr_list_head = php_ctlr; + p = php_ctlr_list_head; + p->pnext = NULL; + } else { + p = php_ctlr_list_head; + + while (p->pnext) + p = p->pnext; + + p->pnext = php_ctlr; + } + spin_unlock(&list_lock); + ctlr_seq_num++; + ctrl->hpc_ctlr_handle = php_ctlr; ctrl->hpc_ops = &pciehp_hpc_ops; DBG_LEAVE_ROUTINE @@ -1357,21 +1543,24 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) /* We end up here for the many possible ways to fail this API. */ abort_disable_intr: - rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); + rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); if (!rc) { temp_word &= ~(intr_enable | HP_INTR_ENABLE); - rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); + rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); } if (rc) err("%s : disabling interrupts failed\n", __FUNCTION__); abort_free_irq: if (pciehp_poll_mode) - del_timer_sync(&ctrl->poll_timer); + del_timer_sync(&php_ctlr->int_poll_timer); else - free_irq(ctrl->pci_dev->irq, ctrl); + free_irq(php_ctlr->irq, ctrl); abort_free_ctlr: + pcie_cap_base = saved_cap_base; + kfree(php_ctlr); +abort: DBG_LEAVE_ROUTINE return -1; } diff --git a/trunk/drivers/pci/hotplug/sgi_hotplug.c b/trunk/drivers/pci/hotplug/sgi_hotplug.c index 78cf0711d1fa..5d188c558386 100644 --- a/trunk/drivers/pci/hotplug/sgi_hotplug.c +++ b/trunk/drivers/pci/hotplug/sgi_hotplug.c @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include "../pci.h" @@ -37,17 +35,14 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)"); MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver"); - -/* SAL call error codes. Keep in sync with prom header io/include/pcibr.h */ +#define PCIIO_ASIC_TYPE_TIOCA 4 #define PCI_SLOT_ALREADY_UP 2 /* slot already up */ #define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */ #define PCI_L1_ERR 7 /* L1 console command error */ #define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */ - - -#define PCIIO_ASIC_TYPE_TIOCA 4 #define PCI_L1_QSIZE 128 /* our L1 message buffer size */ #define SN_MAX_HP_SLOTS 32 /* max hotplug slots */ +#define SGI_HOTPLUG_PROM_REV 0x0430 /* Min. required PROM version */ #define SN_SLOT_NAME_SIZE 33 /* size of name string */ /* internal list head */ @@ -232,7 +227,7 @@ static void sn_bus_free_data(struct pci_dev *dev) } static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, - int device_num, char **ssdt) + int device_num) { struct slot *slot = bss_hotplug_slot->private; struct pcibus_info *pcibus_info; @@ -245,8 +240,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, * Power-on and initialize the slot in the SN * PCI infrastructure. */ - rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp, ssdt); - + rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp); if (rc == PCI_SLOT_ALREADY_UP) { dev_dbg(slot->pci_bus->self, "is already active\n"); @@ -341,7 +335,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) int func, num_funcs; int new_ppb = 0; int rc; - char *ssdt = NULL; void pcibios_fixup_device_resources(struct pci_dev *); /* Serialize the Linux PCI infrastructure */ @@ -349,29 +342,14 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) /* * Power-on and initialize the slot in the SN - * PCI infrastructure. Also, retrieve the ACPI SSDT - * table for the slot (if ACPI capable PROM). + * PCI infrastructure. */ - rc = sn_slot_enable(bss_hotplug_slot, slot->device_num, &ssdt); + rc = sn_slot_enable(bss_hotplug_slot, slot->device_num); if (rc) { mutex_unlock(&sn_hotplug_mutex); return rc; } - if (ssdt) - ssdt = __va(ssdt); - /* Add the new SSDT for the slot to the ACPI namespace */ - if (SN_ACPI_BASE_SUPPORT() && ssdt) { - acpi_status ret; - - ret = acpi_load_table((struct acpi_table_header *)ssdt); - if (ACPI_FAILURE(ret)) { - printk(KERN_ERR "%s: acpi_load_table failed (0x%x)\n", - __FUNCTION__, ret); - /* try to continue on */ - } - } - num_funcs = pci_scan_slot(slot->pci_bus, PCI_DEVFN(slot->device_num + 1, 0)); if (!num_funcs) { @@ -396,10 +374,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) * pdi_host_pcidev_info). */ pcibios_fixup_device_resources(dev); - if (SN_ACPI_BASE_SUPPORT()) - sn_acpi_slot_fixup(dev); - else - sn_io_slot_fixup(dev); + sn_pci_fixup_slot(dev); if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { unsigned char sec_bus; pci_read_config_byte(dev, PCI_SECONDARY_BUS, @@ -413,63 +388,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) } } - /* - * Add the slot's devices to the ACPI infrastructure */ - if (SN_ACPI_BASE_SUPPORT() && ssdt) { - unsigned long adr; - struct acpi_device *pdevice; - struct acpi_device *device; - acpi_handle phandle; - acpi_handle chandle = NULL; - acpi_handle rethandle; - acpi_status ret; - - phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; - - if (acpi_bus_get_device(phandle, &pdevice)) { - dev_dbg(slot->pci_bus->self, - "no parent device, assuming NULL\n"); - pdevice = NULL; - } - - /* - * Walk the rootbus node's immediate children looking for - * the slot's device node(s). There can be more than - * one for multifunction devices. - */ - for (;;) { - rethandle = NULL; - ret = acpi_get_next_object(ACPI_TYPE_DEVICE, - phandle, chandle, - &rethandle); - - if (ret == AE_NOT_FOUND || rethandle == NULL) - break; - - chandle = rethandle; - - ret = acpi_evaluate_integer(chandle, METHOD_NAME__ADR, - NULL, &adr); - - if (ACPI_SUCCESS(ret) && - (adr>>16) == (slot->device_num + 1)) { - - ret = acpi_bus_add(&device, pdevice, chandle, - ACPI_BUS_TYPE_DEVICE); - if (ACPI_FAILURE(ret)) { - printk(KERN_ERR "%s: acpi_bus_add " - "failed (0x%x) for slot %d " - "func %d\n", __FUNCTION__, - ret, (int)(adr>>16), - (int)(adr&0xffff)); - /* try to continue on */ - } else { - acpi_bus_start(device); - } - } - } - } - /* Call the driver for the new device */ pci_bus_add_devices(slot->pci_bus); /* Call the drivers for the new devices subordinate to PPB */ @@ -494,7 +412,6 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) struct pci_dev *dev; int func; int rc; - acpi_owner_id ssdt_id = 0; /* Acquire update access to the bus */ mutex_lock(&sn_hotplug_mutex); @@ -505,52 +422,6 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) if (rc) goto leaving; - /* free the ACPI resources for the slot */ - if (SN_ACPI_BASE_SUPPORT() && - PCI_CONTROLLER(slot->pci_bus)->acpi_handle) { - unsigned long adr; - struct acpi_device *device; - acpi_handle phandle; - acpi_handle chandle = NULL; - acpi_handle rethandle; - acpi_status ret; - - /* Get the rootbus node pointer */ - phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; - - /* - * Walk the rootbus node's immediate children looking for - * the slot's device node(s). There can be more than - * one for multifunction devices. - */ - for (;;) { - rethandle = NULL; - ret = acpi_get_next_object(ACPI_TYPE_DEVICE, - phandle, chandle, - &rethandle); - - if (ret == AE_NOT_FOUND || rethandle == NULL) - break; - - chandle = rethandle; - - ret = acpi_evaluate_integer(chandle, - METHOD_NAME__ADR, - NULL, &adr); - if (ACPI_SUCCESS(ret) && - (adr>>16) == (slot->device_num + 1)) { - /* retain the owner id */ - acpi_get_id(chandle, &ssdt_id); - - ret = acpi_bus_get_device(chandle, - &device); - if (ACPI_SUCCESS(ret)) - acpi_bus_trim(device, 1); - } - } - - } - /* Free the SN resources assigned to the Linux device.*/ for (func = 0; func < 8; func++) { dev = pci_get_slot(slot->pci_bus, @@ -563,18 +434,6 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) } } - /* Remove the SSDT for the slot from the ACPI namespace */ - if (SN_ACPI_BASE_SUPPORT() && ssdt_id) { - acpi_status ret; - ret = acpi_unload_table_id(ssdt_id); - if (ACPI_FAILURE(ret)) { - printk(KERN_ERR "%s: acpi_unload_table_id " - "failed (0x%x) for id %d\n", - __FUNCTION__, ret, ssdt_id); - /* try to continue on */ - } - } - /* free the collected sysdata pointers */ sn_bus_free_sysdata(); diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index 01d31a1f697c..3ca6a4f574b3 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -106,7 +106,7 @@ struct controller { }; /* Define AMD SHPC ID */ -#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 +#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 /* AMD PCIX bridge registers */ @@ -221,7 +221,7 @@ enum ctrl_offsets { }; static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) -{ +{ return hotplug_slot->private; } diff --git a/trunk/drivers/pci/hotplug/shpchp_core.c b/trunk/drivers/pci/hotplug/shpchp_core.c index 5f4bc08a633a..590cd3cbe010 100644 --- a/trunk/drivers/pci/hotplug/shpchp_core.c +++ b/trunk/drivers/pci/hotplug/shpchp_core.c @@ -401,6 +401,10 @@ static int __init shpcd_init(void) { int retval = 0; +#ifdef CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE + shpchp_poll_mode = 1; +#endif + retval = pci_register_driver(&shpc_driver); dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); diff --git a/trunk/drivers/pci/hotplug/shpchp_ctrl.c b/trunk/drivers/pci/hotplug/shpchp_ctrl.c index b746bd265bc6..6bb84734cd6c 100644 --- a/trunk/drivers/pci/hotplug/shpchp_ctrl.c +++ b/trunk/drivers/pci/hotplug/shpchp_ctrl.c @@ -64,7 +64,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl) /* Attention Button Change */ dbg("shpchp: Attention button interrupt received.\n"); - + p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); @@ -128,7 +128,7 @@ u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl) p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); - /* + /* * Save the presence state */ p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); @@ -184,12 +184,12 @@ u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl) return 1; } -/* The following routines constitute the bulk of the +/* The following routines constitute the bulk of the hotplug controller logic */ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed) -{ +{ int rc = 0; dbg("%s: change to speed %d\n", __FUNCTION__, speed); @@ -204,7 +204,7 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, static int fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp) -{ +{ int rc = 0; /* @@ -257,23 +257,23 @@ static int board_added(struct slot *p_slot) err("%s: Failed to power on slot\n", __FUNCTION__); return -1; } - + if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { if (slots_not_empty) return WRONG_BUS_FREQUENCY; - + if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); return WRONG_BUS_FREQUENCY; } - + /* turn on board, blink green LED, turn off Amber LED */ if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); return rc; } } - + rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp); if (rc) { err("%s: Can't get adapter speed or bus mode mismatch\n", @@ -378,7 +378,7 @@ static int remove_board(struct slot *p_slot) err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); return rc; } - + rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); if (rc) { err("%s: Issue of Set Attention command failed\n", __FUNCTION__); diff --git a/trunk/drivers/pci/hotplug/shpchp_hpc.c b/trunk/drivers/pci/hotplug/shpchp_hpc.c index 5183a45d45b5..b7bede4b7c27 100644 --- a/trunk/drivers/pci/hotplug/shpchp_hpc.c +++ b/trunk/drivers/pci/hotplug/shpchp_hpc.c @@ -35,6 +35,38 @@ #include "shpchp.h" +#ifdef DEBUG +#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */ +#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */ +#define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */ +#define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */ +#define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT) +#define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE) +/* Redefine this flagword to set debug level */ +#define DEBUG_LEVEL DBG_K_STANDARD + +#define DEFINE_DBG_BUFFER char __dbg_str_buf[256]; + +#define DBG_PRINT( dbg_flags, args... ) \ + do { \ + if ( DEBUG_LEVEL & ( dbg_flags ) ) \ + { \ + int len; \ + len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \ + __FILE__, __LINE__, __FUNCTION__ ); \ + sprintf( __dbg_str_buf + len, args ); \ + printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \ + } \ + } while (0) + +#define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]"); +#define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]"); +#else +#define DEFINE_DBG_BUFFER +#define DBG_ENTER_ROUTINE +#define DBG_LEAVE_ROUTINE +#endif /* DEBUG */ + /* Slot Available Register I field definition */ #define SLOT_33MHZ 0x0000001f #define SLOT_66MHZ_PCIX 0x00001f00 @@ -179,6 +211,7 @@ #define SLOT_EVENT_LATCH 0x2 #define SLOT_SERR_INT_MASK 0x3 +DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); static irqreturn_t shpc_isr(int irq, void *dev_id); @@ -235,6 +268,8 @@ static void int_poll_timeout(unsigned long data) { struct controller *ctrl = (struct controller *)data; + DBG_ENTER_ROUTINE + /* Poll for interrupt events. regs == NULL => polling */ shpc_isr(0, ctrl); @@ -243,6 +278,8 @@ static void int_poll_timeout(unsigned long data) shpchp_poll_time = 2; /* default polling interval is 2 sec */ start_int_poll_timer(ctrl, shpchp_poll_time); + + DBG_LEAVE_ROUTINE } /* @@ -316,6 +353,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) int retval = 0; u16 temp_word; + DBG_ENTER_ROUTINE + mutex_lock(&slot->ctrl->cmd_lock); if (!shpc_poll_ctrl_busy(ctrl)) { @@ -329,9 +368,9 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) ++t_slot; temp_word = (t_slot << 8) | (cmd & 0xFF); dbg("%s: t_slot %x cmd %x\n", __FUNCTION__, t_slot, cmd); - + /* To make sure the Controller Busy bit is 0 before we send out the - * command. + * command. */ shpc_writew(ctrl, CMD, temp_word); @@ -350,14 +389,20 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) } out: mutex_unlock(&slot->ctrl->cmd_lock); + + DBG_LEAVE_ROUTINE return retval; } static int hpc_check_cmd_status(struct controller *ctrl) { + u16 cmd_status; int retval = 0; - u16 cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F; + DBG_ENTER_ROUTINE + + cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F; + switch (cmd_status >> 1) { case 0: retval = 0; @@ -378,6 +423,7 @@ static int hpc_check_cmd_status(struct controller *ctrl) retval = cmd_status; } + DBG_LEAVE_ROUTINE return retval; } @@ -385,8 +431,13 @@ static int hpc_check_cmd_status(struct controller *ctrl) static int hpc_get_attention_status(struct slot *slot, u8 *status) { struct controller *ctrl = slot->ctrl; - u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - u8 state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT; + u32 slot_reg; + u8 state; + + DBG_ENTER_ROUTINE + + slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT; switch (state) { case ATN_LED_STATE_ON: @@ -403,14 +454,20 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) break; } + DBG_LEAVE_ROUTINE return 0; } static int hpc_get_power_status(struct slot * slot, u8 *status) { struct controller *ctrl = slot->ctrl; - u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - u8 state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT; + u32 slot_reg; + u8 state; + + DBG_ENTER_ROUTINE + + slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT; switch (state) { case SLOT_STATE_PWRONLY: @@ -427,6 +484,7 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) break; } + DBG_LEAVE_ROUTINE return 0; } @@ -434,21 +492,30 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) static int hpc_get_latch_status(struct slot *slot, u8 *status) { struct controller *ctrl = slot->ctrl; - u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + u32 slot_reg; + + DBG_ENTER_ROUTINE + slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); *status = !!(slot_reg & MRL_SENSOR); /* 0 -> close; 1 -> open */ + DBG_LEAVE_ROUTINE return 0; } static int hpc_get_adapter_status(struct slot *slot, u8 *status) { struct controller *ctrl = slot->ctrl; - u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - u8 state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT; + u32 slot_reg; + u8 state; + DBG_ENTER_ROUTINE + + slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT; *status = (state != 0x3) ? 1 : 0; + DBG_LEAVE_ROUTINE return 0; } @@ -456,8 +523,11 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) { struct controller *ctrl = slot->ctrl; + DBG_ENTER_ROUTINE + *prog_int = shpc_readb(ctrl, PROG_INTERFACE); + DBG_LEAVE_ROUTINE return 0; } @@ -469,6 +539,8 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) u8 m66_cap = !!(slot_reg & MHZ66_CAP); u8 pi, pcix_cap; + DBG_ENTER_ROUTINE + if ((retval = hpc_get_prog_int(slot, &pi))) return retval; @@ -510,15 +582,21 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) } dbg("Adapter speed = %d\n", *value); + DBG_LEAVE_ROUTINE return retval; } static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) { - int retval = 0; struct controller *ctrl = slot->ctrl; - u16 sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG); - u8 pi = shpc_readb(ctrl, PROG_INTERFACE); + u16 sec_bus_status; + u8 pi; + int retval = 0; + + DBG_ENTER_ROUTINE + + pi = shpc_readb(ctrl, PROG_INTERFACE); + sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG); if (pi == 2) { *mode = (sec_bus_status & 0x0100) >> 8; @@ -527,14 +605,21 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) } dbg("Mode 1 ECC cap = %d\n", *mode); + + DBG_LEAVE_ROUTINE return retval; } static int hpc_query_power_fault(struct slot * slot) { struct controller *ctrl = slot->ctrl; - u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + u32 slot_reg; + + DBG_ENTER_ROUTINE + + slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + DBG_LEAVE_ROUTINE /* Note: Logic 0 => fault */ return !(slot_reg & POWER_FAULT); } @@ -544,7 +629,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) u8 slot_cmd = 0; switch (value) { - case 0 : + case 0 : slot_cmd = SET_ATTN_OFF; /* OFF */ break; case 1: @@ -581,6 +666,8 @@ static void hpc_release_ctlr(struct controller *ctrl) int i; u32 slot_reg, serr_int; + DBG_ENTER_ROUTINE + /* * Mask event interrupts and SERRs of all slots */ @@ -621,43 +708,61 @@ static void hpc_release_ctlr(struct controller *ctrl) */ if (atomic_dec_and_test(&shpchp_num_controllers)) destroy_workqueue(shpchp_wq); + + DBG_LEAVE_ROUTINE } static int hpc_power_on_slot(struct slot * slot) { int retval; + DBG_ENTER_ROUTINE + retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_PWR); - if (retval) + if (retval) { err("%s: Write command failed!\n", __FUNCTION__); + return retval; + } - return retval; + DBG_LEAVE_ROUTINE + + return 0; } static int hpc_slot_enable(struct slot * slot) { int retval; + DBG_ENTER_ROUTINE + /* Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */ retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_ENABLE | SET_PWR_BLINK | SET_ATTN_OFF); - if (retval) + if (retval) { err("%s: Write command failed!\n", __FUNCTION__); + return retval; + } - return retval; + DBG_LEAVE_ROUTINE + return 0; } static int hpc_slot_disable(struct slot * slot) { int retval; + DBG_ENTER_ROUTINE + /* Slot - Disable, Power Indicator - Off, Attention Indicator - On */ retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_DISABLE | SET_PWR_OFF | SET_ATTN_ON); - if (retval) + if (retval) { err("%s: Write command failed!\n", __FUNCTION__); + return retval; + } - return retval; + DBG_LEAVE_ROUTINE + return 0; } static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) @@ -666,6 +771,8 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) struct controller *ctrl = slot->ctrl; u8 pi, cmd; + DBG_ENTER_ROUTINE + pi = shpc_readb(ctrl, PROG_INTERFACE); if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) return -EINVAL; @@ -721,6 +828,7 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) if (retval) err("%s: Write command failed!\n", __FUNCTION__); + DBG_LEAVE_ROUTINE return retval; } @@ -735,7 +843,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) if (!intr_loc) return IRQ_NONE; - dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); + dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); if(!shpchp_poll_mode) { /* @@ -748,12 +856,12 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); intr_loc2 = shpc_readl(ctrl, INTR_LOC); - dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); + dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); } if (intr_loc & CMD_INTR_PENDING) { - /* - * Command Complete Interrupt Pending + /* + * Command Complete Interrupt Pending * RO only - clear by writing 1 to the Command Completion * Detect bit in Controller SERR-INT register */ @@ -767,7 +875,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) if (!(intr_loc & ~CMD_INTR_PENDING)) goto out; - for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { + for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { /* To find out which slot has interrupt pending */ if (!(intr_loc & SLOT_INTR_PENDING(hp_slot))) continue; @@ -799,7 +907,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) serr_int &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK); shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); } - + return IRQ_HANDLED; } @@ -812,6 +920,8 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); u32 slot_avail2 = shpc_readl(ctrl, SLOT_AVAIL2); + DBG_ENTER_ROUTINE + if (pi == 2) { if (slot_avail2 & SLOT_133MHZ_PCIX_533) bus_speed = PCI_SPEED_133MHz_PCIX_533; @@ -844,7 +954,7 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) *value = bus_speed; dbg("Max bus speed = %d\n", bus_speed); - + DBG_LEAVE_ROUTINE return retval; } @@ -857,6 +967,8 @@ static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) u8 pi = shpc_readb(ctrl, PROG_INTERFACE); u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); + DBG_ENTER_ROUTINE + if ((pi == 1) && (speed_mode > 4)) { *value = PCI_SPEED_UNKNOWN; return -ENODEV; @@ -912,6 +1024,7 @@ static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) } dbg("Current bus speed = %d\n", bus_speed); + DBG_LEAVE_ROUTINE return retval; } @@ -919,7 +1032,7 @@ static struct hpc_ops shpchp_hpc_ops = { .power_on_slot = hpc_power_on_slot, .slot_enable = hpc_slot_enable, .slot_disable = hpc_slot_disable, - .set_bus_speed_mode = hpc_set_bus_speed_mode, + .set_bus_speed_mode = hpc_set_bus_speed_mode, .set_attention_status = hpc_set_attention_status, .get_power_status = hpc_get_power_status, .get_attention_status = hpc_get_attention_status, @@ -936,7 +1049,7 @@ static struct hpc_ops shpchp_hpc_ops = { .green_led_on = hpc_set_green_led_on, .green_led_off = hpc_set_green_led_off, .green_led_blink = hpc_set_green_led_blink, - + .release_ctlr = hpc_release_ctlr, }; @@ -948,6 +1061,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) u32 tempdword, slot_reg, slot_config; u8 i; + DBG_ENTER_ROUTINE + ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == @@ -993,9 +1108,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) ctrl->mmio_size = 0x24 + 0x4 * num_slots; } - info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, + info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); - + rc = pci_enable_device(pdev); if (rc) { err("%s: pci_enable_device failed\n", __FUNCTION__); @@ -1057,7 +1172,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) slot_reg &= ~SLOT_REG_RSVDZ_MASK; shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); } - + if (shpchp_poll_mode) { /* Install interrupt polling timer. Start with 10 sec delay */ init_timer(&ctrl->poll_timer); @@ -1069,7 +1184,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) info("Can't get msi for the hotplug controller\n"); info("Use INTx for the hotplug controller\n"); } - + rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *)ctrl); dbg("%s: request_irq %d for hpc%d (returns %d)\n", @@ -1120,11 +1235,13 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); } + DBG_LEAVE_ROUTINE return 0; /* We end up here for the many possible ways to fail this API. */ abort_iounmap: iounmap(ctrl->creg); abort: + DBG_LEAVE_ROUTINE return rc; } diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 68555c11f556..ed3f7e1a563c 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -24,6 +24,8 @@ #include "pci.h" #include "msi.h" +static DEFINE_SPINLOCK(msi_lock); +static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; static struct kmem_cache* msi_cachep; static int pci_msi_enable = 1; @@ -42,13 +44,13 @@ static void msi_set_mask_bit(unsigned int irq, int flag) { struct msi_desc *entry; - entry = get_irq_msi(irq); + entry = msi_desc[irq]; BUG_ON(!entry || !entry->dev); switch (entry->msi_attrib.type) { case PCI_CAP_ID_MSI: if (entry->msi_attrib.maskbit) { - int pos; - u32 mask_bits; + int pos; + u32 mask_bits; pos = (long)entry->mask_base; pci_read_config_dword(entry->dev, pos, &mask_bits); @@ -72,7 +74,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag) void read_msi_msg(unsigned int irq, struct msi_msg *msg) { - struct msi_desc *entry = get_irq_msi(irq); + struct msi_desc *entry = get_irq_data(irq); switch(entry->msi_attrib.type) { case PCI_CAP_ID_MSI: { @@ -111,7 +113,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg) void write_msi_msg(unsigned int irq, struct msi_msg *msg) { - struct msi_desc *entry = get_irq_msi(irq); + struct msi_desc *entry = get_irq_data(irq); switch (entry->msi_attrib.type) { case PCI_CAP_ID_MSI: { @@ -160,7 +162,6 @@ void unmask_msi_irq(unsigned int irq) } static int msi_free_irq(struct pci_dev* dev, int irq); - static int msi_init(void) { static int status = -ENOMEM; @@ -168,6 +169,13 @@ static int msi_init(void) if (!status) return status; + if (pci_msi_quirk) { + pci_msi_enable = 0; + printk(KERN_WARNING "PCI: MSI quirk detected. MSI disabled.\n"); + status = -EINVAL; + return status; + } + status = msi_cache_init(); if (status < 0) { pci_msi_enable = 0; @@ -192,6 +200,46 @@ static struct msi_desc* alloc_msi_entry(void) return entry; } +static void attach_msi_entry(struct msi_desc *entry, int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&msi_lock, flags); + msi_desc[irq] = entry; + spin_unlock_irqrestore(&msi_lock, flags); +} + +static int create_msi_irq(void) +{ + struct msi_desc *entry; + int irq; + + entry = alloc_msi_entry(); + if (!entry) + return -ENOMEM; + + irq = create_irq(); + if (irq < 0) { + kmem_cache_free(msi_cachep, entry); + return -EBUSY; + } + + set_irq_data(irq, entry); + + return irq; +} + +static void destroy_msi_irq(unsigned int irq) +{ + struct msi_desc *entry; + + entry = get_irq_data(irq); + set_irq_chip(irq, NULL); + set_irq_data(irq, NULL); + destroy_irq(irq); + kmem_cache_free(msi_cachep, entry); +} + static void enable_msi_mode(struct pci_dev *dev, int pos, int type) { u16 control; @@ -230,8 +278,36 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type) pci_intx(dev, 1); /* enable intx */ } +static int msi_lookup_irq(struct pci_dev *dev, int type) +{ + int irq; + unsigned long flags; + + spin_lock_irqsave(&msi_lock, flags); + for (irq = 0; irq < NR_IRQS; irq++) { + if (!msi_desc[irq] || msi_desc[irq]->dev != dev || + msi_desc[irq]->msi_attrib.type != type || + msi_desc[irq]->msi_attrib.default_irq != dev->irq) + continue; + spin_unlock_irqrestore(&msi_lock, flags); + /* This pre-assigned MSI irq for this device + already exits. Override dev->irq with this irq */ + dev->irq = irq; + return 0; + } + spin_unlock_irqrestore(&msi_lock, flags); + + return -EACCES; +} + +void pci_scan_msi_device(struct pci_dev *dev) +{ + if (!dev) + return; +} + #ifdef CONFIG_PM -static int __pci_save_msi_state(struct pci_dev *dev) +int pci_save_msi_state(struct pci_dev *dev) { int pos, i = 0; u16 control; @@ -269,7 +345,7 @@ static int __pci_save_msi_state(struct pci_dev *dev) return 0; } -static void __pci_restore_msi_state(struct pci_dev *dev) +void pci_restore_msi_state(struct pci_dev *dev) { int i = 0, pos; u16 control; @@ -297,16 +373,14 @@ static void __pci_restore_msi_state(struct pci_dev *dev) kfree(save_state); } -static int __pci_save_msix_state(struct pci_dev *dev) +int pci_save_msix_state(struct pci_dev *dev) { int pos; + int temp; int irq, head, tail = 0; u16 control; struct pci_cap_saved_state *save_state; - if (!dev->msix_enabled) - return 0; - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); if (pos <= 0 || dev->no_msi) return 0; @@ -324,46 +398,38 @@ static int __pci_save_msix_state(struct pci_dev *dev) *((u16 *)&save_state->data[0]) = control; /* save the table */ - irq = head = dev->first_msi_irq; + temp = dev->irq; + if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { + kfree(save_state); + return -EINVAL; + } + + irq = head = dev->irq; while (head != tail) { struct msi_desc *entry; - entry = get_irq_msi(irq); + entry = msi_desc[irq]; read_msi_msg(irq, &entry->msg_save); - tail = entry->link.tail; + tail = msi_desc[irq]->link.tail; irq = tail; } + dev->irq = temp; save_state->cap_nr = PCI_CAP_ID_MSIX; pci_add_saved_cap(dev, save_state); return 0; } -int pci_save_msi_state(struct pci_dev *dev) -{ - int rc; - - rc = __pci_save_msi_state(dev); - if (rc) - return rc; - - rc = __pci_save_msix_state(dev); - - return rc; -} - -static void __pci_restore_msix_state(struct pci_dev *dev) +void pci_restore_msix_state(struct pci_dev *dev) { u16 save; int pos; int irq, head, tail = 0; struct msi_desc *entry; + int temp; struct pci_cap_saved_state *save_state; - if (!dev->msix_enabled) - return; - save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX); if (!save_state) return; @@ -376,25 +442,23 @@ static void __pci_restore_msix_state(struct pci_dev *dev) return; /* route the table */ - irq = head = dev->first_msi_irq; + temp = dev->irq; + if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) + return; + irq = head = dev->irq; while (head != tail) { - entry = get_irq_msi(irq); + entry = msi_desc[irq]; write_msi_msg(irq, &entry->msg_save); - tail = entry->link.tail; + tail = msi_desc[irq]->link.tail; irq = tail; } + dev->irq = temp; pci_write_config_word(dev, msi_control_reg(pos), save); enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); } - -void pci_restore_msi_state(struct pci_dev *dev) -{ - __pci_restore_msi_state(dev); - __pci_restore_msix_state(dev); -} -#endif /* CONFIG_PM */ +#endif /** * msi_capability_init - configure device's MSI capability structure @@ -407,6 +471,7 @@ void pci_restore_msi_state(struct pci_dev *dev) **/ static int msi_capability_init(struct pci_dev *dev) { + int status; struct msi_desc *entry; int pos, irq; u16 control; @@ -414,10 +479,13 @@ static int msi_capability_init(struct pci_dev *dev) pos = pci_find_capability(dev, PCI_CAP_ID_MSI); pci_read_config_word(dev, msi_control_reg(pos), &control); /* MSI Entry Initialization */ - entry = alloc_msi_entry(); - if (!entry) - return -ENOMEM; + irq = create_msi_irq(); + if (irq < 0) + return irq; + entry = get_irq_data(irq); + entry->link.head = irq; + entry->link.tail = irq; entry->msi_attrib.type = PCI_CAP_ID_MSI; entry->msi_attrib.is_64 = is_64bit_address(control); entry->msi_attrib.entry_nr = 0; @@ -443,16 +511,13 @@ static int msi_capability_init(struct pci_dev *dev) maskbits); } /* Configure MSI capability structure */ - irq = arch_setup_msi_irq(dev, entry); - if (irq < 0) { - kmem_cache_free(msi_cachep, entry); - return irq; + status = arch_setup_msi_irq(irq, dev); + if (status < 0) { + destroy_msi_irq(irq); + return status; } - entry->link.head = irq; - entry->link.tail = irq; - dev->first_msi_irq = irq; - set_irq_msi(irq, entry); + attach_msi_entry(entry, irq); /* Set MSI enabled bits */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); @@ -474,6 +539,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; + int status; int irq, pos, i, j, nr_entries, temp = 0; unsigned long phys_addr; u32 table_offset; @@ -496,11 +562,13 @@ static int msix_capability_init(struct pci_dev *dev, /* MSI-X Table Initialization */ for (i = 0; i < nvec; i++) { - entry = alloc_msi_entry(); - if (!entry) + irq = create_msi_irq(); + if (irq < 0) break; + entry = get_irq_data(irq); j = entries[i].entry; + entries[i].vector = irq; entry->msi_attrib.type = PCI_CAP_ID_MSIX; entry->msi_attrib.is_64 = 1; entry->msi_attrib.entry_nr = j; @@ -509,14 +577,6 @@ static int msix_capability_init(struct pci_dev *dev, entry->msi_attrib.pos = pos; entry->dev = dev; entry->mask_base = base; - - /* Configure MSI-X capability structure */ - irq = arch_setup_msi_irq(dev, entry); - if (irq < 0) { - kmem_cache_free(msi_cachep, entry); - break; - } - entries[i].vector = irq; if (!head) { entry->link.head = irq; entry->link.tail = irq; @@ -529,8 +589,14 @@ static int msix_capability_init(struct pci_dev *dev, } temp = irq; tail = entry; + /* Configure MSI-X capability structure */ + status = arch_setup_msi_irq(irq, dev); + if (status < 0) { + destroy_msi_irq(irq); + break; + } - set_irq_msi(irq, entry); + attach_msi_entry(entry, irq); } if (i != nvec) { int avail = i - 1; @@ -547,7 +613,6 @@ static int msix_capability_init(struct pci_dev *dev, avail = -EBUSY; return avail; } - dev->first_msi_irq = entries[0].vector; /* Set MSI-X enabled bits */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); @@ -595,11 +660,13 @@ int pci_msi_supported(struct pci_dev * dev) **/ int pci_enable_msi(struct pci_dev* dev) { - int pos, status; + int pos, temp, status; if (pci_msi_supported(dev) < 0) return -EINVAL; + temp = dev->irq; + status = msi_init(); if (status < 0) return status; @@ -608,14 +675,15 @@ int pci_enable_msi(struct pci_dev* dev) if (!pos) return -EINVAL; - WARN_ON(!!dev->msi_enabled); + WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI)); /* Check whether driver already requested for MSI-X irqs */ pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos > 0 && dev->msix_enabled) { + if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { printk(KERN_INFO "PCI: %s: Can't enable MSI. " - "Device already has MSI-X enabled\n", + "Device already has MSI-X irq assigned\n", pci_name(dev)); + dev->irq = temp; return -EINVAL; } status = msi_capability_init(dev); @@ -627,15 +695,13 @@ void pci_disable_msi(struct pci_dev* dev) struct msi_desc *entry; int pos, default_irq; u16 control; + unsigned long flags; if (!pci_msi_enable) return; if (!dev) return; - if (!dev->msi_enabled) - return; - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); if (!pos) return; @@ -644,26 +710,28 @@ void pci_disable_msi(struct pci_dev* dev) if (!(control & PCI_MSI_FLAGS_ENABLE)) return; - disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); - entry = get_irq_msi(dev->first_msi_irq); + spin_lock_irqsave(&msi_lock, flags); + entry = msi_desc[dev->irq]; if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { + spin_unlock_irqrestore(&msi_lock, flags); return; } - if (irq_has_action(dev->first_msi_irq)) { + if (irq_has_action(dev->irq)) { + spin_unlock_irqrestore(&msi_lock, flags); printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " "free_irq() on MSI irq %d\n", - pci_name(dev), dev->first_msi_irq); - BUG_ON(irq_has_action(dev->first_msi_irq)); + pci_name(dev), dev->irq); + BUG_ON(irq_has_action(dev->irq)); } else { default_irq = entry->msi_attrib.default_irq; - msi_free_irq(dev, dev->first_msi_irq); + spin_unlock_irqrestore(&msi_lock, flags); + msi_free_irq(dev, dev->irq); /* Restore dev->irq to its default pin-assertion irq */ dev->irq = default_irq; } - dev->first_msi_irq = 0; } static int msi_free_irq(struct pci_dev* dev, int irq) @@ -671,20 +739,27 @@ static int msi_free_irq(struct pci_dev* dev, int irq) struct msi_desc *entry; int head, entry_nr, type; void __iomem *base; + unsigned long flags; - entry = get_irq_msi(irq); + arch_teardown_msi_irq(irq); + + spin_lock_irqsave(&msi_lock, flags); + entry = msi_desc[irq]; if (!entry || entry->dev != dev) { + spin_unlock_irqrestore(&msi_lock, flags); return -EINVAL; } type = entry->msi_attrib.type; entry_nr = entry->msi_attrib.entry_nr; head = entry->link.head; base = entry->mask_base; - get_irq_msi(entry->link.head)->link.tail = entry->link.tail; - get_irq_msi(entry->link.tail)->link.head = entry->link.head; + msi_desc[entry->link.head]->link.tail = entry->link.tail; + msi_desc[entry->link.tail]->link.head = entry->link.head; + entry->dev = NULL; + msi_desc[irq] = NULL; + spin_unlock_irqrestore(&msi_lock, flags); - arch_teardown_msi_irq(irq); - kmem_cache_free(msi_cachep, entry); + destroy_msi_irq(irq); if (type == PCI_CAP_ID_MSIX) { writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE + @@ -715,7 +790,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq) int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) { int status, pos, nr_entries; - int i, j; + int i, j, temp; u16 control; if (!entries || pci_msi_supported(dev) < 0) @@ -743,14 +818,16 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) return -EINVAL; /* duplicate entry */ } } - WARN_ON(!!dev->msix_enabled); + temp = dev->irq; + WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)); /* Check whether driver already requested for MSI irq */ if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 && - dev->msi_enabled) { + !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { printk(KERN_INFO "PCI: %s: Can't enable MSI-X. " "Device already has an MSI irq assigned\n", pci_name(dev)); + dev->irq = temp; return -EINVAL; } status = msix_capability_init(dev, entries, nvec); @@ -759,8 +836,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) void pci_disable_msix(struct pci_dev* dev) { - int irq, head, tail = 0, warning = 0; - int pos; + int pos, temp; u16 control; if (!pci_msi_enable) @@ -768,9 +844,6 @@ void pci_disable_msix(struct pci_dev* dev) if (!dev) return; - if (!dev->msix_enabled) - return; - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); if (!pos) return; @@ -781,23 +854,31 @@ void pci_disable_msix(struct pci_dev* dev) disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); - irq = head = dev->first_msi_irq; - while (head != tail) { - tail = get_irq_msi(irq)->link.tail; - if (irq_has_action(irq)) - warning = 1; - else if (irq != head) /* Release MSI-X irq */ - msi_free_irq(dev, irq); - irq = tail; - } - msi_free_irq(dev, irq); - if (warning) { - printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " - "free_irq() on all MSI-X irqs\n", - pci_name(dev)); - BUG_ON(warning > 0); + temp = dev->irq; + if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { + int irq, head, tail = 0, warning = 0; + unsigned long flags; + + irq = head = dev->irq; + dev->irq = temp; /* Restore pin IRQ */ + while (head != tail) { + spin_lock_irqsave(&msi_lock, flags); + tail = msi_desc[irq]->link.tail; + spin_unlock_irqrestore(&msi_lock, flags); + if (irq_has_action(irq)) + warning = 1; + else if (irq != head) /* Release MSI-X irq */ + msi_free_irq(dev, irq); + irq = tail; + } + msi_free_irq(dev, irq); + if (warning) { + printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " + "free_irq() on all MSI-X irqs\n", + pci_name(dev)); + BUG_ON(warning > 0); + } } - dev->first_msi_irq = 0; } /** @@ -811,26 +892,35 @@ void pci_disable_msix(struct pci_dev* dev) **/ void msi_remove_pci_irq_vectors(struct pci_dev* dev) { + int pos, temp; + unsigned long flags; + if (!pci_msi_enable || !dev) return; - if (dev->msi_enabled) { - if (irq_has_action(dev->first_msi_irq)) { + temp = dev->irq; /* Save IOAPIC IRQ */ + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { + if (irq_has_action(dev->irq)) { printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " "called without free_irq() on MSI irq %d\n", - pci_name(dev), dev->first_msi_irq); - BUG_ON(irq_has_action(dev->first_msi_irq)); + pci_name(dev), dev->irq); + BUG_ON(irq_has_action(dev->irq)); } else /* Release MSI irq assigned to this device */ - msi_free_irq(dev, dev->first_msi_irq); + msi_free_irq(dev, dev->irq); + dev->irq = temp; /* Restore IOAPIC IRQ */ } - if (dev->msix_enabled) { + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { int irq, head, tail = 0, warning = 0; void __iomem *base = NULL; - irq = head = dev->first_msi_irq; + irq = head = dev->irq; while (head != tail) { - tail = get_irq_msi(irq)->link.tail; - base = get_irq_msi(irq)->mask_base; + spin_lock_irqsave(&msi_lock, flags); + tail = msi_desc[irq]->link.tail; + base = msi_desc[irq]->mask_base; + spin_unlock_irqrestore(&msi_lock, flags); if (irq_has_action(irq)) warning = 1; else if (irq != head) /* Release MSI-X irq */ @@ -845,6 +935,7 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) pci_name(dev)); BUG_ON(warning > 0); } + dev->irq = temp; /* Restore IOAPIC IRQ */ } } diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 4438ae1ede4f..92d5e8db0de7 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -324,7 +324,8 @@ static int pci_default_resume(struct pci_dev *pci_dev) /* restore the PCI config space */ pci_restore_state(pci_dev); /* if the device was enabled before suspend, reenable */ - retval = __pci_reenable_device(pci_dev); + if (atomic_read(&pci_dev->enable_cnt)) + retval = __pci_enable_device(pci_dev); /* if the device was busmaster before the suspend, make it busmaster again */ if (pci_dev->is_busmaster) pci_set_master(pci_dev); @@ -421,8 +422,7 @@ static struct kobj_type pci_driver_kobj_type = { * If no error occurred, the driver remains registered even if * no device was claimed during registration. */ -int __pci_register_driver(struct pci_driver *drv, struct module *owner, - const char *mod_name) +int __pci_register_driver(struct pci_driver *drv, struct module *owner) { int error; @@ -430,7 +430,6 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, drv->driver.name = drv->name; drv->driver.bus = &pci_bus_type; drv->driver.owner = owner; - drv->driver.mod_name = mod_name; drv->driver.kobj.ktype = &pci_driver_kobj_type; if (pci_multithread_probe) diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 84c757ba0664..206c834d263a 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -392,14 +392,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) if (state > PCI_D3hot) state = PCI_D3hot; - /* - * If the device or the parent bridge can't support PCI PM, ignore - * the request if we're doing anything besides putting it into D0 - * (which would only happen on boot). - */ - if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) - return 0; - /* Validate current state: * Can enter D0 from any state, but if we can only go deeper * to sleep if we're already in a low power state @@ -411,6 +403,13 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) } else if (dev->current_state == state) return 0; /* we're already there */ + /* + * If the device or the parent bridge can't support PCI PM, ignore + * the request if we're doing anything besides putting it into D0 + * (which would only happen on boot). + */ + if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) + return 0; /* find PCI PM capability in list */ pm = pci_find_capability(dev, PCI_CAP_ID_PM); @@ -634,6 +633,8 @@ pci_save_state(struct pci_dev *dev) pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); if ((i = pci_save_msi_state(dev)) != 0) return i; + if ((i = pci_save_msix_state(dev)) != 0) + return i; if ((i = pci_save_pcie_state(dev)) != 0) return i; if ((i = pci_save_pcix_state(dev)) != 0) @@ -671,11 +672,22 @@ pci_restore_state(struct pci_dev *dev) } pci_restore_pcix_state(dev); pci_restore_msi_state(dev); - + pci_restore_msix_state(dev); return 0; } -static int do_pci_enable_device(struct pci_dev *dev, int bars) +/** + * pci_enable_device_bars - Initialize some of a device for use + * @dev: PCI device to be initialized + * @bars: bitmask of BAR's that must be configured + * + * Initialize device before it's used by a driver. Ask low-level code + * to enable selected I/O and memory resources. Wake up the device if it + * was suspended. Beware, this function can fail. + */ + +int +pci_enable_device_bars(struct pci_dev *dev, int bars) { int err; @@ -685,47 +697,30 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars) err = pcibios_enable_device(dev, bars); if (err < 0) return err; - pci_fixup_device(pci_fixup_enable, dev); - return 0; } /** - * __pci_reenable_device - Resume abandoned device - * @dev: PCI device to be resumed - * - * Note this function is a backend of pci_default_resume and is not supposed - * to be called by normal code, write proper resume handler and use it instead. - */ -int -__pci_reenable_device(struct pci_dev *dev) -{ - if (atomic_read(&dev->enable_cnt)) - return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1); - return 0; -} - -/** - * pci_enable_device_bars - Initialize some of a device for use + * __pci_enable_device - Initialize device before it's used by a driver. * @dev: PCI device to be initialized - * @bars: bitmask of BAR's that must be configured * * Initialize device before it's used by a driver. Ask low-level code - * to enable selected I/O and memory resources. Wake up the device if it - * was suspended. Beware, this function can fail. + * to enable I/O and memory. Wake up the device if it was suspended. + * Beware, this function can fail. + * + * Note this function is a backend and is not supposed to be called by + * normal code, use pci_enable_device() instead. */ int -pci_enable_device_bars(struct pci_dev *dev, int bars) +__pci_enable_device(struct pci_dev *dev) { int err; - if (atomic_add_return(1, &dev->enable_cnt) > 1) - return 0; /* already enabled */ - - err = do_pci_enable_device(dev, bars); - if (err < 0) - atomic_dec(&dev->enable_cnt); - return err; + err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); + if (err) + return err; + pci_fixup_device(pci_fixup_enable, dev); + return 0; } /** @@ -741,7 +736,13 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) */ int pci_enable_device(struct pci_dev *dev) { - return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); + int result; + if (atomic_add_return(1, &dev->enable_cnt) > 1) + return 0; /* already enabled */ + result = __pci_enable_device(dev); + if (result < 0) + atomic_dec(&dev->enable_cnt); + return result; } /** @@ -920,47 +921,6 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) return -EBUSY; } -/** - * pci_release_selected_regions - Release selected PCI I/O and memory resources - * @pdev: PCI device whose resources were previously reserved - * @bars: Bitmask of BARs to be released - * - * Release selected PCI I/O and memory resources previously reserved. - * Call this function only after all use of the PCI regions has ceased. - */ -void pci_release_selected_regions(struct pci_dev *pdev, int bars) -{ - int i; - - for (i = 0; i < 6; i++) - if (bars & (1 << i)) - pci_release_region(pdev, i); -} - -/** - * pci_request_selected_regions - Reserve selected PCI I/O and memory resources - * @pdev: PCI device whose resources are to be reserved - * @bars: Bitmask of BARs to be requested - * @res_name: Name to be associated with resource - */ -int pci_request_selected_regions(struct pci_dev *pdev, int bars, - const char *res_name) -{ - int i; - - for (i = 0; i < 6; i++) - if (bars & (1 << i)) - if(pci_request_region(pdev, i, res_name)) - goto err_out; - return 0; - -err_out: - while(--i >= 0) - if (bars & (1 << i)) - pci_release_region(pdev, i); - - return -EBUSY; -} /** * pci_release_regions - Release reserved PCI I/O and memory resources @@ -973,7 +933,10 @@ int pci_request_selected_regions(struct pci_dev *pdev, int bars, void pci_release_regions(struct pci_dev *pdev) { - pci_release_selected_regions(pdev, (1 << 6) - 1); + int i; + + for (i = 0; i < 6; i++) + pci_release_region(pdev, i); } /** @@ -991,7 +954,18 @@ void pci_release_regions(struct pci_dev *pdev) */ int pci_request_regions(struct pci_dev *pdev, const char *res_name) { - return pci_request_selected_regions(pdev, ((1 << 6) - 1), res_name); + int i; + + for (i = 0; i < 6; i++) + if(pci_request_region(pdev, i, res_name)) + goto err_out; + return 0; + +err_out: + while(--i >= 0) + pci_release_region(pdev, i); + + return -EBUSY; } /** @@ -1174,23 +1148,7 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) return 0; } #endif - -/** - * pci_select_bars - Make BAR mask from the type of resource - * @pdev: the PCI device for which BAR mask is made - * @flags: resource type mask to be selected - * - * This helper routine makes bar mask from the type of resource. - */ -int pci_select_bars(struct pci_dev *dev, unsigned long flags) -{ - int i, bars = 0; - for (i = 0; i < PCI_NUM_RESOURCES; i++) - if (pci_resource_flags(dev, i) & flags) - bars |= (1 << i); - return bars; -} - + static int __devinit pci_init(void) { struct pci_dev *dev = NULL; @@ -1223,6 +1181,12 @@ early_param("pci", pci_setup); device_initcall(pci_init); +#if defined(CONFIG_ISA) || defined(CONFIG_EISA) +/* FIXME: Some boxes have multiple ISA bridges! */ +struct pci_dev *isa_bridge; +EXPORT_SYMBOL(isa_bridge); +#endif + EXPORT_SYMBOL_GPL(pci_restore_bars); EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device); @@ -1233,8 +1197,6 @@ EXPORT_SYMBOL(pci_release_regions); EXPORT_SYMBOL(pci_request_regions); EXPORT_SYMBOL(pci_release_region); EXPORT_SYMBOL(pci_request_region); -EXPORT_SYMBOL(pci_release_selected_regions); -EXPORT_SYMBOL(pci_request_selected_regions); EXPORT_SYMBOL(pci_set_master); EXPORT_SYMBOL(pci_set_mwi); EXPORT_SYMBOL(pci_clear_mwi); @@ -1243,10 +1205,13 @@ EXPORT_SYMBOL(pci_set_dma_mask); EXPORT_SYMBOL(pci_set_consistent_dma_mask); EXPORT_SYMBOL(pci_assign_resource); EXPORT_SYMBOL(pci_find_parent_resource); -EXPORT_SYMBOL(pci_select_bars); EXPORT_SYMBOL(pci_set_power_state); EXPORT_SYMBOL(pci_save_state); EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_enable_wake); +/* Quirk info */ + +EXPORT_SYMBOL(isa_dma_bridge_buggy); +EXPORT_SYMBOL(pci_pci_problems); diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index a4f2d580625e..398852f526a6 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -1,6 +1,6 @@ /* Functions internal to the PCI core code */ -extern int __must_check __pci_reenable_device(struct pci_dev *); +extern int __must_check __pci_enable_device(struct pci_dev *); extern int pci_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); @@ -43,8 +43,12 @@ extern void pci_remove_legacy_files(struct pci_bus *bus); /* Lock for read/write access to pci device and bus lists */ extern struct rw_semaphore pci_bus_sem; +#ifdef CONFIG_PCI_MSI +extern int pci_msi_quirk; +#else +#define pci_msi_quirk 0 +#endif extern unsigned int pci_pm_d3_delay; - #ifdef CONFIG_PCI_MSI void disable_msi_mode(struct pci_dev *dev, int pos, int type); void pci_no_msi(void); @@ -52,15 +56,17 @@ void pci_no_msi(void); static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { } static inline void pci_no_msi(void) { } #endif - #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) int pci_save_msi_state(struct pci_dev *dev); +int pci_save_msix_state(struct pci_dev *dev); void pci_restore_msi_state(struct pci_dev *dev); +void pci_restore_msix_state(struct pci_dev *dev); #else static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; } +static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; } static inline void pci_restore_msi_state(struct pci_dev *dev) {} +static inline void pci_restore_msix_state(struct pci_dev *dev) {} #endif - static inline int pci_no_d1d2(struct pci_dev *dev) { unsigned int parent_dstates = 0; diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index 2fe1d690eb13..0e0401dd02cb 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -144,32 +144,6 @@ static u32 pci_size(u32 base, u32 maxbase, u32 mask) return size; } -static u64 pci_size64(u64 base, u64 maxbase, u64 mask) -{ - u64 size = mask & maxbase; /* Find the significant bits */ - if (!size) - return 0; - - /* Get the lowest of them to find the decode size, and - from that the extent. */ - size = (size & ~(size-1)) - 1; - - /* base == maxbase can be valid only if the BAR has - already been programmed with all 1s. */ - if (base == maxbase && ((base | size) & mask) != mask) - return 0; - - return size; -} - -static inline int is_64bit_memory(u32 mask) -{ - if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == - (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) - return 1; - return 0; -} - static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) { unsigned int pos, reg, next; @@ -177,10 +151,6 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) struct resource *res; for(pos=0; posresource[pos]; res->name = pci_name(dev); @@ -193,16 +163,9 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) continue; if (l == 0xffffffff) l = 0; - raw_sz = sz; - if ((l & PCI_BASE_ADDRESS_SPACE) == - PCI_BASE_ADDRESS_SPACE_MEMORY) { + if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) { sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK); - /* - * For 64bit prefetchable memory sz could be 0, if the - * real size is bigger than 4G, so we need to check - * szhi for that. - */ - if (!is_64bit_memory(l) && !sz) + if (!sz) continue; res->start = l & PCI_BASE_ADDRESS_MEM_MASK; res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK; @@ -215,36 +178,30 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) } res->end = res->start + (unsigned long) sz; res->flags |= pci_calc_resource_flags(l); - if (is_64bit_memory(l)) { + if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) + == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { u32 szhi, lhi; - pci_read_config_dword(dev, reg+4, &lhi); pci_write_config_dword(dev, reg+4, ~0); pci_read_config_dword(dev, reg+4, &szhi); pci_write_config_dword(dev, reg+4, lhi); - sz64 = ((u64)szhi << 32) | raw_sz; - l64 = ((u64)lhi << 32) | l; - sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK); + szhi = pci_size(lhi, szhi, 0xffffffff); next++; #if BITS_PER_LONG == 64 - if (!sz64) { - res->start = 0; - res->end = 0; - res->flags = 0; - continue; + res->start |= ((unsigned long) lhi) << 32; + res->end = res->start + sz; + if (szhi) { + /* This BAR needs > 4GB? Wow. */ + res->end |= (unsigned long)szhi<<32; } - res->start = l64 & PCI_BASE_ADDRESS_MEM_MASK; - res->end = res->start + sz64; #else - if (sz64 > 0x100000000ULL) { - printk(KERN_ERR "PCI: Unable to handle 64-bit " - "BAR for device %s\n", pci_name(dev)); + if (szhi) { + printk(KERN_ERR "PCI: Unable to handle 64-bit BAR for device %s\n", pci_name(dev)); res->start = 0; res->flags = 0; } else if (lhi) { /* 64-bit wide address, treat as disabled */ - pci_write_config_dword(dev, reg, - l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK); + pci_write_config_dword(dev, reg, l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK); pci_write_config_dword(dev, reg+4, 0); res->start = 0; res->end = sz; @@ -945,6 +902,7 @@ pci_scan_single_device(struct pci_bus *bus, int devfn) return NULL; pci_device_add(dev, bus); + pci_scan_msi_device(dev); return dev; } diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 11217bda4b9e..c913ea4e545c 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -61,8 +61,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_p This appears to be BIOS not version dependent. So presumably there is a chipset level fix */ -int isa_dma_bridge_buggy; -EXPORT_SYMBOL(isa_dma_bridge_buggy); +int isa_dma_bridge_buggy; /* Exported */ static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev) { @@ -84,7 +83,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_d DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs ); int pci_pci_problems; -EXPORT_SYMBOL(pci_pci_problems); /* * Chipsets where PCI->PCI transfers vanish or hang @@ -96,8 +94,6 @@ static void __devinit quirk_nopcipci(struct pci_dev *dev) pci_pci_problems |= PCIPCI_FAIL; } } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci ); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci ); static void __devinit quirk_nopciamd(struct pci_dev *dev) { @@ -109,6 +105,9 @@ static void __devinit quirk_nopciamd(struct pci_dev *dev) pci_pci_problems |= PCIAGP_FAIL; } } + +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci ); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopciamd ); /* @@ -977,51 +976,52 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x1626: /* L3C notebook */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) + if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) switch(dev->subsystem_device) { case 0x80b1: /* P4GE-V */ case 0x80b2: /* P4PE */ case 0x8093: /* P4B533-V */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82850_HB) + if (dev->device == PCI_DEVICE_ID_INTEL_82850_HB) switch(dev->subsystem_device) { case 0x8030: /* P4T533 */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_7205_0) + if (dev->device == PCI_DEVICE_ID_INTEL_7205_0) switch (dev->subsystem_device) { case 0x8070: /* P4G8X Deluxe */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH) + if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH) switch (dev->subsystem_device) { case 0x80c9: /* PU-DLS */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) + if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) switch (dev->subsystem_device) { case 0x1751: /* M2N notebook */ case 0x1821: /* M5N notebook */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) + if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch (dev->subsystem_device) { case 0x184b: /* W1N notebook */ case 0x186a: /* M6Ne notebook */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) + if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) switch (dev->subsystem_device) { case 0x80f2: /* P4P800-X */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) + if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { switch (dev->subsystem_device) { case 0x1882: /* M6V notebook */ case 0x1977: /* A6VA notebook */ asus_hides_smbus = 1; } + } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) { if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch(dev->subsystem_device) { @@ -1029,24 +1029,25 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x0890: /* HP Compaq nc6000 */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) + if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) switch (dev->subsystem_device) { case 0x12bc: /* HP D330L */ case 0x12bd: /* HP D530 */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) + if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { switch (dev->subsystem_device) { case 0x099c: /* HP Compaq nx6110 */ asus_hides_smbus = 1; } + } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) { if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) switch(dev->subsystem_device) { case 0x0001: /* Toshiba Satellite A40 */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) + if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch(dev->subsystem_device) { case 0x0001: /* Toshiba Tecra M2 */ asus_hides_smbus = 1; @@ -1135,14 +1136,6 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev) pci_write_config_byte(dev, 0x77, val & ~0x10); } } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); /* * ... This is further complicated by the fact that some SiS96x south @@ -1152,6 +1145,8 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_ * * We can also enable the sis96x bit in the discovery register.. */ +static int __devinitdata sis_96x_compatible = 0; + #define SIS_DETECT_REGISTER 0x40 static void quirk_sis_503(struct pci_dev *dev) @@ -1167,6 +1162,9 @@ static void quirk_sis_503(struct pci_dev *dev) return; } + /* Make people aware that we changed the config.. */ + printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503 (compatible=%d)\n", devid, sis_96x_compatible); + /* * Ok, it now shows up as a 96x.. run the 96x quirk by * hand in case it has already been processed. @@ -1175,10 +1173,20 @@ static void quirk_sis_503(struct pci_dev *dev) dev->device = devid; quirk_sis_96x_smbus(dev); } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); +static void __init quirk_sis_96x_compatible(struct pci_dev *dev) +{ + sis_96x_compatible = 1; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_645, quirk_sis_96x_compatible ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_646, quirk_sis_96x_compatible ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_648, quirk_sis_96x_compatible ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650, quirk_sis_96x_compatible ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_compatible ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); /* * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller * and MC97 modem controller are disabled when a second PCI soundcard is @@ -1209,8 +1217,21 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); + + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); + DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); + +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); + #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) /* @@ -1255,6 +1276,7 @@ static void quirk_jmicron_dualfn(struct pci_dev *pdev) break; } } + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); @@ -1398,7 +1420,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_intel_ide_co int pcie_mch_quirk; -EXPORT_SYMBOL(pcie_mch_quirk); static void __devinit quirk_pcie_mch(struct pci_dev *pdev) { @@ -1460,24 +1481,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2609, quirk_intel_pcie_pm); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); -/* - * Toshiba TC86C001 IDE controller reports the standard 8-byte BAR0 size - * but the PIO transfers won't work if BAR0 falls at the odd 8 bytes. - * Re-allocate the region if needed... - */ -static void __init quirk_tc86c001_ide(struct pci_dev *dev) -{ - struct resource *r = &dev->resource[0]; - - if (r->start & 0x8) { - r->start = 0; - r->end = 0xf; - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2, - PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE, - quirk_tc86c001_ide); - static void __devinit quirk_netmos(struct pci_dev *dev) { unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4; @@ -1643,7 +1646,6 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) } pci_do_fixups(dev, start, end); } -EXPORT_SYMBOL(pci_fixup_device); /* Enable 1k I/O space granularity on the Intel P64H2 */ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) @@ -1671,31 +1673,6 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); -/* Fix the IOBL_ADR for 1k I/O space granularity on the Intel P64H2 - * The IOBL_ADR gets re-written to 4k boundaries in pci_setup_bridge() - * in drivers/pci/setup-bus.c - */ -static void __devinit quirk_p64h2_1k_io_fix_iobl(struct pci_dev *dev) -{ - u16 en1k, iobl_adr, iobl_adr_1k; - struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES; - - pci_read_config_word(dev, 0x40, &en1k); - - if (en1k & 0x200) { - pci_read_config_word(dev, PCI_IO_BASE, &iobl_adr); - - iobl_adr_1k = iobl_adr | (res->start >> 8) | (res->end & 0xfc00); - - if (iobl_adr != iobl_adr_1k) { - printk(KERN_INFO "PCI: Fixing P64H2 IOBL_ADR from 0x%x to 0x%x for 1 KB Granularity\n", - iobl_adr,iobl_adr_1k); - pci_write_config_word(dev, PCI_IO_BASE, iobl_adr_1k); - } - } -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io_fix_iobl); - /* Under some circumstances, AER is not linked with extended capabilities. * Force it to be linked by setting the corresponding control bit in the * config space. @@ -1718,6 +1695,9 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_pcie_aer_ext_cap); #ifdef CONFIG_PCI_MSI +/* To disable MSI globally */ +int pci_msi_quirk; + /* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually * some other busses controlled by the chipset even if Linux is not aware of it. @@ -1726,8 +1706,8 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, */ static void __init quirk_svw_msi(struct pci_dev *dev) { - pci_no_msi(); - printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n"); + pci_msi_quirk = 1; + printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n"); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi); @@ -1808,3 +1788,8 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap); #endif /* CONFIG_PCI_MSI */ + +EXPORT_SYMBOL(pcie_mch_quirk); +#ifdef CONFIG_HOTPLUG +EXPORT_SYMBOL(pci_fixup_device); +#endif diff --git a/trunk/drivers/pci/search.c b/trunk/drivers/pci/search.c index ff98eaddaa73..b2653c4afe9e 100644 --- a/trunk/drivers/pci/search.c +++ b/trunk/drivers/pci/search.c @@ -357,6 +357,43 @@ pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev return dev; } +/** + * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id + * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids + * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids + * @from: Previous PCI device found in search, or %NULL for new search. + * + * Iterates through the list of known PCI devices in the reverse order of + * pci_find_device(). + * If a PCI device is found with a matching @vendor and @device, a pointer to + * its device structure is returned. Otherwise, %NULL is returned. + * A new search is initiated by passing %NULL as the @from argument. + * Otherwise if @from is not %NULL, searches continue from previous device + * on the global list. + */ +struct pci_dev * +pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from) +{ + struct list_head *n; + struct pci_dev *dev; + + WARN_ON(in_interrupt()); + down_read(&pci_bus_sem); + n = from ? from->global_list.prev : pci_devices.prev; + + while (n && (n != &pci_devices)) { + dev = pci_dev_g(n); + if ((vendor == PCI_ANY_ID || dev->vendor == vendor) && + (device == PCI_ANY_ID || dev->device == device)) + goto exit; + n = n->prev; + } + dev = NULL; +exit: + up_read(&pci_bus_sem); + return dev; +} + /** * pci_get_class - begin or continue searching for a PCI device by class * @class: search for a PCI device with this class designation @@ -432,6 +469,7 @@ EXPORT_SYMBOL(pci_dev_present); EXPORT_SYMBOL(pci_find_present); EXPORT_SYMBOL(pci_find_device); +EXPORT_SYMBOL(pci_find_device_reverse); EXPORT_SYMBOL(pci_find_slot); /* For boot time work */ EXPORT_SYMBOL(pci_find_bus); diff --git a/trunk/drivers/pcmcia/cs.c b/trunk/drivers/pcmcia/cs.c index ac004248324a..606a46740338 100644 --- a/trunk/drivers/pcmcia/cs.c +++ b/trunk/drivers/pcmcia/cs.c @@ -110,7 +110,7 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state) down_read(&pcmcia_socket_list_rwsem); list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { - if (socket->dev.parent != dev) + if (socket->dev.dev != dev) continue; mutex_lock(&socket->skt_mutex); socket_suspend(socket); @@ -128,7 +128,7 @@ int pcmcia_socket_dev_resume(struct device *dev) down_read(&pcmcia_socket_list_rwsem); list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { - if (socket->dev.parent != dev) + if (socket->dev.dev != dev) continue; mutex_lock(&socket->skt_mutex); socket_resume(socket); @@ -143,12 +143,12 @@ EXPORT_SYMBOL(pcmcia_socket_dev_resume); struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt) { - struct device *dev = get_device(&skt->dev); - if (!dev) + struct class_device *cl_dev = class_device_get(&skt->dev); + if (!cl_dev) return NULL; - skt = dev_get_drvdata(dev); + skt = class_get_devdata(cl_dev); if (!try_module_get(skt->owner)) { - put_device(&skt->dev); + class_device_put(&skt->dev); return NULL; } return (skt); @@ -159,14 +159,14 @@ EXPORT_SYMBOL(pcmcia_get_socket); void pcmcia_put_socket(struct pcmcia_socket *skt) { module_put(skt->owner); - put_device(&skt->dev); + class_device_put(&skt->dev); } EXPORT_SYMBOL(pcmcia_put_socket); -static void pcmcia_release_socket(struct device *dev) +static void pcmcia_release_socket(struct class_device *class_dev) { - struct pcmcia_socket *socket = dev_get_drvdata(dev); + struct pcmcia_socket *socket = class_get_devdata(class_dev); complete(&socket->socket_released); } @@ -181,7 +181,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) struct task_struct *tsk; int ret; - if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops) + if (!socket || !socket->ops || !socket->dev.dev || !socket->resource_ops) return -EINVAL; cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops); @@ -226,9 +226,9 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) #endif /* set proper values in socket->dev */ - dev_set_drvdata(&socket->dev, socket); + socket->dev.class_data = socket; socket->dev.class = &pcmcia_socket_class; - snprintf(socket->dev.bus_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock); + snprintf(socket->dev.class_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock); /* base address = 0, map = 0 */ socket->cis_mem.flags = 0; @@ -640,7 +640,7 @@ static int pccardd(void *__skt) skt->ops->set_socket(skt, &skt->socket); /* register with the device core */ - ret = device_register(&skt->dev); + ret = class_device_register(&skt->dev); if (ret) { printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n", skt); @@ -689,7 +689,7 @@ static int pccardd(void *__skt) remove_wait_queue(&skt->thread_wait, &wait); /* remove from the device core */ - device_unregister(&skt->dev); + class_device_unregister(&skt->dev); return 0; } @@ -904,7 +904,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) EXPORT_SYMBOL(pcmcia_insert_card); -static int pcmcia_socket_uevent(struct device *dev, char **envp, +static int pcmcia_socket_uevent(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); @@ -930,8 +930,8 @@ static void pcmcia_release_socket_class(struct class *data) struct class pcmcia_socket_class = { .name = "pcmcia_socket", - .dev_uevent = pcmcia_socket_uevent, - .dev_release = pcmcia_release_socket, + .uevent = pcmcia_socket_uevent, + .release = pcmcia_release_socket, .class_release = pcmcia_release_socket_class, }; EXPORT_SYMBOL(pcmcia_socket_class); diff --git a/trunk/drivers/pcmcia/cs_internal.h b/trunk/drivers/pcmcia/cs_internal.h index 9fa207e3c7b3..f573ea04db6f 100644 --- a/trunk/drivers/pcmcia/cs_internal.h +++ b/trunk/drivers/pcmcia/cs_internal.h @@ -142,7 +142,7 @@ struct pcmcia_callback{ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c); -#define cs_socket_name(skt) ((skt)->dev.bus_id) +#define cs_socket_name(skt) ((skt)->dev.class_id) #ifdef DEBUG extern int cs_debug_level(int); @@ -158,6 +158,6 @@ extern int cs_debug_level(int); #endif #define cs_err(skt, fmt, arg...) \ - printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg) + printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.class_id , ## arg) #endif /* _LINUX_CS_INTERNAL_H */ diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index 18e111e12339..7355eb455a88 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -572,7 +572,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f p_dev->func = function; p_dev->dev.bus = &pcmcia_bus_type; - p_dev->dev.parent = s->dev.parent; + p_dev->dev.parent = s->dev.dev; p_dev->dev.release = pcmcia_release_dev; bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); @@ -1328,10 +1328,10 @@ static struct pcmcia_callback pcmcia_bus_callback = { .resume = pcmcia_bus_resume, }; -static int __devinit pcmcia_bus_add_socket(struct device *dev, +static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, struct class_interface *class_intf) { - struct pcmcia_socket *socket = dev_get_drvdata(dev); + struct pcmcia_socket *socket = class_get_devdata(class_dev); int ret; socket = pcmcia_get_socket(socket); @@ -1364,10 +1364,10 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, return 0; } -static void pcmcia_bus_remove_socket(struct device *dev, +static void pcmcia_bus_remove_socket(struct class_device *class_dev, struct class_interface *class_intf) { - struct pcmcia_socket *socket = dev_get_drvdata(dev); + struct pcmcia_socket *socket = class_get_devdata(class_dev); if (!socket) return; @@ -1389,8 +1389,8 @@ static void pcmcia_bus_remove_socket(struct device *dev, /* the pcmcia_bus_interface is used to handle pcmcia socket devices */ static struct class_interface pcmcia_bus_interface = { .class = &pcmcia_socket_class, - .add_dev = &pcmcia_bus_add_socket, - .remove_dev = &pcmcia_bus_remove_socket, + .add = &pcmcia_bus_add_socket, + .remove = &pcmcia_bus_remove_socket, }; diff --git a/trunk/drivers/pcmcia/i82092.c b/trunk/drivers/pcmcia/i82092.c index df21e2d16f87..c2ea07aa7a12 100644 --- a/trunk/drivers/pcmcia/i82092.c +++ b/trunk/drivers/pcmcia/i82092.c @@ -161,7 +161,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de pci_set_drvdata(dev, &sockets[i].socket); for (i = 0; idev; + sockets[i].socket.dev.dev = &dev->dev; sockets[i].socket.ops = &i82092aa_operations; sockets[i].socket.resource_ops = &pccard_nonstatic_ops; ret = pcmcia_register_socket(&sockets[i].socket); diff --git a/trunk/drivers/pcmcia/i82365.c b/trunk/drivers/pcmcia/i82365.c index 72ff2f615b33..ea74f98a7350 100644 --- a/trunk/drivers/pcmcia/i82365.c +++ b/trunk/drivers/pcmcia/i82365.c @@ -1298,7 +1298,7 @@ static int __init init_i82365(void) /* register sockets with the pcmcia core */ for (i = 0; i < sockets; i++) { - socket[i].socket.dev.parent = &i82365_device->dev; + socket[i].socket.dev.dev = &i82365_device->dev; socket[i].socket.ops = &pcic_operations; socket[i].socket.resource_ops = &pccard_nonstatic_ops; socket[i].socket.owner = THIS_MODULE; diff --git a/trunk/drivers/pcmcia/pcmcia_ioctl.c b/trunk/drivers/pcmcia/pcmcia_ioctl.c index 88494149e910..327372b7a54e 100644 --- a/trunk/drivers/pcmcia/pcmcia_ioctl.c +++ b/trunk/drivers/pcmcia/pcmcia_ioctl.c @@ -59,6 +59,7 @@ typedef struct user_info_t { #ifdef DEBUG extern int ds_pc_debug; +#define cs_socket_name(skt) ((skt)->dev.class_id) #define ds_dbg(lvl, fmt, arg...) do { \ if (ds_pc_debug >= lvl) \ diff --git a/trunk/drivers/pcmcia/pcmcia_resource.c b/trunk/drivers/pcmcia/pcmcia_resource.c index 0ce39de834c4..b9201c2ec38b 100644 --- a/trunk/drivers/pcmcia/pcmcia_resource.c +++ b/trunk/drivers/pcmcia/pcmcia_resource.c @@ -48,6 +48,7 @@ static u8 pcmcia_used_irq[NR_IRQS]; #ifdef DEBUG extern int ds_pc_debug; +#define cs_socket_name(skt) ((skt)->dev.class_id) #define ds_dbg(skt, lvl, fmt, arg...) do { \ if (ds_pc_debug >= lvl) \ diff --git a/trunk/drivers/pcmcia/pd6729.c b/trunk/drivers/pcmcia/pd6729.c index dd0ddf19ee57..360c24896548 100644 --- a/trunk/drivers/pcmcia/pd6729.c +++ b/trunk/drivers/pcmcia/pd6729.c @@ -682,7 +682,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, socket[i].socket.ops = &pd6729_operations; socket[i].socket.resource_ops = &pccard_nonstatic_ops; - socket[i].socket.dev.parent = &dev->dev; + socket[i].socket.dev.dev = &dev->dev; socket[i].socket.driver_data = &socket[i]; } diff --git a/trunk/drivers/pcmcia/rsrc_nonstatic.c b/trunk/drivers/pcmcia/rsrc_nonstatic.c index bfcaad6021cf..c3176b16b7be 100644 --- a/trunk/drivers/pcmcia/rsrc_nonstatic.c +++ b/trunk/drivers/pcmcia/rsrc_nonstatic.c @@ -616,7 +616,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star static struct resource *nonstatic_find_io_region(unsigned long base, int num, unsigned long align, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.bus_id); + struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id); struct socket_data *s_data = s->resource_data; struct pcmcia_align_data data; unsigned long min = base; @@ -650,7 +650,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, static struct resource * nonstatic_find_mem_region(u_long base, u_long num, u_long align, int low, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.bus_id); + struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id); struct socket_data *s_data = s->resource_data; struct pcmcia_align_data data; unsigned long min, max; @@ -897,10 +897,9 @@ EXPORT_SYMBOL(pccard_nonstatic_ops); /* sysfs interface to the resource database */ -static ssize_t show_io_db(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_io_db(struct class_device *class_dev, char *buf) { - struct pcmcia_socket *s = dev_get_drvdata(dev); + struct pcmcia_socket *s = class_get_devdata(class_dev); struct socket_data *data; struct resource_map *p; ssize_t ret = 0; @@ -921,11 +920,9 @@ static ssize_t show_io_db(struct device *dev, return (ret); } -static ssize_t store_io_db(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size_t count) { - struct pcmcia_socket *s = dev_get_drvdata(dev); + struct pcmcia_socket *s = class_get_devdata(class_dev); unsigned long start_addr, end_addr; unsigned int add = ADD_MANAGED_RESOURCE; ssize_t ret = 0; @@ -950,12 +947,11 @@ static ssize_t store_io_db(struct device *dev, return ret ? ret : count; } -static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db); +static CLASS_DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db); -static ssize_t show_mem_db(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_mem_db(struct class_device *class_dev, char *buf) { - struct pcmcia_socket *s = dev_get_drvdata(dev); + struct pcmcia_socket *s = class_get_devdata(class_dev); struct socket_data *data; struct resource_map *p; ssize_t ret = 0; @@ -976,11 +972,9 @@ static ssize_t show_mem_db(struct device *dev, return (ret); } -static ssize_t store_mem_db(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, size_t count) { - struct pcmcia_socket *s = dev_get_drvdata(dev); + struct pcmcia_socket *s = class_get_devdata(class_dev); unsigned long start_addr, end_addr; unsigned int add = ADD_MANAGED_RESOURCE; ssize_t ret = 0; @@ -1005,25 +999,25 @@ static ssize_t store_mem_db(struct device *dev, return ret ? ret : count; } -static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db); +static CLASS_DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db); -static struct device_attribute *pccard_rsrc_attributes[] = { - &dev_attr_available_resources_io, - &dev_attr_available_resources_mem, +static struct class_device_attribute *pccard_rsrc_attributes[] = { + &class_device_attr_available_resources_io, + &class_device_attr_available_resources_mem, NULL, }; -static int __devinit pccard_sysfs_add_rsrc(struct device *dev, +static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev, struct class_interface *class_intf) { - struct pcmcia_socket *s = dev_get_drvdata(dev); - struct device_attribute **attr; + struct pcmcia_socket *s = class_get_devdata(class_dev); + struct class_device_attribute **attr; int ret = 0; if (s->resource_ops != &pccard_nonstatic_ops) return 0; for (attr = pccard_rsrc_attributes; *attr; attr++) { - ret = device_create_file(dev, *attr); + ret = class_device_create_file(class_dev, *attr); if (ret) break; } @@ -1031,23 +1025,23 @@ static int __devinit pccard_sysfs_add_rsrc(struct device *dev, return ret; } -static void __devexit pccard_sysfs_remove_rsrc(struct device *dev, +static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev, struct class_interface *class_intf) { - struct pcmcia_socket *s = dev_get_drvdata(dev); - struct device_attribute **attr; + struct pcmcia_socket *s = class_get_devdata(class_dev); + struct class_device_attribute **attr; if (s->resource_ops != &pccard_nonstatic_ops) return; for (attr = pccard_rsrc_attributes; *attr; attr++) - device_remove_file(dev, *attr); + class_device_remove_file(class_dev, *attr); } static struct class_interface pccard_rsrc_interface = { .class = &pcmcia_socket_class, - .add_dev = &pccard_sysfs_add_rsrc, - .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc), + .add = &pccard_sysfs_add_rsrc, + .remove = __devexit_p(&pccard_sysfs_remove_rsrc), }; static int __init nonstatic_sysfs_init(void) diff --git a/trunk/drivers/pcmcia/soc_common.c b/trunk/drivers/pcmcia/soc_common.c index d2a3bea55de2..e433704e026a 100644 --- a/trunk/drivers/pcmcia/soc_common.c +++ b/trunk/drivers/pcmcia/soc_common.c @@ -478,10 +478,10 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i * * Returns: the number of characters added to the buffer */ -static ssize_t show_status(struct device *dev, char *buf) +static ssize_t show_status(struct class_device *class_dev, char *buf) { struct soc_pcmcia_socket *skt = - container_of(dev, struct soc_pcmcia_socket, socket.dev); + container_of(class_dev, struct soc_pcmcia_socket, socket.dev); char *p = buf; p+=sprintf(p, "slot : %d\n", skt->nr); @@ -747,7 +747,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops add_timer(&skt->poll_timer); - device_create_file(&skt->socket.dev, &device_attr_status); + class_device_create_file(&skt->socket.dev, &class_device_attr_status); } dev_set_drvdata(dev, sinfo); diff --git a/trunk/drivers/pcmcia/socket_sysfs.c b/trunk/drivers/pcmcia/socket_sysfs.c index ea5765c3bdc0..b005602d6b53 100644 --- a/trunk/drivers/pcmcia/socket_sysfs.c +++ b/trunk/drivers/pcmcia/socket_sysfs.c @@ -40,8 +40,7 @@ #define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev) -static ssize_t pccard_show_type(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t pccard_show_type(struct class_device *dev, char *buf) { struct pcmcia_socket *s = to_socket(dev); @@ -51,10 +50,9 @@ static ssize_t pccard_show_type(struct device *dev, struct device_attribute *att return sprintf(buf, "32-bit\n"); return sprintf(buf, "16-bit\n"); } -static DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL); +static CLASS_DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL); -static ssize_t pccard_show_voltage(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t pccard_show_voltage(struct class_device *dev, char *buf) { struct pcmcia_socket *s = to_socket(dev); @@ -65,31 +63,28 @@ static ssize_t pccard_show_voltage(struct device *dev, struct device_attribute * s->socket.Vcc % 10); return sprintf(buf, "X.XV\n"); } -static DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL); +static CLASS_DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL); -static ssize_t pccard_show_vpp(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t pccard_show_vpp(struct class_device *dev, char *buf) { struct pcmcia_socket *s = to_socket(dev); if (!(s->state & SOCKET_PRESENT)) return -ENODEV; return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10); } -static DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL); +static CLASS_DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL); -static ssize_t pccard_show_vcc(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t pccard_show_vcc(struct class_device *dev, char *buf) { struct pcmcia_socket *s = to_socket(dev); if (!(s->state & SOCKET_PRESENT)) return -ENODEV; return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10); } -static DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL); +static CLASS_DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL); -static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count) { ssize_t ret; struct pcmcia_socket *s = to_socket(dev); @@ -101,20 +96,16 @@ static ssize_t pccard_store_insert(struct device *dev, struct device_attribute * return ret ? ret : count; } -static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert); +static CLASS_DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert); -static ssize_t pccard_show_card_pm_state(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t pccard_show_card_pm_state(struct class_device *dev, char *buf) { struct pcmcia_socket *s = to_socket(dev); return sprintf(buf, "%s\n", s->state & SOCKET_SUSPEND ? "off" : "on"); } -static ssize_t pccard_store_card_pm_state(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t pccard_store_card_pm_state(struct class_device *dev, const char *buf, size_t count) { ssize_t ret = -EINVAL; struct pcmcia_socket *s = to_socket(dev); @@ -129,11 +120,9 @@ static ssize_t pccard_store_card_pm_state(struct device *dev, return ret ? -ENODEV : count; } -static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state); +static CLASS_DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state); -static ssize_t pccard_store_eject(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, size_t count) { ssize_t ret; struct pcmcia_socket *s = to_socket(dev); @@ -145,20 +134,16 @@ static ssize_t pccard_store_eject(struct device *dev, return ret ? ret : count; } -static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject); +static CLASS_DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject); -static ssize_t pccard_show_irq_mask(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t pccard_show_irq_mask(struct class_device *dev, char *buf) { struct pcmcia_socket *s = to_socket(dev); return sprintf(buf, "0x%04x\n", s->irq_mask); } -static ssize_t pccard_store_irq_mask(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t pccard_store_irq_mask(struct class_device *dev, const char *buf, size_t count) { ssize_t ret; struct pcmcia_socket *s = to_socket(dev); @@ -176,19 +161,16 @@ static ssize_t pccard_store_irq_mask(struct device *dev, return ret ? ret : count; } -static DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask); +static CLASS_DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask); -static ssize_t pccard_show_resource(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t pccard_show_resource(struct class_device *dev, char *buf) { struct pcmcia_socket *s = to_socket(dev); return sprintf(buf, "%s\n", s->resource_setup_done ? "yes" : "no"); } -static ssize_t pccard_store_resource(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t pccard_store_resource(struct class_device *dev, const char *buf, size_t count) { unsigned long flags; struct pcmcia_socket *s = to_socket(dev); @@ -214,7 +196,7 @@ static ssize_t pccard_store_resource(struct device *dev, return count; } -static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource); +static CLASS_DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource); static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off, size_t count) @@ -297,7 +279,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size if (off + count > size) count = size - off; - s = to_socket(container_of(kobj, struct device, kobj)); + s = to_socket(container_of(kobj, struct class_device, kobj)); if (!(s->state & SOCKET_PRESENT)) return -ENODEV; @@ -314,7 +296,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count) { - struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj)); + struct pcmcia_socket *s = to_socket(container_of(kobj, struct class_device, kobj)); cisdump_t *cis; int error; @@ -353,16 +335,16 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz } -static struct device_attribute *pccard_socket_attributes[] = { - &dev_attr_card_type, - &dev_attr_card_voltage, - &dev_attr_card_vpp, - &dev_attr_card_vcc, - &dev_attr_card_insert, - &dev_attr_card_pm_state, - &dev_attr_card_eject, - &dev_attr_card_irq_mask, - &dev_attr_available_resources_setup_done, +static struct class_device_attribute *pccard_socket_attributes[] = { + &class_device_attr_card_type, + &class_device_attr_card_voltage, + &class_device_attr_card_vpp, + &class_device_attr_card_vcc, + &class_device_attr_card_insert, + &class_device_attr_card_pm_state, + &class_device_attr_card_eject, + &class_device_attr_card_irq_mask, + &class_device_attr_available_resources_setup_done, NULL, }; @@ -373,35 +355,35 @@ static struct bin_attribute pccard_cis_attr = { .write = pccard_store_cis, }; -static int __devinit pccard_sysfs_add_socket(struct device *dev, +static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev, struct class_interface *class_intf) { - struct device_attribute **attr; + struct class_device_attribute **attr; int ret = 0; for (attr = pccard_socket_attributes; *attr; attr++) { - ret = device_create_file(dev, *attr); + ret = class_device_create_file(class_dev, *attr); if (ret) break; } if (!ret) - ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr); + ret = sysfs_create_bin_file(&class_dev->kobj, &pccard_cis_attr); return ret; } -static void __devexit pccard_sysfs_remove_socket(struct device *dev, +static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev, struct class_interface *class_intf) { - struct device_attribute **attr; + struct class_device_attribute **attr; - sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr); + sysfs_remove_bin_file(&class_dev->kobj, &pccard_cis_attr); for (attr = pccard_socket_attributes; *attr; attr++) - device_remove_file(dev, *attr); + class_device_remove_file(class_dev, *attr); } struct class_interface pccard_sysfs_interface = { .class = &pcmcia_socket_class, - .add_dev = &pccard_sysfs_add_socket, - .remove_dev = __devexit_p(&pccard_sysfs_remove_socket), + .add = &pccard_sysfs_add_socket, + .remove = __devexit_p(&pccard_sysfs_remove_socket), }; diff --git a/trunk/drivers/pcmcia/tcic.c b/trunk/drivers/pcmcia/tcic.c index c158cf38b9dd..2d2f415f80a8 100644 --- a/trunk/drivers/pcmcia/tcic.c +++ b/trunk/drivers/pcmcia/tcic.c @@ -512,7 +512,7 @@ static int __init init_tcic(void) for (i = 0; i < sockets; i++) { socket_table[i].socket.ops = &tcic_operations; socket_table[i].socket.resource_ops = &pccard_nonstatic_ops; - socket_table[i].socket.dev.parent = &tcic_device.dev; + socket_table[i].socket.dev.dev = &tcic_device.dev; ret = pcmcia_register_socket(&socket_table[i].socket); if (ret && i) pcmcia_unregister_socket(&socket_table[0].socket); diff --git a/trunk/drivers/pcmcia/yenta_socket.c b/trunk/drivers/pcmcia/yenta_socket.c index a61d768f6e0e..da471bddc972 100644 --- a/trunk/drivers/pcmcia/yenta_socket.c +++ b/trunk/drivers/pcmcia/yenta_socket.c @@ -1104,7 +1104,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i /* prepare pcmcia_socket */ socket->socket.ops = ¥ta_socket_operations; socket->socket.resource_ops = &pccard_nonstatic_ops; - socket->socket.dev.parent = &dev->dev; + socket->socket.dev.dev = &dev->dev; socket->socket.driver_data = socket; socket->socket.owner = THIS_MODULE; socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD; diff --git a/trunk/drivers/pnp/pnpacpi/Kconfig b/trunk/drivers/pnp/pnpacpi/Kconfig index ad27e5e0101f..b1854171b963 100644 --- a/trunk/drivers/pnp/pnpacpi/Kconfig +++ b/trunk/drivers/pnp/pnpacpi/Kconfig @@ -2,8 +2,8 @@ # Plug and Play ACPI configuration # config PNPACPI - bool "Plug and Play ACPI support" - depends on PNP && ACPI + bool "Plug and Play ACPI support (EXPERIMENTAL)" + depends on PNP && ACPI && EXPERIMENTAL default y ---help--- Linux uses the PNPACPI to autodetect built-in diff --git a/trunk/drivers/pnp/system.c b/trunk/drivers/pnp/system.c index 2065e74bb63f..d42015c382af 100644 --- a/trunk/drivers/pnp/system.c +++ b/trunk/drivers/pnp/system.c @@ -3,8 +3,7 @@ * * Some code is based on pnpbios_core.c * Copyright 2002 Adam Belay - * (c) Copyright 2007 Hewlett-Packard Development Company, L.P. - * Bjorn Helgaas + * */ #include @@ -22,21 +21,18 @@ static const struct pnp_device_id pnp_dev_table[] = { { "", 0 } }; -static void reserve_range(char *pnpid, int start, int end, int port) +static void reserve_ioport_range(char *pnpid, int start, int end) { struct resource *res; char *regionid; regionid = kmalloc(16, GFP_KERNEL); - if (regionid == NULL) + if ( regionid == NULL ) return; snprintf(regionid, 16, "pnp %s", pnpid); - if (port) - res = request_region(start,end-start+1,regionid); - else - res = request_mem_region(start,end-start+1,regionid); - if (res == NULL) - kfree(regionid); + res = request_region(start,end-start+1,regionid); + if ( res == NULL ) + kfree( regionid ); else res->flags &= ~IORESOURCE_BUSY; /* @@ -45,20 +41,26 @@ static void reserve_range(char *pnpid, int start, int end, int port) * have double reservations. */ printk(KERN_INFO - "pnp: %s: %s range 0x%x-0x%x %s reserved\n", - pnpid, port ? "ioport" : "iomem", start, end, - NULL != res ? "has been" : "could not be"); + "pnp: %s: ioport range 0x%x-0x%x %s reserved\n", + pnpid, start, end, + NULL != res ? "has been" : "could not be" + ); + + return; } -static void reserve_resources_of_dev(struct pnp_dev *dev) +static void reserve_resources_of_dev( struct pnp_dev *dev ) { int i; - for (i = 0; i < PNP_MAX_PORT; i++) { + for (i=0;idev.bus_id, pnp_port_start(dev, i), - pnp_port_end(dev, i), 1); - } - - for (i = 0; i < PNP_MAX_MEM; i++) { - if (!pnp_mem_valid(dev, i)) + /* invalid endpoint */ + /* Do nothing */ continue; - - reserve_range(dev->dev.bus_id, pnp_mem_start(dev, i), - pnp_mem_end(dev, i), 0); + reserve_ioport_range( + dev->dev.bus_id, + pnp_port_start(dev, i), + pnp_port_end(dev, i) + ); } return; diff --git a/trunk/drivers/ps3/Makefile b/trunk/drivers/ps3/Makefile index d547cf50ca9d..8433eb7562cb 100644 --- a/trunk/drivers/ps3/Makefile +++ b/trunk/drivers/ps3/Makefile @@ -1 +1,2 @@ +obj-y += system-bus.o obj-$(CONFIG_PS3_VUART) += vuart.o diff --git a/trunk/arch/powerpc/platforms/ps3/system-bus.c b/trunk/drivers/ps3/system-bus.c similarity index 94% rename from trunk/arch/powerpc/platforms/ps3/system-bus.c rename to trunk/drivers/ps3/system-bus.c index bce6136cbce7..d79f949bcb2a 100644 --- a/trunk/arch/powerpc/platforms/ps3/system-bus.c +++ b/trunk/drivers/ps3/system-bus.c @@ -25,11 +25,10 @@ #include #include +#include #include #include -#include "platform.h" - #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__) static void _dump_mmio_region(const struct ps3_mmio_region* r, const char* func, int line) @@ -51,7 +50,7 @@ int ps3_mmio_region_create(struct ps3_mmio_region *r) if (result) { pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n", __func__, __LINE__, ps3_result(result)); - r->lpar_addr = 0; + r->lpar_addr = r->len = r->bus_addr = 0; } dump_mmio_region(r); @@ -63,13 +62,13 @@ int ps3_free_mmio_region(struct ps3_mmio_region *r) int result; result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id, - r->lpar_addr); + r->bus_addr); if (result) pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n", __func__, __LINE__, ps3_result(result)); - r->lpar_addr = 0; + r->lpar_addr = r->len = r->bus_addr = 0; return result; } @@ -159,7 +158,7 @@ static int ps3_system_bus_remove(struct device *_dev) } struct bus_type ps3_system_bus_type = { - .name = "ps3_system_bus", + .name = "ps3_system_bus", .match = ps3_system_bus_match, .probe = ps3_system_bus_probe, .remove = ps3_system_bus_remove, @@ -272,29 +271,10 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents, enum dma_data_direction direction) { - struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); - int i; - #if defined(CONFIG_PS3_DYNAMIC_DMA) BUG_ON("do"); - return -EPERM; -#else - for (i = 0; i < nents; i++, sg++) { - int result = ps3_dma_map(dev->d_region, - page_to_phys(sg->page) + sg->offset, sg->length, - &sg->dma_address); - - if (result) { - pr_debug("%s:%d: ps3_dma_map failed (%d)\n", - __func__, __LINE__, result); - return -EINVAL; - } - - sg->dma_length = sg->length; - } - - return nents; #endif + return 0; } static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg, @@ -307,7 +287,7 @@ static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg, static int ps3_dma_supported(struct device *_dev, u64 mask) { - return mask >= DMA_32BIT_MASK; + return 1; } static struct dma_mapping_ops ps3_dma_ops = { diff --git a/trunk/drivers/ps3/vuart.c b/trunk/drivers/ps3/vuart.c index a72da8f651f8..6974f65bcda5 100644 --- a/trunk/drivers/ps3/vuart.c +++ b/trunk/drivers/ps3/vuart.c @@ -783,8 +783,8 @@ static int ps3_vuart_probe(struct device *_dev) vuart_private.in_use++; if (vuart_private.in_use == 1) { - result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY, - (void*)&vuart_private.bmp.status, &vuart_private.virq); + result = ps3_alloc_vuart_irq((void*)&vuart_private.bmp.status, + &vuart_private.virq); if (result) { dev_dbg(&dev->core, diff --git a/trunk/drivers/ps3/vuart.h b/trunk/drivers/ps3/vuart.h index 11c421cf7a03..28fd89f0c8aa 100644 --- a/trunk/drivers/ps3/vuart.h +++ b/trunk/drivers/ps3/vuart.h @@ -21,6 +21,37 @@ #if !defined(_PS3_VUART_H) #define _PS3_VUART_H +struct ps3_vuart_stats { + unsigned long bytes_written; + unsigned long bytes_read; + unsigned long tx_interrupts; + unsigned long rx_interrupts; + unsigned long disconnect_interrupts; +}; + +/** + * struct ps3_vuart_port_device - a device on a vuart port + */ + +struct ps3_vuart_port_device { + enum ps3_match_id match_id; + struct device core; + + /* private driver variables */ + unsigned int port_number; + unsigned long interrupt_mask; + struct { + spinlock_t lock; + struct list_head head; + } tx_list; + struct { + unsigned long bytes_held; + spinlock_t lock; + struct list_head head; + } rx_list; + struct ps3_vuart_stats stats; +}; + /** * struct ps3_vuart_port_driver - a driver for a device on a vuart port */ @@ -37,9 +68,9 @@ struct ps3_vuart_port_driver { /* int (*resume)(struct ps3_vuart_port_device *); */ }; +int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev); int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv); void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv); - int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf, unsigned int bytes); int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf, @@ -55,4 +86,9 @@ static inline struct ps3_vuart_port_device *to_ps3_vuart_port_device( return container_of(_dev, struct ps3_vuart_port_device, core); } +int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf, + unsigned int bytes); +int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf, + unsigned int bytes); + #endif diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 821386c7b576..b318500785e5 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -7558,6 +7558,9 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B8, + 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 925fb607d8c4..08e55fdc882a 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -40,7 +40,6 @@ #include #include -#include #include #include @@ -146,7 +145,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) /* was hostalloc but changed cause it blows away the */ /* large tlb mapping when pinning the kernel area */ mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); - dma_addr = (u32)cpm_dpram_phys(mem_addr); + dma_addr = (u32)mem_addr; } else mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, GFP_KERNEL); @@ -206,7 +205,7 @@ int __init cpm_uart_init_portdesc(void) (unsigned long)&cpmp->cp_smc[0]; cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock(); + cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; #endif @@ -218,7 +217,7 @@ int __init cpm_uart_init_portdesc(void) (unsigned long)&cpmp->cp_smc[1]; cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock(); + cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; #endif @@ -232,7 +231,7 @@ int __init cpm_uart_init_portdesc(void) ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock(); + cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; #endif @@ -246,7 +245,7 @@ int __init cpm_uart_init_portdesc(void) ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock(); + cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; #endif @@ -260,7 +259,7 @@ int __init cpm_uart_init_portdesc(void) ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock(); + cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq); cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; #endif @@ -274,7 +273,7 @@ int __init cpm_uart_init_portdesc(void) ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock(); + cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq); cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; #endif return 0; diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.h index a99e45e2b6d8..5eb49ea63bfe 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.h +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.h @@ -20,6 +20,9 @@ #define SCC3_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC3) #define SCC4_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC4) +/* the CPM address */ +#define CPM_ADDR IMAP_ADDR + static inline void cpm_set_brg(int brg, int baud) { cpm_setbrg(brg, baud); diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm2.h index 1b3219f56c81..4b779111eaf9 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm2.h +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm2.h @@ -20,6 +20,9 @@ #define SCC3_IRQ SIU_INT_SCC3 #define SCC4_IRQ SIU_INT_SCC4 +/* the CPM address */ +#define CPM_ADDR CPM_MAP_ADDR + static inline void cpm_set_brg(int brg, int baud) { cpm_setbrg(brg, baud); diff --git a/trunk/drivers/usb/atm/speedtch.c b/trunk/drivers/usb/atm/speedtch.c index 638b8009b3bc..8ed6c75adf0f 100644 --- a/trunk/drivers/usb/atm/speedtch.c +++ b/trunk/drivers/usb/atm/speedtch.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include "usbatm.h" diff --git a/trunk/drivers/usb/class/usblp.c b/trunk/drivers/usb/class/usblp.c index 63e50a1f1396..6377db1b446d 100644 --- a/trunk/drivers/usb/class/usblp.c +++ b/trunk/drivers/usb/class/usblp.c @@ -398,9 +398,6 @@ static int usblp_open(struct inode *inode, struct file *file) retval = 0; #endif - retval = usb_autopm_get_interface(intf); - if (retval < 0) - goto out; usblp->used = 1; file->private_data = usblp; @@ -445,7 +442,6 @@ static int usblp_release(struct inode *inode, struct file *file) usblp->used = 0; if (usblp->present) { usblp_unlink_urbs(usblp); - usb_autopm_put_interface(usblp->intf); } else /* finish cleanup from disconnect */ usblp_cleanup (usblp); mutex_unlock (&usblp_mutex); @@ -1207,9 +1203,14 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message) { struct usblp *usblp = usb_get_intfdata (intf); + /* this races against normal access and open */ + mutex_lock (&usblp_mutex); + mutex_lock (&usblp->mut); /* we take no more IO */ usblp->sleeping = 1; usblp_unlink_urbs(usblp); + mutex_unlock (&usblp->mut); + mutex_unlock (&usblp_mutex); return 0; } @@ -1219,9 +1220,15 @@ static int usblp_resume (struct usb_interface *intf) struct usblp *usblp = usb_get_intfdata (intf); int r; + mutex_lock (&usblp_mutex); + mutex_lock (&usblp->mut); + usblp->sleeping = 0; r = handle_bidir (usblp); + mutex_unlock (&usblp->mut); + mutex_unlock (&usblp_mutex); + return r; } @@ -1244,7 +1251,6 @@ static struct usb_driver usblp_driver = { .suspend = usblp_suspend, .resume = usblp_resume, .id_table = usblp_ids, - .supports_autosuspend = 1, }; static int __init usblp_init(void) diff --git a/trunk/drivers/usb/core/Kconfig b/trunk/drivers/usb/core/Kconfig index 2fc0f88a3d86..3e66b2a9974a 100644 --- a/trunk/drivers/usb/core/Kconfig +++ b/trunk/drivers/usb/core/Kconfig @@ -33,6 +33,19 @@ config USB_DEVICEFS Most users want to say Y here. +config USB_BANDWIDTH + bool "Enforce USB bandwidth allocation (EXPERIMENTAL)" + depends on USB && EXPERIMENTAL + help + If you say Y here, the USB subsystem enforces USB bandwidth + allocation and will prevent some device opens from succeeding + if they would cause USB bandwidth usage to go above 90% of + the bus bandwidth. + + If you say N here, these conditions will cause warning messages + about USB bandwidth usage to be logged and some devices or + drivers may not work correctly. + config USB_DYNAMIC_MINORS bool "Dynamic USB minor allocation (EXPERIMENTAL)" depends on USB && EXPERIMENTAL diff --git a/trunk/drivers/usb/core/buffer.c b/trunk/drivers/usb/core/buffer.c index ead2475406b8..c3915dc28608 100644 --- a/trunk/drivers/usb/core/buffer.c +++ b/trunk/drivers/usb/core/buffer.c @@ -49,9 +49,9 @@ static const size_t pool_max [HCD_BUFFER_POOLS] = { * * Call hcd_buffer_destroy() to clean up after using those pools. */ -int hcd_buffer_create(struct usb_hcd *hcd) +int hcd_buffer_create (struct usb_hcd *hcd) { - char name[16]; + char name [16]; int i, size; if (!hcd->self.controller->dma_mask) @@ -60,11 +60,11 @@ int hcd_buffer_create(struct usb_hcd *hcd) for (i = 0; i < HCD_BUFFER_POOLS; i++) { if (!(size = pool_max [i])) continue; - snprintf(name, sizeof name, "buffer-%d", size); - hcd->pool[i] = dma_pool_create(name, hcd->self.controller, + snprintf (name, sizeof name, "buffer-%d", size); + hcd->pool [i] = dma_pool_create (name, hcd->self.controller, size, size, 0); if (!hcd->pool [i]) { - hcd_buffer_destroy(hcd); + hcd_buffer_destroy (hcd); return -ENOMEM; } } @@ -79,14 +79,14 @@ int hcd_buffer_create(struct usb_hcd *hcd) * * This frees the buffer pools created by hcd_buffer_create(). */ -void hcd_buffer_destroy(struct usb_hcd *hcd) +void hcd_buffer_destroy (struct usb_hcd *hcd) { int i; for (i = 0; i < HCD_BUFFER_POOLS; i++) { - struct dma_pool *pool = hcd->pool[i]; + struct dma_pool *pool = hcd->pool [i]; if (pool) { - dma_pool_destroy(pool); + dma_pool_destroy (pool); hcd->pool[i] = NULL; } } @@ -97,8 +97,8 @@ void hcd_buffer_destroy(struct usb_hcd *hcd) * better sharing and to leverage mm/slab.c intelligence. */ -void *hcd_buffer_alloc( - struct usb_bus *bus, +void *hcd_buffer_alloc ( + struct usb_bus *bus, size_t size, gfp_t mem_flags, dma_addr_t *dma @@ -110,18 +110,18 @@ void *hcd_buffer_alloc( /* some USB hosts just use PIO */ if (!bus->controller->dma_mask) { *dma = ~(dma_addr_t) 0; - return kmalloc(size, mem_flags); + return kmalloc (size, mem_flags); } for (i = 0; i < HCD_BUFFER_POOLS; i++) { if (size <= pool_max [i]) - return dma_pool_alloc(hcd->pool [i], mem_flags, dma); + return dma_pool_alloc (hcd->pool [i], mem_flags, dma); } - return dma_alloc_coherent(hcd->self.controller, size, dma, 0); + return dma_alloc_coherent (hcd->self.controller, size, dma, 0); } -void hcd_buffer_free( - struct usb_bus *bus, +void hcd_buffer_free ( + struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma @@ -134,15 +134,15 @@ void hcd_buffer_free( return; if (!bus->controller->dma_mask) { - kfree(addr); + kfree (addr); return; } for (i = 0; i < HCD_BUFFER_POOLS; i++) { if (size <= pool_max [i]) { - dma_pool_free(hcd->pool [i], addr, dma); + dma_pool_free (hcd->pool [i], addr, dma); return; } } - dma_free_coherent(hcd->self.controller, size, addr, dma); + dma_free_coherent (hcd->self.controller, size, addr, dma); } diff --git a/trunk/drivers/usb/core/devices.c b/trunk/drivers/usb/core/devices.c index a47c30b2d764..ea398e5d50af 100644 --- a/trunk/drivers/usb/core/devices.c +++ b/trunk/drivers/usb/core/devices.c @@ -104,7 +104,7 @@ static const char *format_config = static const char *format_iface = /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ - "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; + "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; static const char *format_endpt = /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ @@ -164,10 +164,10 @@ static const char *class_decode(const int class) for (ix = 0; clas_info[ix].class != -1; ix++) if (clas_info[ix].class == class) break; - return clas_info[ix].class_name; + return (clas_info[ix].class_name); } -static char *usb_dump_endpoint_descriptor( +static char *usb_dump_endpoint_descriptor ( int speed, char *start, char *end, @@ -212,9 +212,9 @@ static char *usb_dump_endpoint_descriptor( break; case USB_ENDPOINT_XFER_INT: type = "Int."; - if (speed == USB_SPEED_HIGH) + if (speed == USB_SPEED_HIGH) { interval = 1 << (desc->bInterval - 1); - else + } else interval = desc->bInterval; break; default: /* "can't happen" */ @@ -242,19 +242,15 @@ static char *usb_dump_interface_descriptor(char *start, char *end, { const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc; const char *driver_name = ""; - int active = 0; if (start > end) return start; down_read(&usb_bus_type.subsys.rwsem); - if (iface) { + if (iface) driver_name = (iface->dev.driver ? iface->dev.driver->name : "(none)"); - active = (desc == &iface->cur_altsetting->desc); - } start += sprintf(start, format_iface, - active ? '*' : ' ', /* mark active altsetting */ desc->bInterfaceNumber, desc->bAlternateSetting, desc->bNumEndpoints, @@ -347,7 +343,7 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb if (start > end) return start; - start += sprintf(start, format_device1, + start += sprintf (start, format_device1, bcdUSB >> 8, bcdUSB & 0xff, desc->bDeviceClass, class_decode (desc->bDeviceClass), @@ -367,7 +363,7 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb /* * Dump the different strings that this device holds. */ -static char *usb_dump_device_strings(char *start, char *end, struct usb_device *dev) +static char *usb_dump_device_strings (char *start, char *end, struct usb_device *dev) { if (start > end) return start; @@ -399,7 +395,7 @@ static char *usb_dump_desc(char *start, char *end, struct usb_device *dev) if (start > end) return start; - start = usb_dump_device_strings(start, end, dev); + start = usb_dump_device_strings (start, end, dev); for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { if (start > end) diff --git a/trunk/drivers/usb/core/devio.c b/trunk/drivers/usb/core/devio.c index 2087766f9e88..4b3a6ab29bd3 100644 --- a/trunk/drivers/usb/core/devio.c +++ b/trunk/drivers/usb/core/devio.c @@ -522,19 +522,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig static struct usb_device *usbdev_lookup_minor(int minor) { - struct device *device; - struct usb_device *udev = NULL; + struct class_device *class_dev; + struct usb_device *dev = NULL; down(&usb_device_class->sem); - list_for_each_entry(device, &usb_device_class->devices, node) { - if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { - udev = device->platform_data; + list_for_each_entry(class_dev, &usb_device_class->children, node) { + if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { + dev = class_dev->class_data; break; } } up(&usb_device_class->sem); - return udev; + return dev; }; /* @@ -570,7 +570,6 @@ static int usbdev_open(struct inode *inode, struct file *file) ps->dev = dev; ps->file = file; spin_lock_init(&ps->lock); - INIT_LIST_HEAD(&ps->list); INIT_LIST_HEAD(&ps->async_pending); INIT_LIST_HEAD(&ps->async_completed); init_waitqueue_head(&ps->wait); @@ -1597,19 +1596,19 @@ static int usbdev_add(struct usb_device *dev) { int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); - dev->usbfs_dev = device_create(usb_device_class, &dev->dev, - MKDEV(USB_DEVICE_MAJOR, minor), + dev->class_dev = class_device_create(usb_device_class, NULL, + MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, "usbdev%d.%d", dev->bus->busnum, dev->devnum); - if (IS_ERR(dev->usbfs_dev)) - return PTR_ERR(dev->usbfs_dev); + if (IS_ERR(dev->class_dev)) + return PTR_ERR(dev->class_dev); - dev->usbfs_dev->platform_data = dev; + dev->class_dev->class_data = dev; return 0; } static void usbdev_remove(struct usb_device *dev) { - device_unregister(dev->usbfs_dev); + class_device_unregister(dev->class_dev); } static int usbdev_notify(struct notifier_block *self, unsigned long action, diff --git a/trunk/drivers/usb/core/driver.c b/trunk/drivers/usb/core/driver.c index 600d1bc8272a..d6eb5ce1dd1d 100644 --- a/trunk/drivers/usb/core/driver.c +++ b/trunk/drivers/usb/core/driver.c @@ -28,16 +28,24 @@ #include "hcd.h" #include "usb.h" +static int usb_match_one_id(struct usb_interface *interface, + const struct usb_device_id *id); + +struct usb_dynid { + struct list_head node; + struct usb_device_id id; +}; + #ifdef CONFIG_HOTPLUG /* * Adds a new dynamic USBdevice ID to this driver, * and cause the driver to probe for all devices again. */ -ssize_t usb_store_new_id(struct usb_dynids *dynids, - struct device_driver *driver, - const char *buf, size_t count) +static ssize_t store_new_id(struct device_driver *driver, + const char *buf, size_t count) { + struct usb_driver *usb_drv = to_usb_driver(driver); struct usb_dynid *dynid; u32 idVendor = 0; u32 idProduct = 0; @@ -57,9 +65,9 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, dynid->id.idProduct = idProduct; dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; - spin_lock(&dynids->lock); - list_add_tail(&dynids->list, &dynid->node); - spin_unlock(&dynids->lock); + spin_lock(&usb_drv->dynids.lock); + list_add_tail(&usb_drv->dynids.list, &dynid->node); + spin_unlock(&usb_drv->dynids.lock); if (get_driver(driver)) { retval = driver_attach(driver); @@ -70,15 +78,6 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, return retval; return count; } -EXPORT_SYMBOL_GPL(usb_store_new_id); - -static ssize_t store_new_id(struct device_driver *driver, - const char *buf, size_t count) -{ - struct usb_driver *usb_drv = to_usb_driver(driver); - - return usb_store_new_id(&usb_drv->dynids, driver, buf, count); -} static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); static int usb_create_newid_file(struct usb_driver *usb_drv) @@ -366,8 +365,8 @@ void usb_driver_release_interface(struct usb_driver *driver, EXPORT_SYMBOL(usb_driver_release_interface); /* returns 0 if no match, 1 if match */ -int usb_match_one_id(struct usb_interface *interface, - const struct usb_device_id *id) +static int usb_match_one_id(struct usb_interface *interface, + const struct usb_device_id *id) { struct usb_host_interface *intf; struct usb_device *dev; @@ -433,8 +432,6 @@ int usb_match_one_id(struct usb_interface *interface, return 1; } -EXPORT_SYMBOL_GPL(usb_match_one_id); - /** * usb_match_id - find first usb_device_id matching device or interface * @interface: the interface of interest @@ -753,8 +750,7 @@ EXPORT_SYMBOL_GPL(usb_deregister_device_driver); * usb_register_dev() to enable that functionality. This function no longer * takes care of that. */ -int usb_register_driver(struct usb_driver *new_driver, struct module *owner, - const char *mod_name) +int usb_register_driver(struct usb_driver *new_driver, struct module *owner) { int retval = 0; @@ -767,7 +763,6 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner, new_driver->drvwrap.driver.probe = usb_probe_interface; new_driver->drvwrap.driver.remove = usb_unbind_interface; new_driver->drvwrap.driver.owner = owner; - new_driver->drvwrap.driver.mod_name = mod_name; spin_lock_init(&new_driver->dynids.lock); INIT_LIST_HEAD(&new_driver->dynids.list); diff --git a/trunk/drivers/usb/core/file.c b/trunk/drivers/usb/core/file.c index 01c857ac27af..f794f07cfb33 100644 --- a/trunk/drivers/usb/core/file.c +++ b/trunk/drivers/usb/core/file.c @@ -194,13 +194,14 @@ int usb_register_dev(struct usb_interface *intf, ++temp; else temp = name; - intf->usb_dev = device_create(usb_class->class, &intf->dev, - MKDEV(USB_MAJOR, minor), "%s", temp); - if (IS_ERR(intf->usb_dev)) { + intf->class_dev = class_device_create(usb_class->class, NULL, + MKDEV(USB_MAJOR, minor), + &intf->dev, "%s", temp); + if (IS_ERR(intf->class_dev)) { spin_lock (&minor_lock); usb_minors[intf->minor] = NULL; spin_unlock (&minor_lock); - retval = PTR_ERR(intf->usb_dev); + retval = PTR_ERR(intf->class_dev); } exit: return retval; @@ -241,8 +242,8 @@ void usb_deregister_dev(struct usb_interface *intf, spin_unlock (&minor_lock); snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); - device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); - intf->usb_dev = NULL; + class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); + intf->class_dev = NULL; intf->minor = -1; destroy_usb_class(); } diff --git a/trunk/drivers/usb/core/generic.c b/trunk/drivers/usb/core/generic.c index b531a4fd30c2..ebb20ff7ac58 100644 --- a/trunk/drivers/usb/core/generic.c +++ b/trunk/drivers/usb/core/generic.c @@ -25,20 +25,6 @@ static inline const char *plural(int n) return (n == 1 ? "" : "s"); } -static int is_rndis(struct usb_interface_descriptor *desc) -{ - return desc->bInterfaceClass == USB_CLASS_COMM - && desc->bInterfaceSubClass == 2 - && desc->bInterfaceProtocol == 0xff; -} - -static int is_activesync(struct usb_interface_descriptor *desc) -{ - return desc->bInterfaceClass == USB_CLASS_MISC - && desc->bInterfaceSubClass == 1 - && desc->bInterfaceProtocol == 1; -} - static int choose_configuration(struct usb_device *udev) { int i; @@ -101,12 +87,14 @@ static int choose_configuration(struct usb_device *udev) continue; } - /* When the first config's first interface is one of Microsoft's - * pet nonstandard Ethernet-over-USB protocols, ignore it unless - * this kernel has enabled the necessary host side driver. - */ - if (i == 0 && desc && (is_rndis(desc) || is_activesync(desc))) { -#if !defined(CONFIG_USB_NET_RNDIS_HOST) && !defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) + /* If the first config's first interface is COMM/2/0xff + * (MSFT RNDIS), rule it out unless Linux has host-side + * RNDIS support. */ + if (i == 0 && desc + && desc->bInterfaceClass == USB_CLASS_COMM + && desc->bInterfaceSubClass == 2 + && desc->bInterfaceProtocol == 0xff) { +#ifndef CONFIG_USB_NET_RNDIS_HOST continue; #else best = c; diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index b26c19e8d19f..10064af65d17 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -45,6 +45,8 @@ #include "hub.h" +// #define USB_BANDWIDTH_MESSAGES + /*-------------------------------------------------------------------------*/ /* @@ -889,6 +891,136 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount) } EXPORT_SYMBOL (usb_calc_bus_time); +/* + * usb_check_bandwidth(): + * + * old_alloc is from host_controller->bandwidth_allocated in microseconds; + * bustime is from calc_bus_time(), but converted to microseconds. + * + * returns if successful, + * or -ENOSPC if bandwidth request fails. + * + * FIXME: + * This initial implementation does not use Endpoint.bInterval + * in managing bandwidth allocation. + * It probably needs to be expanded to use Endpoint.bInterval. + * This can be done as a later enhancement (correction). + * + * This will also probably require some kind of + * frame allocation tracking...meaning, for example, + * that if multiple drivers request interrupts every 10 USB frames, + * they don't all have to be allocated at + * frame numbers N, N+10, N+20, etc. Some of them could be at + * N+11, N+21, N+31, etc., and others at + * N+12, N+22, N+32, etc. + * + * Similarly for isochronous transfers... + * + * Individual HCDs can schedule more directly ... this logic + * is not correct for high speed transfers. + */ +int usb_check_bandwidth (struct usb_device *dev, struct urb *urb) +{ + unsigned int pipe = urb->pipe; + long bustime; + int is_in = usb_pipein (pipe); + int is_iso = usb_pipeisoc (pipe); + int old_alloc = dev->bus->bandwidth_allocated; + int new_alloc; + + + bustime = NS_TO_US (usb_calc_bus_time (dev->speed, is_in, is_iso, + usb_maxpacket (dev, pipe, !is_in))); + if (is_iso) + bustime /= urb->number_of_packets; + + new_alloc = old_alloc + (int) bustime; + if (new_alloc > FRAME_TIME_MAX_USECS_ALLOC) { +#ifdef DEBUG + char *mode = +#ifdef CONFIG_USB_BANDWIDTH + ""; +#else + "would have "; +#endif + dev_dbg (&dev->dev, "usb_check_bandwidth %sFAILED: %d + %ld = %d usec\n", + mode, old_alloc, bustime, new_alloc); +#endif +#ifdef CONFIG_USB_BANDWIDTH + bustime = -ENOSPC; /* report error */ +#endif + } + + return bustime; +} +EXPORT_SYMBOL (usb_check_bandwidth); + + +/** + * usb_claim_bandwidth - records bandwidth for a periodic transfer + * @dev: source/target of request + * @urb: request (urb->dev == dev) + * @bustime: bandwidth consumed, in (average) microseconds per frame + * @isoc: true iff the request is isochronous + * + * Bus bandwidth reservations are recorded purely for diagnostic purposes. + * HCDs are expected not to overcommit periodic bandwidth, and to record such + * reservations whenever endpoints are added to the periodic schedule. + * + * FIXME averaging per-frame is suboptimal. Better to sum over the HCD's + * entire periodic schedule ... 32 frames for OHCI, 1024 for UHCI, settable + * for EHCI (256/512/1024 frames, default 1024) and have the bus expose how + * large its periodic schedule is. + */ +void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc) +{ + dev->bus->bandwidth_allocated += bustime; + if (isoc) + dev->bus->bandwidth_isoc_reqs++; + else + dev->bus->bandwidth_int_reqs++; + urb->bandwidth = bustime; + +#ifdef USB_BANDWIDTH_MESSAGES + dev_dbg (&dev->dev, "bandwidth alloc increased by %d (%s) to %d for %d requesters\n", + bustime, + isoc ? "ISOC" : "INTR", + dev->bus->bandwidth_allocated, + dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); +#endif +} +EXPORT_SYMBOL (usb_claim_bandwidth); + + +/** + * usb_release_bandwidth - reverses effect of usb_claim_bandwidth() + * @dev: source/target of request + * @urb: request (urb->dev == dev) + * @isoc: true iff the request is isochronous + * + * This records that previously allocated bandwidth has been released. + * Bandwidth is released when endpoints are removed from the host controller's + * periodic schedule. + */ +void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, int isoc) +{ + dev->bus->bandwidth_allocated -= urb->bandwidth; + if (isoc) + dev->bus->bandwidth_isoc_reqs--; + else + dev->bus->bandwidth_int_reqs--; + +#ifdef USB_BANDWIDTH_MESSAGES + dev_dbg (&dev->dev, "bandwidth alloc reduced by %d (%s) to %d for %d requesters\n", + urb->bandwidth, + isoc ? "ISOC" : "INTR", + dev->bus->bandwidth_allocated, + dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); +#endif + urb->bandwidth = 0; +} +EXPORT_SYMBOL (usb_release_bandwidth); + /*-------------------------------------------------------------------------*/ @@ -902,6 +1034,11 @@ static void urb_unlink (struct urb *urb) { unsigned long flags; + /* Release any periodic transfer bandwidth */ + if (urb->bandwidth) + usb_release_bandwidth (urb->dev, urb, + usb_pipeisoc (urb->pipe)); + /* clear all state linking urb to this dev (and hcd) */ spin_lock_irqsave (&hcd_data_lock, flags); diff --git a/trunk/drivers/usb/core/hcd.h b/trunk/drivers/usb/core/hcd.h index 2a269ca20517..8f8df0d4382e 100644 --- a/trunk/drivers/usb/core/hcd.h +++ b/trunk/drivers/usb/core/hcd.h @@ -308,6 +308,10 @@ extern void usb_destroy_configuration(struct usb_device *dev); #define NS_TO_US(ns) ((ns + 500L) / 1000L) /* convert & round nanoseconds to microseconds */ +extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, + int bustime, int isoc); +extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, + int isoc); /* * Full/low speed bandwidth allocation constants/support. @@ -320,6 +324,8 @@ extern void usb_destroy_configuration(struct usb_device *dev); #define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) #define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) +extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); + /* * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 590ec82d0515..1988224b362b 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -87,6 +87,9 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); static struct task_struct *khubd_task; +/* multithreaded probe logic */ +static int multithread_probe = 0; + /* cycle leds on hubs that aren't blinking for attention */ static int blinkenlights = 0; module_param (blinkenlights, bool, S_IRUGO); @@ -1253,28 +1256,9 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) static int __usb_port_suspend(struct usb_device *, int port1); #endif -/** - * usb_new_device - perform initial device setup (usbcore-internal) - * @udev: newly addressed device (in ADDRESS state) - * - * This is called with devices which have been enumerated, but not yet - * configured. The device descriptor is available, but not descriptors - * for any device configuration. The caller must have locked either - * the parent hub (if udev is a normal device) or else the - * usb_bus_list_lock (if udev is a root hub). The parent's pointer to - * udev has already been installed, but udev is not yet visible through - * sysfs or other filesystem code. - * - * It will return if the device is configured properly or not. Zero if - * the interface was registered with the driver core; else a negative - * errno value. - * - * This call is synchronous, and may not be used in an interrupt context. - * - * Only the hub driver or root-hub registrar should ever call this. - */ -int usb_new_device(struct usb_device *udev) +static int __usb_new_device(void *void_data) { + struct usb_device *udev = void_data; int err; /* Lock ourself into memory in order to keep a probe sequence @@ -1391,6 +1375,44 @@ int usb_new_device(struct usb_device *udev) goto exit; } +/** + * usb_new_device - perform initial device setup (usbcore-internal) + * @udev: newly addressed device (in ADDRESS state) + * + * This is called with devices which have been enumerated, but not yet + * configured. The device descriptor is available, but not descriptors + * for any device configuration. The caller must have locked either + * the parent hub (if udev is a normal device) or else the + * usb_bus_list_lock (if udev is a root hub). The parent's pointer to + * udev has already been installed, but udev is not yet visible through + * sysfs or other filesystem code. + * + * The return value for this function depends on if the + * multithread_probe variable is set or not. If it's set, it will + * return a if the probe thread was successfully created or not. If the + * variable is not set, it will return if the device is configured + * properly or not. interfaces, in sysfs); else a negative errno value. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Only the hub driver or root-hub registrar should ever call this. + */ +int usb_new_device(struct usb_device *udev) +{ + struct task_struct *probe_task; + int ret = 0; + + if (multithread_probe) { + probe_task = kthread_run(__usb_new_device, udev, + "usb-probe-%s", udev->devnum); + if (IS_ERR(probe_task)) + ret = PTR_ERR(probe_task); + } else + ret = __usb_new_device(udev); + + return ret; +} + static int hub_port_status(struct usb_hub *hub, int port1, u16 *status, u16 *change) { diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 8aca3574c2b5..149aa8bfb1fe 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -1545,7 +1545,11 @@ int usb_driver_set_configuration(struct usb_device *udev, int config) INIT_WORK(&req->work, driver_set_config_work); usb_get_dev(udev); - schedule_work(&req->work); + if (!schedule_work(&req->work)) { + usb_put_dev(udev); + kfree(req); + return -EINVAL; + } return 0; } EXPORT_SYMBOL_GPL(usb_driver_set_configuration); diff --git a/trunk/drivers/usb/core/sysfs.c b/trunk/drivers/usb/core/sysfs.c index 4eaa0ee8e72f..55d8f575206d 100644 --- a/trunk/drivers/usb/core/sysfs.c +++ b/trunk/drivers/usb/core/sysfs.c @@ -16,16 +16,16 @@ /* Active configuration fields */ #define usb_actconfig_show(field, multiplier, format_string) \ -static ssize_t show_##field(struct device *dev, \ +static ssize_t show_##field (struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct usb_device *udev; \ struct usb_host_config *actconfig; \ \ - udev = to_usb_device(dev); \ + udev = to_usb_device (dev); \ actconfig = udev->actconfig; \ if (actconfig) \ - return sprintf(buf, format_string, \ + return sprintf (buf, format_string, \ actconfig->desc.field * multiplier); \ else \ return 0; \ @@ -35,9 +35,9 @@ static ssize_t show_##field(struct device *dev, \ usb_actconfig_show(field, multiplier, format_string) \ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); -usb_actconfig_attr(bNumInterfaces, 1, "%2d\n") -usb_actconfig_attr(bmAttributes, 1, "%2x\n") -usb_actconfig_attr(bMaxPower, 2, "%3dmA\n") +usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") +usb_actconfig_attr (bmAttributes, 1, "%2x\n") +usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf) @@ -45,7 +45,7 @@ static ssize_t show_configuration_string(struct device *dev, struct usb_device *udev; struct usb_host_config *actconfig; - udev = to_usb_device(dev); + udev = to_usb_device (dev); actconfig = udev->actconfig; if ((!actconfig) || (!actconfig->string)) return 0; @@ -57,16 +57,16 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); usb_actconfig_show(bConfigurationValue, 1, "%u\n"); static ssize_t -set_bConfigurationValue(struct device *dev, struct device_attribute *attr, +set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct usb_device *udev = to_usb_device(dev); + struct usb_device *udev = to_usb_device (dev); int config, value; - if (sscanf(buf, "%u", &config) != 1 || config > 255) + if (sscanf (buf, "%u", &config) != 1 || config > 255) return -EINVAL; usb_lock_device(udev); - value = usb_set_configuration(udev, config); + value = usb_set_configuration (udev, config); usb_unlock_device(udev); return (value < 0) ? value : count; } @@ -81,7 +81,7 @@ static ssize_t show_##name(struct device *dev, \ { \ struct usb_device *udev; \ \ - udev = to_usb_device(dev); \ + udev = to_usb_device (dev); \ return sprintf(buf, "%s\n", udev->name); \ } \ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); @@ -91,12 +91,12 @@ usb_string_attr(manufacturer); usb_string_attr(serial); static ssize_t -show_speed(struct device *dev, struct device_attribute *attr, char *buf) +show_speed (struct device *dev, struct device_attribute *attr, char *buf) { struct usb_device *udev; char *speed; - udev = to_usb_device(dev); + udev = to_usb_device (dev); switch (udev->speed) { case USB_SPEED_LOW: @@ -112,22 +112,22 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf) default: speed = "unknown"; } - return sprintf(buf, "%s\n", speed); + return sprintf (buf, "%s\n", speed); } static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); static ssize_t -show_devnum(struct device *dev, struct device_attribute *attr, char *buf) +show_devnum (struct device *dev, struct device_attribute *attr, char *buf) { struct usb_device *udev; - udev = to_usb_device(dev); - return sprintf(buf, "%d\n", udev->devnum); + udev = to_usb_device (dev); + return sprintf (buf, "%d\n", udev->devnum); } static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); static ssize_t -show_version(struct device *dev, struct device_attribute *attr, char *buf) +show_version (struct device *dev, struct device_attribute *attr, char *buf) { struct usb_device *udev; u16 bcdUSB; @@ -139,25 +139,25 @@ show_version(struct device *dev, struct device_attribute *attr, char *buf) static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); static ssize_t -show_maxchild(struct device *dev, struct device_attribute *attr, char *buf) +show_maxchild (struct device *dev, struct device_attribute *attr, char *buf) { struct usb_device *udev; - udev = to_usb_device(dev); - return sprintf(buf, "%d\n", udev->maxchild); + udev = to_usb_device (dev); + return sprintf (buf, "%d\n", udev->maxchild); } static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); /* Descriptor fields */ #define usb_descriptor_attr_le16(field, format_string) \ static ssize_t \ -show_##field(struct device *dev, struct device_attribute *attr, \ +show_##field (struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ struct usb_device *udev; \ \ - udev = to_usb_device(dev); \ - return sprintf(buf, format_string, \ + udev = to_usb_device (dev); \ + return sprintf (buf, format_string, \ le16_to_cpu(udev->descriptor.field)); \ } \ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); @@ -168,21 +168,21 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n") #define usb_descriptor_attr(field, format_string) \ static ssize_t \ -show_##field(struct device *dev, struct device_attribute *attr, \ +show_##field (struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ struct usb_device *udev; \ \ - udev = to_usb_device(dev); \ - return sprintf(buf, format_string, udev->descriptor.field); \ + udev = to_usb_device (dev); \ + return sprintf (buf, format_string, udev->descriptor.field); \ } \ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); -usb_descriptor_attr(bDeviceClass, "%02x\n") -usb_descriptor_attr(bDeviceSubClass, "%02x\n") -usb_descriptor_attr(bDeviceProtocol, "%02x\n") -usb_descriptor_attr(bNumConfigurations, "%d\n") -usb_descriptor_attr(bMaxPacketSize0, "%d\n") +usb_descriptor_attr (bDeviceClass, "%02x\n") +usb_descriptor_attr (bDeviceSubClass, "%02x\n") +usb_descriptor_attr (bDeviceProtocol, "%02x\n") +usb_descriptor_attr (bNumConfigurations, "%d\n") +usb_descriptor_attr (bMaxPacketSize0, "%d\n") static struct attribute *dev_attrs[] = { /* current configuration's attributes */ @@ -220,17 +220,17 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) return retval; if (udev->manufacturer) { - retval = device_create_file(dev, &dev_attr_manufacturer); + retval = device_create_file (dev, &dev_attr_manufacturer); if (retval) goto error; } if (udev->product) { - retval = device_create_file(dev, &dev_attr_product); + retval = device_create_file (dev, &dev_attr_product); if (retval) goto error; } if (udev->serial) { - retval = device_create_file(dev, &dev_attr_serial); + retval = device_create_file (dev, &dev_attr_serial); if (retval) goto error; } @@ -246,7 +246,7 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) return retval; } -void usb_remove_sysfs_dev_files(struct usb_device *udev) +void usb_remove_sysfs_dev_files (struct usb_device *udev) { struct device *dev = &udev->dev; @@ -264,22 +264,22 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) /* Interface fields */ #define usb_intf_attr(field, format_string) \ static ssize_t \ -show_##field(struct device *dev, struct device_attribute *attr, \ +show_##field (struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ + struct usb_interface *intf = to_usb_interface (dev); \ \ - return sprintf(buf, format_string, \ + return sprintf (buf, format_string, \ intf->cur_altsetting->desc.field); \ } \ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); -usb_intf_attr(bInterfaceNumber, "%02x\n") -usb_intf_attr(bAlternateSetting, "%2d\n") -usb_intf_attr(bNumEndpoints, "%02x\n") -usb_intf_attr(bInterfaceClass, "%02x\n") -usb_intf_attr(bInterfaceSubClass, "%02x\n") -usb_intf_attr(bInterfaceProtocol, "%02x\n") +usb_intf_attr (bInterfaceNumber, "%02x\n") +usb_intf_attr (bAlternateSetting, "%2d\n") +usb_intf_attr (bNumEndpoints, "%02x\n") +usb_intf_attr (bInterfaceClass, "%02x\n") +usb_intf_attr (bInterfaceSubClass, "%02x\n") +usb_intf_attr (bInterfaceProtocol, "%02x\n") static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf) @@ -288,8 +288,8 @@ static ssize_t show_interface_string(struct device *dev, struct usb_device *udev; int len; - intf = to_usb_interface(dev); - udev = interface_to_usbdev(intf); + intf = to_usb_interface (dev); + udev = interface_to_usbdev (intf); len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); if (len < 0) return 0; @@ -384,7 +384,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf) return retval; } -void usb_remove_sysfs_intf_files(struct usb_interface *intf) +void usb_remove_sysfs_intf_files (struct usb_interface *intf) { usb_remove_intf_ep_files(intf); sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); diff --git a/trunk/drivers/usb/core/urb.c b/trunk/drivers/usb/core/urb.c index 94ea9727ff55..9801d08edacf 100644 --- a/trunk/drivers/usb/core/urb.c +++ b/trunk/drivers/usb/core/urb.c @@ -235,15 +235,16 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) urb->status = -EINPROGRESS; urb->actual_length = 0; + urb->bandwidth = 0; /* Lots of sanity checks, so HCDs can rely on clean data * and don't need to duplicate tests */ pipe = urb->pipe; - temp = usb_pipetype(pipe); - is_out = usb_pipeout(pipe); + temp = usb_pipetype (pipe); + is_out = usb_pipeout (pipe); - if (!usb_pipecontrol(pipe) && dev->state < USB_STATE_CONFIGURED) + if (!usb_pipecontrol (pipe) && dev->state < USB_STATE_CONFIGURED) return -ENODEV; /* FIXME there should be a sharable lock protecting us against @@ -252,11 +253,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) * checks get made.) */ - max = usb_maxpacket(dev, pipe, is_out); + max = usb_maxpacket (dev, pipe, is_out); if (max <= 0) { dev_dbg(&dev->dev, "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", - usb_pipeendpoint(pipe), is_out ? "out" : "in", + usb_pipeendpoint (pipe), is_out ? "out" : "in", __FUNCTION__, max); return -EMSGSIZE; } @@ -278,11 +279,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) if (urb->number_of_packets <= 0) return -EINVAL; for (n = 0; n < urb->number_of_packets; n++) { - len = urb->iso_frame_desc[n].length; + len = urb->iso_frame_desc [n].length; if (len < 0 || len > max) return -EMSGSIZE; - urb->iso_frame_desc[n].status = -EXDEV; - urb->iso_frame_desc[n].actual_length = 0; + urb->iso_frame_desc [n].status = -EXDEV; + urb->iso_frame_desc [n].actual_length = 0; } } @@ -321,7 +322,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) /* fail if submitter gave bogus flags */ if (urb->transfer_flags != orig_flags) { - err("BOGUS urb flags, %x --> %x", + err ("BOGUS urb flags, %x --> %x", orig_flags, urb->transfer_flags); return -EINVAL; } @@ -372,7 +373,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) urb->interval = temp; } - return usb_hcd_submit_urb(urb, mem_flags); + return usb_hcd_submit_urb (urb, mem_flags); } /*-------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/core/usb.c b/trunk/drivers/usb/core/usb.c index 3db721cd557a..02426d0b9a34 100644 --- a/trunk/drivers/usb/core/usb.c +++ b/trunk/drivers/usb/core/usb.c @@ -233,7 +233,7 @@ static void usb_autosuspend_work(struct work_struct *work) * @parent: hub to which device is connected; null to allocate a root hub * @bus: bus used to access the device * @port1: one-based index of port; ignored for root hubs - * Context: !in_interrupt() + * Context: !in_interrupt () * * Only hub drivers (including virtual root hub drivers for host * controllers) should ever call this. @@ -277,22 +277,22 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) * as stable: bus->busnum changes easily from modprobe order, * cardbus or pci hotplugging, and so on. */ - if (unlikely(!parent)) { - dev->devpath[0] = '0'; + if (unlikely (!parent)) { + dev->devpath [0] = '0'; dev->dev.parent = bus->controller; - sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum); + sprintf (&dev->dev.bus_id[0], "usb%d", bus->busnum); } else { /* match any labeling on the hubs; it's one-based */ - if (parent->devpath[0] == '0') - snprintf(dev->devpath, sizeof dev->devpath, + if (parent->devpath [0] == '0') + snprintf (dev->devpath, sizeof dev->devpath, "%d", port1); else - snprintf(dev->devpath, sizeof dev->devpath, + snprintf (dev->devpath, sizeof dev->devpath, "%s.%d", parent->devpath, port1); dev->dev.parent = &parent->dev; - sprintf(&dev->dev.bus_id[0], "%d-%s", + sprintf (&dev->dev.bus_id[0], "%d-%s", bus->busnum, dev->devpath); /* hub driver sets up TT records */ @@ -463,7 +463,7 @@ static struct usb_device *match_device(struct usb_device *dev, /* see if this device matches */ if ((vendor_id == le16_to_cpu(dev->descriptor.idVendor)) && (product_id == le16_to_cpu(dev->descriptor.idProduct))) { - dev_dbg(&dev->dev, "matched this device!\n"); + dev_dbg (&dev->dev, "matched this device!\n"); ret_dev = usb_get_dev(dev); goto exit; } @@ -535,7 +535,7 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id) */ int usb_get_current_frame_number(struct usb_device *dev) { - return usb_hcd_get_frame_number(dev); + return usb_hcd_get_frame_number (dev); } /*-------------------------------------------------------------------*/ @@ -593,7 +593,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, * * When the buffer is no longer used, free it with usb_buffer_free(). */ -void *usb_buffer_alloc( +void *usb_buffer_alloc ( struct usb_device *dev, size_t size, gfp_t mem_flags, @@ -602,7 +602,7 @@ void *usb_buffer_alloc( { if (!dev || !dev->bus) return NULL; - return hcd_buffer_alloc(dev->bus, size, mem_flags, dma); + return hcd_buffer_alloc (dev->bus, size, mem_flags, dma); } /** @@ -616,7 +616,7 @@ void *usb_buffer_alloc( * been allocated using usb_buffer_alloc(), and the parameters must match * those provided in that allocation request. */ -void usb_buffer_free( +void usb_buffer_free ( struct usb_device *dev, size_t size, void *addr, @@ -627,7 +627,7 @@ void usb_buffer_free( return; if (!addr) return; - hcd_buffer_free(dev->bus, size, addr, dma); + hcd_buffer_free (dev->bus, size, addr, dma); } /** @@ -647,7 +647,7 @@ void usb_buffer_free( * Reverse the effect of this call with usb_buffer_unmap(). */ #if 0 -struct urb *usb_buffer_map(struct urb *urb) +struct urb *usb_buffer_map (struct urb *urb) { struct usb_bus *bus; struct device *controller; @@ -659,14 +659,14 @@ struct urb *usb_buffer_map(struct urb *urb) return NULL; if (controller->dma_mask) { - urb->transfer_dma = dma_map_single(controller, + urb->transfer_dma = dma_map_single (controller, urb->transfer_buffer, urb->transfer_buffer_length, - usb_pipein(urb->pipe) + usb_pipein (urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); - if (usb_pipecontrol(urb->pipe)) - urb->setup_dma = dma_map_single(controller, + if (usb_pipecontrol (urb->pipe)) + urb->setup_dma = dma_map_single (controller, urb->setup_packet, - sizeof(struct usb_ctrlrequest), + sizeof (struct usb_ctrlrequest), DMA_TO_DEVICE); // FIXME generic api broken like pci, can't report errors // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; @@ -689,7 +689,7 @@ struct urb *usb_buffer_map(struct urb *urb) * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s) * @urb: urb whose transfer_buffer/setup_packet will be synchronized */ -void usb_buffer_dmasync(struct urb *urb) +void usb_buffer_dmasync (struct urb *urb) { struct usb_bus *bus; struct device *controller; @@ -702,14 +702,14 @@ void usb_buffer_dmasync(struct urb *urb) return; if (controller->dma_mask) { - dma_sync_single(controller, + dma_sync_single (controller, urb->transfer_dma, urb->transfer_buffer_length, - usb_pipein(urb->pipe) + usb_pipein (urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); - if (usb_pipecontrol(urb->pipe)) - dma_sync_single(controller, + if (usb_pipecontrol (urb->pipe)) + dma_sync_single (controller, urb->setup_dma, - sizeof(struct usb_ctrlrequest), + sizeof (struct usb_ctrlrequest), DMA_TO_DEVICE); } } @@ -722,7 +722,7 @@ void usb_buffer_dmasync(struct urb *urb) * Reverses the effect of usb_buffer_map(). */ #if 0 -void usb_buffer_unmap(struct urb *urb) +void usb_buffer_unmap (struct urb *urb) { struct usb_bus *bus; struct device *controller; @@ -735,14 +735,14 @@ void usb_buffer_unmap(struct urb *urb) return; if (controller->dma_mask) { - dma_unmap_single(controller, + dma_unmap_single (controller, urb->transfer_dma, urb->transfer_buffer_length, - usb_pipein(urb->pipe) + usb_pipein (urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); - if (usb_pipecontrol(urb->pipe)) - dma_unmap_single(controller, + if (usb_pipecontrol (urb->pipe)) + dma_unmap_single (controller, urb->setup_dma, - sizeof(struct usb_ctrlrequest), + sizeof (struct usb_ctrlrequest), DMA_TO_DEVICE); } urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP @@ -783,15 +783,15 @@ int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, struct device *controller; if (!dev - || usb_pipecontrol(pipe) + || usb_pipecontrol (pipe) || !(bus = dev->bus) || !(controller = bus->controller) || !controller->dma_mask) return -1; // FIXME generic api broken like pci, can't report errors - return dma_map_sg(controller, sg, nents, - usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + return dma_map_sg (controller, sg, nents, + usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } /* XXX DISABLED, no users currently. If you wish to re-enable this @@ -823,8 +823,8 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, || !controller->dma_mask) return; - dma_sync_sg(controller, sg, n_hw_ents, - usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + dma_sync_sg (controller, sg, n_hw_ents, + usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } #endif @@ -849,8 +849,8 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, || !controller->dma_mask) return; - dma_unmap_sg(controller, sg, n_hw_ents, - usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + dma_unmap_sg (controller, sg, n_hw_ents, + usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } /* format to disable USB on kernel command line is: nousb */ @@ -871,7 +871,7 @@ static int __init usb_init(void) { int retval; if (nousb) { - pr_info("%s: USB support disabled\n", usbcore_name); + pr_info ("%s: USB support disabled\n", usbcore_name); return 0; } @@ -971,19 +971,19 @@ EXPORT_SYMBOL(__usb_get_extra_descriptor); EXPORT_SYMBOL(usb_find_device); EXPORT_SYMBOL(usb_get_current_frame_number); -EXPORT_SYMBOL(usb_buffer_alloc); -EXPORT_SYMBOL(usb_buffer_free); +EXPORT_SYMBOL (usb_buffer_alloc); +EXPORT_SYMBOL (usb_buffer_free); #if 0 -EXPORT_SYMBOL(usb_buffer_map); -EXPORT_SYMBOL(usb_buffer_dmasync); -EXPORT_SYMBOL(usb_buffer_unmap); +EXPORT_SYMBOL (usb_buffer_map); +EXPORT_SYMBOL (usb_buffer_dmasync); +EXPORT_SYMBOL (usb_buffer_unmap); #endif -EXPORT_SYMBOL(usb_buffer_map_sg); +EXPORT_SYMBOL (usb_buffer_map_sg); #if 0 -EXPORT_SYMBOL(usb_buffer_dmasync_sg); +EXPORT_SYMBOL (usb_buffer_dmasync_sg); #endif -EXPORT_SYMBOL(usb_buffer_unmap_sg); +EXPORT_SYMBOL (usb_buffer_unmap_sg); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/gadget/at91_udc.c b/trunk/drivers/usb/gadget/at91_udc.c index f39050145f1f..812c733ba8ce 100644 --- a/trunk/drivers/usb/gadget/at91_udc.c +++ b/trunk/drivers/usb/gadget/at91_udc.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include @@ -1807,13 +1807,16 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg) || !wake || at91_suspend_entering_slow_clock()) { pullup(udc, 0); - wake = 0; + disable_irq_wake(udc->udp_irq); } else enable_irq_wake(udc->udp_irq); - udc->active_suspend = wake; - if (udc->board.vbus_pin > 0 && wake) - enable_irq_wake(udc->board.vbus_pin); + if (udc->board.vbus_pin > 0) { + if (wake) + enable_irq_wake(udc->board.vbus_pin); + else + disable_irq_wake(udc->board.vbus_pin); + } return 0; } @@ -1821,14 +1824,8 @@ static int at91udc_resume(struct platform_device *pdev) { struct at91_udc *udc = platform_get_drvdata(pdev); - if (udc->board.vbus_pin > 0 && udc->active_suspend) - disable_irq_wake(udc->board.vbus_pin); - /* maybe reconnect to host; if so, clocks on */ - if (udc->active_suspend) - disable_irq_wake(udc->udp_irq); - else - pullup(udc, 1); + pullup(udc, 1); return 0; } #else diff --git a/trunk/drivers/usb/gadget/at91_udc.h b/trunk/drivers/usb/gadget/at91_udc.h index 7e34e2f864f9..677089baa59d 100644 --- a/trunk/drivers/usb/gadget/at91_udc.h +++ b/trunk/drivers/usb/gadget/at91_udc.h @@ -136,7 +136,6 @@ struct at91_udc { unsigned wait_for_addr_ack:1; unsigned wait_for_config_ack:1; unsigned selfpowered:1; - unsigned active_suspend:1; u8 addr; struct at91_udc_data board; struct clk *iclk, *fclk; diff --git a/trunk/drivers/usb/gadget/config.c b/trunk/drivers/usb/gadget/config.c index d18901b92cda..83b4866df9af 100644 --- a/trunk/drivers/usb/gadget/config.c +++ b/trunk/drivers/usb/gadget/config.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include diff --git a/trunk/drivers/usb/gadget/epautoconf.c b/trunk/drivers/usb/gadget/epautoconf.c index f28af06905a5..53d584589c26 100644 --- a/trunk/drivers/usb/gadget/epautoconf.c +++ b/trunk/drivers/usb/gadget/epautoconf.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include "gadget_chips.h" diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index 22e3c9443641..d15bf22b9a03 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -47,7 +47,7 @@ #include #include -#include +#include #include #include @@ -72,18 +72,9 @@ * * There's some hardware that can't talk CDC. We make that hardware * implement a "minimalist" vendor-agnostic CDC core: same framing, but - * link-level setup only requires activating the configuration. Only the - * endpoint descriptors, and product/vendor IDs, are relevant; no control - * operations are available. Linux supports it, but other host operating - * systems may not. (This is a subset of CDC Ethernet.) - * - * It turns out that if you add a few descriptors to that "CDC Subset", - * (Windows) host side drivers from MCCI can treat it as one submode of - * a proprietary scheme called "SAFE" ... without needing to know about - * specific product/vendor IDs. So we do that, making it easier to use - * those MS-Windows drivers. Those added descriptors make it resemble a - * CDC MDLM device, but they don't change device behavior at all. (See - * MCCI Engineering report 950198 "SAFE Networking Functions".) + * link-level setup only requires activating the configuration. + * Linux supports it, but other host operating systems may not. + * (This is a subset of CDC Ethernet.) * * A third option is also in use. Rather than CDC Ethernet, or something * simpler, Microsoft pushes their own approach: RNDIS. The published @@ -263,10 +254,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_CDC #endif -#ifdef CONFIG_USB_GADGET_S3C2410 -#define DEV_CONFIG_CDC -#endif - #ifdef CONFIG_USB_GADGET_AT91 #define DEV_CONFIG_CDC #endif @@ -279,10 +266,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_CDC #endif -#ifdef CONFIG_USB_GADGET_HUSB2DEV -#define DEV_CONFIG_CDC -#endif - /* For CDC-incapable hardware, choose the simple cdc subset. * Anything that talks bulk (without notable bugs) can do this. @@ -300,6 +283,9 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_SUBSET #endif +#ifdef CONFIG_USB_GADGET_S3C2410 +#define DEV_CONFIG_CDC +#endif /*-------------------------------------------------------------------------*/ @@ -501,17 +487,8 @@ rndis_config = { * endpoint. Both have a "data" interface and two bulk endpoints. * There are also differences in how control requests are handled. * - * RNDIS shares a lot with CDC-Ethernet, since it's a variant of the - * CDC-ACM (modem) spec. Unfortunately MSFT's RNDIS driver is buggy; it - * may hang or oops. Since bugfixes (or accurate specs, letting Linux - * work around those bugs) are unlikely to ever come from MSFT, you may - * wish to avoid using RNDIS. - * - * MCCI offers an alternative to RNDIS if you need to connect to Windows - * but have hardware that can't support CDC Ethernet. We add descriptors - * to present the CDC Subset as a (nonconformant) CDC MDLM variant called - * "SAFE". That borrows from both CDC Ethernet and CDC MDLM. You can - * get those drivers from MCCI, or bundled with various products. + * RNDIS shares a lot with CDC-Ethernet, since it's a variant of + * the CDC-ACM (modem) spec. */ #ifdef DEV_CONFIG_CDC @@ -545,6 +522,8 @@ rndis_control_intf = { }; #endif +#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) + static const struct usb_cdc_header_desc header_desc = { .bLength = sizeof header_desc, .bDescriptorType = USB_DT_CS_INTERFACE, @@ -553,8 +532,6 @@ static const struct usb_cdc_header_desc header_desc = { .bcdCDC = __constant_cpu_to_le16 (0x0110), }; -#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) - static const struct usb_cdc_union_desc union_desc = { .bLength = sizeof union_desc, .bDescriptorType = USB_DT_CS_INTERFACE, @@ -587,40 +564,7 @@ static const struct usb_cdc_acm_descriptor acm_descriptor = { #endif -#ifndef DEV_CONFIG_CDC - -/* "SAFE" loosely follows CDC WMC MDLM, violating the spec in various - * ways: data endpoints live in the control interface, there's no data - * interface, and it's not used to talk to a cell phone radio. - */ - -static const struct usb_cdc_mdlm_desc mdlm_desc = { - .bLength = sizeof mdlm_desc, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_MDLM_TYPE, - - .bcdVersion = __constant_cpu_to_le16(0x0100), - .bGUID = { - 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, - 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, - }, -}; - -/* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we - * can't really use its struct. All we do here is say that we're using - * the submode of "SAFE" which directly matches the CDC Subset. - */ -static const u8 mdlm_detail_desc[] = { - 6, - USB_DT_CS_INTERFACE, - USB_CDC_MDLM_DETAIL_TYPE, - - 0, /* "SAFE" */ - 0, /* network control capabilities (none) */ - 0, /* network data capabilities ("raw" encapsulation) */ -}; - -#endif +#ifdef DEV_CONFIG_CDC static const struct usb_cdc_ether_desc ether_desc = { .bLength = sizeof ether_desc, @@ -635,6 +579,7 @@ static const struct usb_cdc_ether_desc ether_desc = { .bNumberPowerFilters = 0, }; +#endif #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) @@ -727,9 +672,6 @@ rndis_data_intf = { /* * "Simple" CDC-subset option is a simple vendor-neutral model that most * full speed controllers can handle: one interface, two bulk endpoints. - * - * To assist host side drivers, we fancy it up a bit, and add descriptors - * so some host side drivers will understand it as a "SAFE" variant. */ static const struct usb_interface_descriptor @@ -740,8 +682,8 @@ subset_data_intf = { .bInterfaceNumber = 0, .bAlternateSetting = 0, .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, .iInterface = STRING_DATA, }; @@ -789,15 +731,10 @@ static const struct usb_descriptor_header *fs_eth_function [11] = { static inline void __init fs_subset_descriptors(void) { #ifdef DEV_CONFIG_SUBSET - /* behavior is "CDC Subset"; extra descriptors say "SAFE" */ fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; - fs_eth_function[2] = (struct usb_descriptor_header *) &header_desc; - fs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc; - fs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc; - fs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc; - fs_eth_function[6] = (struct usb_descriptor_header *) &fs_source_desc; - fs_eth_function[7] = (struct usb_descriptor_header *) &fs_sink_desc; - fs_eth_function[8] = NULL; + fs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc; + fs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc; + fs_eth_function[4] = NULL; #else fs_eth_function[1] = NULL; #endif @@ -891,15 +828,10 @@ static const struct usb_descriptor_header *hs_eth_function [11] = { static inline void __init hs_subset_descriptors(void) { #ifdef DEV_CONFIG_SUBSET - /* behavior is "CDC Subset"; extra descriptors say "SAFE" */ hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; - hs_eth_function[2] = (struct usb_descriptor_header *) &header_desc; - hs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc; - hs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc; - hs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc; - hs_eth_function[6] = (struct usb_descriptor_header *) &hs_source_desc; - hs_eth_function[7] = (struct usb_descriptor_header *) &hs_sink_desc; - hs_eth_function[8] = NULL; + hs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc; + hs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc; + hs_eth_function[4] = NULL; #else hs_eth_function[1] = NULL; #endif @@ -946,8 +878,10 @@ static char manufacturer [50]; static char product_desc [40] = DRIVER_DESC; static char serial_number [20]; +#ifdef DEV_CONFIG_CDC /* address that the host will use ... usually assigned at random */ static char ethaddr [2 * ETH_ALEN + 1]; +#endif /* static strings, in UTF-8 */ static struct usb_string strings [] = { @@ -955,9 +889,9 @@ static struct usb_string strings [] = { { STRING_PRODUCT, product_desc, }, { STRING_SERIALNUMBER, serial_number, }, { STRING_DATA, "Ethernet Data", }, - { STRING_ETHADDR, ethaddr, }, #ifdef DEV_CONFIG_CDC { STRING_CDC, "CDC Ethernet", }, + { STRING_ETHADDR, ethaddr, }, { STRING_CONTROL, "CDC Communications Control", }, #endif #ifdef DEV_CONFIG_SUBSET @@ -1052,10 +986,10 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags) } #endif - dev->in = ep_desc(gadget, &hs_source_desc, &fs_source_desc); + dev->in = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc); dev->in_ep->driver_data = dev; - dev->out = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); + dev->out = ep_desc (dev->gadget, &hs_sink_desc, &fs_sink_desc); dev->out_ep->driver_data = dev; /* With CDC, the host isn't allowed to use these two data @@ -2344,10 +2278,10 @@ eth_bind (struct usb_gadget *gadget) "RNDIS/%s", driver_desc); /* CDC subset ... recognized by Linux since 2.4.10, but Windows - * drivers aren't widely available. (That may be improved by - * supporting one submode of the "SAFE" variant of MDLM.) + * drivers aren't widely available. */ } else if (!cdc) { + device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; device_desc.idVendor = __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); device_desc.idProduct = @@ -2418,10 +2352,6 @@ eth_bind (struct usb_gadget *gadget) if (!cdc) { eth_config.bNumInterfaces = 1; eth_config.iConfiguration = STRING_SUBSET; - - /* use functions to set these up, in case we're built to work - * with multiple controllers and must override CDC Ethernet. - */ fs_subset_descriptors(); hs_subset_descriptors(); } @@ -2485,20 +2415,22 @@ eth_bind (struct usb_gadget *gadget) /* Module params for these addresses should come from ID proms. * The host side address is used with CDC and RNDIS, and commonly - * ends up in a persistent config database. It's not clear if - * host side code for the SAFE thing cares -- its original BLAN - * thing didn't, Sharp never assigned those addresses on Zaurii. + * ends up in a persistent config database. */ if (get_ether_addr(dev_addr, net->dev_addr)) dev_warn(&gadget->dev, "using random %s ethernet address\n", "self"); - if (get_ether_addr(host_addr, dev->host_mac)) - dev_warn(&gadget->dev, - "using random %s ethernet address\n", "host"); - snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", - dev->host_mac [0], dev->host_mac [1], - dev->host_mac [2], dev->host_mac [3], - dev->host_mac [4], dev->host_mac [5]); + if (cdc || rndis) { + if (get_ether_addr(host_addr, dev->host_mac)) + dev_warn(&gadget->dev, + "using random %s ethernet address\n", "host"); +#ifdef DEV_CONFIG_CDC + snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", + dev->host_mac [0], dev->host_mac [1], + dev->host_mac [2], dev->host_mac [3], + dev->host_mac [4], dev->host_mac [5]); +#endif + } if (rndis) { status = rndis_init(); diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index f04a29a46646..72f2ae96fbf3 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -253,7 +253,7 @@ #include #include -#include +#include #include #include "gadget_chips.h" @@ -1148,7 +1148,7 @@ static int ep0_queue(struct fsg_dev *fsg) static void ep0_complete(struct usb_ep *ep, struct usb_request *req) { - struct fsg_dev *fsg = ep->driver_data; + struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; if (req->actual > 0) dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); @@ -1170,8 +1170,8 @@ static void ep0_complete(struct usb_ep *ep, struct usb_request *req) static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) { - struct fsg_dev *fsg = ep->driver_data; - struct fsg_buffhd *bh = req->context; + struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; + struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; if (req->status || req->actual != req->length) DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, @@ -1190,8 +1190,8 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) { - struct fsg_dev *fsg = ep->driver_data; - struct fsg_buffhd *bh = req->context; + struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; + struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; dump_msg(fsg, "bulk-out", req->buf, req->actual); if (req->status || req->actual != bh->bulk_out_intended_length) @@ -1214,8 +1214,8 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) #ifdef CONFIG_USB_FILE_STORAGE_TEST static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) { - struct fsg_dev *fsg = ep->driver_data; - struct fsg_buffhd *bh = req->context; + struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; + struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; if (req->status || req->actual != req->length) DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, @@ -2577,7 +2577,7 @@ static int send_status(struct fsg_dev *fsg) } if (transport_is_bbb()) { - struct bulk_cs_wrap *csw = bh->buf; + struct bulk_cs_wrap *csw = (struct bulk_cs_wrap *) bh->buf; /* Store and send the Bulk-only CSW */ csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); @@ -2596,7 +2596,8 @@ static int send_status(struct fsg_dev *fsg) return 0; } else { // USB_PR_CBI - struct interrupt_data *buf = bh->buf; + struct interrupt_data *buf = (struct interrupt_data *) + bh->buf; /* Store and send the Interrupt data. UFI sends the ASC * and ASCQ bytes. Everything else sends a Type (which @@ -2981,7 +2982,7 @@ static int do_scsi_command(struct fsg_dev *fsg) static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) { struct usb_request *req = bh->outreq; - struct bulk_cb_wrap *cbw = req->buf; + struct bulk_cb_wrap *cbw = (struct bulk_cb_wrap *) req->buf; /* Was this a real packet? */ if (req->status) @@ -3427,7 +3428,7 @@ static void handle_exception(struct fsg_dev *fsg) static int fsg_main_thread(void *fsg_) { - struct fsg_dev *fsg = fsg_; + struct fsg_dev *fsg = (struct fsg_dev *) fsg_; /* Allow the thread to be killed by a signal, but set the signal mask * to block everything but INT, TERM, KILL, and USR1. */ @@ -3599,7 +3600,7 @@ static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char * static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) { struct lun *curlun = dev_to_lun(dev); - struct fsg_dev *fsg = dev_get_drvdata(dev); + struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); char *p; ssize_t rc; @@ -3628,7 +3629,7 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const { ssize_t rc = count; struct lun *curlun = dev_to_lun(dev); - struct fsg_dev *fsg = dev_get_drvdata(dev); + struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); int i; if (sscanf(buf, "%d", &i) != 1) @@ -3651,7 +3652,7 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct lun *curlun = dev_to_lun(dev); - struct fsg_dev *fsg = dev_get_drvdata(dev); + struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); int rc = 0; if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) { @@ -3699,7 +3700,7 @@ static void fsg_release(struct kref *ref) static void lun_release(struct device *dev) { - struct fsg_dev *fsg = dev_get_drvdata(dev); + struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); kref_put(&fsg->ref, fsg_release); } diff --git a/trunk/drivers/usb/gadget/gadget_chips.h b/trunk/drivers/usb/gadget/gadget_chips.h index 2e3d6620d216..aa80f0910720 100644 --- a/trunk/drivers/usb/gadget/gadget_chips.h +++ b/trunk/drivers/usb/gadget/gadget_chips.h @@ -75,12 +75,6 @@ #define gadget_is_pxa27x(g) 0 #endif -#ifdef CONFIG_USB_GADGET_HUSB2DEV -#define gadget_is_husb2dev(g) !strcmp("husb2_udc", (g)->name) -#else -#define gadget_is_husb2dev(g) 0 -#endif - #ifdef CONFIG_USB_GADGET_S3C2410 #define gadget_is_s3c2410(g) !strcmp("s3c2410_udc", (g)->name) #else @@ -175,7 +169,5 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x16; else if (gadget_is_mpc8272(gadget)) return 0x17; - else if (gadget_is_husb2dev(gadget)) - return 0x18; return -ENOENT; } diff --git a/trunk/drivers/usb/gadget/gmidi.c b/trunk/drivers/usb/gadget/gmidi.c index d08a8d0e6427..f1a679656c96 100644 --- a/trunk/drivers/usb/gadget/gmidi.c +++ b/trunk/drivers/usb/gadget/gmidi.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/goku_udc.c b/trunk/drivers/usb/gadget/goku_udc.c index e873cf488246..d0ef1d6b3fac 100644 --- a/trunk/drivers/usb/gadget/goku_udc.c +++ b/trunk/drivers/usb/gadget/goku_udc.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/usb/gadget/inode.c b/trunk/drivers/usb/gadget/inode.c index 34296e79edcf..3fb1044a4db0 100644 --- a/trunk/drivers/usb/gadget/inode.c +++ b/trunk/drivers/usb/gadget/inode.c @@ -20,7 +20,7 @@ */ -// #define DEBUG /* data to help fault diagnosis */ +// #define DEBUG /* data to help fault diagnosis */ // #define VERBOSE /* extra debug messages (success too) */ #include @@ -59,11 +59,11 @@ * may serve as a source of device events, used to handle all control * requests other than basic enumeration. * - * - Then, after a SET_CONFIGURATION control request, ep_config() is - * called when each /dev/gadget/ep* file is configured (by writing - * endpoint descriptors). Afterwards these files are used to write() - * IN data or to read() OUT data. To halt the endpoint, a "wrong - * direction" request is issued (like reading an IN endpoint). + * - Then either immediately, or after a SET_CONFIGURATION control request, + * ep_config() is called when each /dev/gadget/ep* file is configured + * (by writing endpoint descriptors). Afterwards these files are used + * to write() IN data or to read() OUT data. To halt the endpoint, a + * "wrong direction" request is issued (like reading an IN endpoint). * * Unlike "usbfs" the only ioctl()s are for things that are rare, and maybe * not possible on all hardware. For example, precise fault handling with @@ -98,16 +98,16 @@ enum ep0_state { * must always write descriptors to initialize the device, then * the device becomes UNCONNECTED until enumeration. */ - STATE_DEV_OPENED, + STATE_OPENED, /* From then on, ep0 fd is in either of two basic modes: * - (UN)CONNECTED: read usb_gadgetfs_event(s) from it * - SETUP: read/write will transfer control data and succeed; * or if "wrong direction", performs protocol stall */ - STATE_DEV_UNCONNECTED, - STATE_DEV_CONNECTED, - STATE_DEV_SETUP, + STATE_UNCONNECTED, + STATE_CONNECTED, + STATE_SETUP, /* UNBOUND means the driver closed ep0, so the device won't be * accessible again (DEV_DISABLED) until all fds are closed. @@ -121,7 +121,7 @@ enum ep0_state { struct dev_data { spinlock_t lock; atomic_t count; - enum ep0_state state; /* P: lock */ + enum ep0_state state; struct usb_gadgetfs_event event [N_EVENT]; unsigned ev_next; struct fasync_struct *fasync; @@ -188,6 +188,7 @@ static struct dev_data *dev_new (void) enum ep_state { STATE_EP_DISABLED = 0, STATE_EP_READY, + STATE_EP_DEFER_ENABLE, STATE_EP_ENABLED, STATE_EP_UNBOUND, }; @@ -312,10 +313,18 @@ get_ready_ep (unsigned f_flags, struct ep_data *epdata) if ((val = down_interruptible (&epdata->lock)) < 0) return val; - +newstate: switch (epdata->state) { case STATE_EP_ENABLED: break; + case STATE_EP_DEFER_ENABLE: + DBG (epdata->dev, "%s wait for host\n", epdata->name); + if ((val = wait_event_interruptible (epdata->wait, + epdata->state != STATE_EP_DEFER_ENABLE + || epdata->dev->state == STATE_DEV_UNBOUND + )) < 0) + goto fail; + goto newstate; // case STATE_EP_DISABLED: /* "can't happen" */ // case STATE_EP_READY: /* "can't happen" */ default: /* error! */ @@ -324,6 +333,7 @@ get_ready_ep (unsigned f_flags, struct ep_data *epdata) // FALLTHROUGH case STATE_EP_UNBOUND: /* clean disconnect */ val = -ENODEV; +fail: up (&epdata->lock); } return val; @@ -555,28 +565,29 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb) ssize_t len, total; int i; - /* we "retry" to get the right mm context for this: */ - - /* copy stuff into user buffers */ - total = priv->actual; - len = 0; - for (i=0; i < priv->nr_segs; i++) { - ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total); - - if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) { - if (len == 0) - len = -EFAULT; - break; - } - - total -= this; - len += this; - if (total == 0) - break; - } - kfree(priv->buf); - kfree(priv); - return len; + /* we "retry" to get the right mm context for this: */ + + /* copy stuff into user buffers */ + total = priv->actual; + len = 0; + for (i=0; i < priv->nr_segs; i++) { + ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total); + + if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) { + if (len == 0) + len = -EFAULT; + break; + } + + total -= this; + len += this; + if (total == 0) + break; + } + kfree(priv->buf); + kfree(priv); + aio_put_req(iocb); + return len; } static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) @@ -589,17 +600,18 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) spin_lock(&epdata->dev->lock); priv->req = NULL; priv->epdata = NULL; - - /* if this was a write or a read returning no data then we - * don't need to copy anything to userspace, so we can - * complete the aio request immediately. - */ - if (priv->iv == NULL || unlikely(req->actual == 0)) { + if (priv->iv == NULL + || unlikely(req->actual == 0) + || unlikely(kiocbIsCancelled(iocb))) { kfree(req->buf); kfree(priv); iocb->private = NULL; /* aio_complete() reports bytes-transferred _and_ faults */ - aio_complete(iocb, req->actual ? req->actual : req->status, + if (unlikely(kiocbIsCancelled(iocb))) + aio_put_req(iocb); + else + aio_complete(iocb, + req->actual ? req->actual : req->status, req->status); } else { /* retry() won't report both; so we hide some faults */ @@ -624,7 +636,7 @@ ep_aio_rwtail( size_t len, struct ep_data *epdata, const struct iovec *iv, - unsigned long nr_segs + unsigned long nr_segs ) { struct kiocb_priv *priv; @@ -840,9 +852,9 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) break; #endif default: - DBG(data->dev, "unconnected, %s init abandoned\n", + DBG (data->dev, "unconnected, %s init deferred\n", data->name); - value = -EINVAL; + data->state = STATE_EP_DEFER_ENABLE; } if (value == 0) { fd->f_op = &ep_io_operations; @@ -931,24 +943,22 @@ static void clean_req (struct usb_ep *ep, struct usb_request *req) static void ep0_complete (struct usb_ep *ep, struct usb_request *req) { struct dev_data *dev = ep->driver_data; - unsigned long flags; int free = 1; /* for control OUT, data must still get to userspace */ - spin_lock_irqsave(&dev->lock, flags); if (!dev->setup_in) { dev->setup_out_error = (req->status != 0); if (!dev->setup_out_error) free = 0; dev->setup_out_ready = 1; ep0_readable (dev); - } + } else if (dev->state == STATE_SETUP) + dev->state = STATE_CONNECTED; /* clean up as appropriate */ if (free && req->buf != &dev->rbuf) clean_req (ep, req); req->complete = epio_complete; - spin_unlock_irqrestore(&dev->lock, flags); } static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) @@ -988,13 +998,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) } /* control DATA stage */ - if ((state = dev->state) == STATE_DEV_SETUP) { + if ((state = dev->state) == STATE_SETUP) { if (dev->setup_in) { /* stall IN */ VDEBUG(dev, "ep0in stall\n"); (void) usb_ep_set_halt (dev->gadget->ep0); retval = -EL2HLT; - dev->state = STATE_DEV_CONNECTED; + dev->state = STATE_CONNECTED; } else if (len == 0) { /* ack SET_CONFIGURATION etc */ struct usb_ep *ep = dev->gadget->ep0; @@ -1002,7 +1012,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) if ((retval = setup_req (ep, req, 0)) == 0) retval = usb_ep_queue (ep, req, GFP_ATOMIC); - dev->state = STATE_DEV_CONNECTED; + dev->state = STATE_CONNECTED; /* assume that was SET_CONFIGURATION */ if (dev->current_config) { @@ -1030,13 +1040,6 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) spin_lock_irq (&dev->lock); if (retval) goto done; - - if (dev->state != STATE_DEV_SETUP) { - retval = -ECANCELED; - goto done; - } - dev->state = STATE_DEV_CONNECTED; - if (dev->setup_out_error) retval = -EIO; else { @@ -1063,36 +1066,39 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) /* return queued events right away */ if (dev->ev_next != 0) { unsigned i, n; + int tmp = dev->ev_next; + len = min (len, tmp * sizeof (struct usb_gadgetfs_event)); n = len / sizeof (struct usb_gadgetfs_event); - if (dev->ev_next < n) - n = dev->ev_next; - /* ep0 i/o has special semantics during STATE_DEV_SETUP */ + /* ep0 can't deliver events when STATE_SETUP */ for (i = 0; i < n; i++) { if (dev->event [i].type == GADGETFS_SETUP) { - dev->state = STATE_DEV_SETUP; - n = i + 1; + len = i + 1; + len *= sizeof (struct usb_gadgetfs_event); + n = 0; break; } } spin_unlock_irq (&dev->lock); - len = n * sizeof (struct usb_gadgetfs_event); if (copy_to_user (buf, &dev->event, len)) retval = -EFAULT; else retval = len; if (len > 0) { + len /= sizeof (struct usb_gadgetfs_event); + /* NOTE this doesn't guard against broken drivers; * concurrent ep0 readers may lose events. */ spin_lock_irq (&dev->lock); - if (dev->ev_next > n) { - memmove(&dev->event[0], &dev->event[n], + dev->ev_next -= len; + if (dev->ev_next != 0) + memmove (&dev->event, &dev->event [len], sizeof (struct usb_gadgetfs_event) - * (dev->ev_next - n)); - } - dev->ev_next -= n; + * (tmp - len)); + if (n == 0) + dev->state = STATE_SETUP; spin_unlock_irq (&dev->lock); } return retval; @@ -1107,8 +1113,8 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) DBG (dev, "fail %s, state %d\n", __FUNCTION__, state); retval = -ESRCH; break; - case STATE_DEV_UNCONNECTED: - case STATE_DEV_CONNECTED: + case STATE_UNCONNECTED: + case STATE_CONNECTED: spin_unlock_irq (&dev->lock); DBG (dev, "%s wait\n", __FUNCTION__); @@ -1135,7 +1141,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) switch (type) { /* these events purge the queue */ case GADGETFS_DISCONNECT: - if (dev->state == STATE_DEV_SETUP) + if (dev->state == STATE_SETUP) dev->setup_abort = 1; // FALL THROUGH case GADGETFS_CONNECT: @@ -1147,7 +1153,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) for (i = 0; i != dev->ev_next; i++) { if (dev->event [i].type != type) continue; - DBG(dev, "discard old event[%d] %d\n", i, type); + DBG (dev, "discard old event %d\n", type); dev->ev_next--; if (i == dev->ev_next) break; @@ -1160,9 +1166,9 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) default: BUG (); } - VDEBUG(dev, "event[%d] = %d\n", dev->ev_next, type); event = &dev->event [dev->ev_next++]; BUG_ON (dev->ev_next > N_EVENT); + VDEBUG (dev, "ev %d, next %d\n", type, dev->ev_next); memset (event, 0, sizeof *event); event->type = type; return event; @@ -1182,13 +1188,12 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) retval = -EIDRM; /* data and/or status stage for control request */ - } else if (dev->state == STATE_DEV_SETUP) { + } else if (dev->state == STATE_SETUP) { /* IN DATA+STATUS caller makes len <= wLength */ if (dev->setup_in) { retval = setup_req (dev->gadget->ep0, dev->req, len); if (retval == 0) { - dev->state = STATE_DEV_CONNECTED; spin_unlock_irq (&dev->lock); if (copy_from_user (dev->req->buf, buf, len)) retval = -EFAULT; @@ -1214,7 +1219,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) VDEBUG(dev, "ep0out stall\n"); (void) usb_ep_set_halt (dev->gadget->ep0); retval = -EL2HLT; - dev->state = STATE_DEV_CONNECTED; + dev->state = STATE_CONNECTED; } else { DBG(dev, "bogus ep0out stall!\n"); } @@ -1256,9 +1261,7 @@ dev_release (struct inode *inode, struct file *fd) put_dev (dev); /* other endpoints were all decoupled from this device */ - spin_lock_irq(&dev->lock); dev->state = STATE_DEV_DISABLED; - spin_unlock_irq(&dev->lock); return 0; } @@ -1279,7 +1282,7 @@ ep0_poll (struct file *fd, poll_table *wait) goto out; } - if (dev->state == STATE_DEV_SETUP) { + if (dev->state == STATE_SETUP) { if (dev->setup_in || dev->setup_can_stall) mask = POLLOUT; } else { @@ -1389,29 +1392,52 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) spin_lock (&dev->lock); dev->setup_abort = 0; - if (dev->state == STATE_DEV_UNCONNECTED) { + if (dev->state == STATE_UNCONNECTED) { + struct usb_ep *ep; + struct ep_data *data; + + dev->state = STATE_CONNECTED; + dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; + #ifdef CONFIG_USB_GADGET_DUALSPEED if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { - spin_unlock(&dev->lock); ERROR (dev, "no high speed config??\n"); return -EINVAL; } #endif /* CONFIG_USB_GADGET_DUALSPEED */ - dev->state = STATE_DEV_CONNECTED; - dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; - INFO (dev, "connected\n"); event = next_event (dev, GADGETFS_CONNECT); event->u.speed = gadget->speed; ep0_readable (dev); + list_for_each_entry (ep, &gadget->ep_list, ep_list) { + data = ep->driver_data; + /* ... down_trylock (&data->lock) ... */ + if (data->state != STATE_EP_DEFER_ENABLE) + continue; +#ifdef CONFIG_USB_GADGET_DUALSPEED + if (gadget->speed == USB_SPEED_HIGH) + value = usb_ep_enable (ep, &data->hs_desc); + else +#endif /* CONFIG_USB_GADGET_DUALSPEED */ + value = usb_ep_enable (ep, &data->desc); + if (value) { + ERROR (dev, "deferred %s enable --> %d\n", + data->name, value); + continue; + } + data->state = STATE_EP_ENABLED; + wake_up (&data->wait); + DBG (dev, "woke up %s waiters\n", data->name); + } + /* host may have given up waiting for response. we can miss control * requests handled lower down (device/endpoint status and features); * then ep0_{read,write} will report the wrong status. controller * driver will have aborted pending i/o. */ - } else if (dev->state == STATE_DEV_SETUP) + } else if (dev->state == STATE_SETUP) dev->setup_abort = 1; req->buf = dev->rbuf; @@ -1557,7 +1583,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) } /* proceed with data transfer and status phases? */ - if (value >= 0 && dev->state != STATE_DEV_SETUP) { + if (value >= 0 && dev->state != STATE_SETUP) { req->length = value; req->zero = value < w_length; value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); @@ -1721,9 +1747,7 @@ gadgetfs_bind (struct usb_gadget *gadget) goto enomem; INFO (dev, "bound to %s driver\n", gadget->name); - spin_lock_irq(&dev->lock); - dev->state = STATE_DEV_UNCONNECTED; - spin_unlock_irq(&dev->lock); + dev->state = STATE_UNCONNECTED; get_dev (dev); return 0; @@ -1738,9 +1762,11 @@ gadgetfs_disconnect (struct usb_gadget *gadget) struct dev_data *dev = get_gadget_data (gadget); spin_lock (&dev->lock); - if (dev->state == STATE_DEV_UNCONNECTED) + if (dev->state == STATE_UNCONNECTED) { + DBG (dev, "already unconnected\n"); goto exit; - dev->state = STATE_DEV_UNCONNECTED; + } + dev->state = STATE_UNCONNECTED; INFO (dev, "disconnected\n"); next_event (dev, GADGETFS_DISCONNECT); @@ -1757,9 +1783,9 @@ gadgetfs_suspend (struct usb_gadget *gadget) INFO (dev, "suspended from state %d\n", dev->state); spin_lock (&dev->lock); switch (dev->state) { - case STATE_DEV_SETUP: // VERY odd... host died?? - case STATE_DEV_CONNECTED: - case STATE_DEV_UNCONNECTED: + case STATE_SETUP: // VERY odd... host died?? + case STATE_CONNECTED: + case STATE_UNCONNECTED: next_event (dev, GADGETFS_SUSPEND); ep0_readable (dev); /* FALLTHROUGH */ @@ -1782,7 +1808,7 @@ static struct usb_gadget_driver gadgetfs_driver = { .disconnect = gadgetfs_disconnect, .suspend = gadgetfs_suspend, - .driver = { + .driver = { .name = (char *) shortname, }, }; @@ -1803,7 +1829,7 @@ static struct usb_gadget_driver probe_driver = { .unbind = gadgetfs_nop, .setup = (void *)gadgetfs_nop, .disconnect = gadgetfs_nop, - .driver = { + .driver = { .name = "nop", }, }; @@ -1823,16 +1849,19 @@ static struct usb_gadget_driver probe_driver = { * . full/low speed config ... all wTotalLength bytes (with interface, * class, altsetting, endpoint, and other descriptors) * . high speed config ... all descriptors, for high speed operation; - * this one's optional except for high-speed hardware + * this one's optional except for high-speed hardware * . device descriptor * - * Endpoints are not yet enabled. Drivers must wait until device - * configuration and interface altsetting changes create + * Endpoints are not yet enabled. Drivers may want to immediately + * initialize them, using the /dev/gadget/ep* files that are available + * as soon as the kernel sees the configuration, or they can wait + * until device configuration and interface altsetting changes create * the need to configure (or unconfigure) them. * * After initialization, the device stays active for as long as that - * $CHIP file is open. Events must then be read from that descriptor, - * such as configuration notifications. + * $CHIP file is open. Events may then be read from that descriptor, + * such as configuration notifications. More complex drivers will handle + * some control requests in user space. */ static int is_valid_config (struct usb_config_descriptor *config) @@ -1855,6 +1884,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) u32 tag; char *kbuf; + if (dev->state != STATE_OPENED) + return -EEXIST; + if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) return -EINVAL; @@ -1946,15 +1978,13 @@ dev_open (struct inode *inode, struct file *fd) struct dev_data *dev = inode->i_private; int value = -EBUSY; - spin_lock_irq(&dev->lock); if (dev->state == STATE_DEV_DISABLED) { dev->ev_next = 0; - dev->state = STATE_DEV_OPENED; + dev->state = STATE_OPENED; fd->private_data = dev; get_dev (dev); value = 0; } - spin_unlock_irq(&dev->lock); return value; } diff --git a/trunk/drivers/usb/gadget/lh7a40x_udc.h b/trunk/drivers/usb/gadget/lh7a40x_udc.h index b3fe197e1eeb..e3bb78524c88 100644 --- a/trunk/drivers/usb/gadget/lh7a40x_udc.h +++ b/trunk/drivers/usb/gadget/lh7a40x_udc.h @@ -49,7 +49,7 @@ #include #include -#include +#include #include /* diff --git a/trunk/drivers/usb/gadget/net2280.c b/trunk/drivers/usb/gadget/net2280.c index 7617ff7bd5ac..569eb8ccf232 100644 --- a/trunk/drivers/usb/gadget/net2280.c +++ b/trunk/drivers/usb/gadget/net2280.c @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/usb/gadget/omap_udc.c b/trunk/drivers/usb/gadget/omap_udc.c index 140104341db4..cdcfd42843d4 100644 --- a/trunk/drivers/usb/gadget/omap_udc.c +++ b/trunk/drivers/usb/gadget/omap_udc.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/pxa2xx_udc.c b/trunk/drivers/usb/gadget/pxa2xx_udc.c index 0d225369847d..b78de9694665 100644 --- a/trunk/drivers/usb/gadget/pxa2xx_udc.c +++ b/trunk/drivers/usb/gadget/pxa2xx_udc.c @@ -56,7 +56,7 @@ #include #endif -#include +#include #include #include diff --git a/trunk/drivers/usb/gadget/serial.c b/trunk/drivers/usb/gadget/serial.c index 6c742a909225..f8a3ec64635d 100644 --- a/trunk/drivers/usb/gadget/serial.c +++ b/trunk/drivers/usb/gadget/serial.c @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include diff --git a/trunk/drivers/usb/gadget/usbstring.c b/trunk/drivers/usb/gadget/usbstring.c index 3459ea6c6c0b..b1735767660b 100644 --- a/trunk/drivers/usb/gadget/usbstring.c +++ b/trunk/drivers/usb/gadget/usbstring.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/trunk/drivers/usb/gadget/zero.c b/trunk/drivers/usb/gadget/zero.c index ebe04e0d2879..40710ea1b490 100644 --- a/trunk/drivers/usb/gadget/zero.c +++ b/trunk/drivers/usb/gadget/zero.c @@ -84,7 +84,7 @@ #include #include -#include +#include #include #include "gadget_chips.h" diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index 62711870f8ee..cc60759083bf 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -67,11 +67,6 @@ config USB_EHCI_TT_NEWSCHED If unsure, say N. -config USB_EHCI_BIG_ENDIAN_MMIO - bool - depends on USB_EHCI_HCD - default n - config USB_ISP116X_HCD tristate "ISP116X HCD support" depends on USB @@ -106,48 +101,21 @@ config USB_OHCI_HCD_PPC_SOC bool "OHCI support for on-chip PPC USB controller" depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) default y - select USB_OHCI_BIG_ENDIAN_DESC - select USB_OHCI_BIG_ENDIAN_MMIO + select USB_OHCI_BIG_ENDIAN ---help--- Enables support for the USB controller on the MPC52xx or STB03xxx processor chip. If unsure, say Y. -config USB_OHCI_HCD_PPC_OF - bool "OHCI support for PPC USB controller on OF platform bus" - depends on USB_OHCI_HCD && PPC_OF - default y - ---help--- - Enables support for the USB controller PowerPC present on the - OpenFirmware platform bus. - -config USB_OHCI_HCD_PPC_OF_BE - bool "Support big endian HC" - depends on USB_OHCI_HCD_PPC_OF - default y - select USB_OHCI_BIG_ENDIAN_DESC - select USB_OHCI_BIG_ENDIAN_MMIO - -config USB_OHCI_HCD_PPC_OF_LE - bool "Support little endian HC" - depends on USB_OHCI_HCD_PPC_OF - default n - select USB_OHCI_LITTLE_ENDIAN - config USB_OHCI_HCD_PCI bool "OHCI support for PCI-bus USB controllers" - depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx || USB_OHCI_HCD_PPC_OF) + depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx) default y select USB_OHCI_LITTLE_ENDIAN ---help--- Enables support for PCI-bus plug-in USB controller cards. If unsure, say Y. -config USB_OHCI_BIG_ENDIAN_DESC - bool - depends on USB_OHCI_HCD - default n - -config USB_OHCI_BIG_ENDIAN_MMIO +config USB_OHCI_BIG_ENDIAN bool depends on USB_OHCI_HCD default n diff --git a/trunk/drivers/usb/host/ehci-dbg.c b/trunk/drivers/usb/host/ehci-dbg.c index 246afea9e83b..56349d21e6ea 100644 --- a/trunk/drivers/usb/host/ehci-dbg.c +++ b/trunk/drivers/usb/host/ehci-dbg.c @@ -43,7 +43,7 @@ */ static void dbg_hcs_params (struct ehci_hcd *ehci, char *label) { - u32 params = ehci_readl(ehci, &ehci->caps->hcs_params); + u32 params = readl (&ehci->caps->hcs_params); ehci_dbg (ehci, "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n", @@ -87,7 +87,7 @@ static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {} * */ static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) { - u32 params = ehci_readl(ehci, &ehci->caps->hcc_params); + u32 params = readl (&ehci->caps->hcc_params); if (HCC_ISOC_CACHE (params)) { ehci_dbg (ehci, @@ -653,7 +653,7 @@ show_registers (struct class_device *class_dev, char *buf) } /* Capability Registers */ - i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); + i = HC_VERSION(readl (&ehci->caps->hc_capbase)); temp = scnprintf (next, size, "bus %s, device %s (driver " DRIVER_VERSION ")\n" "%s\n" @@ -673,7 +673,7 @@ show_registers (struct class_device *class_dev, char *buf) unsigned count = 256/4; pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); - offset = HCC_EXT_CAPS (ehci_readl(ehci, &ehci->caps->hcc_params)); + offset = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); while (offset && count--) { pci_read_config_dword (pdev, offset, &cap); switch (cap & 0xff) { @@ -704,50 +704,50 @@ show_registers (struct class_device *class_dev, char *buf) #endif // FIXME interpret both types of params - i = ehci_readl(ehci, &ehci->caps->hcs_params); + i = readl (&ehci->caps->hcs_params); temp = scnprintf (next, size, "structural params 0x%08x\n", i); size -= temp; next += temp; - i = ehci_readl(ehci, &ehci->caps->hcc_params); + i = readl (&ehci->caps->hcc_params); temp = scnprintf (next, size, "capability params 0x%08x\n", i); size -= temp; next += temp; /* Operational Registers */ temp = dbg_status_buf (scratch, sizeof scratch, label, - ehci_readl(ehci, &ehci->regs->status)); + readl (&ehci->regs->status)); temp = scnprintf (next, size, fmt, temp, scratch); size -= temp; next += temp; temp = dbg_command_buf (scratch, sizeof scratch, label, - ehci_readl(ehci, &ehci->regs->command)); + readl (&ehci->regs->command)); temp = scnprintf (next, size, fmt, temp, scratch); size -= temp; next += temp; temp = dbg_intr_buf (scratch, sizeof scratch, label, - ehci_readl(ehci, &ehci->regs->intr_enable)); + readl (&ehci->regs->intr_enable)); temp = scnprintf (next, size, fmt, temp, scratch); size -= temp; next += temp; temp = scnprintf (next, size, "uframe %04x\n", - ehci_readl(ehci, &ehci->regs->frame_index)); + readl (&ehci->regs->frame_index)); size -= temp; next += temp; for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) { temp = dbg_port_buf (scratch, sizeof scratch, label, i, - ehci_readl(ehci, &ehci->regs->port_status [i - 1])); + readl (&ehci->regs->port_status [i - 1])); temp = scnprintf (next, size, fmt, temp, scratch); size -= temp; next += temp; if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) { temp = scnprintf (next, size, " debug control %08x\n", - ehci_readl(ehci, &ehci->debug->control)); + readl (&ehci->debug->control)); size -= temp; next += temp; } diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index a52480505f78..1a915e982c1c 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -177,7 +177,7 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci, case FSL_USB2_PHY_NONE: break; } - ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); + writel(portsc, &ehci->regs->port_status[port_offset]); } static void mpc83xx_usb_setup(struct usb_hcd *hcd) @@ -214,7 +214,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd) } /* put controller in host mode. */ - ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMODE); + writel(0x00000003, non_ehci + FSL_SOC_USB_USBMODE); out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); @@ -238,12 +238,12 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache this readonly data; minimize chip reads */ - ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); + ehci->hcs_params = readl(&ehci->caps->hcs_params); retval = ehci_halt(ehci); if (retval) diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 185721dba42b..025d33313681 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -157,13 +157,12 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); * before driver shutdown. But it also seems to be caused by bugs in cardbus * bridge shutdown: shutting down the bridge before the devices using it. */ -static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, - u32 mask, u32 done, int usec) +static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec) { u32 result; do { - result = ehci_readl(ehci, ptr); + result = readl (ptr); if (result == ~(u32)0) /* card removed */ return -ENODEV; result &= mask; @@ -178,19 +177,18 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, /* force HC to halt state from unknown (EHCI spec section 2.3) */ static int ehci_halt (struct ehci_hcd *ehci) { - u32 temp = ehci_readl(ehci, &ehci->regs->status); + u32 temp = readl (&ehci->regs->status); /* disable any irqs left enabled by previous code */ - ehci_writel(ehci, 0, &ehci->regs->intr_enable); + writel (0, &ehci->regs->intr_enable); if ((temp & STS_HALT) != 0) return 0; - temp = ehci_readl(ehci, &ehci->regs->command); + temp = readl (&ehci->regs->command); temp &= ~CMD_RUN; - ehci_writel(ehci, temp, &ehci->regs->command); - return handshake (ehci, &ehci->regs->status, - STS_HALT, STS_HALT, 16 * 125); + writel (temp, &ehci->regs->command); + return handshake (&ehci->regs->status, STS_HALT, STS_HALT, 16 * 125); } /* put TDI/ARC silicon into EHCI mode */ @@ -200,24 +198,23 @@ static void tdi_reset (struct ehci_hcd *ehci) u32 tmp; reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68); - tmp = ehci_readl(ehci, reg_ptr); + tmp = readl (reg_ptr); tmp |= 0x3; - ehci_writel(ehci, tmp, reg_ptr); + writel (tmp, reg_ptr); } /* reset a non-running (STS_HALT == 1) controller */ static int ehci_reset (struct ehci_hcd *ehci) { int retval; - u32 command = ehci_readl(ehci, &ehci->regs->command); + u32 command = readl (&ehci->regs->command); command |= CMD_RESET; dbg_cmd (ehci, "reset", command); - ehci_writel(ehci, command, &ehci->regs->command); + writel (command, &ehci->regs->command); ehci_to_hcd(ehci)->state = HC_STATE_HALT; ehci->next_statechange = jiffies; - retval = handshake (ehci, &ehci->regs->command, - CMD_RESET, 0, 250 * 1000); + retval = handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000); if (retval) return retval; @@ -239,21 +236,21 @@ static void ehci_quiesce (struct ehci_hcd *ehci) #endif /* wait for any schedule enables/disables to take effect */ - temp = ehci_readl(ehci, &ehci->regs->command) << 10; + temp = readl (&ehci->regs->command) << 10; temp &= STS_ASS | STS_PSS; - if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, + if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, temp, 16 * 125) != 0) { ehci_to_hcd(ehci)->state = HC_STATE_HALT; return; } /* then disable anything that's still active */ - temp = ehci_readl(ehci, &ehci->regs->command); + temp = readl (&ehci->regs->command); temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); - ehci_writel(ehci, temp, &ehci->regs->command); + writel (temp, &ehci->regs->command); /* hardware can take 16 microframes to turn off ... */ - if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, + if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, 0, 16 * 125) != 0) { ehci_to_hcd(ehci)->state = HC_STATE_HALT; return; @@ -280,11 +277,11 @@ static void ehci_watchdog (unsigned long param) /* lost IAA irqs wedge things badly; seen with a vt8235 */ if (ehci->reclaim) { - u32 status = ehci_readl(ehci, &ehci->regs->status); + u32 status = readl (&ehci->regs->status); if (status & STS_IAA) { ehci_vdbg (ehci, "lost IAA\n"); COUNT (ehci->stats.lost_iaa); - ehci_writel(ehci, STS_IAA, &ehci->regs->status); + writel (STS_IAA, &ehci->regs->status); ehci->reclaim_ready = 1; } } @@ -312,7 +309,7 @@ ehci_shutdown (struct usb_hcd *hcd) (void) ehci_halt (ehci); /* make BIOS/etc use companion controller during reboot */ - ehci_writel(ehci, 0, &ehci->regs->configured_flag); + writel (0, &ehci->regs->configured_flag); } static void ehci_port_power (struct ehci_hcd *ehci, int is_on) @@ -382,13 +379,12 @@ static void ehci_stop (struct usb_hcd *hcd) ehci_quiesce (ehci); ehci_reset (ehci); - ehci_writel(ehci, 0, &ehci->regs->intr_enable); + writel (0, &ehci->regs->intr_enable); spin_unlock_irq(&ehci->lock); /* let companion controllers work when we aren't */ - ehci_writel(ehci, 0, &ehci->regs->configured_flag); + writel (0, &ehci->regs->configured_flag); - remove_companion_file(ehci); remove_debug_files (ehci); /* root hub is shut down separately (first, when possible) */ @@ -406,8 +402,7 @@ static void ehci_stop (struct usb_hcd *hcd) ehci->stats.complete, ehci->stats.unlink); #endif - dbg_status (ehci, "ehci_stop completed", - ehci_readl(ehci, &ehci->regs->status)); + dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); } /* one-time init, only for memory state */ @@ -433,7 +428,7 @@ static int ehci_init(struct usb_hcd *hcd) return retval; /* controllers may cache some of the periodic schedule ... */ - hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); + hcc_params = readl(&ehci->caps->hcc_params); if (HCC_ISOC_CACHE(hcc_params)) // full frame cache ehci->i_thresh = 8; else // N microframes cached @@ -501,16 +496,13 @@ static int ehci_run (struct usb_hcd *hcd) u32 temp; u32 hcc_params; - hcd->uses_new_polling = 1; - hcd->poll_rh = 0; - /* EHCI spec section 4.1 */ if ((retval = ehci_reset(ehci)) != 0) { ehci_mem_cleanup(ehci); return retval; } - ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); - ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); + writel(ehci->periodic_dma, &ehci->regs->frame_list); + writel((u32)ehci->async->qh_dma, &ehci->regs->async_next); /* * hcc_params controls whether ehci->regs->segment must (!!!) @@ -524,9 +516,9 @@ static int ehci_run (struct usb_hcd *hcd) * Scsi_Host.highmem_io, and so forth. It's readonly to all * host side drivers though. */ - hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); + hcc_params = readl(&ehci->caps->hcc_params); if (HCC_64BIT_ADDR(hcc_params)) { - ehci_writel(ehci, 0, &ehci->regs->segment); + writel(0, &ehci->regs->segment); #if 0 // this is deeply broken on almost all architectures if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK)) @@ -539,7 +531,7 @@ static int ehci_run (struct usb_hcd *hcd) // root hub will detect new devices (why?); NEC doesn't ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); ehci->command |= CMD_RUN; - ehci_writel(ehci, ehci->command, &ehci->regs->command); + writel (ehci->command, &ehci->regs->command); dbg_cmd (ehci, "init", ehci->command); /* @@ -549,25 +541,23 @@ static int ehci_run (struct usb_hcd *hcd) * and there's no companion controller unless maybe for USB OTG.) */ hcd->state = HC_STATE_RUNNING; - ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); - ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ + writel (FLAG_CF, &ehci->regs->configured_flag); + readl (&ehci->regs->command); /* unblock posted writes */ - temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); + temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); ehci_info (ehci, "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), temp >> 8, temp & 0xff, DRIVER_VERSION, ignore_oc ? ", overcurrent ignored" : ""); - ehci_writel(ehci, INTR_MASK, - &ehci->regs->intr_enable); /* Turn On Interrupts */ + writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ /* GRR this is run-once init(), being done every time the HC starts. * So long as they're part of class devices, we can't do it init() * since the class device isn't created that early. */ create_debug_files(ehci); - create_companion_file(ehci); return 0; } @@ -577,12 +567,12 @@ static int ehci_run (struct usb_hcd *hcd) static irqreturn_t ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - u32 status, pcd_status = 0; + u32 status; int bh; spin_lock (&ehci->lock); - status = ehci_readl(ehci, &ehci->regs->status); + status = readl (&ehci->regs->status); /* e.g. cardbus physical eject */ if (status == ~(u32) 0) { @@ -597,8 +587,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) } /* clear (just) interrupts */ - ehci_writel(ehci, status, &ehci->regs->status); - ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ + writel (status, &ehci->regs->status); + readl (&ehci->regs->command); /* unblock posted write */ bh = 0; #ifdef EHCI_VERBOSE_DEBUG @@ -627,15 +617,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* remote wakeup [4.3.1] */ if (status & STS_PCD) { unsigned i = HCS_N_PORTS (ehci->hcs_params); - pcd_status = status; /* resume root hub? */ - if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN)) + if (!(readl(&ehci->regs->command) & CMD_RUN)) usb_hcd_resume_root_hub(hcd); while (i--) { - int pstatus = ehci_readl(ehci, - &ehci->regs->port_status [i]); + int pstatus = readl (&ehci->regs->port_status [i]); if (pstatus & PORT_OWNER) continue; @@ -655,15 +643,14 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* PCI errors [4.15.2.4] */ if (unlikely ((status & STS_FATAL) != 0)) { /* bogus "fatal" IRQs appear on some chips... why? */ - status = ehci_readl(ehci, &ehci->regs->status); - dbg_cmd (ehci, "fatal", ehci_readl(ehci, - &ehci->regs->command)); + status = readl (&ehci->regs->status); + dbg_cmd (ehci, "fatal", readl (&ehci->regs->command)); dbg_status (ehci, "fatal", status); if (status & STS_HALT) { ehci_err (ehci, "fatal error\n"); dead: ehci_reset (ehci); - ehci_writel(ehci, 0, &ehci->regs->configured_flag); + writel (0, &ehci->regs->configured_flag); /* generic layer kills/unlinks all urbs, then * uses ehci_stop to clean up the rest */ @@ -674,8 +661,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) if (bh) ehci_work (ehci); spin_unlock (&ehci->lock); - if (pcd_status & STS_PCD) - usb_hcd_poll_rh_status(hcd); return IRQ_HANDLED; } @@ -888,8 +873,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) static int ehci_get_frame (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) % - ehci->periodic_size; + return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; } /*-------------------------------------------------------------------------*/ @@ -915,13 +899,7 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver #endif -#ifdef CONFIG_PPC_PS3 -#include "ehci-ps3.c" -#define PS3_SYSTEM_BUS_DRIVER ps3_ehci_sb_driver -#endif - -#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ - !defined(PS3_SYSTEM_BUS_DRIVER) +#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) #error "missing bus glue for ehci-hcd" #endif @@ -946,20 +924,6 @@ static int __init ehci_hcd_init(void) #ifdef PLATFORM_DRIVER platform_driver_unregister(&PLATFORM_DRIVER); #endif - return retval; - } -#endif - -#ifdef PS3_SYSTEM_BUS_DRIVER - retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); - if (retval < 0) { -#ifdef PLATFORM_DRIVER - platform_driver_unregister(&PLATFORM_DRIVER); -#endif -#ifdef PCI_DRIVER - pci_unregister_driver(&PCI_DRIVER); -#endif - return retval; } #endif @@ -975,9 +939,6 @@ static void __exit ehci_hcd_cleanup(void) #ifdef PCI_DRIVER pci_unregister_driver(&PCI_DRIVER); #endif -#ifdef PS3_SYSTEM_BUS_DRIVER - ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); -#endif } module_exit(ehci_hcd_cleanup); diff --git a/trunk/drivers/usb/host/ehci-hub.c b/trunk/drivers/usb/host/ehci-hub.c index 0d83c6df1a3b..bfe5f307cba6 100644 --- a/trunk/drivers/usb/host/ehci-hub.c +++ b/trunk/drivers/usb/host/ehci-hub.c @@ -47,7 +47,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ehci_quiesce (ehci); hcd->state = HC_STATE_QUIESCING; } - ehci->command = ehci_readl(ehci, &ehci->regs->command); + ehci->command = readl (&ehci->regs->command); if (ehci->reclaim) ehci->reclaim_ready = 1; ehci_work(ehci); @@ -60,7 +60,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ehci->bus_suspended = 0; while (port--) { u32 __iomem *reg = &ehci->regs->port_status [port]; - u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; + u32 t1 = readl (reg) & ~PORT_RWC_BITS; u32 t2 = t1; /* keep track of which ports we suspend */ @@ -79,7 +79,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) if (t1 != t2) { ehci_vdbg (ehci, "port %d, %08x -> %08x\n", port + 1, t1, t2); - ehci_writel(ehci, t2, reg); + writel (t2, reg); } } @@ -92,8 +92,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) mask = INTR_MASK; if (!device_may_wakeup(&hcd->self.root_hub->dev)) mask &= ~STS_PCD; - ehci_writel(ehci, mask, &ehci->regs->intr_enable); - ehci_readl(ehci, &ehci->regs->intr_enable); + writel(mask, &ehci->regs->intr_enable); + readl(&ehci->regs->intr_enable); ehci->next_statechange = jiffies + msecs_to_jiffies(10); spin_unlock_irq (&ehci->lock); @@ -118,26 +118,26 @@ static int ehci_bus_resume (struct usb_hcd *hcd) * the last user of the controller, not reset/pm hardware keeping * state we gave to it. */ - temp = ehci_readl(ehci, &ehci->regs->intr_enable); + temp = readl(&ehci->regs->intr_enable); ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); /* at least some APM implementations will try to deliver * IRQs right away, so delay them until we're ready. */ - ehci_writel(ehci, 0, &ehci->regs->intr_enable); + writel(0, &ehci->regs->intr_enable); /* re-init operational registers */ - ehci_writel(ehci, 0, &ehci->regs->segment); - ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); - ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next); + writel(0, &ehci->regs->segment); + writel(ehci->periodic_dma, &ehci->regs->frame_list); + writel((u32) ehci->async->qh_dma, &ehci->regs->async_next); /* restore CMD_RUN, framelist size, and irq threshold */ - ehci_writel(ehci, ehci->command, &ehci->regs->command); + writel (ehci->command, &ehci->regs->command); /* manually resume the ports we suspended during bus_suspend() */ i = HCS_N_PORTS (ehci->hcs_params); while (i--) { - temp = ehci_readl(ehci, &ehci->regs->port_status [i]); + temp = readl (&ehci->regs->port_status [i]); temp &= ~(PORT_RWC_BITS | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); if (test_bit(i, &ehci->bus_suspended) && @@ -145,20 +145,20 @@ static int ehci_bus_resume (struct usb_hcd *hcd) ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); temp |= PORT_RESUME; } - ehci_writel(ehci, temp, &ehci->regs->port_status [i]); + writel (temp, &ehci->regs->port_status [i]); } i = HCS_N_PORTS (ehci->hcs_params); mdelay (20); while (i--) { - temp = ehci_readl(ehci, &ehci->regs->port_status [i]); + temp = readl (&ehci->regs->port_status [i]); if (test_bit(i, &ehci->bus_suspended) && (temp & PORT_SUSPEND)) { temp &= ~(PORT_RWC_BITS | PORT_RESUME); - ehci_writel(ehci, temp, &ehci->regs->port_status [i]); + writel (temp, &ehci->regs->port_status [i]); ehci_vdbg (ehci, "resumed port %d\n", i + 1); } } - (void) ehci_readl(ehci, &ehci->regs->command); + (void) readl (&ehci->regs->command); /* maybe re-activate the schedule(s) */ temp = 0; @@ -168,14 +168,14 @@ static int ehci_bus_resume (struct usb_hcd *hcd) temp |= CMD_PSE; if (temp) { ehci->command |= temp; - ehci_writel(ehci, ehci->command, &ehci->regs->command); + writel (ehci->command, &ehci->regs->command); } ehci->next_statechange = jiffies + msecs_to_jiffies(5); hcd->state = HC_STATE_RUNNING; /* Now we can safely re-enable irqs */ - ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); + writel(INTR_MASK, &ehci->regs->intr_enable); spin_unlock_irq (&ehci->lock); return 0; @@ -188,109 +188,11 @@ static int ehci_bus_resume (struct usb_hcd *hcd) #endif /* CONFIG_PM */ -/*-------------------------------------------------------------------------*/ - -/* Display the ports dedicated to the companion controller */ -static ssize_t show_companion(struct class_device *class_dev, char *buf) -{ - struct ehci_hcd *ehci; - int nports, index, n; - int count = PAGE_SIZE; - char *ptr = buf; - - ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); - nports = HCS_N_PORTS(ehci->hcs_params); - - for (index = 0; index < nports; ++index) { - if (test_bit(index, &ehci->companion_ports)) { - n = scnprintf(ptr, count, "%d\n", index + 1); - ptr += n; - count -= n; - } - } - return ptr - buf; -} - -/* - * Dedicate or undedicate a port to the companion controller. - * Syntax is "[-]portnum", where a leading '-' sign means - * return control of the port to the EHCI controller. - */ -static ssize_t store_companion(struct class_device *class_dev, - const char *buf, size_t count) -{ - struct ehci_hcd *ehci; - int portnum, new_owner, try; - u32 __iomem *status_reg; - u32 port_status; - - ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); - new_owner = PORT_OWNER; /* Owned by companion */ - if (sscanf(buf, "%d", &portnum) != 1) - return -EINVAL; - if (portnum < 0) { - portnum = - portnum; - new_owner = 0; /* Owned by EHCI */ - } - if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params)) - return -ENOENT; - status_reg = &ehci->regs->port_status[--portnum]; - if (new_owner) - set_bit(portnum, &ehci->companion_ports); - else - clear_bit(portnum, &ehci->companion_ports); - - /* - * The controller won't set the OWNER bit if the port is - * enabled, so this loop will sometimes require at least two - * iterations: one to disable the port and one to set OWNER. - */ - - for (try = 4; try > 0; --try) { - spin_lock_irq(&ehci->lock); - port_status = ehci_readl(ehci, status_reg); - if ((port_status & PORT_OWNER) == new_owner - || (port_status & (PORT_OWNER | PORT_CONNECT)) - == 0) - try = 0; - else { - port_status ^= PORT_OWNER; - port_status &= ~(PORT_PE | PORT_RWC_BITS); - ehci_writel(ehci, port_status, status_reg); - } - spin_unlock_irq(&ehci->lock); - if (try > 1) - msleep(5); - } - return count; -} -static CLASS_DEVICE_ATTR(companion, 0644, show_companion, store_companion); - -static inline void create_companion_file(struct ehci_hcd *ehci) -{ - int i; - - /* with integrated TT there is no companion! */ - if (!ehci_is_TDI(ehci)) - i = class_device_create_file(ehci_to_hcd(ehci)->self.class_dev, - &class_device_attr_companion); -} - -static inline void remove_companion_file(struct ehci_hcd *ehci) -{ - /* with integrated TT there is no companion! */ - if (!ehci_is_TDI(ehci)) - class_device_remove_file(ehci_to_hcd(ehci)->self.class_dev, - &class_device_attr_companion); -} - - /*-------------------------------------------------------------------------*/ static int check_reset_complete ( struct ehci_hcd *ehci, int index, - u32 __iomem *status_reg, int port_status ) { if (!(port_status & PORT_CONNECT)) { @@ -315,7 +217,7 @@ static int check_reset_complete ( // what happens if HCS_N_CC(params) == 0 ? port_status |= PORT_OWNER; port_status &= ~PORT_RWC_BITS; - ehci_writel(ehci, port_status, status_reg); + writel (port_status, &ehci->regs->port_status [index]); } else ehci_dbg (ehci, "port %d high speed\n", index + 1); @@ -366,21 +268,22 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) /* port N changes (bit N)? */ spin_lock_irqsave (&ehci->lock, flags); for (i = 0; i < ports; i++) { - temp = ehci_readl(ehci, &ehci->regs->port_status [i]); - - /* - * Return status information even for ports with OWNER set. - * Otherwise khubd wouldn't see the disconnect event when a - * high-speed device is switched over to the companion - * controller by the user. - */ - + temp = readl (&ehci->regs->port_status [i]); + if (temp & PORT_OWNER) { + /* don't report this in GetPortStatus */ + if (temp & PORT_CSC) { + temp &= ~PORT_RWC_BITS; + temp |= PORT_CSC; + writel (temp, &ehci->regs->port_status [i]); + } + continue; + } if (!(temp & PORT_CONNECT)) ehci->reset_done [i] = 0; if ((temp & mask) != 0 || ((temp & PORT_RESUME) != 0 - && time_after_eq(jiffies, - ehci->reset_done[i]))) { + && time_after (jiffies, + ehci->reset_done [i]))) { if (i < 7) buf [0] |= 1 << (i + 1); else @@ -442,7 +345,6 @@ static int ehci_hub_control ( ) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); int ports = HCS_N_PORTS (ehci->hcs_params); - u32 __iomem *status_reg = &ehci->regs->port_status[wIndex - 1]; u32 temp, status; unsigned long flags; int retval = 0; @@ -471,22 +373,18 @@ static int ehci_hub_control ( if (!wIndex || wIndex > ports) goto error; wIndex--; - temp = ehci_readl(ehci, status_reg); - - /* - * Even if OWNER is set, so the port is owned by the - * companion controller, khubd needs to be able to clear - * the port-change status bits (especially - * USB_PORT_FEAT_C_CONNECTION). - */ + temp = readl (&ehci->regs->port_status [wIndex]); + if (temp & PORT_OWNER) + break; switch (wValue) { case USB_PORT_FEAT_ENABLE: - ehci_writel(ehci, temp & ~PORT_PE, status_reg); + writel (temp & ~PORT_PE, + &ehci->regs->port_status [wIndex]); break; case USB_PORT_FEAT_C_ENABLE: - ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC, - status_reg); + writel((temp & ~PORT_RWC_BITS) | PORT_PEC, + &ehci->regs->port_status [wIndex]); break; case USB_PORT_FEAT_SUSPEND: if (temp & PORT_RESET) @@ -498,8 +396,8 @@ static int ehci_hub_control ( goto error; /* resume signaling for 20 msec */ temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); - ehci_writel(ehci, temp | PORT_RESUME, - status_reg); + writel (temp | PORT_RESUME, + &ehci->regs->port_status [wIndex]); ehci->reset_done [wIndex] = jiffies + msecs_to_jiffies (20); } @@ -509,17 +407,16 @@ static int ehci_hub_control ( break; case USB_PORT_FEAT_POWER: if (HCS_PPC (ehci->hcs_params)) - ehci_writel(ehci, - temp & ~(PORT_RWC_BITS | PORT_POWER), - status_reg); + writel (temp & ~(PORT_RWC_BITS | PORT_POWER), + &ehci->regs->port_status [wIndex]); break; case USB_PORT_FEAT_C_CONNECTION: - ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC, - status_reg); + writel((temp & ~PORT_RWC_BITS) | PORT_CSC, + &ehci->regs->port_status [wIndex]); break; case USB_PORT_FEAT_C_OVER_CURRENT: - ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC, - status_reg); + writel((temp & ~PORT_RWC_BITS) | PORT_OCC, + &ehci->regs->port_status [wIndex]); break; case USB_PORT_FEAT_C_RESET: /* GetPortStatus clears reset */ @@ -527,7 +424,7 @@ static int ehci_hub_control ( default: goto error; } - ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ + readl (&ehci->regs->command); /* unblock posted write */ break; case GetHubDescriptor: ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *) @@ -543,7 +440,7 @@ static int ehci_hub_control ( goto error; wIndex--; status = 0; - temp = ehci_readl(ehci, status_reg); + temp = readl (&ehci->regs->port_status [wIndex]); // wPortChange bits if (temp & PORT_CSC) @@ -554,55 +451,42 @@ static int ehci_hub_control ( status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; /* whoever resumes must GetPortStatus to complete it!! */ - if (temp & PORT_RESUME) { - - /* Remote Wakeup received? */ - if (!ehci->reset_done[wIndex]) { - /* resume signaling for 20 msec */ - ehci->reset_done[wIndex] = jiffies - + msecs_to_jiffies(20); - /* check the port again */ - mod_timer(&ehci_to_hcd(ehci)->rh_timer, - ehci->reset_done[wIndex]); - } + if ((temp & PORT_RESUME) + && time_after (jiffies, + ehci->reset_done [wIndex])) { + status |= 1 << USB_PORT_FEAT_C_SUSPEND; + ehci->reset_done [wIndex] = 0; - /* resume completed? */ - else if (time_after_eq(jiffies, - ehci->reset_done[wIndex])) { - status |= 1 << USB_PORT_FEAT_C_SUSPEND; - ehci->reset_done[wIndex] = 0; - - /* stop resume signaling */ - temp = ehci_readl(ehci, status_reg); - ehci_writel(ehci, - temp & ~(PORT_RWC_BITS | PORT_RESUME), - status_reg); - retval = handshake(ehci, status_reg, - PORT_RESUME, 0, 2000 /* 2msec */); - if (retval != 0) { - ehci_err(ehci, - "port %d resume error %d\n", - wIndex + 1, retval); - goto error; - } - temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); + /* stop resume signaling */ + temp = readl (&ehci->regs->port_status [wIndex]); + writel (temp & ~(PORT_RWC_BITS | PORT_RESUME), + &ehci->regs->port_status [wIndex]); + retval = handshake ( + &ehci->regs->port_status [wIndex], + PORT_RESUME, 0, 2000 /* 2msec */); + if (retval != 0) { + ehci_err (ehci, "port %d resume error %d\n", + wIndex + 1, retval); + goto error; } + temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); } /* whoever resets must GetPortStatus to complete it!! */ if ((temp & PORT_RESET) - && time_after_eq(jiffies, - ehci->reset_done[wIndex])) { + && time_after (jiffies, + ehci->reset_done [wIndex])) { status |= 1 << USB_PORT_FEAT_C_RESET; ehci->reset_done [wIndex] = 0; /* force reset to complete */ - ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET), - status_reg); + writel (temp & ~(PORT_RWC_BITS | PORT_RESET), + &ehci->regs->port_status [wIndex]); /* REVISIT: some hardware needs 550+ usec to clear * this bit; seems too long to spin routinely... */ - retval = handshake(ehci, status_reg, + retval = handshake ( + &ehci->regs->port_status [wIndex], PORT_RESET, 0, 750); if (retval != 0) { ehci_err (ehci, "port %d reset error %d\n", @@ -611,41 +495,28 @@ static int ehci_hub_control ( } /* see what we found out */ - temp = check_reset_complete (ehci, wIndex, status_reg, - ehci_readl(ehci, status_reg)); + temp = check_reset_complete (ehci, wIndex, + readl (&ehci->regs->port_status [wIndex])); } - /* transfer dedicated ports to the companion hc */ - if ((temp & PORT_CONNECT) && - test_bit(wIndex, &ehci->companion_ports)) { - temp &= ~PORT_RWC_BITS; - temp |= PORT_OWNER; - ehci_writel(ehci, temp, status_reg); - ehci_dbg(ehci, "port %d --> companion\n", wIndex + 1); - temp = ehci_readl(ehci, status_reg); - } - - /* - * Even if OWNER is set, there's no harm letting khubd - * see the wPortStatus values (they should all be 0 except - * for PORT_POWER anyway). - */ - - if (temp & PORT_CONNECT) { - status |= 1 << USB_PORT_FEAT_CONNECTION; - // status may be from integrated TT - status |= ehci_port_speed(ehci, temp); + // don't show wPortStatus if it's owned by a companion hc + if (!(temp & PORT_OWNER)) { + if (temp & PORT_CONNECT) { + status |= 1 << USB_PORT_FEAT_CONNECTION; + // status may be from integrated TT + status |= ehci_port_speed(ehci, temp); + } + if (temp & PORT_PE) + status |= 1 << USB_PORT_FEAT_ENABLE; + if (temp & (PORT_SUSPEND|PORT_RESUME)) + status |= 1 << USB_PORT_FEAT_SUSPEND; + if (temp & PORT_OC) + status |= 1 << USB_PORT_FEAT_OVER_CURRENT; + if (temp & PORT_RESET) + status |= 1 << USB_PORT_FEAT_RESET; + if (temp & PORT_POWER) + status |= 1 << USB_PORT_FEAT_POWER; } - if (temp & PORT_PE) - status |= 1 << USB_PORT_FEAT_ENABLE; - if (temp & (PORT_SUSPEND|PORT_RESUME)) - status |= 1 << USB_PORT_FEAT_SUSPEND; - if (temp & PORT_OC) - status |= 1 << USB_PORT_FEAT_OVER_CURRENT; - if (temp & PORT_RESET) - status |= 1 << USB_PORT_FEAT_RESET; - if (temp & PORT_POWER) - status |= 1 << USB_PORT_FEAT_POWER; #ifndef EHCI_VERBOSE_DEBUG if (status & ~0xffff) /* only if wPortChange is interesting */ @@ -670,7 +541,7 @@ static int ehci_hub_control ( if (!wIndex || wIndex > ports) goto error; wIndex--; - temp = ehci_readl(ehci, status_reg); + temp = readl (&ehci->regs->port_status [wIndex]); if (temp & PORT_OWNER) break; @@ -684,12 +555,13 @@ static int ehci_hub_control ( goto error; if (device_may_wakeup(&hcd->self.root_hub->dev)) temp |= PORT_WAKE_BITS; - ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); + writel (temp | PORT_SUSPEND, + &ehci->regs->port_status [wIndex]); break; case USB_PORT_FEAT_POWER: if (HCS_PPC (ehci->hcs_params)) - ehci_writel(ehci, temp | PORT_POWER, - status_reg); + writel (temp | PORT_POWER, + &ehci->regs->port_status [wIndex]); break; case USB_PORT_FEAT_RESET: if (temp & PORT_RESUME) @@ -717,7 +589,7 @@ static int ehci_hub_control ( ehci->reset_done [wIndex] = jiffies + msecs_to_jiffies (50); } - ehci_writel(ehci, temp, status_reg); + writel (temp, &ehci->regs->port_status [wIndex]); break; /* For downstream facing ports (these): one hub port is put @@ -732,13 +604,13 @@ static int ehci_hub_control ( ehci_quiesce(ehci); ehci_halt(ehci); temp |= selector << 16; - ehci_writel(ehci, temp, status_reg); + writel (temp, &ehci->regs->port_status [wIndex]); break; default: goto error; } - ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ + readl (&ehci->regs->command); /* unblock posted writes */ break; default: diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index 12edc723ec73..4bc7970ba3ef 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -38,7 +38,7 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) if ((temp & (3 << 13)) == (1 << 13)) { temp &= 0x1fff; ehci->debug = ehci_to_hcd(ehci)->regs + temp; - temp = ehci_readl(ehci, &ehci->debug->control); + temp = readl(&ehci->debug->control); ehci_info(ehci, "debug port %d%s\n", HCS_DEBUG_PORT(ehci->hcs_params), (temp & DBGP_ENABLED) @@ -71,24 +71,8 @@ static int ehci_pci_setup(struct usb_hcd *hcd) u32 temp; int retval; - switch (pdev->vendor) { - case PCI_VENDOR_ID_TOSHIBA_2: - /* celleb's companion chip */ - if (pdev->device == 0x01b5) { -#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO - ehci->big_endian_mmio = 1; -#else - ehci_warn(ehci, - "unsupported big endian Toshiba quirk\n"); -#endif - } - break; - } - ehci->caps = hcd->regs; - ehci->regs = hcd->regs + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); - + ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); @@ -117,7 +101,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } /* cache this readonly data; minimize chip reads */ - ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); + ehci->hcs_params = readl(&ehci->caps->hcs_params); retval = ehci_halt(ehci); if (retval) @@ -251,8 +235,8 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) rc = -EINVAL; goto bail; } - ehci_writel(ehci, 0, &ehci->regs->intr_enable); - (void)ehci_readl(ehci, &ehci->regs->intr_enable); + writel (0, &ehci->regs->intr_enable); + (void)readl(&ehci->regs->intr_enable); /* make sure snapshot being resumed re-enumerates everything */ if (message.event == PM_EVENT_PRETHAW) { @@ -286,13 +270,13 @@ static int ehci_pci_resume(struct usb_hcd *hcd) /* If CF is still set, we maintained PCI Vaux power. * Just undo the effect of ehci_pci_suspend(). */ - if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { + if (readl(&ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; if (!device_may_wakeup(&hcd->self.root_hub->dev)) mask &= ~STS_PCD; - ehci_writel(ehci, mask, &ehci->regs->intr_enable); - ehci_readl(ehci, &ehci->regs->intr_enable); + writel(mask, &ehci->regs->intr_enable); + readl(&ehci->regs->intr_enable); return 0; } @@ -316,9 +300,9 @@ static int ehci_pci_resume(struct usb_hcd *hcd) /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); - ehci_writel(ehci, ehci->command, &ehci->regs->command); - ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); - ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ + writel(ehci->command, &ehci->regs->command); + writel(FLAG_CF, &ehci->regs->configured_flag); + readl(&ehci->regs->command); /* unblock posted writes */ hcd->state = HC_STATE_SUSPENDED; return 0; diff --git a/trunk/drivers/usb/host/ehci-ps3.c b/trunk/drivers/usb/host/ehci-ps3.c deleted file mode 100644 index 371f194a9d39..000000000000 --- a/trunk/drivers/usb/host/ehci-ps3.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * PS3 EHCI Host Controller driver - * - * Copyright (C) 2006 Sony Computer Entertainment Inc. - * Copyright 2006 Sony Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -static int ps3_ehci_hc_reset(struct usb_hcd *hcd) -{ - int result; - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - - ehci->big_endian_mmio = 1; - - ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, - &ehci->caps->hc_capbase)); - - dbg_hcs_params(ehci, "reset"); - dbg_hcc_params(ehci, "reset"); - - ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - - result = ehci_halt(ehci); - - if (result) - return result; - - result = ehci_init(hcd); - - if (result) - return result; - - ehci_port_power(ehci, 0); - - return result; -} - -static const struct hc_driver ps3_ehci_hc_driver = { - .description = hcd_name, - .product_desc = "PS3 EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - .reset = ps3_ehci_hc_reset, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .get_frame_number = ehci_get_frame, - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, -#if defined(CONFIG_PM) - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, -#endif -}; - -#if !defined(DEBUG) -#undef dev_dbg -static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( - const struct device *_dev, const char *fmt, ...) {return 0;} -#endif - - -static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) -{ - int result; - struct usb_hcd *hcd; - unsigned int virq; - static u64 dummy_mask = DMA_32BIT_MASK; - - if (usb_disabled()) { - result = -ENODEV; - goto fail_start; - } - - result = ps3_mmio_region_create(dev->m_region); - - if (result) { - dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", - __func__, __LINE__); - result = -EPERM; - goto fail_mmio; - } - - dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, - __LINE__, dev->m_region->lpar_addr); - - result = ps3_alloc_io_irq(dev->interrupt_id, &virq); - - if (result) { - dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", - __func__, __LINE__, virq); - result = -EPERM; - goto fail_irq; - } - - dev->core.power.power_state = PMSG_ON; - dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ - - hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev->core.bus_id); - - if (!hcd) { - dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__, - __LINE__); - result = -ENOMEM; - goto fail_create_hcd; - } - - hcd->rsrc_start = dev->m_region->lpar_addr; - hcd->rsrc_len = dev->m_region->len; - hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); - - if (!hcd->regs) { - dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__, - __LINE__); - result = -EPERM; - goto fail_ioremap; - } - - dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__, - (unsigned long)hcd->rsrc_start); - dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__, - (unsigned long)hcd->rsrc_len); - dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__, - (unsigned long)hcd->regs); - dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, - (unsigned long)virq); - - ps3_system_bus_set_driver_data(dev, hcd); - - result = usb_add_hcd(hcd, virq, IRQF_DISABLED); - - if (result) { - dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", - __func__, __LINE__, result); - goto fail_add_hcd; - } - - return result; - -fail_add_hcd: - iounmap(hcd->regs); -fail_ioremap: - usb_put_hcd(hcd); -fail_create_hcd: - ps3_free_io_irq(virq); -fail_irq: - ps3_free_mmio_region(dev->m_region); -fail_mmio: -fail_start: - return result; -} - -static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev) -{ - struct usb_hcd *hcd = - (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); - - usb_put_hcd(hcd); - ps3_system_bus_set_driver_data(dev, NULL); - - return 0; -} - -MODULE_ALIAS("ps3-ehci"); - -static struct ps3_system_bus_driver ps3_ehci_sb_driver = { - .match_id = PS3_MATCH_ID_EHCI, - .core = { - .name = "ps3-ehci-driver", - }, - .probe = ps3_ehci_sb_probe, - .remove = ps3_ehci_sb_remove, -}; diff --git a/trunk/drivers/usb/host/ehci-q.c b/trunk/drivers/usb/host/ehci-q.c index e7fbbd00e7cd..62e46dc60e86 100644 --- a/trunk/drivers/usb/host/ehci-q.c +++ b/trunk/drivers/usb/host/ehci-q.c @@ -789,14 +789,13 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) head = ehci->async; timer_action_done (ehci, TIMER_ASYNC_OFF); if (!head->qh_next.qh) { - u32 cmd = ehci_readl(ehci, &ehci->regs->command); + u32 cmd = readl (&ehci->regs->command); if (!(cmd & CMD_ASE)) { /* in case a clear of CMD_ASE didn't take yet */ - (void)handshake(ehci, &ehci->regs->status, - STS_ASS, 0, 150); + (void) handshake (&ehci->regs->status, STS_ASS, 0, 150); cmd |= CMD_ASE | CMD_RUN; - ehci_writel(ehci, cmd, &ehci->regs->command); + writel (cmd, &ehci->regs->command); ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; /* posted write need not be known to HC yet ... */ } @@ -1008,7 +1007,7 @@ static void end_unlink_async (struct ehci_hcd *ehci) static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) { - int cmd = ehci_readl(ehci, &ehci->regs->command); + int cmd = readl (&ehci->regs->command); struct ehci_qh *prev; #ifdef DEBUG @@ -1026,8 +1025,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) if (ehci_to_hcd(ehci)->state != HC_STATE_HALT && !ehci->reclaim) { /* ... and CMD_IAAD clear */ - ehci_writel(ehci, cmd & ~CMD_ASE, - &ehci->regs->command); + writel (cmd & ~CMD_ASE, &ehci->regs->command); wmb (); // handshake later, if we need to timer_action_done (ehci, TIMER_ASYNC_OFF); @@ -1056,8 +1054,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ehci->reclaim_ready = 0; cmd |= CMD_IAAD; - ehci_writel(ehci, cmd, &ehci->regs->command); - (void)ehci_readl(ehci, &ehci->regs->command); + writel (cmd, &ehci->regs->command); + (void) readl (&ehci->regs->command); timer_action (ehci, TIMER_IAA_WATCHDOG); } diff --git a/trunk/drivers/usb/host/ehci-sched.c b/trunk/drivers/usb/host/ehci-sched.c index 7b5ae7111f23..65c402a0fa7a 100644 --- a/trunk/drivers/usb/host/ehci-sched.c +++ b/trunk/drivers/usb/host/ehci-sched.c @@ -433,20 +433,20 @@ static int enable_periodic (struct ehci_hcd *ehci) /* did clearing PSE did take effect yet? * takes effect only at frame boundaries... */ - status = handshake(ehci, &ehci->regs->status, STS_PSS, 0, 9 * 125); + status = handshake (&ehci->regs->status, STS_PSS, 0, 9 * 125); if (status != 0) { ehci_to_hcd(ehci)->state = HC_STATE_HALT; return status; } - cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; - ehci_writel(ehci, cmd, &ehci->regs->command); + cmd = readl (&ehci->regs->command) | CMD_PSE; + writel (cmd, &ehci->regs->command); /* posted write ... PSS happens later */ ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; /* make sure ehci_work scans these */ - ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) - % (ehci->periodic_size << 3); + ehci->next_uframe = readl (&ehci->regs->frame_index) + % (ehci->periodic_size << 3); return 0; } @@ -458,14 +458,14 @@ static int disable_periodic (struct ehci_hcd *ehci) /* did setting PSE not take effect yet? * takes effect only at frame boundaries... */ - status = handshake(ehci, &ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); + status = handshake (&ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); if (status != 0) { ehci_to_hcd(ehci)->state = HC_STATE_HALT; return status; } - cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; - ehci_writel(ehci, cmd, &ehci->regs->command); + cmd = readl (&ehci->regs->command) & ~CMD_PSE; + writel (cmd, &ehci->regs->command); /* posted write ... */ ehci->next_uframe = -1; @@ -1336,7 +1336,7 @@ iso_stream_schedule ( goto fail; } - now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; + now = readl (&ehci->regs->frame_index) % mod; /* when's the last uframe this urb could start? */ max = now + mod; @@ -2088,7 +2088,7 @@ scan_periodic (struct ehci_hcd *ehci) */ now_uframe = ehci->next_uframe; if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) - clock = ehci_readl(ehci, &ehci->regs->frame_index); + clock = readl (&ehci->regs->frame_index); else clock = now_uframe + mod - 1; clock %= mod; @@ -2213,7 +2213,7 @@ scan_periodic (struct ehci_hcd *ehci) if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) break; ehci->next_uframe = now_uframe; - now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; + now = readl (&ehci->regs->frame_index) % mod; if (now_uframe == now) break; diff --git a/trunk/drivers/usb/host/ehci.h b/trunk/drivers/usb/host/ehci.h index ec0da0343be4..74dbc6c8228f 100644 --- a/trunk/drivers/usb/host/ehci.h +++ b/trunk/drivers/usb/host/ehci.h @@ -74,11 +74,7 @@ struct ehci_hcd { /* one per controller */ /* per root hub port */ unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; - /* bit vectors (one bit per port) */ - unsigned long bus_suspended; /* which ports were - already suspended at the start of a bus suspend */ - unsigned long companion_ports; /* which ports are - dedicated to the companion controller */ + unsigned long bus_suspended; /* per-HC memory pools (could be per-bus, but ...) */ struct dma_pool *qh_pool; /* qh per active urb */ @@ -96,7 +92,6 @@ struct ehci_hcd { /* one per controller */ unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ unsigned no_selective_suspend:1; unsigned has_fsl_port_bug:1; /* FreeScale */ - unsigned big_endian_mmio:1; u8 sbrn; /* packed release number */ @@ -656,45 +651,6 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) #define ehci_has_fsl_portno_bug(e) (0) #endif -/* - * While most USB host controllers implement their registers in - * little-endian format, a minority (celleb companion chip) implement - * them in big endian format. - * - * This attempts to support either format at compile time without a - * runtime penalty, or both formats with the additional overhead - * of checking a flag bit. - */ - -#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO -#define ehci_big_endian_mmio(e) ((e)->big_endian_mmio) -#else -#define ehci_big_endian_mmio(e) 0 -#endif - -static inline unsigned int ehci_readl (const struct ehci_hcd *ehci, - __u32 __iomem * regs) -{ -#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO - return ehci_big_endian_mmio(ehci) ? - readl_be((__force u32 *)regs) : - readl((__force u32 *)regs); -#else - return readl((__force u32 *)regs); -#endif -} - -static inline void ehci_writel (const struct ehci_hcd *ehci, - const unsigned int val, __u32 __iomem *regs) -{ -#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO - ehci_big_endian_mmio(ehci) ? - writel_be(val, (__force u32 *)regs) : - writel(val, (__force u32 *)regs); -#else - writel(val, (__force u32 *)regs); -#endif -} /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/host/ohci-at91.c b/trunk/drivers/usb/host/ohci-at91.c index 930346487278..cc405512fa1c 100644 --- a/trunk/drivers/usb/host/ohci-at91.c +++ b/trunk/drivers/usb/host/ohci-at91.c @@ -170,6 +170,7 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd, at91_stop_hc(pdev); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + disable_irq_wake(hcd->irq); clk_put(fclk); clk_put(iclk); @@ -270,6 +271,8 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) if (device_may_wakeup(&pdev->dev)) enable_irq_wake(hcd->irq); + else + disable_irq_wake(hcd->irq); /* * The integrated transceivers seem unable to notice disconnect, @@ -290,11 +293,6 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) { - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - if (device_may_wakeup(&pdev->dev)) - disable_irq_wake(hcd->irq); - if (!clocked) { clk_enable(iclk); clk_enable(fclk); @@ -322,3 +320,18 @@ static struct platform_driver ohci_hcd_at91_driver = { }, }; +static int __init ohci_hcd_at91_init (void) +{ + if (usb_disabled()) + return -ENODEV; + + return platform_driver_register(&ohci_hcd_at91_driver); +} + +static void __exit ohci_hcd_at91_cleanup (void) +{ + platform_driver_unregister(&ohci_hcd_at91_driver); +} + +module_init (ohci_hcd_at91_init); +module_exit (ohci_hcd_at91_cleanup); diff --git a/trunk/drivers/usb/host/ohci-au1xxx.c b/trunk/drivers/usb/host/ohci-au1xxx.c index 663a0600b6e7..e70b2430e2a9 100644 --- a/trunk/drivers/usb/host/ohci-au1xxx.c +++ b/trunk/drivers/usb/host/ohci-au1xxx.c @@ -345,3 +345,19 @@ static struct platform_driver ohci_hcd_au1xxx_driver = { }, }; +static int __init ohci_hcd_au1xxx_init (void) +{ + pr_debug (DRIVER_INFO " (Au1xxx)"); + pr_debug ("block sizes: ed %d td %d\n", + sizeof (struct ed), sizeof (struct td)); + + return platform_driver_register(&ohci_hcd_au1xxx_driver); +} + +static void __exit ohci_hcd_au1xxx_cleanup (void) +{ + platform_driver_unregister(&ohci_hcd_au1xxx_driver); +} + +module_init (ohci_hcd_au1xxx_init); +module_exit (ohci_hcd_au1xxx_cleanup); diff --git a/trunk/drivers/usb/host/ohci-ep93xx.c b/trunk/drivers/usb/host/ohci-ep93xx.c index 44c60fba76e1..3348b07f0fe5 100644 --- a/trunk/drivers/usb/host/ohci-ep93xx.c +++ b/trunk/drivers/usb/host/ohci-ep93xx.c @@ -214,3 +214,15 @@ static struct platform_driver ohci_hcd_ep93xx_driver = { }, }; +static int __init ohci_hcd_ep93xx_init(void) +{ + return platform_driver_register(&ohci_hcd_ep93xx_driver); +} + +static void __exit ohci_hcd_ep93xx_cleanup(void) +{ + platform_driver_unregister(&ohci_hcd_ep93xx_driver); +} + +module_init(ohci_hcd_ep93xx_init); +module_exit(ohci_hcd_ep93xx_cleanup); diff --git a/trunk/drivers/usb/host/ohci-hcd.c b/trunk/drivers/usb/host/ohci-hcd.c index fa6a7ceaa0db..c1c1d871aba4 100644 --- a/trunk/drivers/usb/host/ohci-hcd.c +++ b/trunk/drivers/usb/host/ohci-hcd.c @@ -855,167 +855,63 @@ MODULE_LICENSE ("GPL"); #ifdef CONFIG_PCI #include "ohci-pci.c" -#define PCI_DRIVER ohci_pci_driver #endif #ifdef CONFIG_SA1111 #include "ohci-sa1111.c" -#define SA1111_DRIVER ohci_hcd_sa1111_driver #endif #ifdef CONFIG_ARCH_S3C2410 #include "ohci-s3c2410.c" -#define PLATFORM_DRIVER ohci_hcd_s3c2410_driver #endif #ifdef CONFIG_ARCH_OMAP #include "ohci-omap.c" -#define PLATFORM_DRIVER ohci_hcd_omap_driver #endif #ifdef CONFIG_ARCH_LH7A404 #include "ohci-lh7a404.c" -#define PLATFORM_DRIVER ohci_hcd_lh7a404_driver #endif #ifdef CONFIG_PXA27x #include "ohci-pxa27x.c" -#define PLATFORM_DRIVER ohci_hcd_pxa27x_driver #endif #ifdef CONFIG_ARCH_EP93XX #include "ohci-ep93xx.c" -#define PLATFORM_DRIVER ohci_hcd_ep93xx_driver #endif #ifdef CONFIG_SOC_AU1X00 #include "ohci-au1xxx.c" -#define PLATFORM_DRIVER ohci_hcd_au1xxx_driver #endif #ifdef CONFIG_PNX8550 #include "ohci-pnx8550.c" -#define PLATFORM_DRIVER ohci_hcd_pnx8550_driver #endif #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC #include "ohci-ppc-soc.c" -#define PLATFORM_DRIVER ohci_hcd_ppc_soc_driver #endif #ifdef CONFIG_ARCH_AT91 #include "ohci-at91.c" -#define PLATFORM_DRIVER ohci_hcd_at91_driver #endif #ifdef CONFIG_ARCH_PNX4008 #include "ohci-pnx4008.c" -#define PLATFORM_DRIVER usb_hcd_pnx4008_driver #endif - -#ifdef CONFIG_USB_OHCI_HCD_PPC_OF -#include "ohci-ppc-of.c" -#define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver -#endif - -#ifdef CONFIG_PPC_PS3 -#include "ohci-ps3.c" -#define PS3_SYSTEM_BUS_DRIVER ps3_ohci_sb_driver -#endif - -#if !defined(PCI_DRIVER) && \ - !defined(PLATFORM_DRIVER) && \ - !defined(OF_PLATFORM_DRIVER) && \ - !defined(SA1111_DRIVER) && \ - !defined(PS3_SYSTEM_BUS_DRIVER) +#if !(defined(CONFIG_PCI) \ + || defined(CONFIG_SA1111) \ + || defined(CONFIG_ARCH_S3C2410) \ + || defined(CONFIG_ARCH_OMAP) \ + || defined (CONFIG_ARCH_LH7A404) \ + || defined (CONFIG_PXA27x) \ + || defined (CONFIG_ARCH_EP93XX) \ + || defined (CONFIG_SOC_AU1X00) \ + || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ + || defined (CONFIG_ARCH_AT91) \ + || defined (CONFIG_ARCH_PNX4008) \ + ) #error "missing bus glue for ohci-hcd" #endif - -static int __init ohci_hcd_mod_init(void) -{ - int retval = 0; - - if (usb_disabled()) - return -ENODEV; - - printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name); - pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, - sizeof (struct ed), sizeof (struct td)); - -#ifdef PS3_SYSTEM_BUS_DRIVER - retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); - if (retval < 0) - goto error_ps3; -#endif - -#ifdef PLATFORM_DRIVER - retval = platform_driver_register(&PLATFORM_DRIVER); - if (retval < 0) - goto error_platform; -#endif - -#ifdef OF_PLATFORM_DRIVER - retval = of_register_platform_driver(&OF_PLATFORM_DRIVER); - if (retval < 0) - goto error_of_platform; -#endif - -#ifdef SA1111_DRIVER - retval = sa1111_driver_register(&SA1111_DRIVER); - if (retval < 0) - goto error_sa1111; -#endif - -#ifdef PCI_DRIVER - retval = pci_register_driver(&PCI_DRIVER); - if (retval < 0) - goto error_pci; -#endif - - return retval; - - /* Error path */ -#ifdef PCI_DRIVER - error_pci: -#endif -#ifdef SA1111_DRIVER - sa1111_driver_unregister(&SA1111_DRIVER); - error_sa1111: -#endif -#ifdef OF_PLATFORM_DRIVER - of_unregister_platform_driver(&OF_PLATFORM_DRIVER); - error_of_platform: -#endif -#ifdef PLATFORM_DRIVER - platform_driver_unregister(&PLATFORM_DRIVER); - error_platform: -#endif -#ifdef PS3_SYSTEM_BUS_DRIVER - ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); - error_ps3: -#endif - return retval; -} -module_init(ohci_hcd_mod_init); - -static void __exit ohci_hcd_mod_exit(void) -{ -#ifdef PCI_DRIVER - pci_unregister_driver(&PCI_DRIVER); -#endif -#ifdef SA1111_DRIVER - sa1111_driver_unregister(&SA1111_DRIVER); -#endif -#ifdef OF_PLATFORM_DRIVER - of_unregister_platform_driver(&OF_PLATFORM_DRIVER); -#endif -#ifdef PLATFORM_DRIVER - platform_driver_unregister(&PLATFORM_DRIVER); -#endif -#ifdef PS3_SYSTEM_BUS_DRIVER - ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); -#endif -} -module_exit(ohci_hcd_mod_exit); - diff --git a/trunk/drivers/usb/host/ohci-lh7a404.c b/trunk/drivers/usb/host/ohci-lh7a404.c index 4a043abd85ea..e9807cf73a2f 100644 --- a/trunk/drivers/usb/host/ohci-lh7a404.c +++ b/trunk/drivers/usb/host/ohci-lh7a404.c @@ -251,3 +251,19 @@ static struct platform_driver ohci_hcd_lh7a404_driver = { }, }; +static int __init ohci_hcd_lh7a404_init (void) +{ + pr_debug (DRIVER_INFO " (LH7A404)"); + pr_debug ("block sizes: ed %d td %d\n", + sizeof (struct ed), sizeof (struct td)); + + return platform_driver_register(&ohci_hcd_lh7a404_driver); +} + +static void __exit ohci_hcd_lh7a404_cleanup (void) +{ + platform_driver_unregister(&ohci_hcd_lh7a404_driver); +} + +module_init (ohci_hcd_lh7a404_init); +module_exit (ohci_hcd_lh7a404_cleanup); diff --git a/trunk/drivers/usb/host/ohci-omap.c b/trunk/drivers/usb/host/ohci-omap.c index 5cfa3d1c4413..27be1f936885 100644 --- a/trunk/drivers/usb/host/ohci-omap.c +++ b/trunk/drivers/usb/host/ohci-omap.c @@ -544,3 +544,22 @@ static struct platform_driver ohci_hcd_omap_driver = { }, }; +static int __init ohci_hcd_omap_init (void) +{ + printk (KERN_DEBUG "%s: " DRIVER_INFO " (OMAP)\n", hcd_name); + if (usb_disabled()) + return -ENODEV; + + pr_debug("%s: block sizes: ed %Zd td %Zd\n", hcd_name, + sizeof (struct ed), sizeof (struct td)); + + return platform_driver_register(&ohci_hcd_omap_driver); +} + +static void __exit ohci_hcd_omap_cleanup (void) +{ + platform_driver_unregister(&ohci_hcd_omap_driver); +} + +module_init (ohci_hcd_omap_init); +module_exit (ohci_hcd_omap_cleanup); diff --git a/trunk/drivers/usb/host/ohci-pci.c b/trunk/drivers/usb/host/ohci-pci.c index b331ac4d0d62..596e0b41e606 100644 --- a/trunk/drivers/usb/host/ohci-pci.c +++ b/trunk/drivers/usb/host/ohci-pci.c @@ -20,154 +20,79 @@ /*-------------------------------------------------------------------------*/ -/* AMD 756, for most chips (early revs), corrupts register - * values on read ... so enable the vendor workaround. - */ -static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd) +static int +ohci_pci_reset (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); - ohci->flags = OHCI_QUIRK_AMD756; - ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); - - /* also erratum 10 (suspend/resume issues) */ - device_init_wakeup(&hcd->self.root_hub->dev, 0); - - return 0; + ohci_hcd_init (ohci); + return ohci_init (ohci); } -/* Apple's OHCI driver has a lot of bizarre workarounds - * for this chip. Evidently control and bulk lists - * can get confused. (B&W G3 models, and ...) - */ -static int __devinit ohci_quirk_opti(struct usb_hcd *hcd) +static int __devinit +ohci_pci_start (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); + int ret; - ohci_dbg (ohci, "WARNING: OPTi workarounds unavailable\n"); - - return 0; -} - -/* Check for NSC87560. We have to look at the bridge (fn1) to - * identify the USB (fn2). This quirk might apply to more or - * even all NSC stuff. - */ -static int __devinit ohci_quirk_ns(struct usb_hcd *hcd) -{ - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); - struct pci_dev *b; - - b = pci_get_slot (pdev->bus, PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); - if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO - && b->vendor == PCI_VENDOR_ID_NS) { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - - ohci->flags |= OHCI_QUIRK_SUPERIO; - ohci_dbg (ohci, "Using NSC SuperIO setup\n"); - } - pci_dev_put(b); - - return 0; -} - -/* Check for Compaq's ZFMicro chipset, which needs short - * delays before control or bulk queues get re-activated - * in finish_unlinks() - */ -static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - - ohci->flags |= OHCI_QUIRK_ZFMICRO; - ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n"); - - return 0; -} - -/* Check for Toshiba SCC OHCI which has big endian registers - * and little endian in memory data structures - */ -static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - - /* That chip is only present in the southbridge of some - * cell based platforms which are supposed to select - * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO. We verify here if - * that was the case though. - */ -#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO - ohci->flags |= OHCI_QUIRK_BE_MMIO; - ohci_dbg (ohci, "enabled big endian Toshiba quirk\n"); - return 0; -#else - ohci_err (ohci, "unsupported big endian Toshiba quirk\n"); - return -ENXIO; -#endif -} - -/* List of quirks for OHCI */ -static const struct pci_device_id ohci_pci_quirks[] = { - { - PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x740c), - .driver_data = (unsigned long)ohci_quirk_amd756, - }, - { - PCI_DEVICE(PCI_VENDOR_ID_OPTI, 0xc861), - .driver_data = (unsigned long)ohci_quirk_opti, - }, - { - PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_ANY_ID), - .driver_data = (unsigned long)ohci_quirk_ns, - }, - { - PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8), - .driver_data = (unsigned long)ohci_quirk_zfmicro, - }, - { - PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6), - .driver_data = (unsigned long)ohci_quirk_toshiba_scc, - }, - /* FIXME for some of the early AMD 760 southbridges, OHCI - * won't work at all. blacklist them. + /* REVISIT this whole block should move to reset(), which handles + * all the other one-time init. */ - - {}, -}; - -static int ohci_pci_reset (struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int ret = 0; - if (hcd->self.controller) { struct pci_dev *pdev = to_pci_dev(hcd->self.controller); - const struct pci_device_id *quirk_id; - quirk_id = pci_match_id(ohci_pci_quirks, pdev); - if (quirk_id != NULL) { - int (*quirk)(struct usb_hcd *ohci); - quirk = (void *)quirk_id->driver_data; - ret = quirk(hcd); + /* AMD 756, for most chips (early revs), corrupts register + * values on read ... so enable the vendor workaround. + */ + if (pdev->vendor == PCI_VENDOR_ID_AMD + && pdev->device == 0x740c) { + ohci->flags = OHCI_QUIRK_AMD756; + ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); + /* also erratum 10 (suspend/resume issues) */ + device_init_wakeup(&hcd->self.root_hub->dev, 0); } - } - if (ret == 0) { - ohci_hcd_init (ohci); - return ohci_init (ohci); - } - return ret; -} + /* FIXME for some of the early AMD 760 southbridges, OHCI + * won't work at all. blacklist them. + */ -static int __devinit ohci_pci_start (struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int ret; + /* Apple's OHCI driver has a lot of bizarre workarounds + * for this chip. Evidently control and bulk lists + * can get confused. (B&W G3 models, and ...) + */ + else if (pdev->vendor == PCI_VENDOR_ID_OPTI + && pdev->device == 0xc861) { + ohci_dbg (ohci, + "WARNING: OPTi workarounds unavailable\n"); + } -#ifdef CONFIG_PM /* avoid warnings about unused pdev */ - if (hcd->self.controller) { - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + /* Check for NSC87560. We have to look at the bridge (fn1) to + * identify the USB (fn2). This quirk might apply to more or + * even all NSC stuff. + */ + else if (pdev->vendor == PCI_VENDOR_ID_NS) { + struct pci_dev *b; + + b = pci_get_slot (pdev->bus, + PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); + if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO + && b->vendor == PCI_VENDOR_ID_NS) { + ohci->flags |= OHCI_QUIRK_SUPERIO; + ohci_dbg (ohci, "Using NSC SuperIO setup\n"); + } + pci_dev_put(b); + } + + /* Check for Compaq's ZFMicro chipset, which needs short + * delays before control or bulk queues get re-activated + * in finish_unlinks() + */ + else if (pdev->vendor == PCI_VENDOR_ID_COMPAQ + && pdev->device == 0xa0f8) { + ohci->flags |= OHCI_QUIRK_ZFMICRO; + ohci_dbg (ohci, + "enabled Compaq ZFMicro chipset quirk\n"); + } /* RWC may not be set for add-in PCI cards, since boot * firmware probably ignored them. This transfers PCI @@ -176,14 +101,16 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd) if (device_may_wakeup(&pdev->dev)) ohci->hc_control |= OHCI_CTRL_RWC; } -#endif /* CONFIG_PM */ - ret = ohci_run (ohci); - if (ret < 0) { + /* NOTE: there may have already been a first reset, to + * keep bios/smm irqs from making trouble + */ + if ((ret = ohci_run (ohci)) < 0) { ohci_err (ohci, "can't start\n"); ohci_stop (hcd); + return ret; } - return ret; + return 0; } #ifdef CONFIG_PM @@ -311,3 +238,23 @@ static struct pci_driver ohci_pci_driver = { .shutdown = usb_hcd_pci_shutdown, }; + +static int __init ohci_hcd_pci_init (void) +{ + printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name); + if (usb_disabled()) + return -ENODEV; + + pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, + sizeof (struct ed), sizeof (struct td)); + return pci_register_driver (&ohci_pci_driver); +} +module_init (ohci_hcd_pci_init); + +/*-------------------------------------------------------------------------*/ + +static void __exit ohci_hcd_pci_cleanup (void) +{ + pci_unregister_driver (&ohci_pci_driver); +} +module_exit (ohci_hcd_pci_cleanup); diff --git a/trunk/drivers/usb/host/ohci-pnx4008.c b/trunk/drivers/usb/host/ohci-pnx4008.c index 893b172384da..3a8cbfb69054 100644 --- a/trunk/drivers/usb/host/ohci-pnx4008.c +++ b/trunk/drivers/usb/host/ohci-pnx4008.c @@ -465,3 +465,15 @@ static struct platform_driver usb_hcd_pnx4008_driver = { .remove = usb_hcd_pnx4008_remove, }; +static int __init usb_hcd_pnx4008_init(void) +{ + return platform_driver_register(&usb_hcd_pnx4008_driver); +} + +static void __exit usb_hcd_pnx4008_cleanup(void) +{ + return platform_driver_unregister(&usb_hcd_pnx4008_driver); +} + +module_init(usb_hcd_pnx4008_init); +module_exit(usb_hcd_pnx4008_cleanup); diff --git a/trunk/drivers/usb/host/ohci-pnx8550.c b/trunk/drivers/usb/host/ohci-pnx8550.c index de45eb0051a7..6922b91b1704 100644 --- a/trunk/drivers/usb/host/ohci-pnx8550.c +++ b/trunk/drivers/usb/host/ohci-pnx8550.c @@ -240,3 +240,19 @@ static struct platform_driver ohci_hcd_pnx8550_driver = { .remove = ohci_hcd_pnx8550_drv_remove, }; +static int __init ohci_hcd_pnx8550_init (void) +{ + pr_debug (DRIVER_INFO " (pnx8550)"); + pr_debug ("block sizes: ed %d td %d\n", + sizeof (struct ed), sizeof (struct td)); + + return platform_driver_register(&ohci_hcd_pnx8550_driver); +} + +static void __exit ohci_hcd_pnx8550_cleanup (void) +{ + platform_driver_unregister(&ohci_hcd_pnx8550_driver); +} + +module_init (ohci_hcd_pnx8550_init); +module_exit (ohci_hcd_pnx8550_cleanup); diff --git a/trunk/drivers/usb/host/ohci-ppc-of.c b/trunk/drivers/usb/host/ohci-ppc-of.c deleted file mode 100644 index 08e237c7bc43..000000000000 --- a/trunk/drivers/usb/host/ohci-ppc-of.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2002 David Brownell - * (C) Copyright 2002 Hewlett-Packard Company - * (C) Copyright 2006 Sylvain Munaut - * - * Bus glue for OHCI HC on the of_platform bus - * - * Modified for of_platform bus from ohci-sa1111.c - * - * This file is licenced under the GPL. - */ - -#include - -#include -#include - - -static int __devinit -ohci_ppc_of_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - if ((ret = ohci_init(ohci)) < 0) - return ret; - - if ((ret = ohci_run(ohci)) < 0) { - err("can't start %s", ohci_to_hcd(ohci)->self.bus_name); - ohci_stop(hcd); - return ret; - } - - return 0; -} - -static const struct hc_driver ohci_ppc_of_hc_driver = { - .description = hcd_name, - .product_desc = "OF OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_ppc_of_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - - -static int __devinit -ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) -{ - struct device_node *dn = op->node; - struct usb_hcd *hcd; - struct ohci_hcd *ohci; - struct resource res; - int irq; - - int rv; - int is_bigendian; - - if (usb_disabled()) - return -ENODEV; - - is_bigendian = - device_is_compatible(dn, "ohci-bigendian") || - device_is_compatible(dn, "ohci-be"); - - dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n"); - - rv = of_address_to_resource(dn, 0, &res); - if (rv) - return rv; - - hcd = usb_create_hcd(&ohci_ppc_of_hc_driver, &op->dev, "PPC-OF USB"); - if (!hcd) - return -ENOMEM; - - hcd->rsrc_start = res.start; - hcd->rsrc_len = res.end - res.start + 1; - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); - rv = -EBUSY; - goto err_rmr; - } - - irq = irq_of_parse_and_map(dn, 0); - if (irq == NO_IRQ) { - printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); - rv = -EBUSY; - goto err_irq; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - printk(KERN_ERR __FILE__ ": ioremap failed\n"); - rv = -ENOMEM; - goto err_ioremap; - } - - ohci = hcd_to_ohci(hcd); - if (is_bigendian) - ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; - - ohci_hcd_init(ohci); - - rv = usb_add_hcd(hcd, irq, 0); - if (rv == 0) - return 0; - - iounmap(hcd->regs); -err_ioremap: - irq_dispose_mapping(irq); -err_irq: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err_rmr: - usb_put_hcd(hcd); - - return rv; -} - -static int ohci_hcd_ppc_of_remove(struct of_device *op) -{ - struct usb_hcd *hcd = dev_get_drvdata(&op->dev); - dev_set_drvdata(&op->dev, NULL); - - dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n"); - - usb_remove_hcd(hcd); - - iounmap(hcd->regs); - irq_dispose_mapping(hcd->irq); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - - usb_put_hcd(hcd); - - return 0; -} - -static int ohci_hcd_ppc_of_shutdown(struct of_device *op) -{ - struct usb_hcd *hcd = dev_get_drvdata(&op->dev); - - if (hcd->driver->shutdown) - hcd->driver->shutdown(hcd); - - return 0; -} - - -static struct of_device_id ohci_hcd_ppc_of_match[] = { -#ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE - { - .name = "usb", - .compatible = "ohci-bigendian", - }, - { - .name = "usb", - .compatible = "ohci-be", - }, -#endif -#ifdef CONFIG_USB_OHCI_HCD_PPC_OF_LE - { - .name = "usb", - .compatible = "ohci-littledian", - }, - { - .name = "usb", - .compatible = "ohci-le", - }, -#endif - {}, -}; -MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match); - -#if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \ - !defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE) -#error "No endianess selected for ppc-of-ohci" -#endif - - -static struct of_platform_driver ohci_hcd_ppc_of_driver = { - .name = "ppc-of-ohci", - .match_table = ohci_hcd_ppc_of_match, - .probe = ohci_hcd_ppc_of_probe, - .remove = ohci_hcd_ppc_of_remove, - .shutdown = ohci_hcd_ppc_of_shutdown, -#ifdef CONFIG_PM - /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ - /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ -#endif - .driver = { - .name = "ppc-of-ohci", - .owner = THIS_MODULE, - }, -}; - diff --git a/trunk/drivers/usb/host/ohci-ppc-soc.c b/trunk/drivers/usb/host/ohci-ppc-soc.c index 1a2e1777ca61..e1a7eb817313 100644 --- a/trunk/drivers/usb/host/ohci-ppc-soc.c +++ b/trunk/drivers/usb/host/ohci-ppc-soc.c @@ -72,7 +72,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, } ohci = hcd_to_ohci(hcd); - ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; + ohci->flags |= OHCI_BIG_ENDIAN; ohci_hcd_init(ohci); retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); @@ -208,3 +208,19 @@ static struct platform_driver ohci_hcd_ppc_soc_driver = { }, }; +static int __init ohci_hcd_ppc_soc_init(void) +{ + pr_debug(DRIVER_INFO " (PPC SOC)\n"); + pr_debug("block sizes: ed %d td %d\n", sizeof(struct ed), + sizeof(struct td)); + + return platform_driver_register(&ohci_hcd_ppc_soc_driver); +} + +static void __exit ohci_hcd_ppc_soc_cleanup(void) +{ + platform_driver_unregister(&ohci_hcd_ppc_soc_driver); +} + +module_init(ohci_hcd_ppc_soc_init); +module_exit(ohci_hcd_ppc_soc_cleanup); diff --git a/trunk/drivers/usb/host/ohci-ps3.c b/trunk/drivers/usb/host/ohci-ps3.c deleted file mode 100644 index 69d948b4a701..000000000000 --- a/trunk/drivers/usb/host/ohci-ps3.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * PS3 OHCI Host Controller driver - * - * Copyright (C) 2006 Sony Computer Entertainment Inc. - * Copyright 2006 Sony Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -static int ps3_ohci_hc_reset(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - - ohci->flags |= OHCI_QUIRK_BE_MMIO; - ohci_hcd_init(ohci); - return ohci_init(ohci); -} - -static int __devinit ps3_ohci_hc_start(struct usb_hcd *hcd) -{ - int result; - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - - /* Handle root hub init quirk in spider south bridge. */ - /* Also set PwrOn2PwrGood to 0x7f (254ms). */ - - ohci_writel(ohci, 0x7f000000 | RH_A_PSM | RH_A_OCPM, - &ohci->regs->roothub.a); - ohci_writel(ohci, 0x00060000, &ohci->regs->roothub.b); - - result = ohci_run(ohci); - - if (result < 0) { - err("can't start %s", hcd->self.bus_name); - ohci_stop(hcd); - } - - return result; -} - -static const struct hc_driver ps3_ohci_hc_driver = { - .description = hcd_name, - .product_desc = "PS3 OHCI Host Controller", - .hcd_priv_size = sizeof(struct ohci_hcd), - .irq = ohci_irq, - .flags = HCD_MEMORY | HCD_USB11, - .reset = ps3_ohci_hc_reset, - .start = ps3_ohci_hc_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - .get_frame_number = ohci_get_frame, - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, - .start_port_reset = ohci_start_port_reset, -#if defined(CONFIG_PM) - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif -}; - -/* redefine dev_dbg to do a syntax check */ - -#if !defined(DEBUG) -#undef dev_dbg -static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( - const struct device *_dev, const char *fmt, ...) {return 0;} -#endif - -static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) -{ - int result; - struct usb_hcd *hcd; - unsigned int virq; - static u64 dummy_mask = DMA_32BIT_MASK; - - if (usb_disabled()) { - result = -ENODEV; - goto fail_start; - } - - result = ps3_mmio_region_create(dev->m_region); - - if (result) { - dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", - __func__, __LINE__); - result = -EPERM; - goto fail_mmio; - } - - dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, - __LINE__, dev->m_region->lpar_addr); - - result = ps3_alloc_io_irq(dev->interrupt_id, &virq); - - if (result) { - dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", - __func__, __LINE__, virq); - result = -EPERM; - goto fail_irq; - } - - dev->core.power.power_state = PMSG_ON; - dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ - - hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev->core.bus_id); - - if (!hcd) { - dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__, - __LINE__); - result = -ENOMEM; - goto fail_create_hcd; - } - - hcd->rsrc_start = dev->m_region->lpar_addr; - hcd->rsrc_len = dev->m_region->len; - hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); - - if (!hcd->regs) { - dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__, - __LINE__); - result = -EPERM; - goto fail_ioremap; - } - - dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__, - (unsigned long)hcd->rsrc_start); - dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__, - (unsigned long)hcd->rsrc_len); - dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__, - (unsigned long)hcd->regs); - dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, - (unsigned long)virq); - - ps3_system_bus_set_driver_data(dev, hcd); - - result = usb_add_hcd(hcd, virq, IRQF_DISABLED); - - if (result) { - dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", - __func__, __LINE__, result); - goto fail_add_hcd; - } - - return result; - -fail_add_hcd: - iounmap(hcd->regs); -fail_ioremap: - usb_put_hcd(hcd); -fail_create_hcd: - ps3_free_io_irq(virq); -fail_irq: - ps3_free_mmio_region(dev->m_region); -fail_mmio: -fail_start: - return result; -} - -static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev) -{ - struct usb_hcd *hcd = - (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); - - usb_put_hcd(hcd); - ps3_system_bus_set_driver_data(dev, NULL); - - return 0; -} - -MODULE_ALIAS("ps3-ohci"); - -static struct ps3_system_bus_driver ps3_ohci_sb_driver = { - .match_id = PS3_MATCH_ID_OHCI, - .core = { - .name = "ps3-ohci-driver", - }, - .probe = ps3_ohci_sb_probe, - .remove = ps3_ohci_sb_remove, -}; diff --git a/trunk/drivers/usb/host/ohci-pxa27x.c b/trunk/drivers/usb/host/ohci-pxa27x.c index f1563dc319d3..3bbea844a9e3 100644 --- a/trunk/drivers/usb/host/ohci-pxa27x.c +++ b/trunk/drivers/usb/host/ohci-pxa27x.c @@ -369,3 +369,19 @@ static struct platform_driver ohci_hcd_pxa27x_driver = { }, }; +static int __init ohci_hcd_pxa27x_init (void) +{ + pr_debug (DRIVER_INFO " (pxa27x)"); + pr_debug ("block sizes: ed %d td %d\n", + sizeof (struct ed), sizeof (struct td)); + + return platform_driver_register(&ohci_hcd_pxa27x_driver); +} + +static void __exit ohci_hcd_pxa27x_cleanup (void) +{ + platform_driver_unregister(&ohci_hcd_pxa27x_driver); +} + +module_init (ohci_hcd_pxa27x_init); +module_exit (ohci_hcd_pxa27x_cleanup); diff --git a/trunk/drivers/usb/host/ohci-s3c2410.c b/trunk/drivers/usb/host/ohci-s3c2410.c index 6829814b7aaf..b350d45033e7 100644 --- a/trunk/drivers/usb/host/ohci-s3c2410.c +++ b/trunk/drivers/usb/host/ohci-s3c2410.c @@ -501,3 +501,15 @@ static struct platform_driver ohci_hcd_s3c2410_driver = { }, }; +static int __init ohci_hcd_s3c2410_init (void) +{ + return platform_driver_register(&ohci_hcd_s3c2410_driver); +} + +static void __exit ohci_hcd_s3c2410_cleanup (void) +{ + platform_driver_unregister(&ohci_hcd_s3c2410_driver); +} + +module_init (ohci_hcd_s3c2410_init); +module_exit (ohci_hcd_s3c2410_cleanup); diff --git a/trunk/drivers/usb/host/ohci-sa1111.c b/trunk/drivers/usb/host/ohci-sa1111.c index 0f48f2d99226..fe0090e33675 100644 --- a/trunk/drivers/usb/host/ohci-sa1111.c +++ b/trunk/drivers/usb/host/ohci-sa1111.c @@ -269,3 +269,19 @@ static struct sa1111_driver ohci_hcd_sa1111_driver = { .remove = ohci_hcd_sa1111_drv_remove, }; +static int __init ohci_hcd_sa1111_init (void) +{ + dbg (DRIVER_INFO " (SA-1111)"); + dbg ("block sizes: ed %d td %d", + sizeof (struct ed), sizeof (struct td)); + + return sa1111_driver_register(&ohci_hcd_sa1111_driver); +} + +static void __exit ohci_hcd_sa1111_cleanup (void) +{ + sa1111_driver_unregister(&ohci_hcd_sa1111_driver); +} + +module_init (ohci_hcd_sa1111_init); +module_exit (ohci_hcd_sa1111_cleanup); diff --git a/trunk/drivers/usb/host/ohci.h b/trunk/drivers/usb/host/ohci.h index 0dafcda37291..405257f3e853 100644 --- a/trunk/drivers/usb/host/ohci.h +++ b/trunk/drivers/usb/host/ohci.h @@ -394,9 +394,8 @@ struct ohci_hcd { #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ -#define OHCI_QUIRK_BE_DESC 0x08 /* BE descriptors */ -#define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ -#define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ +#define OHCI_BIG_ENDIAN 0x08 /* big endian HC */ +#define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq ZFMicro chipset*/ // there are also chip quirks/bugs in init logic }; @@ -440,164 +439,117 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci) * a minority (notably the IBM STB04XXX and the Motorola MPC5200 * processors) implement them in big endian format. * - * In addition some more exotic implementations like the Toshiba - * Spider (aka SCC) cell southbridge are "mixed" endian, that is, - * they have a different endianness for registers vs. in-memory - * descriptors. - * * This attempts to support either format at compile time without a * runtime penalty, or both formats with the additional overhead * of checking a flag bit. - * - * That leads to some tricky Kconfig rules howevber. There are - * different defaults based on some arch/ppc platforms, though - * the basic rules are: - * - * Controller type Kconfig options needed - * --------------- ---------------------- - * little endian CONFIG_USB_OHCI_LITTLE_ENDIAN - * - * fully big endian CONFIG_USB_OHCI_BIG_ENDIAN_DESC _and_ - * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO - * - * mixed endian CONFIG_USB_OHCI_LITTLE_ENDIAN _and_ - * CONFIG_USB_OHCI_BIG_ENDIAN_{MMIO,DESC} - * - * (If you have a mixed endian controller, you -must- also define - * CONFIG_USB_OHCI_LITTLE_ENDIAN or things will not work when building - * both your mixed endian and a fully big endian controller support in - * the same kernel image). */ -#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_DESC -#ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN -#define big_endian_desc(ohci) (ohci->flags & OHCI_QUIRK_BE_DESC) -#else -#define big_endian_desc(ohci) 1 /* only big endian */ -#endif -#else -#define big_endian_desc(ohci) 0 /* only little endian */ -#endif +#ifdef CONFIG_USB_OHCI_BIG_ENDIAN -#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN -#define big_endian_mmio(ohci) (ohci->flags & OHCI_QUIRK_BE_MMIO) +#define big_endian(ohci) (ohci->flags & OHCI_BIG_ENDIAN) /* either */ #else -#define big_endian_mmio(ohci) 1 /* only big endian */ -#endif -#else -#define big_endian_mmio(ohci) 0 /* only little endian */ +#define big_endian(ohci) 1 /* only big endian */ #endif /* * Big-endian read/write functions are arch-specific. * Other arches can be added if/when they're needed. - * - * REVISIT: arch/powerpc now has readl/writel_be, so the - * definition below can die once the STB04xxx support is - * finally ported over. */ -#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE) +#if defined(CONFIG_PPC) #define readl_be(addr) in_be32((__force unsigned *)addr) #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) #endif -static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, - __hc32 __iomem * regs) +static inline unsigned int ohci_readl (const struct ohci_hcd *ohci, + __hc32 __iomem * regs) { -#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO - return big_endian_mmio(ohci) ? - readl_be ((__force u32 *)regs) : - readl ((__force u32 *)regs); -#else - return readl ((__force u32 *)regs); -#endif + return big_endian(ohci) ? readl_be (regs) : readl ((__force u32 *)regs); } -static inline void _ohci_writel (const struct ohci_hcd *ohci, - const unsigned int val, __hc32 __iomem *regs) +static inline void ohci_writel (const struct ohci_hcd *ohci, + const unsigned int val, __hc32 __iomem *regs) { -#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO - big_endian_mmio(ohci) ? - writel_be (val, (__force u32 *)regs) : - writel (val, (__force u32 *)regs); -#else - writel (val, (__force u32 *)regs); -#endif + big_endian(ohci) ? writel_be (val, regs) : + writel (val, (__force u32 *)regs); } +#else /* !CONFIG_USB_OHCI_BIG_ENDIAN */ + +#define big_endian(ohci) 0 /* only little endian */ + #ifdef CONFIG_ARCH_LH7A404 -/* Marc Singer: at the time this code was written, the LH7A404 - * had a problem reading the USB host registers. This - * implementation of the ohci_readl function performs the read - * twice as a work-around. - */ -#define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r)) -#define ohci_writel(o,v,r) _ohci_writel(o,v,r) + /* Marc Singer: at the time this code was written, the LH7A404 + * had a problem reading the USB host registers. This + * implementation of the ohci_readl function performs the read + * twice as a work-around. + */ +static inline unsigned int +ohci_readl (const struct ohci_hcd *ohci, const __hc32 *regs) +{ + *(volatile __force unsigned int*) regs; + return *(volatile __force unsigned int*) regs; +} #else -#define ohci_readl(o,r) _ohci_readl(o,r) -#define ohci_writel(o,v,r) _ohci_writel(o,v,r) + /* Standard version of ohci_readl uses standard, platform + * specific implementation. */ +static inline unsigned int +ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs) +{ + return readl(regs); +} #endif +static inline void ohci_writel (const struct ohci_hcd *ohci, + const unsigned int val, __hc32 __iomem *regs) +{ + writel (val, regs); +} + +#endif /* !CONFIG_USB_OHCI_BIG_ENDIAN */ /*-------------------------------------------------------------------------*/ /* cpu to ohci */ static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) { - return big_endian_desc(ohci) ? - (__force __hc16)cpu_to_be16(x) : - (__force __hc16)cpu_to_le16(x); + return big_endian(ohci) ? (__force __hc16)cpu_to_be16(x) : (__force __hc16)cpu_to_le16(x); } static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) { - return big_endian_desc(ohci) ? - cpu_to_be16p(x) : - cpu_to_le16p(x); + return big_endian(ohci) ? cpu_to_be16p(x) : cpu_to_le16p(x); } static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) { - return big_endian_desc(ohci) ? - (__force __hc32)cpu_to_be32(x) : - (__force __hc32)cpu_to_le32(x); + return big_endian(ohci) ? (__force __hc32)cpu_to_be32(x) : (__force __hc32)cpu_to_le32(x); } static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) { - return big_endian_desc(ohci) ? - cpu_to_be32p(x) : - cpu_to_le32p(x); + return big_endian(ohci) ? cpu_to_be32p(x) : cpu_to_le32p(x); } /* ohci to cpu */ static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) { - return big_endian_desc(ohci) ? - be16_to_cpu((__force __be16)x) : - le16_to_cpu((__force __le16)x); + return big_endian(ohci) ? be16_to_cpu((__force __be16)x) : le16_to_cpu((__force __le16)x); } static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) { - return big_endian_desc(ohci) ? - be16_to_cpup((__force __be16 *)x) : - le16_to_cpup((__force __le16 *)x); + return big_endian(ohci) ? be16_to_cpup((__force __be16 *)x) : le16_to_cpup((__force __le16 *)x); } static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) { - return big_endian_desc(ohci) ? - be32_to_cpu((__force __be32)x) : - le32_to_cpu((__force __le32)x); + return big_endian(ohci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); } static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) { - return big_endian_desc(ohci) ? - be32_to_cpup((__force __be32 *)x) : - le32_to_cpup((__force __le32 *)x); + return big_endian(ohci) ? be32_to_cpup((__force __be32 *)x) : le32_to_cpup((__force __le32 *)x); } /*-------------------------------------------------------------------------*/ @@ -605,9 +557,6 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all * hardware handles 16 bit reads. That creates a different confusion on * some big-endian SOC implementations. Same thing happens with PSW access. - * - * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over - * to arch/powerpc */ #ifdef CONFIG_STB03xxx @@ -619,7 +568,7 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) { u32 tmp; - if (big_endian_desc(ohci)) { + if (big_endian(ohci)) { tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); tmp >>= OHCI_BE_FRAME_NO_SHIFT; } else @@ -631,7 +580,7 @@ static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, const struct td *td, int index) { - return (__hc16 *)(big_endian_desc(ohci) ? + return (__hc16 *)(big_endian(ohci) ? &td->hwPSW[index ^ 1] : &td->hwPSW[index]); } diff --git a/trunk/drivers/usb/host/uhci-debug.c b/trunk/drivers/usb/host/uhci-debug.c index 5d6c06bc4524..e345f15b7d87 100644 --- a/trunk/drivers/usb/host/uhci-debug.c +++ b/trunk/drivers/usb/host/uhci-debug.c @@ -168,13 +168,9 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) space, "", qh, qtype, le32_to_cpu(qh->link), le32_to_cpu(element)); if (qh->type == USB_ENDPOINT_XFER_ISOC) - out += sprintf(out, "%*s period %d phase %d load %d us, " - "frame %x desc [%p]\n", - space, "", qh->period, qh->phase, qh->load, - qh->iso_frame, qh->iso_packet_desc); - else if (qh->type == USB_ENDPOINT_XFER_INT) - out += sprintf(out, "%*s period %d phase %d load %d us\n", - space, "", qh->period, qh->phase, qh->load); + out += sprintf(out, "%*s period %d frame %x desc [%p]\n", + space, "", qh->period, qh->iso_frame, + qh->iso_packet_desc); if (element & UHCI_PTR_QH) out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); @@ -212,7 +208,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) space, "", nurbs); } - if (qh->dummy_td) { + if (qh->udev) { out += sprintf(out, "%*s Dummy TD\n", space, ""); out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); } @@ -351,80 +347,31 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) struct uhci_qh *qh; struct uhci_td *td; struct list_head *tmp, *head; - int nframes, nerrs; out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); out += sprintf(out, "HC status\n"); out += uhci_show_status(uhci, out, len - (out - buf)); - - out += sprintf(out, "Periodic load table\n"); - for (i = 0; i < MAX_PHASE; ++i) { - out += sprintf(out, "\t%d", uhci->load[i]); - if (i % 8 == 7) - *out++ = '\n'; - } - out += sprintf(out, "Total: %d, #INT: %d, #ISO: %d\n", - uhci->total_load, - uhci_to_hcd(uhci)->self.bandwidth_int_reqs, - uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs); if (debug <= 1) return out - buf; out += sprintf(out, "Frame List\n"); - nframes = 10; - nerrs = 0; for (i = 0; i < UHCI_NUMFRAMES; ++i) { - __le32 link, qh_dma; - - j = 0; td = uhci->frame_cpu[i]; - link = uhci->frame[i]; if (!td) - goto check_link; + continue; - if (nframes > 0) { - out += sprintf(out, "- Frame %d -> (%08x)\n", - i, le32_to_cpu(link)); - j = 1; - } + out += sprintf(out, "- Frame %d\n", i); \ + if (td->dma_handle != (dma_addr_t)uhci->frame[i]) + out += sprintf(out, " frame list does not match td->dma_handle!\n"); head = &td->fl_list; tmp = head; do { td = list_entry(tmp, struct uhci_td, fl_list); tmp = tmp->next; - if (cpu_to_le32(td->dma_handle) != link) { - if (nframes > 0) - out += sprintf(out, " link does " - "not match list entry!\n"); - else - ++nerrs; - } - if (nframes > 0) - out += uhci_show_td(td, out, - len - (out - buf), 4); - link = td->link; + out += uhci_show_td(td, out, len - (out - buf), 4); } while (tmp != head); - -check_link: - qh_dma = uhci_frame_skel_link(uhci, i); - if (link != qh_dma) { - if (nframes > 0) { - if (!j) { - out += sprintf(out, - "- Frame %d -> (%08x)\n", - i, le32_to_cpu(link)); - j = 1; - } - out += sprintf(out, " link does not match " - "QH (%08x)!\n", le32_to_cpu(qh_dma)); - } else - ++nerrs; - } - nframes -= j; } - if (nerrs > 0) - out += sprintf(out, "Skipped %d bad links\n", nerrs); out += sprintf(out, "Skeleton QHs\n"); diff --git a/trunk/drivers/usb/host/uhci-hcd.c b/trunk/drivers/usb/host/uhci-hcd.c index 49b9d390b95f..e0d4c2358b39 100644 --- a/trunk/drivers/usb/host/uhci-hcd.c +++ b/trunk/drivers/usb/host/uhci-hcd.c @@ -92,34 +92,6 @@ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state); static void wakeup_rh(struct uhci_hcd *uhci); static void uhci_get_current_frame_number(struct uhci_hcd *uhci); -/* - * Calculate the link pointer DMA value for the first Skeleton QH in a frame. - */ -static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) -{ - int skelnum; - - /* - * The interrupt queues will be interleaved as evenly as possible. - * There's not much to be done about period-1 interrupts; they have - * to occur in every frame. But we can schedule period-2 interrupts - * in odd-numbered frames, period-4 interrupts in frames congruent - * to 2 (mod 4), and so on. This way each frame only has two - * interrupt QHs, which will help spread out bandwidth utilization. - * - * ffs (Find First bit Set) does exactly what we need: - * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], - * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. - * ffs >= 7 => not on any high-period queue, so use - * skel_int1_qh = skelqh[9]. - * Add in UHCI_NUMFRAMES to insure at least one bit is set. - */ - skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); - if (skelnum <= 1) - skelnum = 9; - return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle); -} - #include "uhci-debug.c" #include "uhci-q.c" #include "uhci-hub.c" @@ -659,11 +631,32 @@ static int uhci_start(struct usb_hcd *hcd) /* * Fill the frame list: make all entries point to the proper * interrupt queue. + * + * The interrupt queues will be interleaved as evenly as possible. + * There's not much to be done about period-1 interrupts; they have + * to occur in every frame. But we can schedule period-2 interrupts + * in odd-numbered frames, period-4 interrupts in frames congruent + * to 2 (mod 4), and so on. This way each frame only has two + * interrupt QHs, which will help spread out bandwidth utilization. */ for (i = 0; i < UHCI_NUMFRAMES; i++) { + int irq; + + /* + * ffs (Find First bit Set) does exactly what we need: + * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], + * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. + * ffs >= 7 => not on any high-period queue, so use + * skel_int1_qh = skelqh[9]. + * Add UHCI_NUMFRAMES to insure at least one bit is set. + */ + irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES); + if (irq <= 1) + irq = 9; /* Only place we don't use the frame list routines */ - uhci->frame[i] = uhci_frame_skel_link(uhci, i); + uhci->frame[i] = UHCI_PTR_QH | + cpu_to_le32(uhci->skelqh[irq]->dma_handle); } /* diff --git a/trunk/drivers/usb/host/uhci-hcd.h b/trunk/drivers/usb/host/uhci-hcd.h index 74469b5bcb61..108e3de2dc26 100644 --- a/trunk/drivers/usb/host/uhci-hcd.h +++ b/trunk/drivers/usb/host/uhci-hcd.h @@ -83,7 +83,6 @@ #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames * can be scheduled */ -#define MAX_PHASE 32 /* Periodic scheduling length */ /* When no queues need Full-Speed Bandwidth Reclamation, * delay this long before turning FSBR off */ @@ -142,8 +141,6 @@ struct uhci_qh { unsigned long advance_jiffies; /* Time of last queue advance */ unsigned int unlink_frame; /* When the QH was unlinked */ unsigned int period; /* For Interrupt and Isochronous QHs */ - short phase; /* Between 0 and period-1 */ - short load; /* Periodic time requirement, in us */ unsigned int iso_frame; /* Frame # for iso_packet_desc */ int iso_status; /* Status for Isochronous URBs */ @@ -156,8 +153,6 @@ struct uhci_qh { unsigned int needs_fixup:1; /* Must fix the TD toggle values */ unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ - unsigned int bandwidth_reserved:1; /* Periodic bandwidth has - * been allocated */ } __attribute__((aligned(16))); /* @@ -419,9 +414,6 @@ struct uhci_hcd { wait_queue_head_t waitqh; /* endpoint_disable waiters */ int num_waiting; /* Number of waiters */ - - int total_load; /* Sum of array values */ - short load[MAX_PHASE]; /* Periodic allocations */ }; /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index 2cbb239e63f8..30b88459ac7d 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -248,26 +248,16 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, INIT_LIST_HEAD(&qh->node); if (udev) { /* Normal QH */ - qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; - if (qh->type != USB_ENDPOINT_XFER_ISOC) { - qh->dummy_td = uhci_alloc_td(uhci); - if (!qh->dummy_td) { - dma_pool_free(uhci->qh_pool, qh, dma_handle); - return NULL; - } + qh->dummy_td = uhci_alloc_td(uhci); + if (!qh->dummy_td) { + dma_pool_free(uhci->qh_pool, qh, dma_handle); + return NULL; } qh->state = QH_STATE_IDLE; qh->hep = hep; qh->udev = udev; hep->hcpriv = qh; - - if (qh->type == USB_ENDPOINT_XFER_INT || - qh->type == USB_ENDPOINT_XFER_ISOC) - qh->load = usb_calc_bus_time(udev->speed, - usb_endpoint_dir_in(&hep->desc), - qh->type == USB_ENDPOINT_XFER_ISOC, - le16_to_cpu(hep->desc.wMaxPacketSize)) - / 1000 + 1; + qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; } else { /* Skeleton QH */ qh->state = QH_STATE_ACTIVE; @@ -285,8 +275,7 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) list_del(&qh->node); if (qh->udev) { qh->hep->hcpriv = NULL; - if (qh->dummy_td) - uhci_free_td(uhci, qh->dummy_td); + uhci_free_td(uhci, qh->dummy_td); } dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); } @@ -338,7 +327,7 @@ static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, goto done; qh->element = UHCI_PTR_TERM; - /* Control pipes don't have to worry about toggles */ + /* Control pipes have to worry about toggles */ if (qh->type == USB_ENDPOINT_XFER_CONTROL) goto done; @@ -504,121 +493,6 @@ static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh) wake_up_all(&uhci->waitqh); } -/* - * Find the highest existing bandwidth load for a given phase and period. - */ -static int uhci_highest_load(struct uhci_hcd *uhci, int phase, int period) -{ - int highest_load = uhci->load[phase]; - - for (phase += period; phase < MAX_PHASE; phase += period) - highest_load = max_t(int, highest_load, uhci->load[phase]); - return highest_load; -} - -/* - * Set qh->phase to the optimal phase for a periodic transfer and - * check whether the bandwidth requirement is acceptable. - */ -static int uhci_check_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) -{ - int minimax_load; - - /* Find the optimal phase (unless it is already set) and get - * its load value. */ - if (qh->phase >= 0) - minimax_load = uhci_highest_load(uhci, qh->phase, qh->period); - else { - int phase, load; - int max_phase = min_t(int, MAX_PHASE, qh->period); - - qh->phase = 0; - minimax_load = uhci_highest_load(uhci, qh->phase, qh->period); - for (phase = 1; phase < max_phase; ++phase) { - load = uhci_highest_load(uhci, phase, qh->period); - if (load < minimax_load) { - minimax_load = load; - qh->phase = phase; - } - } - } - - /* Maximum allowable periodic bandwidth is 90%, or 900 us per frame */ - if (minimax_load + qh->load > 900) { - dev_dbg(uhci_dev(uhci), "bandwidth allocation failed: " - "period %d, phase %d, %d + %d us\n", - qh->period, qh->phase, minimax_load, qh->load); - return -ENOSPC; - } - return 0; -} - -/* - * Reserve a periodic QH's bandwidth in the schedule - */ -static void uhci_reserve_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) -{ - int i; - int load = qh->load; - char *p = "??"; - - for (i = qh->phase; i < MAX_PHASE; i += qh->period) { - uhci->load[i] += load; - uhci->total_load += load; - } - uhci_to_hcd(uhci)->self.bandwidth_allocated = - uhci->total_load / MAX_PHASE; - switch (qh->type) { - case USB_ENDPOINT_XFER_INT: - ++uhci_to_hcd(uhci)->self.bandwidth_int_reqs; - p = "INT"; - break; - case USB_ENDPOINT_XFER_ISOC: - ++uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs; - p = "ISO"; - break; - } - qh->bandwidth_reserved = 1; - dev_dbg(uhci_dev(uhci), - "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n", - "reserve", qh->udev->devnum, - qh->hep->desc.bEndpointAddress, p, - qh->period, qh->phase, load); -} - -/* - * Release a periodic QH's bandwidth reservation - */ -static void uhci_release_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) -{ - int i; - int load = qh->load; - char *p = "??"; - - for (i = qh->phase; i < MAX_PHASE; i += qh->period) { - uhci->load[i] -= load; - uhci->total_load -= load; - } - uhci_to_hcd(uhci)->self.bandwidth_allocated = - uhci->total_load / MAX_PHASE; - switch (qh->type) { - case USB_ENDPOINT_XFER_INT: - --uhci_to_hcd(uhci)->self.bandwidth_int_reqs; - p = "INT"; - break; - case USB_ENDPOINT_XFER_ISOC: - --uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs; - p = "ISO"; - break; - } - qh->bandwidth_reserved = 0; - dev_dbg(uhci_dev(uhci), - "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n", - "release", qh->udev->devnum, - qh->hep->desc.bEndpointAddress, p, - qh->period, qh->phase, load); -} - static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *urb) { @@ -922,6 +796,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, wmb(); qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); qh->dummy_td = td; + qh->period = urb->interval; usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), toggle); @@ -952,42 +827,28 @@ static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, struct uhci_qh *qh) { - int ret; + int exponent; /* USB 1.1 interrupt transfers only involve one packet per interval. * Drivers can submit URBs of any length, but longer ones will need * multiple intervals to complete. */ - if (!qh->bandwidth_reserved) { - int exponent; + /* Figure out which power-of-two queue to use */ + for (exponent = 7; exponent >= 0; --exponent) { + if ((1 << exponent) <= urb->interval) + break; + } + if (exponent < 0) + return -EINVAL; + urb->interval = 1 << exponent; - /* Figure out which power-of-two queue to use */ - for (exponent = 7; exponent >= 0; --exponent) { - if ((1 << exponent) <= urb->interval) - break; - } - if (exponent < 0) - return -EINVAL; - qh->period = 1 << exponent; + if (qh->period == 0) qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; + else if (qh->period != urb->interval) + return -EINVAL; /* Can't change the period */ - /* For now, interrupt phase is fixed by the layout - * of the QH lists. */ - qh->phase = (qh->period / 2) & (MAX_PHASE - 1); - ret = uhci_check_bandwidth(uhci, qh); - if (ret) - return ret; - } else if (qh->period > urb->interval) - return -EINVAL; /* Can't decrease the period */ - - ret = uhci_submit_common(uhci, urb, qh); - if (ret == 0) { - urb->interval = qh->period; - if (!qh->bandwidth_reserved) - uhci_reserve_bandwidth(uhci, qh); - } - return ret; + return uhci_submit_common(uhci, urb, qh); } /* @@ -1134,32 +995,15 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, return -EFBIG; /* Check the period and figure out the starting frame number */ - if (!qh->bandwidth_reserved) { - qh->period = urb->interval; + if (qh->period == 0) { if (urb->transfer_flags & URB_ISO_ASAP) { - qh->phase = -1; /* Find the best phase */ - i = uhci_check_bandwidth(uhci, qh); - if (i) - return i; - - /* Allow a little time to allocate the TDs */ uhci_get_current_frame_number(uhci); - frame = uhci->frame_number + 10; - - /* Move forward to the first frame having the - * correct phase */ - urb->start_frame = frame + ((qh->phase - frame) & - (qh->period - 1)); + urb->start_frame = uhci->frame_number + 10; } else { i = urb->start_frame - uhci->last_iso_frame; if (i <= 0 || i >= UHCI_NUMFRAMES) return -EINVAL; - qh->phase = urb->start_frame & (qh->period - 1); - i = uhci_check_bandwidth(uhci, qh); - if (i) - return i; } - } else if (qh->period != urb->interval) { return -EINVAL; /* Can't change the period */ @@ -1205,6 +1049,9 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, /* Set the interrupt-on-completion flag on the last packet. */ td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); + qh->skel = uhci->skel_iso_qh; + qh->period = urb->interval; + /* Add the TDs to the frame list */ frame = urb->start_frame; list_for_each_entry(td, &urbp->td_list, list) { @@ -1218,9 +1065,6 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, qh->iso_status = 0; } - qh->skel = uhci->skel_iso_qh; - if (!qh->bandwidth_reserved) - uhci_reserve_bandwidth(uhci, qh); return 0; } @@ -1275,6 +1119,7 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, unsigned long flags; struct urb_priv *urbp; struct uhci_qh *qh; + int bustime; spin_lock_irqsave(&uhci->lock, flags); @@ -1304,11 +1149,35 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, ret = uhci_submit_bulk(uhci, urb, qh); break; case USB_ENDPOINT_XFER_INT: - ret = uhci_submit_interrupt(uhci, urb, qh); + if (list_empty(&qh->queue)) { + bustime = usb_check_bandwidth(urb->dev, urb); + if (bustime < 0) + ret = bustime; + else { + ret = uhci_submit_interrupt(uhci, urb, qh); + if (ret == 0) + usb_claim_bandwidth(urb->dev, urb, bustime, 0); + } + } else { /* inherit from parent */ + struct urb_priv *eurbp; + + eurbp = list_entry(qh->queue.prev, struct urb_priv, + node); + urb->bandwidth = eurbp->urb->bandwidth; + ret = uhci_submit_interrupt(uhci, urb, qh); + } break; case USB_ENDPOINT_XFER_ISOC: urb->error_count = 0; + bustime = usb_check_bandwidth(urb->dev, urb); + if (bustime < 0) { + ret = bustime; + break; + } + ret = uhci_submit_isochronous(uhci, urb, qh); + if (ret == 0) + usb_claim_bandwidth(urb->dev, urb, bustime, 1); break; } if (ret != 0) @@ -1405,6 +1274,24 @@ __acquires(uhci->lock) uhci_free_urb_priv(uhci, urbp); + switch (qh->type) { + case USB_ENDPOINT_XFER_ISOC: + /* Release bandwidth for Interrupt or Isoc. transfers */ + if (urb->bandwidth) + usb_release_bandwidth(urb->dev, urb, 1); + break; + case USB_ENDPOINT_XFER_INT: + /* Release bandwidth for Interrupt or Isoc. transfers */ + /* Make sure we don't release if we have a queued URB */ + if (list_empty(&qh->queue) && urb->bandwidth) + usb_release_bandwidth(urb->dev, urb, 0); + else + /* bandwidth was passed on to queued URB, */ + /* so don't let usb_unlink_urb() release it */ + urb->bandwidth = 0; + break; + } + spin_unlock(&uhci->lock); usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); spin_lock(&uhci->lock); @@ -1413,8 +1300,9 @@ __acquires(uhci->lock) * reserved bandwidth. */ if (list_empty(&qh->queue)) { uhci_unlink_qh(uhci, qh); - if (qh->bandwidth_reserved) - uhci_release_bandwidth(uhci, qh); + + /* Bandwidth stuff not yet implemented */ + qh->period = 0; } } diff --git a/trunk/drivers/usb/image/mdc800.c b/trunk/drivers/usb/image/mdc800.c index d308afd06935..63a84bbc310d 100644 --- a/trunk/drivers/usb/image/mdc800.c +++ b/trunk/drivers/usb/image/mdc800.c @@ -565,15 +565,11 @@ static void mdc800_usb_disconnect (struct usb_interface *intf) usb_deregister_dev(intf, &mdc800_class); - /* must be under lock to make sure no URB - is submitted after usb_kill_urb() */ - mutex_lock(&mdc800->io_lock); mdc800->state=NOT_CONNECTED; usb_kill_urb(mdc800->irq_urb); usb_kill_urb(mdc800->write_urb); usb_kill_urb(mdc800->download_urb); - mutex_unlock(&mdc800->io_lock); mdc800->dev = NULL; usb_set_intfdata(intf, NULL); diff --git a/trunk/drivers/usb/input/Kconfig b/trunk/drivers/usb/input/Kconfig index 2e71d3cca198..aa6a620c162f 100644 --- a/trunk/drivers/usb/input/Kconfig +++ b/trunk/drivers/usb/input/Kconfig @@ -352,15 +352,3 @@ config USB_APPLETOUCH To compile this driver as a module, choose M here: the module will be called appletouch. - -config USB_GTCO - tristate "GTCO CalComp/InterWrite USB Support" - depends on USB && INPUT - ---help--- - Say Y here if you want to use the USB version of the GTCO - CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" - (CONFIG_INPUT_EVDEV) as well. - - To compile this driver as a module, choose M here: the - module will be called gtco. diff --git a/trunk/drivers/usb/input/Makefile b/trunk/drivers/usb/input/Makefile index a9d206c945e9..a06024e5cd56 100644 --- a/trunk/drivers/usb/input/Makefile +++ b/trunk/drivers/usb/input/Makefile @@ -48,7 +48,6 @@ obj-$(CONFIG_USB_ACECAD) += acecad.o obj-$(CONFIG_USB_YEALINK) += yealink.o obj-$(CONFIG_USB_XPAD) += xpad.o obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o -obj-$(CONFIG_USB_GTCO) += gtco.o ifeq ($(CONFIG_USB_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff --git a/trunk/drivers/usb/input/gtco.c b/trunk/drivers/usb/input/gtco.c deleted file mode 100644 index 203cdc1bbba4..000000000000 --- a/trunk/drivers/usb/input/gtco.c +++ /dev/null @@ -1,1104 +0,0 @@ -/* -*- linux-c -*- - -GTCO digitizer USB driver - -Use the err(), dbg() and info() macros from usb.h for system logging - -TO CHECK: Is pressure done right on report 5? - -Copyright (C) 2006 GTCO CalComp - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of GTCO-CalComp not be used in advertising -or publicity pertaining to distribution of the software without specific, -written prior permission. GTCO-CalComp makes no representations about the -suitability of this software for any purpose. It is provided "as is" -without express or implied warranty. - -GTCO-CALCOMP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL GTCO-CALCOMP BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTIONS, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - -GTCO CalComp, Inc. -7125 Riverwood Drive -Columbia, MD 21046 - -Jeremy Roberson jroberson@gtcocalcomp.com -Scott Hill shill@gtcocalcomp.com -*/ - - - -/*#define DEBUG*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include - -/* Version with a Major number of 2 is for kernel inclusion only. */ -#define GTCO_VERSION "2.00.0006" - - -/* MACROS */ - -#define VENDOR_ID_GTCO 0x078C -#define PID_400 0x400 -#define PID_401 0x401 -#define PID_1000 0x1000 -#define PID_1001 0x1001 -#define PID_1002 0x1002 - -/* Max size of a single report */ -#define REPORT_MAX_SIZE 10 - - -/* Bitmask whether pen is in range */ -#define MASK_INRANGE 0x20 -#define MASK_BUTTON 0x01F - -#define PATHLENGTH 64 - -/* DATA STRUCTURES */ - -/* Device table */ -static struct usb_device_id gtco_usbid_table [] = { - { USB_DEVICE(VENDOR_ID_GTCO, PID_400) }, - { USB_DEVICE(VENDOR_ID_GTCO, PID_401) }, - { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) }, - { USB_DEVICE(VENDOR_ID_GTCO, PID_1001) }, - { USB_DEVICE(VENDOR_ID_GTCO, PID_1002) }, - { } -}; -MODULE_DEVICE_TABLE (usb, gtco_usbid_table); - - -/* Structure to hold all of our device specific stuff */ -struct gtco { - - struct input_dev *inputdevice; /* input device struct pointer */ - struct usb_device *usbdev; /* the usb device for this device */ - struct urb *urbinfo; /* urb for incoming reports */ - dma_addr_t buf_dma; /* dma addr of the data buffer*/ - unsigned char * buffer; /* databuffer for reports */ - - char usbpath[PATHLENGTH]; - int openCount; - - /* Information pulled from Report Descriptor */ - u32 usage; - u32 min_X; - u32 max_X; - u32 min_Y; - u32 max_Y; - s8 mintilt_X; - s8 maxtilt_X; - s8 mintilt_Y; - s8 maxtilt_Y; - u32 maxpressure; - u32 minpressure; -}; - - - -/* Code for parsing the HID REPORT DESCRIPTOR */ - -/* From HID1.11 spec */ -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - - -#define HID_DESCRIPTOR_SIZE 9 -#define HID_DEVICE_TYPE 33 -#define REPORT_DEVICE_TYPE 34 - - -#define PREF_TAG(x) ((x)>>4) -#define PREF_TYPE(x) ((x>>2)&0x03) -#define PREF_SIZE(x) ((x)&0x03) - -#define TYPE_MAIN 0 -#define TYPE_GLOBAL 1 -#define TYPE_LOCAL 2 -#define TYPE_RESERVED 3 - -#define TAG_MAIN_INPUT 0x8 -#define TAG_MAIN_OUTPUT 0x9 -#define TAG_MAIN_FEATURE 0xB -#define TAG_MAIN_COL_START 0xA -#define TAG_MAIN_COL_END 0xC - -#define TAG_GLOB_USAGE 0 -#define TAG_GLOB_LOG_MIN 1 -#define TAG_GLOB_LOG_MAX 2 -#define TAG_GLOB_PHYS_MIN 3 -#define TAG_GLOB_PHYS_MAX 4 -#define TAG_GLOB_UNIT_EXP 5 -#define TAG_GLOB_UNIT 6 -#define TAG_GLOB_REPORT_SZ 7 -#define TAG_GLOB_REPORT_ID 8 -#define TAG_GLOB_REPORT_CNT 9 -#define TAG_GLOB_PUSH 10 -#define TAG_GLOB_POP 11 - -#define TAG_GLOB_MAX 12 - -#define DIGITIZER_USAGE_TIP_PRESSURE 0x30 -#define DIGITIZER_USAGE_TILT_X 0x3D -#define DIGITIZER_USAGE_TILT_Y 0x3E - - -/* - * - * This is an abbreviated parser for the HID Report Descriptor. We - * know what devices we are talking to, so this is by no means meant - * to be generic. We can make some safe assumptions: - * - * - We know there are no LONG tags, all short - * - We know that we have no MAIN Feature and MAIN Output items - * - We know what the IRQ reports are supposed to look like. - * - * The main purpose of this is to use the HID report desc to figure - * out the mins and maxs of the fields in the IRQ reports. The IRQ - * reports for 400/401 change slightly if the max X is bigger than 64K. - * - */ -static void parse_hid_report_descriptor(struct gtco *device, char * report, - int length) -{ - int x,i=0; - - /* Tag primitive vars */ - __u8 prefix; - __u8 size; - __u8 tag; - __u8 type; - __u8 data = 0; - __u16 data16 = 0; - __u32 data32 = 0; - - - /* For parsing logic */ - int inputnum = 0; - __u32 usage = 0; - - /* Global Values, indexed by TAG */ - __u32 globalval[TAG_GLOB_MAX]; - __u32 oldval[TAG_GLOB_MAX]; - - /* Debug stuff */ - char maintype='x'; - char globtype[12]; - int indent=0; - char indentstr[10]=""; - - - - dbg("======>>>>>>PARSE<<<<<<======"); - - /* Walk this report and pull out the info we need */ - while (imax_X == 0){ - device->max_X = globalval[TAG_GLOB_LOG_MAX]; - device->min_X = globalval[TAG_GLOB_LOG_MIN]; - } - - break; - case 1: /* Y coord */ - dbg("GER: Y Usage: 0x%x",usage); - if (device->max_Y == 0){ - device->max_Y = globalval[TAG_GLOB_LOG_MAX]; - device->min_Y = globalval[TAG_GLOB_LOG_MIN]; - } - break; - default: - /* Tilt X */ - if (usage == DIGITIZER_USAGE_TILT_X){ - if (device->maxtilt_X == 0){ - device->maxtilt_X = globalval[TAG_GLOB_LOG_MAX]; - device->mintilt_X = globalval[TAG_GLOB_LOG_MIN]; - } - } - - /* Tilt Y */ - if (usage == DIGITIZER_USAGE_TILT_Y){ - if (device->maxtilt_Y == 0){ - device->maxtilt_Y = globalval[TAG_GLOB_LOG_MAX]; - device->mintilt_Y = globalval[TAG_GLOB_LOG_MIN]; - } - } - - - /* Pressure */ - if (usage == DIGITIZER_USAGE_TIP_PRESSURE){ - if (device->maxpressure == 0){ - device->maxpressure = globalval[TAG_GLOB_LOG_MAX]; - device->minpressure = globalval[TAG_GLOB_LOG_MIN]; - } - } - - break; - } - - inputnum++; - - - break; - case TAG_MAIN_OUTPUT: - maintype='O'; - break; - case TAG_MAIN_FEATURE: - maintype='F'; - break; - case TAG_MAIN_COL_START: - maintype='S'; - - if (data==0){ - dbg("======>>>>>> Physical"); - strcpy(globtype,"Physical"); - }else{ - dbg("======>>>>>>"); - } - - /* Indent the debug output */ - indent++; - for (x=0;xusage == 0){ - device->usage = data; - } - strcpy(globtype,"USAGE"); - break; - case TAG_GLOB_LOG_MIN : - strcpy(globtype,"LOG_MIN"); - break; - case TAG_GLOB_LOG_MAX : - strcpy(globtype,"LOG_MAX"); - break; - case TAG_GLOB_PHYS_MIN : - strcpy(globtype,"PHYS_MIN"); - break; - case TAG_GLOB_PHYS_MAX : - strcpy(globtype,"PHYS_MAX"); - break; - case TAG_GLOB_UNIT_EXP : - strcpy(globtype,"EXP"); - break; - case TAG_GLOB_UNIT : - strcpy(globtype,"UNIT"); - break; - case TAG_GLOB_REPORT_SZ : - strcpy(globtype,"REPORT_SZ"); - break; - case TAG_GLOB_REPORT_ID : - strcpy(globtype,"REPORT_ID"); - /* New report, restart numbering */ - inputnum=0; - break; - case TAG_GLOB_REPORT_CNT: - strcpy(globtype,"REPORT_CNT"); - break; - case TAG_GLOB_PUSH : - strcpy(globtype,"PUSH"); - break; - case TAG_GLOB_POP: - strcpy(globtype,"POP"); - break; - } - - - /* Check to make sure we have a good tag number - so we don't overflow array */ - if (tag < TAG_GLOB_MAX){ - switch (size){ - case 1: - dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data); - globalval[tag]=data; - break; - case 2: - dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data16); - globalval[tag]=data16; - break; - case 4: - dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data32); - globalval[tag]=data32; - break; - } - }else{ - dbg("%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d ", - indentstr,tag,size); - } - - - break; - - case TYPE_LOCAL: - switch(tag){ - case TAG_GLOB_USAGE: - strcpy(globtype,"USAGE"); - /* Always 1 byte */ - usage = data; - break; - case TAG_GLOB_LOG_MIN : - strcpy(globtype,"MIN"); - break; - case TAG_GLOB_LOG_MAX : - strcpy(globtype,"MAX"); - break; - default: - strcpy(globtype,"UNKNOWN"); - } - - switch (size){ - case 1: - dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", - indentstr,tag,globtype,size,data); - break; - case 2: - dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", - indentstr,tag,globtype,size,data16); - break; - case 4: - dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", - indentstr,tag,globtype,size,data32); - break; - } - - break; - } - - } - -} - - - -/* INPUT DRIVER Routines */ - - -/* - * Called when opening the input device. This will submit the URB to - * the usb system so we start getting reports - */ -static int gtco_input_open(struct input_dev *inputdev) -{ - struct gtco *device; - device = inputdev->private; - - device->urbinfo->dev = device->usbdev; - if (usb_submit_urb(device->urbinfo, GFP_KERNEL)) { - return -EIO; - } - return 0; -} - -/** - Called when closing the input device. This will unlink the URB -*/ -static void gtco_input_close(struct input_dev *inputdev) -{ - struct gtco *device = inputdev->private; - - usb_kill_urb(device->urbinfo); - -} - - -/* - * Setup input device capabilities. Tell the input system what this - * device is capable of generating. - * - * This information is based on what is read from the HID report and - * placed in the struct gtco structure - * - */ -static void gtco_setup_caps(struct input_dev *inputdev) -{ - struct gtco *device = inputdev->private; - - - /* Which events */ - inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); - - - /* Misc event menu block */ - inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ; - - - /* Absolute values based on HID report info */ - input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X, - 0, 0); - input_set_abs_params(inputdev, ABS_Y, device->min_Y, device->max_Y, - 0, 0); - - /* Proximity */ - input_set_abs_params(inputdev, ABS_DISTANCE, 0, 1, 0, 0); - - /* Tilt & pressure */ - input_set_abs_params(inputdev, ABS_TILT_X, device->mintilt_X, - device->maxtilt_X, 0, 0); - input_set_abs_params(inputdev, ABS_TILT_Y, device->mintilt_Y, - device->maxtilt_Y, 0, 0); - input_set_abs_params(inputdev, ABS_PRESSURE, device->minpressure, - device->maxpressure, 0, 0); - - - /* Transducer */ - input_set_abs_params(inputdev, ABS_MISC, 0,0xFF, 0, 0); - -} - - - -/* USB Routines */ - - -/* - * URB callback routine. Called when we get IRQ reports from the - * digitizer. - * - * This bridges the USB and input device worlds. It generates events - * on the input device based on the USB reports. - */ -static void gtco_urb_callback(struct urb *urbinfo) -{ - - - struct gtco *device = urbinfo->context; - struct input_dev *inputdev; - int rc; - u32 val = 0; - s8 valsigned = 0; - char le_buffer[2]; - - inputdev = device->inputdevice; - - - /* Was callback OK? */ - if ((urbinfo->status == -ECONNRESET ) || - (urbinfo->status == -ENOENT ) || - (urbinfo->status == -ESHUTDOWN )){ - - /* Shutdown is occurring. Return and don't queue up any more */ - return; - } - - if (urbinfo->status != 0 ) { - /* Some unknown error. Hopefully temporary. Just go and */ - /* requeue an URB */ - goto resubmit; - } - - /* - * Good URB, now process - */ - - /* PID dependent when we interpret the report */ - if ((inputdev->id.product == PID_1000 )|| - (inputdev->id.product == PID_1001 )|| - (inputdev->id.product == PID_1002 )) - { - - /* - * Switch on the report ID - * Conveniently, the reports have more information, the higher - * the report number. We can just fall through the case - * statements if we start with the highest number report - */ - switch(device->buffer[0]){ - case 5: - /* Pressure is 9 bits */ - val = ((u16)(device->buffer[8]) << 1); - val |= (u16)(device->buffer[7] >> 7); - input_report_abs(inputdev, ABS_PRESSURE, - device->buffer[8]); - - /* Mask out the Y tilt value used for pressure */ - device->buffer[7] = (u8)((device->buffer[7]) & 0x7F); - - - /* Fall thru */ - case 4: - /* Tilt */ - - /* Sign extend these 7 bit numbers. */ - if (device->buffer[6] & 0x40) - device->buffer[6] |= 0x80; - - if (device->buffer[7] & 0x40) - device->buffer[7] |= 0x80; - - - valsigned = (device->buffer[6]); - input_report_abs(inputdev, ABS_TILT_X, (s32)valsigned); - - valsigned = (device->buffer[7]); - input_report_abs(inputdev, ABS_TILT_Y, (s32)valsigned); - - /* Fall thru */ - - case 2: - case 3: - /* Convert buttons, only 5 bits possible */ - val = (device->buffer[5])&MASK_BUTTON; - - /* We don't apply any meaning to the bitmask, - just report */ - input_event(inputdev, EV_MSC, MSC_SERIAL, val); - - /* Fall thru */ - case 1: - - /* All reports have X and Y coords in the same place */ - val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[1]))); - input_report_abs(inputdev, ABS_X, val); - - val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[3]))); - input_report_abs(inputdev, ABS_Y, val); - - - /* Ditto for proximity bit */ - if (device->buffer[5]& MASK_INRANGE){ - val = 1; - }else{ - val=0; - } - input_report_abs(inputdev, ABS_DISTANCE, val); - - - /* Report 1 is an exception to how we handle buttons */ - /* Buttons are an index, not a bitmask */ - if (device->buffer[0] == 1){ - - /* Convert buttons, 5 bit index */ - /* Report value of index set as one, - the rest as 0 */ - val = device->buffer[5]& MASK_BUTTON; - dbg("======>>>>>>REPORT 1: val 0x%X(%d)", - val,val); - - /* - * We don't apply any meaning to the button - * index, just report it - */ - input_event(inputdev, EV_MSC, MSC_SERIAL, val); - - - } - - break; - case 7: - /* Menu blocks */ - input_event(inputdev, EV_MSC, MSC_SCAN, - device->buffer[1]); - - - break; - - } - - - } - /* Other pid class */ - if ((inputdev->id.product == PID_400 )|| - (inputdev->id.product == PID_401 )) - { - - /* Report 2 */ - if (device->buffer[0] == 2){ - /* Menu blocks */ - input_event(inputdev, EV_MSC, MSC_SCAN, - device->buffer[1]); - } - - /* Report 1 */ - if (device->buffer[0] == 1){ - char buttonbyte; - - - /* IF X max > 64K, we still a bit from the y report */ - if (device->max_X > 0x10000){ - - val = (u16)(((u16)(device->buffer[2]<<8))|((u8)(device->buffer[1]))); - val |= (u32)(((u8)device->buffer[3]&0x1)<< 16); - - input_report_abs(inputdev, ABS_X, val); - - le_buffer[0] = (u8)((u8)(device->buffer[3])>>1); - le_buffer[0] |= (u8)((device->buffer[3]&0x1)<<7); - - le_buffer[1] = (u8)(device->buffer[4]>>1); - le_buffer[1] |= (u8)((device->buffer[5]&0x1)<<7); - - val = le16_to_cpu(get_unaligned((__le16 *)(le_buffer))); - - input_report_abs(inputdev, ABS_Y, val); - - - /* - * Shift the button byte right by one to - * make it look like the standard report - */ - buttonbyte = (device->buffer[5])>>1; - }else{ - - val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[1])))); - input_report_abs(inputdev, ABS_X, val); - - val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[3])))); - input_report_abs(inputdev, ABS_Y, val); - - buttonbyte = device->buffer[5]; - - } - - - /* BUTTONS and PROXIMITY */ - if (buttonbyte& MASK_INRANGE){ - val = 1; - }else{ - val=0; - } - input_report_abs(inputdev, ABS_DISTANCE, val); - - /* Convert buttons, only 4 bits possible */ - val = buttonbyte&0x0F; -#ifdef USE_BUTTONS - for ( i=0;i<5;i++){ - input_report_key(inputdev, BTN_DIGI+i,val&(1<buffer[6]); - - } - } - - /* Everybody gets report ID's */ - input_event(inputdev, EV_MSC, MSC_RAW, device->buffer[0]); - - /* Sync it up */ - input_sync(inputdev); - - resubmit: - rc = usb_submit_urb(urbinfo, GFP_ATOMIC); - if (rc != 0) { - err("usb_submit_urb failed rc=0x%x",rc); - } - -} - -/* - * The probe routine. This is called when the kernel find the matching USB - * vendor/product. We do the following: - * - * - Allocate mem for a local structure to manage the device - * - Request a HID Report Descriptor from the device and parse it to - * find out the device parameters - * - Create an input device and assign it attributes - * - Allocate an URB so the device can talk to us when the input - * queue is open - */ -static int gtco_probe(struct usb_interface *usbinterface, - const struct usb_device_id *id) -{ - - struct gtco *device = NULL; - char path[PATHLENGTH]; - struct input_dev *inputdev; - struct hid_descriptor *hid_desc; - char *report; - int result=0, retry; - struct usb_endpoint_descriptor *endpoint; - - /* Allocate memory for device structure */ - device = kzalloc(sizeof(struct gtco), GFP_KERNEL); - if (device == NULL) { - err("No more memory"); - return -ENOMEM; - } - - - device->inputdevice = input_allocate_device(); - if (!device->inputdevice){ - kfree(device); - err("No more memory"); - return -ENOMEM; - } - - /* Get pointer to the input device */ - inputdev = device->inputdevice; - - /* Save interface information */ - device->usbdev = usb_get_dev(interface_to_usbdev(usbinterface)); - - - /* Allocate some data for incoming reports */ - device->buffer = usb_buffer_alloc(device->usbdev, REPORT_MAX_SIZE, - GFP_KERNEL, &(device->buf_dma)); - if (!device->buffer){ - input_free_device(device->inputdevice); - kfree(device); - err("No more memory"); - return -ENOMEM; - } - - /* Allocate URB for reports */ - device->urbinfo = usb_alloc_urb(0, GFP_KERNEL); - if (!device->urbinfo) { - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - input_free_device(device->inputdevice); - kfree(device); - err("No more memory"); - return -ENOMEM; - } - - - /* - * The endpoint is always altsetting 0, we know this since we know - * this device only has one interrupt endpoint - */ - endpoint = &usbinterface->altsetting[0].endpoint[0].desc; - - /* Some debug */ - dbg("gtco # interfaces: %d",usbinterface->num_altsetting); - dbg("num endpoints: %d",usbinterface->cur_altsetting->desc.bNumEndpoints); - dbg("interface class: %d",usbinterface->cur_altsetting->desc.bInterfaceClass); - dbg("endpoint: attribute:0x%x type:0x%x",endpoint->bmAttributes,endpoint->bDescriptorType); - if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) - dbg("endpoint: we have interrupt endpoint\n"); - - dbg("endpoint extra len:%d ",usbinterface->altsetting[0].extralen); - - - - /* - * Find the HID descriptor so we can find out the size of the - * HID report descriptor - */ - if (usb_get_extra_descriptor(usbinterface->cur_altsetting, - HID_DEVICE_TYPE,&hid_desc) != 0){ - err("Can't retrieve exta USB descriptor to get hid report descriptor length"); - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - input_free_device(device->inputdevice); - kfree(device); - return -EIO; - } - - dbg("Extra descriptor success: type:%d len:%d", - hid_desc->bDescriptorType, hid_desc->wDescriptorLength); - - if (!(report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL))) { - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - - input_free_device(device->inputdevice); - kfree(device); - err("No more memory"); - return -ENOMEM; - } - - /* Couple of tries to get reply */ - for (retry=0;retry<3;retry++) { - result = usb_control_msg(device->usbdev, - usb_rcvctrlpipe(device->usbdev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - (REPORT_DEVICE_TYPE << 8), - 0, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - - if (result == hid_desc->wDescriptorLength) - break; - } - - /* If we didn't get the report, fail */ - dbg("usb_control_msg result: :%d", result); - if (result != hid_desc->wDescriptorLength){ - kfree(report); - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - input_free_device(device->inputdevice); - kfree(device); - err("Failed to get HID Report Descriptor of size: %d", - hid_desc->wDescriptorLength); - return -EIO; - } - - - /* Now we parse the report */ - parse_hid_report_descriptor(device,report,result); - - /* Now we delete it */ - kfree(report); - - /* Create a device file node */ - usb_make_path(device->usbdev, path, PATHLENGTH); - sprintf(device->usbpath, "%s/input0", path); - - - /* Set Input device functions */ - inputdev->open = gtco_input_open; - inputdev->close = gtco_input_close; - - /* Set input device information */ - inputdev->name = "GTCO_CalComp"; - inputdev->phys = device->usbpath; - inputdev->private = device; - - - /* Now set up all the input device capabilities */ - gtco_setup_caps(inputdev); - - /* Set input device required ID information */ - usb_to_input_id(device->usbdev, &device->inputdevice->id); - inputdev->cdev.dev = &usbinterface->dev; - - /* Setup the URB, it will be posted later on open of input device */ - endpoint = &usbinterface->altsetting[0].endpoint[0].desc; - - usb_fill_int_urb(device->urbinfo, - device->usbdev, - usb_rcvintpipe(device->usbdev, - endpoint->bEndpointAddress), - device->buffer, - REPORT_MAX_SIZE, - gtco_urb_callback, - device, - endpoint->bInterval); - - device->urbinfo->transfer_dma = device->buf_dma; - device->urbinfo->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - - /* Save device pointer in USB interface device */ - usb_set_intfdata(usbinterface, device); - - /* All done, now register the input device */ - input_register_device(inputdev); - - info( "gtco driver created usb: %s\n", path); - return 0; - -} - -/* - * This function is a standard USB function called when the USB device - * is disconnected. We will get rid of the URV, de-register the input - * device, and free up allocated memory - */ -static void gtco_disconnect(struct usb_interface *interface) -{ - - /* Grab private device ptr */ - struct gtco *device = usb_get_intfdata (interface); - struct input_dev *inputdev; - - inputdev = device->inputdevice; - - /* Now reverse all the registration stuff */ - if (device) { - input_unregister_device(inputdev); - usb_kill_urb(device->urbinfo); - usb_free_urb(device->urbinfo); - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - kfree(device); - } - - info("gtco driver disconnected"); -} - - -/* STANDARD MODULE LOAD ROUTINES */ - -static struct usb_driver gtco_driverinfo_table = { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) - .owner = THIS_MODULE, -#endif - .name = "gtco", - .id_table = gtco_usbid_table, - .probe = gtco_probe, - .disconnect = gtco_disconnect, -}; -/* - * Register this module with the USB subsystem - */ -static int __init gtco_init(void) -{ - int rc; - rc = usb_register(>co_driverinfo_table); - if (rc) { - err("usb_register() failed rc=0x%x", rc); - } - printk("GTCO usb driver version: %s",GTCO_VERSION); - return rc; -} - -/* - * Deregister this module with the USB subsystem - */ -static void __exit gtco_exit(void) -{ - usb_deregister(>co_driverinfo_table); -} - -module_init (gtco_init); -module_exit (gtco_exit); - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index 84983d1b7164..e07a30490726 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -768,9 +768,6 @@ void usbhid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_PANTHERLORD 0x0810 #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 -#define USB_VENDOR_ID_SONY 0x054c -#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 - /* * Alphabetically sorted blacklist by quirk type. */ @@ -952,8 +949,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, - { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, - { 0, 0 } }; @@ -1018,32 +1013,6 @@ static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize) } } -/* - * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller - * to "operational". Without this, the ps3 controller will not report any - * events. - */ -static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) -{ - int result; - char *buf = kmalloc(18, GFP_KERNEL); - - if (!buf) - return; - - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - HID_REQ_GET_REPORT, - USB_DIR_IN | USB_TYPE_CLASS | - USB_RECIP_INTERFACE, - (3 << 8) | 0xf2, ifnum, buf, 17, - USB_CTRL_GET_TIMEOUT); - - if (result < 0) - err("%s failed: %d\n", __func__, result); - - kfree(buf); -} - static struct hid_device *usb_hid_configure(struct usb_interface *intf) { struct usb_host_interface *interface = intf->cur_altsetting; @@ -1334,10 +1303,6 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) if ((hid->claimed & HID_CLAIMED_INPUT)) hid_ff_init(hid); - if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER) - hid_fixup_sony_ps3_controller(interface_to_usbdev(intf), - intf->cur_altsetting->desc.bInterfaceNumber); - printk(KERN_INFO); if (hid->claimed & HID_CLAIMED_INPUT) diff --git a/trunk/drivers/usb/input/hid-lgff.c b/trunk/drivers/usb/input/hid-lgff.c index 4f4fc3be192e..e47466268565 100644 --- a/trunk/drivers/usb/input/hid-lgff.c +++ b/trunk/drivers/usb/input/hid-lgff.c @@ -32,7 +32,7 @@ #include #include "usbhid.h" -struct dev_type { +struct device_type { u16 idVendor; u16 idProduct; const signed short *ff; @@ -48,7 +48,7 @@ static const signed short ff_joystick[] = { -1 }; -static const struct dev_type devices[] = { +static const struct device_type devices[] = { { 0x046d, 0xc211, ff_rumble }, { 0x046d, 0xc219, ff_rumble }, { 0x046d, 0xc283, ff_joystick }, diff --git a/trunk/drivers/usb/misc/idmouse.c b/trunk/drivers/usb/misc/idmouse.c index 15c70bd048c4..c9418535bef8 100644 --- a/trunk/drivers/usb/misc/idmouse.c +++ b/trunk/drivers/usb/misc/idmouse.c @@ -269,7 +269,7 @@ static int idmouse_release(struct inode *inode, struct file *file) /* prevent a race condition with open() */ mutex_lock(&disconnect_mutex); - dev = file->private_data; + dev = (struct usb_idmouse *) file->private_data; if (dev == NULL) { mutex_unlock(&disconnect_mutex); @@ -304,15 +304,17 @@ static int idmouse_release(struct inode *inode, struct file *file) static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos) { - struct usb_idmouse *dev = file->private_data; + struct usb_idmouse *dev; int result; + dev = (struct usb_idmouse *) file->private_data; + /* lock this object */ - down(&dev->sem); + down (&dev->sem); /* verify that the device wasn't unplugged */ if (!dev->present) { - up(&dev->sem); + up (&dev->sem); return -ENODEV; } diff --git a/trunk/drivers/usb/misc/rio500.c b/trunk/drivers/usb/misc/rio500.c index fdf68479a166..384fa3769805 100644 --- a/trunk/drivers/usb/misc/rio500.c +++ b/trunk/drivers/usb/misc/rio500.c @@ -69,7 +69,7 @@ struct rio_usb_data { char *obuf, *ibuf; /* transfer buffers */ char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ wait_queue_head_t wait_q; /* for timeouts */ - struct mutex lock; /* general race avoidance */ + struct semaphore lock; /* general race avoidance */ }; static struct rio_usb_data rio_instance; @@ -78,17 +78,17 @@ static int open_rio(struct inode *inode, struct file *file) { struct rio_usb_data *rio = &rio_instance; - mutex_lock(&(rio->lock)); + down(&(rio->lock)); if (rio->isopen || !rio->present) { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return -EBUSY; } rio->isopen = 1; init_waitqueue_head(&rio->wait_q); - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); info("Rio opened."); @@ -117,7 +117,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, int retries; int retval=0; - mutex_lock(&(rio->lock)); + down(&(rio->lock)); /* Sanity check to make sure rio is connected, powered, etc */ if ( rio == NULL || rio->present == 0 || @@ -257,7 +257,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, err_out: - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return retval; } @@ -275,17 +275,14 @@ write_rio(struct file *file, const char __user *buffer, int result = 0; int maxretry; int errn = 0; - int intr; - intr = mutex_lock_interruptible(&(rio->lock)); - if (intr) - return -EINTR; + down(&(rio->lock)); /* Sanity check to make sure rio is connected, powered, etc */ if ( rio == NULL || rio->present == 0 || rio->rio_dev == NULL ) { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return -ENODEV; } @@ -308,7 +305,7 @@ write_rio(struct file *file, const char __user *buffer, goto error; } if (signal_pending(current)) { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return bytes_written ? bytes_written : -EINTR; } @@ -344,12 +341,12 @@ write_rio(struct file *file, const char __user *buffer, buffer += copy_size; } while (count > 0); - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return bytes_written ? bytes_written : -EIO; error: - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return errn; } @@ -364,17 +361,14 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) int result; int maxretry = 10; char *ibuf; - int intr; - intr = mutex_lock_interruptible(&(rio->lock)); - if (intr) - return -EINTR; + down(&(rio->lock)); /* Sanity check to make sure rio is connected, powered, etc */ if ( rio == NULL || rio->present == 0 || rio->rio_dev == NULL ) { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return -ENODEV; } @@ -385,11 +379,11 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) while (count > 0) { if (signal_pending(current)) { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return read_count ? read_count : -EINTR; } if (!rio->rio_dev) { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return -ENODEV; } this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; @@ -406,7 +400,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) count = this_read = partial; } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ if (!maxretry--) { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); err("read_rio: maxretry timeout"); return -ETIME; } @@ -415,18 +409,18 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) finish_wait(&rio->wait_q, &wait); continue; } else if (result != -EREMOTEIO) { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); err("Read Whoops - result:%u partial:%u this_read:%u", result, partial, this_read); return -EIO; } else { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return (0); } if (this_read) { if (copy_to_user(buffer, ibuf, this_read)) { - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return -EFAULT; } count -= this_read; @@ -434,7 +428,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) buffer += this_read; } } - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return read_count; } @@ -486,7 +480,7 @@ static int probe_rio(struct usb_interface *intf, } dbg("probe_rio: ibuf address:%p", rio->ibuf); - mutex_init(&(rio->lock)); + init_MUTEX(&(rio->lock)); usb_set_intfdata (intf, rio); rio->present = 1; @@ -502,12 +496,12 @@ static void disconnect_rio(struct usb_interface *intf) if (rio) { usb_deregister_dev(intf, &usb_rio_class); - mutex_lock(&(rio->lock)); + down(&(rio->lock)); if (rio->isopen) { rio->isopen = 0; /* better let it finish - the release will do whats needed */ rio->rio_dev = NULL; - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); return; } kfree(rio->ibuf); @@ -516,7 +510,7 @@ static void disconnect_rio(struct usb_interface *intf) info("USB Rio disconnected."); rio->present = 0; - mutex_unlock(&(rio->lock)); + up(&(rio->lock)); } } diff --git a/trunk/drivers/usb/mon/Makefile b/trunk/drivers/usb/mon/Makefile index 90c59535778d..3cf3ea3a88ed 100644 --- a/trunk/drivers/usb/mon/Makefile +++ b/trunk/drivers/usb/mon/Makefile @@ -2,7 +2,7 @@ # Makefile for USB Core files and filesystem # -usbmon-objs := mon_main.o mon_stat.o mon_text.o mon_bin.o mon_dma.o +usbmon-objs := mon_main.o mon_stat.o mon_text.o mon_dma.o # This does not use CONFIG_USB_MON because we want this to use a tristate. obj-$(CONFIG_USB) += usbmon.o diff --git a/trunk/drivers/usb/mon/mon_bin.c b/trunk/drivers/usb/mon/mon_bin.c deleted file mode 100644 index c01dfe603672..000000000000 --- a/trunk/drivers/usb/mon/mon_bin.c +++ /dev/null @@ -1,1172 +0,0 @@ -/* - * The USB Monitor, inspired by Dave Harding's USBMon. - * - * This is a binary format reader. - * - * Copyright (C) 2006 Paolo Abeni (paolo.abeni@email.it) - * Copyright (C) 2006 Pete Zaitcev (zaitcev@redhat.com) - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "usb_mon.h" - -/* - * Defined by USB 2.0 clause 9.3, table 9.2. - */ -#define SETUP_LEN 8 - -/* ioctl macros */ -#define MON_IOC_MAGIC 0x92 - -#define MON_IOCQ_URB_LEN _IO(MON_IOC_MAGIC, 1) -/* #2 used to be MON_IOCX_URB, removed before it got into Linus tree */ -#define MON_IOCG_STATS _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats) -#define MON_IOCT_RING_SIZE _IO(MON_IOC_MAGIC, 4) -#define MON_IOCQ_RING_SIZE _IO(MON_IOC_MAGIC, 5) -#define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) -#define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) -#define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) -#ifdef CONFIG_COMPAT -#define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32) -#define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32) -#endif - -/* - * Some architectures have enormous basic pages (16KB for ia64, 64KB for ppc). - * But it's all right. Just use a simple way to make sure the chunk is never - * smaller than a page. - * - * N.B. An application does not know our chunk size. - * - * Woops, get_zeroed_page() returns a single page. I guess we're stuck with - * page-sized chunks for the time being. - */ -#define CHUNK_SIZE PAGE_SIZE -#define CHUNK_ALIGN(x) (((x)+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1)) - -/* - * The magic limit was calculated so that it allows the monitoring - * application to pick data once in two ticks. This way, another application, - * which presumably drives the bus, gets to hog CPU, yet we collect our data. - * If HZ is 100, a 480 mbit/s bus drives 614 KB every jiffy. USB has an - * enormous overhead built into the bus protocol, so we need about 1000 KB. - * - * This is still too much for most cases, where we just snoop a few - * descriptor fetches for enumeration. So, the default is a "reasonable" - * amount for systems with HZ=250 and incomplete bus saturation. - * - * XXX What about multi-megabyte URBs which take minutes to transfer? - */ -#define BUFF_MAX CHUNK_ALIGN(1200*1024) -#define BUFF_DFL CHUNK_ALIGN(300*1024) -#define BUFF_MIN CHUNK_ALIGN(8*1024) - -/* - * The per-event API header (2 per URB). - * - * This structure is seen in userland as defined by the documentation. - */ -struct mon_bin_hdr { - u64 id; /* URB ID - from submission to callback */ - unsigned char type; /* Same as in text API; extensible. */ - unsigned char xfer_type; /* ISO, Intr, Control, Bulk */ - unsigned char epnum; /* Endpoint number and transfer direction */ - unsigned char devnum; /* Device address */ - unsigned short busnum; /* Bus number */ - char flag_setup; - char flag_data; - s64 ts_sec; /* gettimeofday */ - s32 ts_usec; /* gettimeofday */ - int status; - unsigned int len_urb; /* Length of data (submitted or actual) */ - unsigned int len_cap; /* Delivered length */ - unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ -}; - -/* per file statistic */ -struct mon_bin_stats { - u32 queued; - u32 dropped; -}; - -struct mon_bin_get { - struct mon_bin_hdr __user *hdr; /* Only 48 bytes, not 64. */ - void __user *data; - size_t alloc; /* Length of data (can be zero) */ -}; - -struct mon_bin_mfetch { - u32 __user *offvec; /* Vector of events fetched */ - u32 nfetch; /* Number of events to fetch (out: fetched) */ - u32 nflush; /* Number of events to flush */ -}; - -#ifdef CONFIG_COMPAT -struct mon_bin_get32 { - u32 hdr32; - u32 data32; - u32 alloc32; -}; - -struct mon_bin_mfetch32 { - u32 offvec32; - u32 nfetch32; - u32 nflush32; -}; -#endif - -/* Having these two values same prevents wrapping of the mon_bin_hdr */ -#define PKT_ALIGN 64 -#define PKT_SIZE 64 - -/* max number of USB bus supported */ -#define MON_BIN_MAX_MINOR 128 - -/* - * The buffer: map of used pages. - */ -struct mon_pgmap { - struct page *pg; - unsigned char *ptr; /* XXX just use page_to_virt everywhere? */ -}; - -/* - * This gets associated with an open file struct. - */ -struct mon_reader_bin { - /* The buffer: one per open. */ - spinlock_t b_lock; /* Protect b_cnt, b_in */ - unsigned int b_size; /* Current size of the buffer - bytes */ - unsigned int b_cnt; /* Bytes used */ - unsigned int b_in, b_out; /* Offsets into buffer - bytes */ - unsigned int b_read; /* Amount of read data in curr. pkt. */ - struct mon_pgmap *b_vec; /* The map array */ - wait_queue_head_t b_wait; /* Wait for data here */ - - struct mutex fetch_lock; /* Protect b_read, b_out */ - int mmap_active; - - /* A list of these is needed for "bus 0". Some time later. */ - struct mon_reader r; - - /* Stats */ - unsigned int cnt_lost; -}; - -static inline struct mon_bin_hdr *MON_OFF2HDR(const struct mon_reader_bin *rp, - unsigned int offset) -{ - return (struct mon_bin_hdr *) - (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE); -} - -#define MON_RING_EMPTY(rp) ((rp)->b_cnt == 0) - -static dev_t mon_bin_dev0; -static struct cdev mon_bin_cdev; - -static void mon_buff_area_fill(const struct mon_reader_bin *rp, - unsigned int offset, unsigned int size); -static int mon_bin_wait_event(struct file *file, struct mon_reader_bin *rp); -static int mon_alloc_buff(struct mon_pgmap *map, int npages); -static void mon_free_buff(struct mon_pgmap *map, int npages); - -/* - * This is a "chunked memcpy". It does not manipulate any counters. - * But it returns the new offset for repeated application. - */ -unsigned int mon_copy_to_buff(const struct mon_reader_bin *this, - unsigned int off, const unsigned char *from, unsigned int length) -{ - unsigned int step_len; - unsigned char *buf; - unsigned int in_page; - - while (length) { - /* - * Determine step_len. - */ - step_len = length; - in_page = CHUNK_SIZE - (off & (CHUNK_SIZE-1)); - if (in_page < step_len) - step_len = in_page; - - /* - * Copy data and advance pointers. - */ - buf = this->b_vec[off / CHUNK_SIZE].ptr + off % CHUNK_SIZE; - memcpy(buf, from, step_len); - if ((off += step_len) >= this->b_size) off = 0; - from += step_len; - length -= step_len; - } - return off; -} - -/* - * This is a little worse than the above because it's "chunked copy_to_user". - * The return value is an error code, not an offset. - */ -static int copy_from_buf(const struct mon_reader_bin *this, unsigned int off, - char __user *to, int length) -{ - unsigned int step_len; - unsigned char *buf; - unsigned int in_page; - - while (length) { - /* - * Determine step_len. - */ - step_len = length; - in_page = CHUNK_SIZE - (off & (CHUNK_SIZE-1)); - if (in_page < step_len) - step_len = in_page; - - /* - * Copy data and advance pointers. - */ - buf = this->b_vec[off / CHUNK_SIZE].ptr + off % CHUNK_SIZE; - if (copy_to_user(to, buf, step_len)) - return -EINVAL; - if ((off += step_len) >= this->b_size) off = 0; - to += step_len; - length -= step_len; - } - return 0; -} - -/* - * Allocate an (aligned) area in the buffer. - * This is called under b_lock. - * Returns ~0 on failure. - */ -static unsigned int mon_buff_area_alloc(struct mon_reader_bin *rp, - unsigned int size) -{ - unsigned int offset; - - size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); - if (rp->b_cnt + size > rp->b_size) - return ~0; - offset = rp->b_in; - rp->b_cnt += size; - if ((rp->b_in += size) >= rp->b_size) - rp->b_in -= rp->b_size; - return offset; -} - -/* - * This is the same thing as mon_buff_area_alloc, only it does not allow - * buffers to wrap. This is needed by applications which pass references - * into mmap-ed buffers up their stacks (libpcap can do that). - * - * Currently, we always have the header stuck with the data, although - * it is not strictly speaking necessary. - * - * When a buffer would wrap, we place a filler packet to mark the space. - */ -static unsigned int mon_buff_area_alloc_contiguous(struct mon_reader_bin *rp, - unsigned int size) -{ - unsigned int offset; - unsigned int fill_size; - - size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); - if (rp->b_cnt + size > rp->b_size) - return ~0; - if (rp->b_in + size > rp->b_size) { - /* - * This would wrap. Find if we still have space after - * skipping to the end of the buffer. If we do, place - * a filler packet and allocate a new packet. - */ - fill_size = rp->b_size - rp->b_in; - if (rp->b_cnt + size + fill_size > rp->b_size) - return ~0; - mon_buff_area_fill(rp, rp->b_in, fill_size); - - offset = 0; - rp->b_in = size; - rp->b_cnt += size + fill_size; - } else if (rp->b_in + size == rp->b_size) { - offset = rp->b_in; - rp->b_in = 0; - rp->b_cnt += size; - } else { - offset = rp->b_in; - rp->b_in += size; - rp->b_cnt += size; - } - return offset; -} - -/* - * Return a few (kilo-)bytes to the head of the buffer. - * This is used if a DMA fetch fails. - */ -static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size) -{ - - size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); - rp->b_cnt -= size; - if (rp->b_in < size) - rp->b_in += rp->b_size; - rp->b_in -= size; -} - -/* - * This has to be called under both b_lock and fetch_lock, because - * it accesses both b_cnt and b_out. - */ -static void mon_buff_area_free(struct mon_reader_bin *rp, unsigned int size) -{ - - size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); - rp->b_cnt -= size; - if ((rp->b_out += size) >= rp->b_size) - rp->b_out -= rp->b_size; -} - -static void mon_buff_area_fill(const struct mon_reader_bin *rp, - unsigned int offset, unsigned int size) -{ - struct mon_bin_hdr *ep; - - ep = MON_OFF2HDR(rp, offset); - memset(ep, 0, PKT_SIZE); - ep->type = '@'; - ep->len_cap = size - PKT_SIZE; -} - -static inline char mon_bin_get_setup(unsigned char *setupb, - const struct urb *urb, char ev_type) -{ - - if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') - return '-'; - - if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP) - return mon_dmapeek(setupb, urb->setup_dma, SETUP_LEN); - if (urb->setup_packet == NULL) - return 'Z'; - - memcpy(setupb, urb->setup_packet, SETUP_LEN); - return 0; -} - -static char mon_bin_get_data(const struct mon_reader_bin *rp, - unsigned int offset, struct urb *urb, unsigned int length) -{ - - if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) { - mon_dmapeek_vec(rp, offset, urb->transfer_dma, length); - return 0; - } - - if (urb->transfer_buffer == NULL) - return 'Z'; - - mon_copy_to_buff(rp, offset, urb->transfer_buffer, length); - return 0; -} - -static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, - char ev_type) -{ - unsigned long flags; - struct timeval ts; - unsigned int urb_length; - unsigned int offset; - unsigned int length; - struct mon_bin_hdr *ep; - char data_tag = 0; - - do_gettimeofday(&ts); - - spin_lock_irqsave(&rp->b_lock, flags); - - /* - * Find the maximum allowable length, then allocate space. - */ - urb_length = (ev_type == 'S') ? - urb->transfer_buffer_length : urb->actual_length; - length = urb_length; - - if (length >= rp->b_size/5) - length = rp->b_size/5; - - if (usb_pipein(urb->pipe)) { - if (ev_type == 'S') { - length = 0; - data_tag = '<'; - } - } else { - if (ev_type == 'C') { - length = 0; - data_tag = '>'; - } - } - - if (rp->mmap_active) - offset = mon_buff_area_alloc_contiguous(rp, length + PKT_SIZE); - else - offset = mon_buff_area_alloc(rp, length + PKT_SIZE); - if (offset == ~0) { - rp->cnt_lost++; - spin_unlock_irqrestore(&rp->b_lock, flags); - return; - } - - ep = MON_OFF2HDR(rp, offset); - if ((offset += PKT_SIZE) >= rp->b_size) offset = 0; - - /* - * Fill the allocated area. - */ - memset(ep, 0, PKT_SIZE); - ep->type = ev_type; - ep->xfer_type = usb_pipetype(urb->pipe); - /* We use the fact that usb_pipein() returns 0x80 */ - ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); - ep->devnum = usb_pipedevice(urb->pipe); - ep->busnum = rp->r.m_bus->u_bus->busnum; - ep->id = (unsigned long) urb; - ep->ts_sec = ts.tv_sec; - ep->ts_usec = ts.tv_usec; - ep->status = urb->status; - ep->len_urb = urb_length; - ep->len_cap = length; - - ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type); - if (length != 0) { - ep->flag_data = mon_bin_get_data(rp, offset, urb, length); - if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ - ep->len_cap = 0; - mon_buff_area_shrink(rp, length); - } - } else { - ep->flag_data = data_tag; - } - - spin_unlock_irqrestore(&rp->b_lock, flags); - - wake_up(&rp->b_wait); -} - -static void mon_bin_submit(void *data, struct urb *urb) -{ - struct mon_reader_bin *rp = data; - mon_bin_event(rp, urb, 'S'); -} - -static void mon_bin_complete(void *data, struct urb *urb) -{ - struct mon_reader_bin *rp = data; - mon_bin_event(rp, urb, 'C'); -} - -static void mon_bin_error(void *data, struct urb *urb, int error) -{ - struct mon_reader_bin *rp = data; - unsigned long flags; - unsigned int offset; - struct mon_bin_hdr *ep; - - spin_lock_irqsave(&rp->b_lock, flags); - - offset = mon_buff_area_alloc(rp, PKT_SIZE); - if (offset == ~0) { - /* Not incrementing cnt_lost. Just because. */ - spin_unlock_irqrestore(&rp->b_lock, flags); - return; - } - - ep = MON_OFF2HDR(rp, offset); - - memset(ep, 0, PKT_SIZE); - ep->type = 'E'; - ep->xfer_type = usb_pipetype(urb->pipe); - /* We use the fact that usb_pipein() returns 0x80 */ - ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); - ep->devnum = usb_pipedevice(urb->pipe); - ep->busnum = rp->r.m_bus->u_bus->busnum; - ep->id = (unsigned long) urb; - ep->status = error; - - ep->flag_setup = '-'; - ep->flag_data = 'E'; - - spin_unlock_irqrestore(&rp->b_lock, flags); - - wake_up(&rp->b_wait); -} - -static int mon_bin_open(struct inode *inode, struct file *file) -{ - struct mon_bus *mbus; - struct usb_bus *ubus; - struct mon_reader_bin *rp; - size_t size; - int rc; - - mutex_lock(&mon_lock); - if ((mbus = mon_bus_lookup(iminor(inode))) == NULL) { - mutex_unlock(&mon_lock); - return -ENODEV; - } - if ((ubus = mbus->u_bus) == NULL) { - printk(KERN_ERR TAG ": consistency error on open\n"); - mutex_unlock(&mon_lock); - return -ENODEV; - } - - rp = kzalloc(sizeof(struct mon_reader_bin), GFP_KERNEL); - if (rp == NULL) { - rc = -ENOMEM; - goto err_alloc; - } - spin_lock_init(&rp->b_lock); - init_waitqueue_head(&rp->b_wait); - mutex_init(&rp->fetch_lock); - - rp->b_size = BUFF_DFL; - - size = sizeof(struct mon_pgmap) * (rp->b_size/CHUNK_SIZE); - if ((rp->b_vec = kzalloc(size, GFP_KERNEL)) == NULL) { - rc = -ENOMEM; - goto err_allocvec; - } - - if ((rc = mon_alloc_buff(rp->b_vec, rp->b_size/CHUNK_SIZE)) < 0) - goto err_allocbuff; - - rp->r.m_bus = mbus; - rp->r.r_data = rp; - rp->r.rnf_submit = mon_bin_submit; - rp->r.rnf_error = mon_bin_error; - rp->r.rnf_complete = mon_bin_complete; - - mon_reader_add(mbus, &rp->r); - - file->private_data = rp; - mutex_unlock(&mon_lock); - return 0; - -err_allocbuff: - kfree(rp->b_vec); -err_allocvec: - kfree(rp); -err_alloc: - mutex_unlock(&mon_lock); - return rc; -} - -/* - * Extract an event from buffer and copy it to user space. - * Wait if there is no event ready. - * Returns zero or error. - */ -static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, - struct mon_bin_hdr __user *hdr, void __user *data, unsigned int nbytes) -{ - unsigned long flags; - struct mon_bin_hdr *ep; - size_t step_len; - unsigned int offset; - int rc; - - mutex_lock(&rp->fetch_lock); - - if ((rc = mon_bin_wait_event(file, rp)) < 0) { - mutex_unlock(&rp->fetch_lock); - return rc; - } - - ep = MON_OFF2HDR(rp, rp->b_out); - - if (copy_to_user(hdr, ep, sizeof(struct mon_bin_hdr))) { - mutex_unlock(&rp->fetch_lock); - return -EFAULT; - } - - step_len = min(ep->len_cap, nbytes); - if ((offset = rp->b_out + PKT_SIZE) >= rp->b_size) offset = 0; - - if (copy_from_buf(rp, offset, data, step_len)) { - mutex_unlock(&rp->fetch_lock); - return -EFAULT; - } - - spin_lock_irqsave(&rp->b_lock, flags); - mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); - spin_unlock_irqrestore(&rp->b_lock, flags); - rp->b_read = 0; - - mutex_unlock(&rp->fetch_lock); - return 0; -} - -static int mon_bin_release(struct inode *inode, struct file *file) -{ - struct mon_reader_bin *rp = file->private_data; - struct mon_bus* mbus = rp->r.m_bus; - - mutex_lock(&mon_lock); - - if (mbus->nreaders <= 0) { - printk(KERN_ERR TAG ": consistency error on close\n"); - mutex_unlock(&mon_lock); - return 0; - } - mon_reader_del(mbus, &rp->r); - - mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE); - kfree(rp->b_vec); - kfree(rp); - - mutex_unlock(&mon_lock); - return 0; -} - -static ssize_t mon_bin_read(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) -{ - struct mon_reader_bin *rp = file->private_data; - unsigned long flags; - struct mon_bin_hdr *ep; - unsigned int offset; - size_t step_len; - char *ptr; - ssize_t done = 0; - int rc; - - mutex_lock(&rp->fetch_lock); - - if ((rc = mon_bin_wait_event(file, rp)) < 0) { - mutex_unlock(&rp->fetch_lock); - return rc; - } - - ep = MON_OFF2HDR(rp, rp->b_out); - - if (rp->b_read < sizeof(struct mon_bin_hdr)) { - step_len = min(nbytes, sizeof(struct mon_bin_hdr) - rp->b_read); - ptr = ((char *)ep) + rp->b_read; - if (step_len && copy_to_user(buf, ptr, step_len)) { - mutex_unlock(&rp->fetch_lock); - return -EFAULT; - } - nbytes -= step_len; - buf += step_len; - rp->b_read += step_len; - done += step_len; - } - - if (rp->b_read >= sizeof(struct mon_bin_hdr)) { - step_len = min(nbytes, (size_t)ep->len_cap); - offset = rp->b_out + PKT_SIZE; - offset += rp->b_read - sizeof(struct mon_bin_hdr); - if (offset >= rp->b_size) - offset -= rp->b_size; - if (copy_from_buf(rp, offset, buf, step_len)) { - mutex_unlock(&rp->fetch_lock); - return -EFAULT; - } - nbytes -= step_len; - buf += step_len; - rp->b_read += step_len; - done += step_len; - } - - /* - * Check if whole packet was read, and if so, jump to the next one. - */ - if (rp->b_read >= sizeof(struct mon_bin_hdr) + ep->len_cap) { - spin_lock_irqsave(&rp->b_lock, flags); - mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); - spin_unlock_irqrestore(&rp->b_lock, flags); - rp->b_read = 0; - } - - mutex_unlock(&rp->fetch_lock); - return done; -} - -/* - * Remove at most nevents from chunked buffer. - * Returns the number of removed events. - */ -static int mon_bin_flush(struct mon_reader_bin *rp, unsigned nevents) -{ - unsigned long flags; - struct mon_bin_hdr *ep; - int i; - - mutex_lock(&rp->fetch_lock); - spin_lock_irqsave(&rp->b_lock, flags); - for (i = 0; i < nevents; ++i) { - if (MON_RING_EMPTY(rp)) - break; - - ep = MON_OFF2HDR(rp, rp->b_out); - mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); - } - spin_unlock_irqrestore(&rp->b_lock, flags); - rp->b_read = 0; - mutex_unlock(&rp->fetch_lock); - return i; -} - -/* - * Fetch at most max event offsets into the buffer and put them into vec. - * The events are usually freed later with mon_bin_flush. - * Return the effective number of events fetched. - */ -static int mon_bin_fetch(struct file *file, struct mon_reader_bin *rp, - u32 __user *vec, unsigned int max) -{ - unsigned int cur_out; - unsigned int bytes, avail; - unsigned int size; - unsigned int nevents; - struct mon_bin_hdr *ep; - unsigned long flags; - int rc; - - mutex_lock(&rp->fetch_lock); - - if ((rc = mon_bin_wait_event(file, rp)) < 0) { - mutex_unlock(&rp->fetch_lock); - return rc; - } - - spin_lock_irqsave(&rp->b_lock, flags); - avail = rp->b_cnt; - spin_unlock_irqrestore(&rp->b_lock, flags); - - cur_out = rp->b_out; - nevents = 0; - bytes = 0; - while (bytes < avail) { - if (nevents >= max) - break; - - ep = MON_OFF2HDR(rp, cur_out); - if (put_user(cur_out, &vec[nevents])) { - mutex_unlock(&rp->fetch_lock); - return -EFAULT; - } - - nevents++; - size = ep->len_cap + PKT_SIZE; - size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); - if ((cur_out += size) >= rp->b_size) - cur_out -= rp->b_size; - bytes += size; - } - - mutex_unlock(&rp->fetch_lock); - return nevents; -} - -/* - * Count events. This is almost the same as the above mon_bin_fetch, - * only we do not store offsets into user vector, and we have no limit. - */ -static int mon_bin_queued(struct mon_reader_bin *rp) -{ - unsigned int cur_out; - unsigned int bytes, avail; - unsigned int size; - unsigned int nevents; - struct mon_bin_hdr *ep; - unsigned long flags; - - mutex_lock(&rp->fetch_lock); - - spin_lock_irqsave(&rp->b_lock, flags); - avail = rp->b_cnt; - spin_unlock_irqrestore(&rp->b_lock, flags); - - cur_out = rp->b_out; - nevents = 0; - bytes = 0; - while (bytes < avail) { - ep = MON_OFF2HDR(rp, cur_out); - - nevents++; - size = ep->len_cap + PKT_SIZE; - size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); - if ((cur_out += size) >= rp->b_size) - cur_out -= rp->b_size; - bytes += size; - } - - mutex_unlock(&rp->fetch_lock); - return nevents; -} - -/* - */ -static int mon_bin_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct mon_reader_bin *rp = file->private_data; - // struct mon_bus* mbus = rp->r.m_bus; - int ret = 0; - struct mon_bin_hdr *ep; - unsigned long flags; - - switch (cmd) { - - case MON_IOCQ_URB_LEN: - /* - * N.B. This only returns the size of data, without the header. - */ - spin_lock_irqsave(&rp->b_lock, flags); - if (!MON_RING_EMPTY(rp)) { - ep = MON_OFF2HDR(rp, rp->b_out); - ret = ep->len_cap; - } - spin_unlock_irqrestore(&rp->b_lock, flags); - break; - - case MON_IOCQ_RING_SIZE: - ret = rp->b_size; - break; - - case MON_IOCT_RING_SIZE: - /* - * Changing the buffer size will flush it's contents; the new - * buffer is allocated before releasing the old one to be sure - * the device will stay functional also in case of memory - * pressure. - */ - { - int size; - struct mon_pgmap *vec; - - if (arg < BUFF_MIN || arg > BUFF_MAX) - return -EINVAL; - - size = CHUNK_ALIGN(arg); - if ((vec = kzalloc(sizeof(struct mon_pgmap) * (size/CHUNK_SIZE), - GFP_KERNEL)) == NULL) { - ret = -ENOMEM; - break; - } - - ret = mon_alloc_buff(vec, size/CHUNK_SIZE); - if (ret < 0) { - kfree(vec); - break; - } - - mutex_lock(&rp->fetch_lock); - spin_lock_irqsave(&rp->b_lock, flags); - mon_free_buff(rp->b_vec, size/CHUNK_SIZE); - kfree(rp->b_vec); - rp->b_vec = vec; - rp->b_size = size; - rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0; - rp->cnt_lost = 0; - spin_unlock_irqrestore(&rp->b_lock, flags); - mutex_unlock(&rp->fetch_lock); - } - break; - - case MON_IOCH_MFLUSH: - ret = mon_bin_flush(rp, arg); - break; - - case MON_IOCX_GET: - { - struct mon_bin_get getb; - - if (copy_from_user(&getb, (void __user *)arg, - sizeof(struct mon_bin_get))) - return -EFAULT; - - if (getb.alloc > 0x10000000) /* Want to cast to u32 */ - return -EINVAL; - ret = mon_bin_get_event(file, rp, - getb.hdr, getb.data, (unsigned int)getb.alloc); - } - break; - -#ifdef CONFIG_COMPAT - case MON_IOCX_GET32: { - struct mon_bin_get32 getb; - - if (copy_from_user(&getb, (void __user *)arg, - sizeof(struct mon_bin_get32))) - return -EFAULT; - - ret = mon_bin_get_event(file, rp, - compat_ptr(getb.hdr32), compat_ptr(getb.data32), - getb.alloc32); - } - break; -#endif - - case MON_IOCX_MFETCH: - { - struct mon_bin_mfetch mfetch; - struct mon_bin_mfetch __user *uptr; - - uptr = (struct mon_bin_mfetch __user *)arg; - - if (copy_from_user(&mfetch, uptr, sizeof(mfetch))) - return -EFAULT; - - if (mfetch.nflush) { - ret = mon_bin_flush(rp, mfetch.nflush); - if (ret < 0) - return ret; - if (put_user(ret, &uptr->nflush)) - return -EFAULT; - } - ret = mon_bin_fetch(file, rp, mfetch.offvec, mfetch.nfetch); - if (ret < 0) - return ret; - if (put_user(ret, &uptr->nfetch)) - return -EFAULT; - ret = 0; - } - break; - -#ifdef CONFIG_COMPAT - case MON_IOCX_MFETCH32: - { - struct mon_bin_mfetch32 mfetch; - struct mon_bin_mfetch32 __user *uptr; - - uptr = (struct mon_bin_mfetch32 __user *) compat_ptr(arg); - - if (copy_from_user(&mfetch, uptr, sizeof(mfetch))) - return -EFAULT; - - if (mfetch.nflush32) { - ret = mon_bin_flush(rp, mfetch.nflush32); - if (ret < 0) - return ret; - if (put_user(ret, &uptr->nflush32)) - return -EFAULT; - } - ret = mon_bin_fetch(file, rp, compat_ptr(mfetch.offvec32), - mfetch.nfetch32); - if (ret < 0) - return ret; - if (put_user(ret, &uptr->nfetch32)) - return -EFAULT; - ret = 0; - } - break; -#endif - - case MON_IOCG_STATS: { - struct mon_bin_stats __user *sp; - unsigned int nevents; - unsigned int ndropped; - - spin_lock_irqsave(&rp->b_lock, flags); - ndropped = rp->cnt_lost; - rp->cnt_lost = 0; - spin_unlock_irqrestore(&rp->b_lock, flags); - nevents = mon_bin_queued(rp); - - sp = (struct mon_bin_stats __user *)arg; - if (put_user(rp->cnt_lost, &sp->dropped)) - return -EFAULT; - if (put_user(nevents, &sp->queued)) - return -EFAULT; - - } - break; - - default: - return -ENOTTY; - } - - return ret; -} - -static unsigned int -mon_bin_poll(struct file *file, struct poll_table_struct *wait) -{ - struct mon_reader_bin *rp = file->private_data; - unsigned int mask = 0; - unsigned long flags; - - if (file->f_mode & FMODE_READ) - poll_wait(file, &rp->b_wait, wait); - - spin_lock_irqsave(&rp->b_lock, flags); - if (!MON_RING_EMPTY(rp)) - mask |= POLLIN | POLLRDNORM; /* readable */ - spin_unlock_irqrestore(&rp->b_lock, flags); - return mask; -} - -/* - * open and close: just keep track of how many times the device is - * mapped, to use the proper memory allocation function. - */ -static void mon_bin_vma_open(struct vm_area_struct *vma) -{ - struct mon_reader_bin *rp = vma->vm_private_data; - rp->mmap_active++; -} - -static void mon_bin_vma_close(struct vm_area_struct *vma) -{ - struct mon_reader_bin *rp = vma->vm_private_data; - rp->mmap_active--; -} - -/* - * Map ring pages to user space. - */ -struct page *mon_bin_vma_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - struct mon_reader_bin *rp = vma->vm_private_data; - unsigned long offset, chunk_idx; - struct page *pageptr; - - offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); - if (offset >= rp->b_size) - return NOPAGE_SIGBUS; - chunk_idx = offset / CHUNK_SIZE; - pageptr = rp->b_vec[chunk_idx].pg; - get_page(pageptr); - if (type) - *type = VM_FAULT_MINOR; - return pageptr; -} - -struct vm_operations_struct mon_bin_vm_ops = { - .open = mon_bin_vma_open, - .close = mon_bin_vma_close, - .nopage = mon_bin_vma_nopage, -}; - -int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) -{ - /* don't do anything here: "nopage" will set up page table entries */ - vma->vm_ops = &mon_bin_vm_ops; - vma->vm_flags |= VM_RESERVED; - vma->vm_private_data = filp->private_data; - mon_bin_vma_open(vma); - return 0; -} - -struct file_operations mon_fops_binary = { - .owner = THIS_MODULE, - .open = mon_bin_open, - .llseek = no_llseek, - .read = mon_bin_read, - /* .write = mon_text_write, */ - .poll = mon_bin_poll, - .ioctl = mon_bin_ioctl, - .release = mon_bin_release, -}; - -static int mon_bin_wait_event(struct file *file, struct mon_reader_bin *rp) -{ - DECLARE_WAITQUEUE(waita, current); - unsigned long flags; - - add_wait_queue(&rp->b_wait, &waita); - set_current_state(TASK_INTERRUPTIBLE); - - spin_lock_irqsave(&rp->b_lock, flags); - while (MON_RING_EMPTY(rp)) { - spin_unlock_irqrestore(&rp->b_lock, flags); - - if (file->f_flags & O_NONBLOCK) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&rp->b_wait, &waita); - return -EWOULDBLOCK; /* Same as EAGAIN in Linux */ - } - schedule(); - if (signal_pending(current)) { - remove_wait_queue(&rp->b_wait, &waita); - return -EINTR; - } - set_current_state(TASK_INTERRUPTIBLE); - - spin_lock_irqsave(&rp->b_lock, flags); - } - spin_unlock_irqrestore(&rp->b_lock, flags); - - set_current_state(TASK_RUNNING); - remove_wait_queue(&rp->b_wait, &waita); - return 0; -} - -static int mon_alloc_buff(struct mon_pgmap *map, int npages) -{ - int n; - unsigned long vaddr; - - for (n = 0; n < npages; n++) { - vaddr = get_zeroed_page(GFP_KERNEL); - if (vaddr == 0) { - while (n-- != 0) - free_page((unsigned long) map[n].ptr); - return -ENOMEM; - } - map[n].ptr = (unsigned char *) vaddr; - map[n].pg = virt_to_page(vaddr); - } - return 0; -} - -static void mon_free_buff(struct mon_pgmap *map, int npages) -{ - int n; - - for (n = 0; n < npages; n++) - free_page((unsigned long) map[n].ptr); -} - -int __init mon_bin_init(void) -{ - int rc; - - rc = alloc_chrdev_region(&mon_bin_dev0, 0, MON_BIN_MAX_MINOR, "usbmon"); - if (rc < 0) - goto err_dev; - - cdev_init(&mon_bin_cdev, &mon_fops_binary); - mon_bin_cdev.owner = THIS_MODULE; - - rc = cdev_add(&mon_bin_cdev, mon_bin_dev0, MON_BIN_MAX_MINOR); - if (rc < 0) - goto err_add; - - return 0; - -err_add: - unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR); -err_dev: - return rc; -} - -void __exit mon_bin_exit(void) -{ - cdev_del(&mon_bin_cdev); - unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR); -} diff --git a/trunk/drivers/usb/mon/mon_dma.c b/trunk/drivers/usb/mon/mon_dma.c index 140cc80bd2b1..ddcfc01e77a0 100644 --- a/trunk/drivers/usb/mon/mon_dma.c +++ b/trunk/drivers/usb/mon/mon_dma.c @@ -48,36 +48,6 @@ char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len) local_irq_restore(flags); return 0; } - -void mon_dmapeek_vec(const struct mon_reader_bin *rp, - unsigned int offset, dma_addr_t dma_addr, unsigned int length) -{ - unsigned long flags; - unsigned int step_len; - struct page *pg; - unsigned char *map; - unsigned long page_off, page_len; - - local_irq_save(flags); - while (length) { - /* compute number of bytes we are going to copy in this page */ - step_len = length; - page_off = dma_addr & (PAGE_SIZE-1); - page_len = PAGE_SIZE - page_off; - if (page_len < step_len) - step_len = page_len; - - /* copy data and advance pointers */ - pg = phys_to_page(dma_addr); - map = kmap_atomic(pg, KM_IRQ0); - offset = mon_copy_to_buff(rp, offset, map + page_off, step_len); - kunmap_atomic(map, KM_IRQ0); - dma_addr += step_len; - length -= step_len; - } - local_irq_restore(flags); -} - #endif /* __i386__ */ #ifndef MON_HAS_UNMAP @@ -85,11 +55,4 @@ char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len) { return 'D'; } - -void mon_dmapeek_vec(const struct mon_reader_bin *rp, - unsigned int offset, dma_addr_t dma_addr, unsigned int length) -{ - ; -} - -#endif /* MON_HAS_UNMAP */ +#endif diff --git a/trunk/drivers/usb/mon/mon_main.c b/trunk/drivers/usb/mon/mon_main.c index c9739e7b35e5..394bbf2f68d4 100644 --- a/trunk/drivers/usb/mon/mon_main.c +++ b/trunk/drivers/usb/mon/mon_main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -21,10 +22,11 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb); static void mon_stop(struct mon_bus *mbus); static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); static void mon_bus_drop(struct kref *r); -static void mon_bus_init(struct usb_bus *ubus); +static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus); DEFINE_MUTEX(mon_lock); +static struct dentry *mon_dir; /* /dbg/usbmon */ static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ /* @@ -198,7 +200,7 @@ static void mon_stop(struct mon_bus *mbus) */ static void mon_bus_add(struct usb_bus *ubus) { - mon_bus_init(ubus); + mon_bus_init(mon_dir, ubus); } /* @@ -210,8 +212,8 @@ static void mon_bus_remove(struct usb_bus *ubus) mutex_lock(&mon_lock); list_del(&mbus->bus_link); - if (mbus->text_inited) - mon_text_del(mbus); + debugfs_remove(mbus->dent_t); + debugfs_remove(mbus->dent_s); mon_dissolve(mbus, ubus); kref_put(&mbus->ref, mon_bus_drop); @@ -279,9 +281,13 @@ static void mon_bus_drop(struct kref *r) * - refcount USB bus struct * - link */ -static void mon_bus_init(struct usb_bus *ubus) +static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) { + struct dentry *d; struct mon_bus *mbus; + enum { NAMESZ = 10 }; + char name[NAMESZ]; + int rc; if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) goto err_alloc; @@ -297,54 +303,57 @@ static void mon_bus_init(struct usb_bus *ubus) ubus->mon_bus = mbus; mbus->uses_dma = ubus->uses_dma; - mbus->text_inited = mon_text_add(mbus, ubus); - // mon_bin_add(...) + rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); + if (rc <= 0 || rc >= NAMESZ) + goto err_print_t; + d = debugfs_create_file(name, 0600, mondir, mbus, &mon_fops_text); + if (d == NULL) + goto err_create_t; + mbus->dent_t = d; + + rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); + if (rc <= 0 || rc >= NAMESZ) + goto err_print_s; + d = debugfs_create_file(name, 0600, mondir, mbus, &mon_fops_stat); + if (d == NULL) + goto err_create_s; + mbus->dent_s = d; mutex_lock(&mon_lock); list_add_tail(&mbus->bus_link, &mon_buses); mutex_unlock(&mon_lock); return; +err_create_s: +err_print_s: + debugfs_remove(mbus->dent_t); +err_create_t: +err_print_t: + kfree(mbus); err_alloc: return; } -/* - * Search a USB bus by number. Notice that USB bus numbers start from one, - * which we may later use to identify "all" with zero. - * - * This function must be called with mon_lock held. - * - * This is obviously inefficient and may be revised in the future. - */ -struct mon_bus *mon_bus_lookup(unsigned int num) -{ - struct list_head *p; - struct mon_bus *mbus; - - list_for_each (p, &mon_buses) { - mbus = list_entry(p, struct mon_bus, bus_link); - if (mbus->u_bus->busnum == num) { - return mbus; - } - } - return NULL; -} - static int __init mon_init(void) { struct usb_bus *ubus; - int rc; + struct dentry *mondir; - if ((rc = mon_text_init()) != 0) - goto err_text; - if ((rc = mon_bin_init()) != 0) - goto err_bin; + mondir = debugfs_create_dir("usbmon", NULL); + if (IS_ERR(mondir)) { + printk(KERN_NOTICE TAG ": debugfs is not available\n"); + return -ENODEV; + } + if (mondir == NULL) { + printk(KERN_NOTICE TAG ": unable to create usbmon directory\n"); + return -ENODEV; + } + mon_dir = mondir; if (usb_mon_register(&mon_ops_0) != 0) { printk(KERN_NOTICE TAG ": unable to register with the core\n"); - rc = -ENODEV; - goto err_reg; + debugfs_remove(mondir); + return -ENODEV; } // MOD_INC_USE_COUNT(which_module?); @@ -352,17 +361,10 @@ static int __init mon_init(void) mutex_lock(&usb_bus_list_lock); list_for_each_entry (ubus, &usb_bus_list, bus_list) { - mon_bus_init(ubus); + mon_bus_init(mondir, ubus); } mutex_unlock(&usb_bus_list_lock); return 0; - -err_reg: - mon_bin_exit(); -err_bin: - mon_text_exit(); -err_text: - return rc; } static void __exit mon_exit(void) @@ -379,8 +381,8 @@ static void __exit mon_exit(void) mbus = list_entry(p, struct mon_bus, bus_link); list_del(p); - if (mbus->text_inited) - mon_text_del(mbus); + debugfs_remove(mbus->dent_t); + debugfs_remove(mbus->dent_s); /* * This never happens, because the open/close paths in @@ -399,8 +401,7 @@ static void __exit mon_exit(void) } mutex_unlock(&mon_lock); - mon_text_exit(); - mon_bin_exit(); + debugfs_remove(mon_dir); } module_init(mon_init); diff --git a/trunk/drivers/usb/mon/mon_text.c b/trunk/drivers/usb/mon/mon_text.c index d38a1279d9d9..05cf2c9a8f84 100644 --- a/trunk/drivers/usb/mon/mon_text.c +++ b/trunk/drivers/usb/mon/mon_text.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include "usb_mon.h" @@ -64,8 +63,6 @@ struct mon_reader_text { char slab_name[SLAB_NAME_SZ]; }; -static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */ - static void mon_text_ctor(void *, struct kmem_cache *, unsigned long); /* @@ -439,7 +436,7 @@ static int mon_text_release(struct inode *inode, struct file *file) return 0; } -static const struct file_operations mon_fops_text = { +const struct file_operations mon_fops_text = { .owner = THIS_MODULE, .open = mon_text_open, .llseek = no_llseek, @@ -450,47 +447,6 @@ static const struct file_operations mon_fops_text = { .release = mon_text_release, }; -int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus) -{ - struct dentry *d; - enum { NAMESZ = 10 }; - char name[NAMESZ]; - int rc; - - rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); - if (rc <= 0 || rc >= NAMESZ) - goto err_print_t; - d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text); - if (d == NULL) - goto err_create_t; - mbus->dent_t = d; - - /* XXX The stats do not belong to here (text API), but oh well... */ - rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); - if (rc <= 0 || rc >= NAMESZ) - goto err_print_s; - d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat); - if (d == NULL) - goto err_create_s; - mbus->dent_s = d; - - return 1; - -err_create_s: -err_print_s: - debugfs_remove(mbus->dent_t); - mbus->dent_t = NULL; -err_create_t: -err_print_t: - return 0; -} - -void mon_text_del(struct mon_bus *mbus) -{ - debugfs_remove(mbus->dent_t); - debugfs_remove(mbus->dent_s); -} - /* * Slab interface: constructor. */ @@ -503,24 +459,3 @@ static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sfla memset(mem, 0xe5, sizeof(struct mon_event_text)); } -int __init mon_text_init(void) -{ - struct dentry *mondir; - - mondir = debugfs_create_dir("usbmon", NULL); - if (IS_ERR(mondir)) { - printk(KERN_NOTICE TAG ": debugfs is not available\n"); - return -ENODEV; - } - if (mondir == NULL) { - printk(KERN_NOTICE TAG ": unable to create usbmon directory\n"); - return -ENODEV; - } - mon_dir = mondir; - return 0; -} - -void __exit mon_text_exit(void) -{ - debugfs_remove(mon_dir); -} diff --git a/trunk/drivers/usb/mon/usb_mon.h b/trunk/drivers/usb/mon/usb_mon.h index 4f949ce8a7f3..ab9d02d5df77 100644 --- a/trunk/drivers/usb/mon/usb_mon.h +++ b/trunk/drivers/usb/mon/usb_mon.h @@ -17,11 +17,9 @@ struct mon_bus { struct list_head bus_link; spinlock_t lock; - struct usb_bus *u_bus; - - int text_inited; struct dentry *dent_s; /* Debugging file */ struct dentry *dent_t; /* Text interface file */ + struct usb_bus *u_bus; int uses_dma; /* Ref */ @@ -50,35 +48,13 @@ struct mon_reader { void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); -struct mon_bus *mon_bus_lookup(unsigned int num); - -int /*bool*/ mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus); -void mon_text_del(struct mon_bus *mbus); -// void mon_bin_add(struct mon_bus *); - -int __init mon_text_init(void); -void __exit mon_text_exit(void); -int __init mon_bin_init(void); -void __exit mon_bin_exit(void); - /* - * DMA interface. - * - * XXX The vectored side needs a serious re-thinking. Abstracting vectors, - * like in Paolo's original patch, produces a double pkmap. We need an idea. -*/ + */ extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len); -struct mon_reader_bin; -extern void mon_dmapeek_vec(const struct mon_reader_bin *rp, - unsigned int offset, dma_addr_t dma_addr, unsigned int len); -extern unsigned int mon_copy_to_buff(const struct mon_reader_bin *rp, - unsigned int offset, const unsigned char *from, unsigned int len); - -/* - */ extern struct mutex mon_lock; +extern const struct file_operations mon_fops_text; extern const struct file_operations mon_fops_stat; #endif /* __USB_MON_H */ diff --git a/trunk/drivers/usb/net/Kconfig b/trunk/drivers/usb/net/Kconfig index a2b94ef512bc..e081836014ac 100644 --- a/trunk/drivers/usb/net/Kconfig +++ b/trunk/drivers/usb/net/Kconfig @@ -222,15 +222,13 @@ config USB_NET_MCS7830 adapters marketed under the DeLOCK brand. config USB_NET_RNDIS_HOST - tristate "Host for RNDIS and ActiveSync devices (EXPERIMENTAL)" + tristate "Host for RNDIS devices (EXPERIMENTAL)" depends on USB_USBNET && EXPERIMENTAL select USB_NET_CDCETHER help This option enables hosting "Remote NDIS" USB networking links, as encouraged by Microsoft (instead of CDC Ethernet!) for use in - various devices that may only support this protocol. A variant - of this protocol (with even less public documentation) seems to - be at the root of Microsoft's "ActiveSync" too. + various devices that may only support this protocol. Avoid using this protocol unless you have no better options. The protocol specification is incomplete, and is controlled by diff --git a/trunk/drivers/usb/net/asix.c b/trunk/drivers/usb/net/asix.c index 4206df2d61b7..896449f0cf85 100644 --- a/trunk/drivers/usb/net/asix.c +++ b/trunk/drivers/usb/net/asix.c @@ -1449,10 +1449,6 @@ static const struct usb_device_id products [] = { // Linksys USB1000 USB_DEVICE (0x1737, 0x0039), .driver_info = (unsigned long) &ax88178_info, -}, { - // IO-DATA ETG-US2 - USB_DEVICE (0x04bb, 0x0930), - .driver_info = (unsigned long) &ax88178_info, }, { }, // END }; diff --git a/trunk/drivers/usb/net/cdc_ether.c b/trunk/drivers/usb/net/cdc_ether.c index e5cdafa258dd..44a91547146e 100644 --- a/trunk/drivers/usb/net/cdc_ether.c +++ b/trunk/drivers/usb/net/cdc_ether.c @@ -1,7 +1,6 @@ /* * CDC Ethernet based networking peripherals * Copyright (C) 2003-2005 by David Brownell - * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,29 +35,6 @@ #include "usbnet.h" -#if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) - -static int is_rndis(struct usb_interface_descriptor *desc) -{ - return desc->bInterfaceClass == USB_CLASS_COMM - && desc->bInterfaceSubClass == 2 - && desc->bInterfaceProtocol == 0xff; -} - -static int is_activesync(struct usb_interface_descriptor *desc) -{ - return desc->bInterfaceClass == USB_CLASS_MISC - && desc->bInterfaceSubClass == 1 - && desc->bInterfaceProtocol == 1; -} - -#else - -#define is_rndis(desc) 0 -#define is_activesync(desc) 0 - -#endif - /* * probes control interface, claims data interface, collects the bulk * endpoints, activates data interface (if needed), maybe sets MTU. @@ -95,8 +71,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) /* this assumes that if there's a non-RNDIS vendor variant * of cdc-acm, it'll fail RNDIS requests cleanly. */ - rndis = is_rndis(&intf->cur_altsetting->desc) - || is_activesync(&intf->cur_altsetting->desc); + rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff); memset(info, 0, sizeof *info); info->control = intf; @@ -124,23 +99,6 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) goto bad_desc; } break; - case USB_CDC_ACM_TYPE: - /* paranoia: disambiguate a "real" vendor-specific - * modem interface from an RNDIS non-modem. - */ - if (rndis) { - struct usb_cdc_acm_descriptor *d; - - d = (void *) buf; - if (d->bmCapabilities) { - dev_dbg(&intf->dev, - "ACM capabilities %02x, " - "not really RNDIS?\n", - d->bmCapabilities); - goto bad_desc; - } - } - break; case USB_CDC_UNION_TYPE: if (info->u) { dev_dbg(&intf->dev, "extra CDC union\n"); @@ -213,21 +171,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) buf += buf [0]; } - /* Microsoft ActiveSync based RNDIS devices lack the CDC descriptors, - * so we'll hard-wire the interfaces and not check for descriptors. - */ - if (is_activesync(&intf->cur_altsetting->desc) && !info->u) { - info->control = usb_ifnum_to_if(dev->udev, 0); - info->data = usb_ifnum_to_if(dev->udev, 1); - if (!info->control || !info->data) { - dev_dbg(&intf->dev, - "activesync: master #0/%p slave #1/%p\n", - info->control, - info->data); - goto bad_desc; - } - - } else if (!info->header || !info->u || (!rndis && !info->ether)) { + if (!info->header || !info->u || (!rndis && !info->ether)) { dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n", info->header ? "" : "header ", info->u ? "" : "union ", diff --git a/trunk/drivers/usb/net/kaweth.c b/trunk/drivers/usb/net/kaweth.c index 36a989160a68..fa78326d0bf0 100644 --- a/trunk/drivers/usb/net/kaweth.c +++ b/trunk/drivers/usb/net/kaweth.c @@ -179,7 +179,6 @@ static struct usb_driver kaweth_driver = { .suspend = kaweth_suspend, .resume = kaweth_resume, .id_table = usb_klsi_table, - .supports_autosuspend = 1, }; typedef __u8 eth_addr_t[6]; @@ -226,7 +225,6 @@ struct kaweth_device struct delayed_work lowmem_work; struct usb_device *dev; - struct usb_interface *intf; struct net_device *net; wait_queue_head_t term_wait; @@ -664,14 +662,9 @@ static int kaweth_open(struct net_device *net) dbg("Opening network device."); - res = usb_autopm_get_interface(kaweth->intf); - if (res) { - err("Interface cannot be resumed."); - return -EIO; - } res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); if (res) - goto err_out; + return -EIO; usb_fill_int_urb( kaweth->irq_urb, @@ -688,7 +681,7 @@ static int kaweth_open(struct net_device *net) res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL); if (res) { usb_kill_urb(kaweth->rx_urb); - goto err_out; + return -EIO; } kaweth->opened = 1; @@ -696,14 +689,10 @@ static int kaweth_open(struct net_device *net) kaweth_async_set_rx_mode(kaweth); return 0; - -err_out: - usb_autopm_enable(kaweth->intf); - return -EIO; } /**************************************************************** - * kaweth_kill_urbs + * kaweth_close ****************************************************************/ static void kaweth_kill_urbs(struct kaweth_device *kaweth) { @@ -735,29 +724,17 @@ static int kaweth_close(struct net_device *net) kaweth->status &= ~KAWETH_STATUS_CLOSING; - usb_autopm_enable(kaweth->intf); - return 0; } static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct kaweth_device *kaweth = netdev_priv(dev); strlcpy(info->driver, driver_name, sizeof(info->driver)); - usb_make_path(kaweth->dev, info->bus_info, sizeof (info->bus_info)); -} - -static u32 kaweth_get_link(struct net_device *dev) -{ - struct kaweth_device *kaweth = netdev_priv(dev); - - return kaweth->linkstate; } static struct ethtool_ops ops = { - .get_drvinfo = kaweth_get_drvinfo, - .get_link = kaweth_get_link + .get_drvinfo = kaweth_get_drvinfo }; /**************************************************************** @@ -931,7 +908,6 @@ static int kaweth_suspend(struct usb_interface *intf, pm_message_t message) struct kaweth_device *kaweth = usb_get_intfdata(intf); unsigned long flags; - dbg("Suspending device"); spin_lock_irqsave(&kaweth->device_lock, flags); kaweth->status |= KAWETH_STATUS_SUSPENDING; spin_unlock_irqrestore(&kaweth->device_lock, flags); @@ -948,7 +924,6 @@ static int kaweth_resume(struct usb_interface *intf) struct kaweth_device *kaweth = usb_get_intfdata(intf); unsigned long flags; - dbg("Resuming device"); spin_lock_irqsave(&kaweth->device_lock, flags); kaweth->status &= ~KAWETH_STATUS_SUSPENDING; spin_unlock_irqrestore(&kaweth->device_lock, flags); @@ -1111,8 +1086,6 @@ static int kaweth_probe( dbg("Initializing net device."); - kaweth->intf = intf; - kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!kaweth->tx_urb) goto err_free_netdev; @@ -1292,7 +1265,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, { struct urb *urb; int retv; - int length = 0; /* shut up GCC */ + int length; urb = usb_alloc_urb(0, GFP_NOIO); if (!urb) diff --git a/trunk/drivers/usb/net/pegasus.h b/trunk/drivers/usb/net/pegasus.h index c7467823cd1c..98f6898cae1f 100644 --- a/trunk/drivers/usb/net/pegasus.h +++ b/trunk/drivers/usb/net/pegasus.h @@ -214,9 +214,9 @@ PEGASUS_DEV( "Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511, DEFAULT_GPIO_RESET | PEGASUS_II ) -PEGASUS_DEV( "Corega FEther USB-TX", VENDOR_COREGA, 0x0004, +PEGASUS_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004, DEFAULT_GPIO_RESET ) -PEGASUS_DEV( "Corega FEther USB-TXS", VENDOR_COREGA, 0x000d, +PEGASUS_DEV( "Corega FEter USB-TXS", VENDOR_COREGA, 0x000d, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001, DEFAULT_GPIO_RESET ) diff --git a/trunk/drivers/usb/net/rndis_host.c b/trunk/drivers/usb/net/rndis_host.c index be888d2d813c..a322a16d9cf8 100644 --- a/trunk/drivers/usb/net/rndis_host.c +++ b/trunk/drivers/usb/net/rndis_host.c @@ -49,8 +49,6 @@ * - In some cases, MS-Windows will emit undocumented requests; this * matters more to peripheral implementations than host ones. * - * Moreover there's a no-open-specs variant of RNDIS called "ActiveSync". - * * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and * currently rare) "Ethernet Emulation Model" (EEM). @@ -63,9 +61,6 @@ * - control-in: GET_ENCAPSULATED * * We'll try to ignore the RESPONSE_AVAILABLE notifications. - * - * REVISIT some RNDIS implementations seem to have curious issues still - * to be resolved. */ struct rndis_msg_hdr { __le32 msg_type; /* RNDIS_MSG_* */ @@ -76,14 +71,8 @@ struct rndis_msg_hdr { // ... and more } __attribute__ ((packed)); -/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */ -#define CONTROL_BUFFER_SIZE 1025 - -/* RNDIS defines an (absurdly huge) 10 second control timeout, - * but ActiveSync seems to use a more usual 5 second timeout - * (which matches the USB 2.0 spec). - */ -#define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000) +/* RNDIS defines this (absurdly huge) control timeout */ +#define RNDIS_CONTROL_TIMEOUT_MS (10 * 1000) #define ccpu2 __constant_cpu_to_le32 @@ -281,7 +270,6 @@ static void rndis_status(struct usbnet *dev, struct urb *urb) static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) { struct cdc_state *info = (void *) &dev->data; - int master_ifnum; int retval; unsigned count; __le32 rsp; @@ -291,7 +279,7 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) * disconnect(): either serialize, or dispatch responses on xid */ - /* Issue the request; xid is unique, don't bother byteswapping it */ + /* Issue the request; don't bother byteswapping our xid */ if (likely(buf->msg_type != RNDIS_MSG_HALT && buf->msg_type != RNDIS_MSG_RESET)) { xid = dev->xid++; @@ -299,12 +287,11 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) xid = dev->xid++; buf->request_id = (__force __le32) xid; } - master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber; retval = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), USB_CDC_SEND_ENCAPSULATED_COMMAND, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, master_ifnum, + 0, info->u->bMasterInterface0, buf, le32_to_cpu(buf->msg_len), RNDIS_CONTROL_TIMEOUT_MS); if (unlikely(retval < 0 || xid == 0)) @@ -319,13 +306,13 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) */ rsp = buf->msg_type | RNDIS_MSG_COMPLETION; for (count = 0; count < 10; count++) { - memset(buf, 0, CONTROL_BUFFER_SIZE); + memset(buf, 0, 1024); retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), USB_CDC_GET_ENCAPSULATED_RESPONSE, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, master_ifnum, - buf, CONTROL_BUFFER_SIZE, + 0, info->u->bMasterInterface0, + buf, 1024, RNDIS_CONTROL_TIMEOUT_MS); if (likely(retval >= 8)) { msg_len = le32_to_cpu(buf->msg_len); @@ -363,7 +350,7 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) usb_sndctrlpipe(dev->udev, 0), USB_CDC_SEND_ENCAPSULATED_COMMAND, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, master_ifnum, + 0, info->u->bMasterInterface0, msg, sizeof *msg, RNDIS_CONTROL_TIMEOUT_MS); if (unlikely(retval < 0)) @@ -406,64 +393,38 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) u32 tmp; /* we can't rely on i/o from stack working, or stack allocation */ - u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); + u.buf = kmalloc(1024, GFP_KERNEL); if (!u.buf) return -ENOMEM; retval = usbnet_generic_cdc_bind(dev, intf); if (retval < 0) goto fail; + net->hard_header_len += sizeof (struct rndis_data_hdr); + + /* initialize; max transfer is 16KB at full speed */ u.init->msg_type = RNDIS_MSG_INIT; u.init->msg_len = ccpu2(sizeof *u.init); u.init->major_version = ccpu2(1); u.init->minor_version = ccpu2(0); + u.init->max_transfer_size = ccpu2(net->mtu + net->hard_header_len); - /* max transfer (in spec) is 0x4000 at full speed, but for - * TX we'll stick to one Ethernet packet plus RNDIS framing. - * For RX we handle drivers that zero-pad to end-of-packet. - * Don't let userspace change these settings. - */ - net->hard_header_len += sizeof (struct rndis_data_hdr); - dev->hard_mtu = net->mtu + net->hard_header_len; - - dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1); - dev->rx_urb_size &= ~(dev->maxpacket - 1); - u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size); - - net->change_mtu = NULL; retval = rndis_command(dev, u.header); if (unlikely(retval < 0)) { /* it might not even be an RNDIS device!! */ dev_err(&intf->dev, "RNDIS init failed, %d\n", retval); - goto fail_and_release; - } - tmp = le32_to_cpu(u.init_c->max_transfer_size); - if (tmp < dev->hard_mtu) { - dev_err(&intf->dev, - "dev can't take %u byte packets (max %u)\n", - dev->hard_mtu, tmp); goto fail_and_release; } - + dev->hard_mtu = le32_to_cpu(u.init_c->max_transfer_size); /* REVISIT: peripheral "alignment" request is ignored ... */ - dev_dbg(&intf->dev, - "hard mtu %u (%u from dev), rx buflen %Zu, align %d\n", - dev->hard_mtu, tmp, dev->rx_urb_size, + dev_dbg(&intf->dev, "hard mtu %u, align %d\n", dev->hard_mtu, 1 << le32_to_cpu(u.init_c->packet_alignment)); - /* Get designated host ethernet address. - * - * Adding a payload exactly the same size as the expected response - * payload is an evident requirement MSFT added for ActiveSync. - * This undocumented (and nonsensical) issue was found by sniffing - * protocol requests from the ActiveSync 4.1 Windows driver. - */ - memset(u.get, 0, sizeof *u.get + 48); + /* get designated host ethernet address */ + memset(u.get, 0, sizeof *u.get); u.get->msg_type = RNDIS_MSG_QUERY; - u.get->msg_len = ccpu2(sizeof *u.get + 48); + u.get->msg_len = ccpu2(sizeof *u.get); u.get->oid = OID_802_3_PERMANENT_ADDRESS; - u.get->len = ccpu2(48); - u.get->offset = ccpu2(20); retval = rndis_command(dev, u.header); if (unlikely(retval < 0)) { @@ -471,7 +432,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) goto fail_and_release; } tmp = le32_to_cpu(u.get_c->offset); - if (unlikely((tmp + 8) > (CONTROL_BUFFER_SIZE - ETH_ALEN) + if (unlikely((tmp + 8) > (1024 - ETH_ALEN) || u.get_c->len != ccpu2(ETH_ALEN))) { dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n", tmp, le32_to_cpu(u.get_c->len)); @@ -637,10 +598,6 @@ static const struct usb_device_id products [] = { /* RNDIS is MSFT's un-official variant of CDC ACM */ USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), .driver_info = (unsigned long) &rndis_info, -}, { - /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ - USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), - .driver_info = (unsigned long) &rndis_info, }, { }, // END }; diff --git a/trunk/drivers/usb/serial/aircable.c b/trunk/drivers/usb/serial/aircable.c index 11dad42c3c60..86bcf63b6ba5 100644 --- a/trunk/drivers/usb/serial/aircable.c +++ b/trunk/drivers/usb/serial/aircable.c @@ -572,20 +572,8 @@ static void aircable_unthrottle(struct usb_serial_port *port) schedule_work(&priv->rx_work); } -static struct usb_driver aircable_driver = { - .name = "aircable", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .no_dynamic_id = 1, -}; - static struct usb_serial_driver aircable_device = { - .driver = { - .owner = THIS_MODULE, - .name = "aircable", - }, - .usb_driver = &aircable_driver, + .description = "aircable", .id_table = id_table, .num_ports = 1, .attach = aircable_attach, @@ -599,6 +587,13 @@ static struct usb_serial_driver aircable_device = { .unthrottle = aircable_unthrottle, }; +static struct usb_driver aircable_driver = { + .name = "aircable", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; + static int __init aircable_init (void) { int retval; diff --git a/trunk/drivers/usb/serial/airprime.c b/trunk/drivers/usb/serial/airprime.c index 0af42e32fa0a..f2ca76a9cbac 100644 --- a/trunk/drivers/usb/serial/airprime.c +++ b/trunk/drivers/usb/serial/airprime.c @@ -277,7 +277,6 @@ static struct usb_serial_driver airprime_device = { .owner = THIS_MODULE, .name = "airprime", }, - .usb_driver = &airprime_driver, .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, diff --git a/trunk/drivers/usb/serial/ark3116.c b/trunk/drivers/usb/serial/ark3116.c index edd685791a6b..5261cd22ee6b 100644 --- a/trunk/drivers/usb/serial/ark3116.c +++ b/trunk/drivers/usb/serial/ark3116.c @@ -444,7 +444,6 @@ static struct usb_driver ark3116_driver = { .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = id_table, - .no_dynamic_id = 1, }; static struct usb_serial_driver ark3116_device = { @@ -453,7 +452,6 @@ static struct usb_serial_driver ark3116_device = { .name = "ark3116", }, .id_table = id_table, - .usb_driver = &ark3116_driver, .num_interrupt_in = 1, .num_bulk_in = 1, .num_bulk_out = 1, diff --git a/trunk/drivers/usb/serial/belkin_sa.c b/trunk/drivers/usb/serial/belkin_sa.c index 3b800d277c4b..38b4dae319ee 100644 --- a/trunk/drivers/usb/serial/belkin_sa.c +++ b/trunk/drivers/usb/serial/belkin_sa.c @@ -126,7 +126,6 @@ static struct usb_serial_driver belkin_device = { .name = "belkin", }, .description = "Belkin / Peracom / GoHubs USB Serial Adapter", - .usb_driver = &belkin_driver, .id_table = id_table_combined, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/trunk/drivers/usb/serial/bus.c b/trunk/drivers/usb/serial/bus.c index c08a38402b93..6542f220468f 100644 --- a/trunk/drivers/usb/serial/bus.c +++ b/trunk/drivers/usb/serial/bus.c @@ -103,52 +103,11 @@ static int usb_serial_device_remove (struct device *dev) return retval; } -#ifdef CONFIG_HOTPLUG -static ssize_t store_new_id(struct device_driver *driver, - const char *buf, size_t count) -{ - struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver); - ssize_t retval = usb_store_new_id(&usb_drv->dynids, driver, buf, count); - - if (retval >= 0 && usb_drv->usb_driver != NULL) - retval = usb_store_new_id(&usb_drv->usb_driver->dynids, - &usb_drv->usb_driver->drvwrap.driver, - buf, count); - return retval; -} - -static struct driver_attribute drv_attrs[] = { - __ATTR(new_id, S_IWUSR, NULL, store_new_id), - __ATTR_NULL, -}; - -static void free_dynids(struct usb_serial_driver *drv) -{ - struct usb_dynid *dynid, *n; - - spin_lock(&drv->dynids.lock); - list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { - list_del(&dynid->node); - kfree(dynid); - } - spin_unlock(&drv->dynids.lock); -} - -#else -static struct driver_attribute drv_attrs[] = { - __ATTR_NULL, -}; -static inline void free_dynids(struct usb_driver *drv) -{ -} -#endif - struct bus_type usb_serial_bus_type = { .name = "usb-serial", .match = usb_serial_device_match, .probe = usb_serial_device_probe, .remove = usb_serial_device_remove, - .drv_attrs = drv_attrs, }; int usb_serial_bus_register(struct usb_serial_driver *driver) @@ -156,9 +115,6 @@ int usb_serial_bus_register(struct usb_serial_driver *driver) int retval; driver->driver.bus = &usb_serial_bus_type; - spin_lock_init(&driver->dynids.lock); - INIT_LIST_HEAD(&driver->dynids.list); - retval = driver_register(&driver->driver); return retval; @@ -166,7 +122,6 @@ int usb_serial_bus_register(struct usb_serial_driver *driver) void usb_serial_bus_deregister(struct usb_serial_driver *driver) { - free_dynids(driver); driver_unregister(&driver->driver); } diff --git a/trunk/drivers/usb/serial/cp2101.c b/trunk/drivers/usb/serial/cp2101.c index 06b4fffc189c..7ebaffd6ed86 100644 --- a/trunk/drivers/usb/serial/cp2101.c +++ b/trunk/drivers/usb/serial/cp2101.c @@ -89,7 +89,6 @@ static struct usb_serial_driver cp2101_device = { .owner = THIS_MODULE, .name = "cp2101", }, - .usb_driver = &cp2101_driver, .id_table = id_table, .num_interrupt_in = 0, .num_bulk_in = 0, diff --git a/trunk/drivers/usb/serial/cyberjack.c b/trunk/drivers/usb/serial/cyberjack.c index 4167753ed31f..a63c3286caa0 100644 --- a/trunk/drivers/usb/serial/cyberjack.c +++ b/trunk/drivers/usb/serial/cyberjack.c @@ -88,7 +88,6 @@ static struct usb_serial_driver cyberjack_device = { .name = "cyberjack", }, .description = "Reiner SCT Cyberjack USB card reader", - .usb_driver = &cyberjack_driver, .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -99,7 +98,7 @@ static struct usb_serial_driver cyberjack_device = { .open = cyberjack_open, .close = cyberjack_close, .write = cyberjack_write, - .write_room = cyberjack_write_room, + .write_room = cyberjack_write_room, .read_int_callback = cyberjack_read_int_callback, .read_bulk_callback = cyberjack_read_bulk_callback, .write_bulk_callback = cyberjack_write_bulk_callback, diff --git a/trunk/drivers/usb/serial/cypress_m8.c b/trunk/drivers/usb/serial/cypress_m8.c index 57b8e27285fc..6bc1f404e186 100644 --- a/trunk/drivers/usb/serial/cypress_m8.c +++ b/trunk/drivers/usb/serial/cypress_m8.c @@ -193,7 +193,6 @@ static struct usb_serial_driver cypress_earthmate_device = { .name = "earthmate", }, .description = "DeLorme Earthmate USB", - .usb_driver = &cypress_driver, .id_table = id_table_earthmate, .num_interrupt_in = 1, .num_interrupt_out = 1, @@ -223,7 +222,6 @@ static struct usb_serial_driver cypress_hidcom_device = { .name = "cyphidcom", }, .description = "HID->COM RS232 Adapter", - .usb_driver = &cypress_driver, .id_table = id_table_cyphidcomrs232, .num_interrupt_in = 1, .num_interrupt_out = 1, @@ -253,7 +251,6 @@ static struct usb_serial_driver cypress_ca42v2_device = { .name = "nokiaca42v2", }, .description = "Nokia CA-42 V2 Adapter", - .usb_driver = &cypress_driver, .id_table = id_table_nokiaca42v2, .num_interrupt_in = 1, .num_interrupt_out = 1, diff --git a/trunk/drivers/usb/serial/digi_acceleport.c b/trunk/drivers/usb/serial/digi_acceleport.c index 0b0fb51bad3e..efd9ce3f931f 100644 --- a/trunk/drivers/usb/serial/digi_acceleport.c +++ b/trunk/drivers/usb/serial/digi_acceleport.c @@ -509,7 +509,6 @@ static struct usb_serial_driver digi_acceleport_2_device = { .name = "digi_2", }, .description = "Digi 2 port USB adapter", - .usb_driver = &digi_driver, .id_table = id_table_2, .num_interrupt_in = 0, .num_bulk_in = 4, @@ -539,7 +538,6 @@ static struct usb_serial_driver digi_acceleport_4_device = { .name = "digi_4", }, .description = "Digi 4 port USB adapter", - .usb_driver = &digi_driver, .id_table = id_table_4, .num_interrupt_in = 0, .num_bulk_in = 5, diff --git a/trunk/drivers/usb/serial/empeg.c b/trunk/drivers/usb/serial/empeg.c index 4703c8f85383..92beeb19795f 100644 --- a/trunk/drivers/usb/serial/empeg.c +++ b/trunk/drivers/usb/serial/empeg.c @@ -117,7 +117,6 @@ static struct usb_serial_driver empeg_device = { .name = "empeg", }, .id_table = id_table, - .usb_driver = &empeg_driver, .num_interrupt_in = 0, .num_bulk_in = 1, .num_bulk_out = 1, diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 4695952b6470..6986e756f7c0 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -464,6 +464,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, + { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID) }, { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) }, @@ -614,7 +615,6 @@ static struct usb_serial_driver ftdi_sio_device = { .name = "ftdi_sio", }, .description = "FTDI USB Serial Device", - .usb_driver = &ftdi_driver , .id_table = id_table_combined, .num_interrupt_in = 0, .num_bulk_in = 1, diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index 7eff1c03ba80..40dd394de58d 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -364,6 +364,7 @@ * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices * and I'm not entirely sure which are used by which. */ +#define FTDI_4N_GALAXY_DE_0_PID 0x8372 #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 #define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 diff --git a/trunk/drivers/usb/serial/funsoft.c b/trunk/drivers/usb/serial/funsoft.c index 4092f6dc9efd..2bebd63d5ed1 100644 --- a/trunk/drivers/usb/serial/funsoft.c +++ b/trunk/drivers/usb/serial/funsoft.c @@ -58,7 +58,6 @@ static struct usb_serial_driver funsoft_device = { .name = "funsoft", }, .id_table = id_table, - .usb_driver = &funsoft_driver, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, diff --git a/trunk/drivers/usb/serial/garmin_gps.c b/trunk/drivers/usb/serial/garmin_gps.c index 74660a3aa670..6530d391ebed 100644 --- a/trunk/drivers/usb/serial/garmin_gps.c +++ b/trunk/drivers/usb/serial/garmin_gps.c @@ -1566,7 +1566,6 @@ static struct usb_serial_driver garmin_device = { .name = "garmin_gps", }, .description = "Garmin GPS usb/tty", - .usb_driver = &garmin_driver, .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/trunk/drivers/usb/serial/generic.c b/trunk/drivers/usb/serial/generic.c index 601e0648dec6..36042937e77f 100644 --- a/trunk/drivers/usb/serial/generic.c +++ b/trunk/drivers/usb/serial/generic.c @@ -20,10 +20,6 @@ #include #include -static int generic_probe(struct usb_interface *interface, - const struct usb_device_id *id); - - static int debug; #ifdef CONFIG_USB_SERIAL_GENERIC @@ -38,21 +34,6 @@ MODULE_PARM_DESC(product, "User specified USB idProduct"); static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ -/* we want to look at all devices, as the vendor/product id can change - * depending on the command line argument */ -static struct usb_device_id generic_serial_ids[] = { - {.driver_info = 42}, - {} -}; - -static struct usb_driver generic_driver = { - .name = "usbserial_generic", - .probe = generic_probe, - .disconnect = usb_serial_disconnect, - .id_table = generic_serial_ids, - .no_dynamic_id = 1, -}; - /* All of the device info needed for the Generic Serial Converter */ struct usb_serial_driver usb_serial_generic_device = { .driver = { @@ -60,7 +41,6 @@ struct usb_serial_driver usb_serial_generic_device = { .name = "generic", }, .id_table = generic_device_ids, - .usb_driver = &generic_driver, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, @@ -68,6 +48,13 @@ struct usb_serial_driver usb_serial_generic_device = { .shutdown = usb_serial_generic_shutdown, }; +/* we want to look at all devices, as the vendor/product id can change + * depending on the command line argument */ +static struct usb_device_id generic_serial_ids[] = { + {.driver_info = 42}, + {} +}; + static int generic_probe(struct usb_interface *interface, const struct usb_device_id *id) { @@ -78,6 +65,14 @@ static int generic_probe(struct usb_interface *interface, return usb_serial_probe(interface, id); return -ENODEV; } + +static struct usb_driver generic_driver = { + .name = "usbserial_generic", + .probe = generic_probe, + .disconnect = usb_serial_disconnect, + .id_table = generic_serial_ids, + .no_dynamic_id = 1, +}; #endif int usb_serial_generic_register (int _debug) diff --git a/trunk/drivers/usb/serial/hp4x.c b/trunk/drivers/usb/serial/hp4x.c index 6c6ebae741c9..ebcac701b069 100644 --- a/trunk/drivers/usb/serial/hp4x.c +++ b/trunk/drivers/usb/serial/hp4x.c @@ -49,7 +49,6 @@ static struct usb_serial_driver hp49gp_device = { .name = "hp4X", }, .id_table = id_table, - .usb_driver = &hp49gp_driver, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, diff --git a/trunk/drivers/usb/serial/io_edgeport.c b/trunk/drivers/usb/serial/io_edgeport.c index 6a26a2e683a6..f623d58370a4 100644 --- a/trunk/drivers/usb/serial/io_edgeport.c +++ b/trunk/drivers/usb/serial/io_edgeport.c @@ -146,8 +146,6 @@ struct edgeport_serial { struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ struct edgeport_product_info product_info; /* Product Info */ - struct edge_compatibility_descriptor epic_descriptor; /* Edgeport compatible descriptor */ - int is_epic; /* flag if EPiC device or not */ __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */ unsigned char * interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */ @@ -242,6 +240,14 @@ static void edge_shutdown (struct usb_serial *serial); #include "io_tables.h" /* all of the devices that this driver supports */ +static struct usb_driver io_driver = { + .name = "io_edgeport", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, + .no_dynamic_id = 1, +}; + /* function prototypes for all of our local functions */ static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength); static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3); @@ -391,7 +397,6 @@ static int get_string (struct usb_device *dev, int Id, char *string, int buflen) unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); kfree(pStringDesc); - dbg("%s - USB String %s", __FUNCTION__, string); return strlen(string); } @@ -429,34 +434,6 @@ static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_de } #endif -static void dump_product_info(struct edgeport_product_info *product_info) -{ - // Dump Product Info structure - dbg("**Product Information:"); - dbg(" ProductId %x", product_info->ProductId ); - dbg(" NumPorts %d", product_info->NumPorts ); - dbg(" ProdInfoVer %d", product_info->ProdInfoVer ); - dbg(" IsServer %d", product_info->IsServer); - dbg(" IsRS232 %d", product_info->IsRS232 ); - dbg(" IsRS422 %d", product_info->IsRS422 ); - dbg(" IsRS485 %d", product_info->IsRS485 ); - dbg(" RomSize %d", product_info->RomSize ); - dbg(" RamSize %d", product_info->RamSize ); - dbg(" CpuRev %x", product_info->CpuRev ); - dbg(" BoardRev %x", product_info->BoardRev); - dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, - product_info->BootMinorVersion, - le16_to_cpu(product_info->BootBuildNumber)); - dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, - product_info->FirmwareMinorVersion, - le16_to_cpu(product_info->FirmwareBuildNumber)); - dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], - product_info->ManufactureDescDate[1], - product_info->ManufactureDescDate[2]+1900); - dbg(" iDownloadFile 0x%x", product_info->iDownloadFile); - dbg(" EpicVer %d", product_info->EpicVer); -} - static void get_product_info(struct edgeport_serial *edge_serial) { struct edgeport_product_info *product_info = &edge_serial->product_info; @@ -518,60 +495,30 @@ static void get_product_info(struct edgeport_serial *edge_serial) break; } - dump_product_info(product_info); -} - -static int get_epic_descriptor(struct edgeport_serial *ep) -{ - int result; - struct usb_serial *serial = ep->serial; - struct edgeport_product_info *product_info = &ep->product_info; - struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; - struct edge_compatibility_bits *bits; - - ep->is_epic = 0; - result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - USB_REQUEST_ION_GET_EPIC_DESC, - 0xC0, 0x00, 0x00, - &ep->epic_descriptor, - sizeof(struct edge_compatibility_descriptor), - 300); - - dbg("%s result = %d", __FUNCTION__, result); - - if (result > 0) { - ep->is_epic = 1; - memset(product_info, 0, sizeof(struct edgeport_product_info)); - - product_info->NumPorts = epic->NumPorts; - product_info->ProdInfoVer = 0; - product_info->FirmwareMajorVersion = epic->MajorVersion; - product_info->FirmwareMinorVersion = epic->MinorVersion; - product_info->FirmwareBuildNumber = epic->BuildNumber; - product_info->iDownloadFile = epic->iDownloadFile; - product_info->EpicVer = epic->EpicVer; - product_info->Epic = epic->Supports; - product_info->ProductId = ION_DEVICE_ID_EDGEPORT_COMPATIBLE; - dump_product_info(product_info); - - bits = &ep->epic_descriptor.Supports; - dbg("**EPIC descriptor:"); - dbg(" VendEnableSuspend: %s", bits->VendEnableSuspend ? "TRUE": "FALSE"); - dbg(" IOSPOpen : %s", bits->IOSPOpen ? "TRUE": "FALSE" ); - dbg(" IOSPClose : %s", bits->IOSPClose ? "TRUE": "FALSE" ); - dbg(" IOSPChase : %s", bits->IOSPChase ? "TRUE": "FALSE" ); - dbg(" IOSPSetRxFlow : %s", bits->IOSPSetRxFlow ? "TRUE": "FALSE" ); - dbg(" IOSPSetTxFlow : %s", bits->IOSPSetTxFlow ? "TRUE": "FALSE" ); - dbg(" IOSPSetXChar : %s", bits->IOSPSetXChar ? "TRUE": "FALSE" ); - dbg(" IOSPRxCheck : %s", bits->IOSPRxCheck ? "TRUE": "FALSE" ); - dbg(" IOSPSetClrBreak : %s", bits->IOSPSetClrBreak ? "TRUE": "FALSE" ); - dbg(" IOSPWriteMCR : %s", bits->IOSPWriteMCR ? "TRUE": "FALSE" ); - dbg(" IOSPWriteLCR : %s", bits->IOSPWriteLCR ? "TRUE": "FALSE" ); - dbg(" IOSPSetBaudRate : %s", bits->IOSPSetBaudRate ? "TRUE": "FALSE" ); - dbg(" TrueEdgeport : %s", bits->TrueEdgeport ? "TRUE": "FALSE" ); - } + // Dump Product Info structure + dbg("**Product Information:"); + dbg(" ProductId %x", product_info->ProductId ); + dbg(" NumPorts %d", product_info->NumPorts ); + dbg(" ProdInfoVer %d", product_info->ProdInfoVer ); + dbg(" IsServer %d", product_info->IsServer); + dbg(" IsRS232 %d", product_info->IsRS232 ); + dbg(" IsRS422 %d", product_info->IsRS422 ); + dbg(" IsRS485 %d", product_info->IsRS485 ); + dbg(" RomSize %d", product_info->RomSize ); + dbg(" RamSize %d", product_info->RamSize ); + dbg(" CpuRev %x", product_info->CpuRev ); + dbg(" BoardRev %x", product_info->BoardRev); + dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, + product_info->BootMinorVersion, + le16_to_cpu(product_info->BootBuildNumber)); + dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, + product_info->FirmwareMinorVersion, + le16_to_cpu(product_info->FirmwareBuildNumber)); + dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], + product_info->ManufactureDescDate[1], + product_info->ManufactureDescDate[2]+1900); + dbg(" iDownloadFile 0x%x", product_info->iDownloadFile); - return result; } @@ -1070,30 +1017,22 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) edge_port->closePending = TRUE; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPChase))) { - /* flush and chase */ - edge_port->chaseResponsePending = TRUE; - - dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); - status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); - if (status == 0) { - // block until chase finished - block_until_chase_response(edge_port); - } else { - edge_port->chaseResponsePending = FALSE; - } - } + /* flush and chase */ + edge_port->chaseResponsePending = TRUE; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPClose))) { - /* close the port */ - dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__); - send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); + dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); + status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); + if (status == 0) { + // block until chase finished + block_until_chase_response(edge_port); + } else { + edge_port->chaseResponsePending = FALSE; } + /* close the port */ + dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__); + send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); + //port->close = TRUE; edge_port->closePending = FALSE; edge_port->open = FALSE; @@ -1755,38 +1694,29 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned static void edge_break (struct usb_serial_port *port, int break_state) { struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial); int status; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPChase))) { - /* flush and chase */ - edge_port->chaseResponsePending = TRUE; - - dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); - status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); - if (status == 0) { - // block until chase finished - block_until_chase_response(edge_port); - } else { - edge_port->chaseResponsePending = FALSE; - } + /* flush and chase */ + edge_port->chaseResponsePending = TRUE; + + dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); + status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); + if (status == 0) { + // block until chase finished + block_until_chase_response(edge_port); + } else { + edge_port->chaseResponsePending = FALSE; } - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) { - if (break_state == -1) { - dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__); - status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0); - } else { - dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __FUNCTION__); - status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0); - } - if (status) { - dbg("%s - error sending break set/clear command.", __FUNCTION__); - } + if (break_state == -1) { + dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__); + status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0); + } else { + dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __FUNCTION__); + status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0); + } + if (status) { + dbg("%s - error sending break set/clear command.", __FUNCTION__); } return; @@ -2358,7 +2288,6 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer *****************************************************************************/ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate) { - struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); unsigned char *cmdBuffer; unsigned char *currCmd; int cmdLen = 0; @@ -2366,14 +2295,6 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa int status; unsigned char number = edge_port->port->number - edge_port->port->serial->minor; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) { - dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", - edge_port->port->number, baudRate); - return 0; - } - dbg("%s - port = %d, baud = %d", __FUNCTION__, edge_port->port->number, baudRate); status = calc_baud_rate_divisor (baudRate, &divisor); @@ -2453,7 +2374,6 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor) *****************************************************************************/ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue) { - struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); unsigned char *cmdBuffer; unsigned char *currCmd; unsigned long cmdLen = 0; @@ -2461,22 +2381,6 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) && - (regNum == MCR))) { - dbg("SendCmdWriteUartReg - Not writting to MCR Register"); - return 0; - } - - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) && - (regNum == LCR))) { - dbg ("SendCmdWriteUartReg - Not writting to LCR Register"); - return 0; - } - // Alloc memory for the string of commands. cmdBuffer = kmalloc (0x10, GFP_ATOMIC); if (cmdBuffer == NULL ) { @@ -2510,7 +2414,6 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r #endif static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios) { - struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); struct tty_struct *tty; int baud; unsigned cflag; @@ -2591,12 +2494,8 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi unsigned char stop_char = STOP_CHAR(tty); unsigned char start_char = START_CHAR(tty); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetXChar))) { - send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XON_CHAR, start_char); - send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char); - } + send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_XON_CHAR, start_char); + send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char); /* if we are implementing INBOUND XON/XOFF */ if (I_IXOFF(tty)) { @@ -2616,14 +2515,8 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi } /* Set flow control to the configured value */ - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetRxFlow))) - send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetTxFlow))) - send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); + send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); + send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); edge_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); @@ -2835,13 +2728,6 @@ static int edge_startup (struct usb_serial *serial) struct edgeport_port *edge_port; struct usb_device *dev; int i, j; - int response; - int interrupt_in_found; - int bulk_in_found; - int bulk_out_found; - static __u32 descriptor[3] = { EDGE_COMPATIBILITY_MASK0, - EDGE_COMPATIBILITY_MASK1, - EDGE_COMPATIBILITY_MASK2 }; dev = serial->dev; @@ -2864,50 +2750,38 @@ static int edge_startup (struct usb_serial *serial) dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); - /* Read the epic descriptor */ - if (get_epic_descriptor(edge_serial) <= 0) { - /* memcpy descriptor to Supports structures */ - memcpy(&edge_serial->epic_descriptor.Supports, descriptor, - sizeof(struct edge_compatibility_bits)); - - /* get the manufacturing descriptor for this device */ - get_manufacturing_desc (edge_serial); + /* get the manufacturing descriptor for this device */ + get_manufacturing_desc (edge_serial); - /* get the boot descriptor */ - get_boot_desc (edge_serial); + /* get the boot descriptor */ + get_boot_desc (edge_serial); - get_product_info(edge_serial); - } + get_product_info(edge_serial); /* set the number of ports from the manufacturing description */ /* serial->num_ports = serial->product_info.NumPorts; */ - if ((!edge_serial->is_epic) && - (edge_serial->product_info.NumPorts != serial->num_ports)) { - dev_warn(&serial->dev->dev, "Device Reported %d serial ports " - "vs. core thinking we have %d ports, email " - "greg@kroah.com this information.", - edge_serial->product_info.NumPorts, - serial->num_ports); + if (edge_serial->product_info.NumPorts != serial->num_ports) { + warn("%s - Device Reported %d serial ports vs core " + "thinking we have %d ports, email greg@kroah.com this info.", + __FUNCTION__, edge_serial->product_info.NumPorts, + serial->num_ports); } dbg("%s - time 1 %ld", __FUNCTION__, jiffies); - /* If not an EPiC device */ - if (!edge_serial->is_epic) { - /* now load the application firmware into this device */ - load_application_firmware (edge_serial); - - dbg("%s - time 2 %ld", __FUNCTION__, jiffies); + /* now load the application firmware into this device */ + load_application_firmware (edge_serial); - /* Check current Edgeport EEPROM and update if necessary */ - update_edgeport_E2PROM (edge_serial); + dbg("%s - time 2 %ld", __FUNCTION__, jiffies); - dbg("%s - time 3 %ld", __FUNCTION__, jiffies); + /* Check current Edgeport EEPROM and update if necessary */ + update_edgeport_E2PROM (edge_serial); + + dbg("%s - time 3 %ld", __FUNCTION__, jiffies); - /* set the configuration to use #1 */ -// dbg("set_configuration 1"); -// usb_set_configuration (dev, 1); - } + /* set the configuration to use #1 */ +// dbg("set_configuration 1"); +// usb_set_configuration (dev, 1); /* we set up the pointers to the endpoints in the edge_open function, * as the structures aren't created yet. */ @@ -2930,101 +2804,8 @@ static int edge_startup (struct usb_serial *serial) edge_port->port = serial->port[i]; usb_set_serial_port_data(serial->port[i], edge_port); } - - response = 0; - - if (edge_serial->is_epic) { - /* EPIC thing, set up our interrupt polling now and our read urb, so - * that the device knows it really is connected. */ - interrupt_in_found = bulk_in_found = bulk_out_found = FALSE; - for (i = 0; i < serial->interface->altsetting[0].desc.bNumEndpoints; ++i) { - struct usb_endpoint_descriptor *endpoint; - int buffer_size; - - endpoint = &serial->interface->altsetting[0].endpoint[i].desc; - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - if ((!interrupt_in_found) && - (usb_endpoint_is_int_in(endpoint))) { - /* we found a interrupt in endpoint */ - dbg("found interrupt in"); - - /* not set up yet, so do it now */ - edge_serial->interrupt_read_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!edge_serial->interrupt_read_urb) { - err("out of memory"); - return -ENOMEM; - } - edge_serial->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL); - if (!edge_serial->interrupt_in_buffer) { - err("out of memory"); - usb_free_urb(edge_serial->interrupt_read_urb); - return -ENOMEM; - } - edge_serial->interrupt_in_endpoint = endpoint->bEndpointAddress; - - /* set up our interrupt urb */ - usb_fill_int_urb(edge_serial->interrupt_read_urb, - dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - edge_serial->interrupt_in_buffer, - buffer_size, - edge_interrupt_callback, - edge_serial, - endpoint->bInterval); - - interrupt_in_found = TRUE; - } - - if ((!bulk_in_found) && - (usb_endpoint_is_bulk_in(endpoint))) { - /* we found a bulk in endpoint */ - dbg("found bulk in"); - - /* not set up yet, so do it now */ - edge_serial->read_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!edge_serial->read_urb) { - err("out of memory"); - return -ENOMEM; - } - edge_serial->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); - if (!edge_serial->bulk_in_buffer) { - err ("out of memory"); - usb_free_urb(edge_serial->read_urb); - return -ENOMEM; - } - edge_serial->bulk_in_endpoint = endpoint->bEndpointAddress; - - /* set up our bulk in urb */ - usb_fill_bulk_urb(edge_serial->read_urb, dev, - usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), - edge_serial->bulk_in_buffer, - endpoint->wMaxPacketSize, - edge_bulk_in_callback, - edge_serial); - bulk_in_found = TRUE; - } - - if ((!bulk_out_found) && - (usb_endpoint_is_bulk_out(endpoint))) { - /* we found a bulk out endpoint */ - dbg("found bulk out"); - edge_serial->bulk_out_endpoint = endpoint->bEndpointAddress; - bulk_out_found = TRUE; - } - } - - if ((!interrupt_in_found) || (!bulk_in_found) || (!bulk_out_found)) { - err ("Error - the proper endpoints were not found!"); - return -ENODEV; - } - - /* start interrupt read for this edgeport this interrupt will - * continue as long as the edgeport is connected */ - response = usb_submit_urb(edge_serial->interrupt_read_urb, GFP_KERNEL); - if (response) - err("%s - Error %d submitting control urb", __FUNCTION__, response); - } - return response; + + return 0; } @@ -3034,7 +2815,6 @@ static int edge_startup (struct usb_serial *serial) ****************************************************************************/ static void edge_shutdown (struct usb_serial *serial) { - struct edgeport_serial *edge_serial = usb_get_serial_data(serial); int i; dbg("%s", __FUNCTION__); @@ -3044,18 +2824,7 @@ static void edge_shutdown (struct usb_serial *serial) kfree (usb_get_serial_port_data(serial->port[i])); usb_set_serial_port_data(serial->port[i], NULL); } - /* free up our endpoint stuff */ - if (edge_serial->is_epic) { - usb_unlink_urb(edge_serial->interrupt_read_urb); - usb_free_urb(edge_serial->interrupt_read_urb); - kfree(edge_serial->interrupt_in_buffer); - - usb_unlink_urb(edge_serial->read_urb); - usb_free_urb(edge_serial->read_urb); - kfree(edge_serial->bulk_in_buffer); - } - - kfree(edge_serial); + kfree (usb_get_serial_data(serial)); usb_set_serial_data(serial, NULL); } @@ -3077,9 +2846,6 @@ static int __init edgeport_init(void) retval = usb_serial_register(&edgeport_8port_device); if (retval) goto failed_8port_device_register; - retval = usb_serial_register(&epic_device); - if (retval) - goto failed_epic_device_register; retval = usb_register(&io_driver); if (retval) goto failed_usb_register; @@ -3087,8 +2853,6 @@ static int __init edgeport_init(void) return 0; failed_usb_register: - usb_serial_deregister(&epic_device); -failed_epic_device_register: usb_serial_deregister(&edgeport_8port_device); failed_8port_device_register: usb_serial_deregister(&edgeport_4port_device); @@ -3109,7 +2873,6 @@ static void __exit edgeport_exit (void) usb_serial_deregister (&edgeport_2port_device); usb_serial_deregister (&edgeport_4port_device); usb_serial_deregister (&edgeport_8port_device); - usb_serial_deregister (&epic_device); } module_init(edgeport_init); diff --git a/trunk/drivers/usb/serial/io_edgeport.h b/trunk/drivers/usb/serial/io_edgeport.h index 29a913a6daca..123fa8a904e6 100644 --- a/trunk/drivers/usb/serial/io_edgeport.h +++ b/trunk/drivers/usb/serial/io_edgeport.h @@ -111,12 +111,10 @@ struct edgeport_product_info { __le16 FirmwareBuildNumber; /* zzzz (LE format) */ __u8 ManufactureDescDate[3]; /* MM/DD/YY when descriptor template was compiled */ - __u8 HardwareType; + __u8 Unused1[1]; /* Available */ __u8 iDownloadFile; /* What to download to EPiC device */ - __u8 EpicVer; /* What version of EPiC spec this device supports */ - - struct edge_compatibility_bits Epic; + __u8 Unused2[2]; /* Available */ }; /* diff --git a/trunk/drivers/usb/serial/io_tables.h b/trunk/drivers/usb/serial/io_tables.h index 6d3008772540..fad561c04c76 100644 --- a/trunk/drivers/usb/serial/io_tables.h +++ b/trunk/drivers/usb/serial/io_tables.h @@ -47,18 +47,6 @@ static struct usb_device_id edgeport_8port_id_table [] = { { } }; -static struct usb_device_id Epic_port_id_table [] = { - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) }, - { } -}; - /* Devices that this driver supports */ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, @@ -82,34 +70,17 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, id_table_combined); -static struct usb_driver io_driver = { - .name = "io_edgeport", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, - .no_dynamic_id = 1, -}; - static struct usb_serial_driver edgeport_2port_device = { .driver = { .owner = THIS_MODULE, .name = "edgeport_2", }, .description = "Edgeport 2 port adapter", - .usb_driver = &io_driver, .id_table = edgeport_2port_id_table, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -140,7 +111,6 @@ static struct usb_serial_driver edgeport_4port_device = { .name = "edgeport_4", }, .description = "Edgeport 4 port adapter", - .usb_driver = &io_driver, .id_table = edgeport_4port_id_table, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -171,7 +141,6 @@ static struct usb_serial_driver edgeport_8port_device = { .name = "edgeport_8", }, .description = "Edgeport 8 port adapter", - .usb_driver = &io_driver, .id_table = edgeport_8port_id_table, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -196,35 +165,5 @@ static struct usb_serial_driver edgeport_8port_device = { .write_bulk_callback = edge_bulk_out_data_callback, }; -static struct usb_serial_driver epic_device = { - .driver = { - .owner = THIS_MODULE, - .name = "epic", - }, - .description = "EPiC device", - .id_table = Epic_port_id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, - .num_ports = 1, - .open = edge_open, - .close = edge_close, - .throttle = edge_throttle, - .unthrottle = edge_unthrottle, - .attach = edge_startup, - .shutdown = edge_shutdown, - .ioctl = edge_ioctl, - .set_termios = edge_set_termios, - .tiocmget = edge_tiocmget, - .tiocmset = edge_tiocmset, - .write = edge_write, - .write_room = edge_write_room, - .chars_in_buffer = edge_chars_in_buffer, - .break_ctl = edge_break, - .read_int_callback = edge_interrupt_callback, - .read_bulk_callback = edge_bulk_in_callback, - .write_bulk_callback = edge_bulk_out_data_callback, -}; - #endif diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index 544098d2b775..980285c0233a 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/drivers/usb/serial/io_ti.c @@ -2979,7 +2979,6 @@ static struct usb_serial_driver edgeport_1port_device = { .name = "edgeport_ti_1", }, .description = "Edgeport TI 1 port adapter", - .usb_driver = &io_driver, .id_table = edgeport_1port_id_table, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -3010,7 +3009,6 @@ static struct usb_serial_driver edgeport_2port_device = { .name = "edgeport_ti_2", }, .description = "Edgeport TI 2 port adapter", - .usb_driver = &io_driver, .id_table = edgeport_2port_id_table, .num_interrupt_in = 1, .num_bulk_in = 2, diff --git a/trunk/drivers/usb/serial/io_usbvend.h b/trunk/drivers/usb/serial/io_usbvend.h index e57fa117e486..f1804fd5a3dd 100644 --- a/trunk/drivers/usb/serial/io_usbvend.h +++ b/trunk/drivers/usb/serial/io_usbvend.h @@ -30,7 +30,6 @@ #define USB_VENDOR_ID_ION 0x1608 // Our VID #define USB_VENDOR_ID_TI 0x0451 // TI VID -#define USB_VENDOR_ID_AXIOHM 0x05D9 /* Axiohm VID */ // // Definitions of USB product IDs (PID) @@ -335,10 +334,6 @@ struct edge_compatibility_bits }; -#define EDGE_COMPATIBILITY_MASK0 0x0001 -#define EDGE_COMPATIBILITY_MASK1 0x3FFF -#define EDGE_COMPATIBILITY_MASK2 0x0001 - struct edge_compatibility_descriptor { __u8 Length; // Descriptor Length (per USB spec) diff --git a/trunk/drivers/usb/serial/ipaq.c b/trunk/drivers/usb/serial/ipaq.c index a408184334ea..42f757a5b876 100644 --- a/trunk/drivers/usb/serial/ipaq.c +++ b/trunk/drivers/usb/serial/ipaq.c @@ -563,7 +563,6 @@ static struct usb_serial_driver ipaq_device = { .name = "ipaq", }, .description = "PocketPC PDA", - .usb_driver = &ipaq_driver, .id_table = ipaq_id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, diff --git a/trunk/drivers/usb/serial/ipw.c b/trunk/drivers/usb/serial/ipw.c index 1bc586064c77..d3b9a351cef8 100644 --- a/trunk/drivers/usb/serial/ipw.c +++ b/trunk/drivers/usb/serial/ipw.c @@ -442,7 +442,6 @@ static struct usb_serial_driver ipw_device = { .name = "ipw", }, .description = "IPWireless converter", - .usb_driver = &usb_ipw_driver, .id_table = usb_ipw_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, diff --git a/trunk/drivers/usb/serial/ir-usb.c b/trunk/drivers/usb/serial/ir-usb.c index 9d847f69291c..8fdf486e3465 100644 --- a/trunk/drivers/usb/serial/ir-usb.c +++ b/trunk/drivers/usb/serial/ir-usb.c @@ -138,7 +138,6 @@ static struct usb_serial_driver ir_device = { .name = "ir-usb", }, .description = "IR Dongle", - .usb_driver = &ir_driver, .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/trunk/drivers/usb/serial/keyspan.c b/trunk/drivers/usb/serial/keyspan.c index e6966f12ed5a..9d2fdfd6865f 100644 --- a/trunk/drivers/usb/serial/keyspan.c +++ b/trunk/drivers/usb/serial/keyspan.c @@ -1275,31 +1275,11 @@ static int keyspan_fake_startup (struct usb_serial *serial) } /* Helper functions used by keyspan_setup_urbs */ -static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const *serial, - int endpoint) -{ - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *ep; - int i; - - iface_desc = serial->interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - ep = &iface_desc->endpoint[i].desc; - if (ep->bEndpointAddress == endpoint) - return ep; - } - dev_warn(&serial->interface->dev, "found no endpoint descriptor for " - "endpoint %x\n", endpoint); - return NULL; -} - static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, int dir, void *ctx, char *buf, int len, void (*callback)(struct urb *)) { struct urb *urb; - struct usb_endpoint_descriptor const *ep_desc; - char const *ep_type_name; if (endpoint == -1) return NULL; /* endpoint not needed */ @@ -1311,32 +1291,11 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, return NULL; } - ep_desc = find_ep(serial, endpoint); - if (!ep_desc) { - /* leak the urb, something's wrong and the callers don't care */ - return urb; - } - if (usb_endpoint_xfer_int(ep_desc)) { - ep_type_name = "INT"; - usb_fill_int_urb(urb, serial->dev, - usb_sndintpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx, - ep_desc->bInterval); - } else if (usb_endpoint_xfer_bulk(ep_desc)) { - ep_type_name = "BULK"; - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx); - } else { - dev_warn(&serial->interface->dev, - "unsupported endpoint type %x\n", - ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); - usb_free_urb(urb); - return NULL; - } + /* Fill URB using supplied data. */ + usb_fill_bulk_urb(urb, serial->dev, + usb_sndbulkpipe(serial->dev, endpoint) | dir, + buf, len, callback, ctx); - dbg("%s - using urb %p for %s endpoint %x", - __func__, urb, ep_type_name, endpoint); return urb; } diff --git a/trunk/drivers/usb/serial/keyspan.h b/trunk/drivers/usb/serial/keyspan.h index c6830cbdc6df..6413d73c139c 100644 --- a/trunk/drivers/usb/serial/keyspan.h +++ b/trunk/drivers/usb/serial/keyspan.h @@ -229,6 +229,7 @@ struct ezusb_hex_record { #define keyspan_usa28_product_id 0x010f #define keyspan_usa28x_product_id 0x0110 #define keyspan_usa28xa_product_id 0x0115 +#define keyspan_usa28xb_product_id 0x0110 #define keyspan_usa49w_product_id 0x010a #define keyspan_usa49wlc_product_id 0x012a @@ -510,6 +511,7 @@ static struct usb_device_id keyspan_ids_combined[] = { { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, + { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)}, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, { } /* Terminating entry */ @@ -557,6 +559,7 @@ static struct usb_device_id keyspan_2port_ids[] = { { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, + { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) }, { } /* Terminating entry */ }; @@ -573,7 +576,6 @@ static struct usb_serial_driver keyspan_pre_device = { .name = "keyspan_no_firm", }, .description = "Keyspan - (without firmware)", - .usb_driver = &keyspan_driver, .id_table = keyspan_pre_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -588,7 +590,6 @@ static struct usb_serial_driver keyspan_1port_device = { .name = "keyspan_1", }, .description = "Keyspan 1 port adapter", - .usb_driver = &keyspan_driver, .id_table = keyspan_1port_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -616,7 +617,6 @@ static struct usb_serial_driver keyspan_2port_device = { .name = "keyspan_2", }, .description = "Keyspan 2 port adapter", - .usb_driver = &keyspan_driver, .id_table = keyspan_2port_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -644,7 +644,6 @@ static struct usb_serial_driver keyspan_4port_device = { .name = "keyspan_4", }, .description = "Keyspan 4 port adapter", - .usb_driver = &keyspan_driver, .id_table = keyspan_4port_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 5, diff --git a/trunk/drivers/usb/serial/keyspan_pda.c b/trunk/drivers/usb/serial/keyspan_pda.c index da514cb785b3..126b9703bbaf 100644 --- a/trunk/drivers/usb/serial/keyspan_pda.c +++ b/trunk/drivers/usb/serial/keyspan_pda.c @@ -793,7 +793,6 @@ static struct usb_serial_driver keyspan_pda_fake_device = { .name = "keyspan_pda_pre", }, .description = "Keyspan PDA - (prerenumeration)", - .usb_driver = &keyspan_pda_driver, .id_table = id_table_fake, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -810,7 +809,6 @@ static struct usb_serial_driver xircom_pgs_fake_device = { .name = "xircom_no_firm", }, .description = "Xircom / Entregra PGS - (prerenumeration)", - .usb_driver = &keyspan_pda_driver, .id_table = id_table_fake_xircom, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -826,7 +824,6 @@ static struct usb_serial_driver keyspan_pda_device = { .name = "keyspan_pda", }, .description = "Keyspan PDA", - .usb_driver = &keyspan_pda_driver, .id_table = id_table_std, .num_interrupt_in = 1, .num_bulk_in = 0, diff --git a/trunk/drivers/usb/serial/kl5kusb105.c b/trunk/drivers/usb/serial/kl5kusb105.c index b2097c45a235..5c4b06a99ac0 100644 --- a/trunk/drivers/usb/serial/kl5kusb105.c +++ b/trunk/drivers/usb/serial/kl5kusb105.c @@ -124,7 +124,6 @@ static struct usb_serial_driver kl5kusb105d_device = { .name = "kl5kusb105d", }, .description = "KL5KUSB105D / PalmConnect", - .usb_driver = &kl5kusb105d_driver, .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/trunk/drivers/usb/serial/kobil_sct.c b/trunk/drivers/usb/serial/kobil_sct.c index 0683b51f0932..62bea0c923bd 100644 --- a/trunk/drivers/usb/serial/kobil_sct.c +++ b/trunk/drivers/usb/serial/kobil_sct.c @@ -110,7 +110,6 @@ static struct usb_serial_driver kobil_device = { .name = "kobil", }, .description = "KOBIL USB smart card terminal", - .usb_driver = &kobil_driver, .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 0, diff --git a/trunk/drivers/usb/serial/mct_u232.c b/trunk/drivers/usb/serial/mct_u232.c index 4cd839b1407f..38b1d17e06ef 100644 --- a/trunk/drivers/usb/serial/mct_u232.c +++ b/trunk/drivers/usb/serial/mct_u232.c @@ -137,7 +137,6 @@ static struct usb_serial_driver mct_u232_device = { .name = "mct_u232", }, .description = "MCT U232", - .usb_driver = &mct_u232_driver, .id_table = id_table_combined, .num_interrupt_in = 2, .num_bulk_in = 0, diff --git a/trunk/drivers/usb/serial/mos7720.c b/trunk/drivers/usb/serial/mos7720.c index 6109c6704a73..e55f4ed81d7b 100644 --- a/trunk/drivers/usb/serial/mos7720.c +++ b/trunk/drivers/usb/serial/mos7720.c @@ -1605,21 +1605,12 @@ static void mos7720_shutdown(struct usb_serial *serial) usb_set_serial_data(serial, NULL); } -static struct usb_driver usb_driver = { - .name = "moschip7720", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = moschip_port_id_table, - .no_dynamic_id = 1, -}; - static struct usb_serial_driver moschip7720_2port_driver = { .driver = { .owner = THIS_MODULE, .name = "moschip7720", }, .description = "Moschip 2 port adapter", - .usb_driver = &usb_driver, .id_table = moschip_port_id_table, .num_interrupt_in = 1, .num_bulk_in = 2, @@ -1640,6 +1631,13 @@ static struct usb_serial_driver moschip7720_2port_driver = { .read_bulk_callback = mos7720_bulk_in_callback, }; +static struct usb_driver usb_driver = { + .name = "moschip7720", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = moschip_port_id_table, +}; + static int __init moschip7720_init(void) { int retval; diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index b2264a87617b..83f661403ba1 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -2834,21 +2834,12 @@ static void mos7840_shutdown(struct usb_serial *serial) } -static struct usb_driver io_driver = { - .name = "mos7840", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = moschip_id_table_combined, - .no_dynamic_id = 1, -}; - static struct usb_serial_driver moschip7840_4port_device = { .driver = { .owner = THIS_MODULE, .name = "mos7840", }, .description = DRIVER_DESC, - .usb_driver = &io_driver, .id_table = moschip_port_id_table, .num_interrupt_in = 1, //NUM_DONT_CARE,//1, #ifdef check @@ -2878,6 +2869,13 @@ static struct usb_serial_driver moschip7840_4port_device = { .read_int_callback = mos7840_interrupt_callback, }; +static struct usb_driver io_driver = { + .name = "mos7840", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = moschip_id_table_combined, +}; + /**************************************************************************** * moschip7840_init * This is called by the module subsystem, or on startup to initialize us diff --git a/trunk/drivers/usb/serial/navman.c b/trunk/drivers/usb/serial/navman.c index 90701111d746..054abee81652 100644 --- a/trunk/drivers/usb/serial/navman.c +++ b/trunk/drivers/usb/serial/navman.c @@ -119,7 +119,6 @@ static struct usb_serial_driver navman_device = { .name = "navman", }, .id_table = id_table, - .usb_driver = &navman_driver, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, diff --git a/trunk/drivers/usb/serial/omninet.c b/trunk/drivers/usb/serial/omninet.c index 0216ac12a27d..bc91d3b726fc 100644 --- a/trunk/drivers/usb/serial/omninet.c +++ b/trunk/drivers/usb/serial/omninet.c @@ -93,7 +93,6 @@ static struct usb_serial_driver zyxel_omninet_device = { .name = "omninet", }, .description = "ZyXEL - omni.net lcd plus usb", - .usb_driver = &omninet_driver, .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index ced9f32b29d9..0fed43a96871 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -135,7 +135,6 @@ static struct usb_serial_driver option_1port_device = { .name = "option1", }, .description = "GSM modem (1-port)", - .usb_driver = &option_driver, .id_table = option_ids1, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index 6c083d4e2c9b..5dc2ac9afa90 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -1118,7 +1118,6 @@ static struct usb_serial_driver pl2303_device = { .name = "pl2303", }, .id_table = id_table, - .usb_driver = &pl2303_driver, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, .num_bulk_out = 1, diff --git a/trunk/drivers/usb/serial/safe_serial.c b/trunk/drivers/usb/serial/safe_serial.c index 5a03a3fc9386..30b7ebc8d45d 100644 --- a/trunk/drivers/usb/serial/safe_serial.c +++ b/trunk/drivers/usb/serial/safe_serial.c @@ -402,7 +402,6 @@ static struct usb_serial_driver safe_device = { .name = "safe_serial", }, .id_table = id_table, - .usb_driver = &safe_driver, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index ecedd833818d..6d8e91e00ecf 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -13,9 +13,10 @@ Portions based on the option driver by Matthias Urlichs Whom based his on the Keyspan driver by Hugh Blemings + History: */ -#define DRIVER_VERSION "v.1.0.6" +#define DRIVER_VERSION "v.1.0.5" #define DRIVER_AUTHOR "Kevin Lloyd " #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" @@ -30,15 +31,14 @@ static struct usb_device_id id_table [] = { - { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ + { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ - { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ + { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ - { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ + { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ @@ -55,15 +55,14 @@ static struct usb_device_id id_table_1port [] = { }; static struct usb_device_id id_table_3port [] = { - { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ + { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ - { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ + { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ - { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ + { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ { } @@ -82,7 +81,7 @@ static int debug; /* per port private data */ #define N_IN_URB 4 -#define N_OUT_URB 4 +#define N_OUT_URB 1 #define IN_BUFLEN 4096 #define OUT_BUFLEN 128 @@ -397,8 +396,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) struct usb_serial *serial = port->serial; int i, err; struct urb *urb; - int result; - __u16 set_mode_dzero = 0x0000; portdata = usb_get_serial_port_data(port); @@ -445,12 +442,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) port->tty->low_latency = 1; - /* set mode to D0 */ - result = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0x00, 0x40, set_mode_dzero, 0, NULL, - 0, USB_CTRL_SET_TIMEOUT); - sierra_send_setup(port); return (0); @@ -623,7 +614,6 @@ static struct usb_serial_driver sierra_1port_device = { }, .description = "Sierra USB modem (1 port)", .id_table = id_table_1port, - .usb_driver = &sierra_driver, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, .num_bulk_out = 1, @@ -652,7 +642,6 @@ static struct usb_serial_driver sierra_3port_device = { }, .description = "Sierra USB modem (3 port)", .id_table = id_table_3port, - .usb_driver = &sierra_driver, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 3, .num_bulk_out = 3, diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.c b/trunk/drivers/usb/serial/ti_usb_3410_5052.c index 4203e2b1a761..83189005c6fb 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.c +++ b/trunk/drivers/usb/serial/ti_usb_3410_5052.c @@ -262,7 +262,6 @@ static struct usb_serial_driver ti_1port_device = { .name = "ti_usb_3410_5052_1", }, .description = "TI USB 3410 1 port adapter", - .usb_driver = &ti_usb_driver, .id_table = ti_id_table_3410, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -293,7 +292,6 @@ static struct usb_serial_driver ti_2port_device = { .name = "ti_usb_3410_5052_2", }, .description = "TI USB 5052 2 port adapter", - .usb_driver = &ti_usb_driver, .id_table = ti_id_table_5052, .num_interrupt_in = 1, .num_bulk_in = 2, diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 6bf22a28adb8..716f6806cc89 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -59,19 +59,14 @@ static struct usb_driver usb_serial_driver = { static int debug; static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ -static spinlock_t table_lock; static LIST_HEAD(usb_serial_driver_list); struct usb_serial *usb_serial_get_by_index(unsigned index) { - struct usb_serial *serial; - - spin_lock(&table_lock); - serial = serial_table[index]; + struct usb_serial *serial = serial_table[index]; if (serial) kref_get(&serial->kref); - spin_unlock(&table_lock); return serial; } @@ -83,7 +78,6 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po dbg("%s %d", __FUNCTION__, num_ports); *minor = 0; - spin_lock(&table_lock); for (i = 0; i < SERIAL_TTY_MINORS; ++i) { if (serial_table[i]) continue; @@ -102,10 +96,8 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po dbg("%s - minor base = %d", __FUNCTION__, *minor); for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) serial_table[i] = serial; - spin_unlock(&table_lock); return serial; } - spin_unlock(&table_lock); return NULL; } @@ -118,11 +110,9 @@ static void return_serial(struct usb_serial *serial) if (serial == NULL) return; - spin_lock(&table_lock); for (i = 0; i < serial->num_ports; ++i) { serial_table[serial->minor + i] = NULL; } - spin_unlock(&table_lock); } static void destroy_serial(struct kref *kref) @@ -281,7 +271,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) { struct usb_serial_port *port = tty->driver_data; - int retval = -ENODEV; + int retval = -EINVAL; if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) goto exit; @@ -289,7 +279,6 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); if (!port->open_count) { - retval = -EINVAL; dbg("%s - port not opened", __FUNCTION__); goto exit; } @@ -570,20 +559,15 @@ static void port_release(struct device *dev) port_free(port); } -static void kill_traffic(struct usb_serial_port *port) -{ - usb_kill_urb(port->read_urb); - usb_kill_urb(port->write_urb); - usb_kill_urb(port->interrupt_in_urb); - usb_kill_urb(port->interrupt_out_urb); -} - static void port_free(struct usb_serial_port *port) { - kill_traffic(port); + usb_kill_urb(port->read_urb); usb_free_urb(port->read_urb); + usb_kill_urb(port->write_urb); usb_free_urb(port->write_urb); + usb_kill_urb(port->interrupt_in_urb); usb_free_urb(port->interrupt_in_urb); + usb_kill_urb(port->interrupt_out_urb); usb_free_urb(port->interrupt_out_urb); kfree(port->bulk_in_buffer); kfree(port->bulk_out_buffer); @@ -612,39 +596,6 @@ static struct usb_serial * create_serial (struct usb_device *dev, return serial; } -static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf, - struct usb_serial_driver *drv) -{ - struct usb_dynid *dynid; - - spin_lock(&drv->dynids.lock); - list_for_each_entry(dynid, &drv->dynids.list, node) { - if (usb_match_one_id(intf, &dynid->id)) { - spin_unlock(&drv->dynids.lock); - return &dynid->id; - } - } - spin_unlock(&drv->dynids.lock); - return NULL; -} - -static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv, - struct usb_interface *intf) -{ - const struct usb_device_id *id; - - id = usb_match_id(intf, drv->id_table); - if (id) { - dbg("static descriptor matches"); - goto exit; - } - id = match_dynamic_id(intf, drv); - if (id) - dbg("dynamic descriptor matches"); -exit: - return id; -} - static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) { struct list_head *p; @@ -654,9 +605,11 @@ static struct usb_serial_driver *search_serial_device(struct usb_interface *ifac /* Check if the usb id matches a known device */ list_for_each(p, &usb_serial_driver_list) { t = list_entry(p, struct usb_serial_driver, driver_list); - id = get_iface_id(t, iface); - if (id) + id = usb_match_id(iface, t->id_table); + if (id != NULL) { + dbg("descriptor matches"); return t; + } } return NULL; @@ -686,17 +639,14 @@ int usb_serial_probe(struct usb_interface *interface, int num_ports = 0; int max_endpoints; - lock_kernel(); /* guard against unloading a serial driver module */ type = search_serial_device(interface); if (!type) { - unlock_kernel(); dbg("none matched"); return -ENODEV; } serial = create_serial (dev, interface, type); if (!serial) { - unlock_kernel(); dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); return -ENOMEM; } @@ -706,18 +656,16 @@ int usb_serial_probe(struct usb_interface *interface, const struct usb_device_id *id; if (!try_module_get(type->driver.owner)) { - unlock_kernel(); dev_err(&interface->dev, "module get failed, exiting\n"); kfree (serial); return -EIO; } - id = get_iface_id(type, interface); + id = usb_match_id(interface, type->id_table); retval = type->probe(serial, id); module_put(type->driver.owner); if (retval) { - unlock_kernel(); dbg ("sub driver rejected device"); kfree (serial); return retval; @@ -787,7 +735,6 @@ int usb_serial_probe(struct usb_interface *interface, * properly during a later invocation of usb_serial_probe */ if (num_bulk_in == 0 || num_bulk_out == 0) { - unlock_kernel(); dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); kfree (serial); return -ENODEV; @@ -803,7 +750,6 @@ int usb_serial_probe(struct usb_interface *interface, if (type == &usb_serial_generic_device) { num_ports = num_bulk_out; if (num_ports == 0) { - unlock_kernel(); dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); kfree (serial); return -EIO; @@ -814,7 +760,6 @@ int usb_serial_probe(struct usb_interface *interface, /* if this device type has a calc_num_ports function, call it */ if (type->calc_num_ports) { if (!try_module_get(type->driver.owner)) { - unlock_kernel(); dev_err(&interface->dev, "module get failed, exiting\n"); kfree (serial); return -EIO; @@ -826,6 +771,12 @@ int usb_serial_probe(struct usb_interface *interface, num_ports = type->num_ports; } + if (get_free_serial (serial, num_ports, &minor) == NULL) { + dev_err(&interface->dev, "No more free serial devices\n"); + kfree (serial); + return -ENOMEM; + } + serial->minor = minor; serial->num_ports = num_ports; serial->num_bulk_in = num_bulk_in; @@ -840,8 +791,6 @@ int usb_serial_probe(struct usb_interface *interface, max_endpoints = max(max_endpoints, num_interrupt_out); max_endpoints = max(max_endpoints, (int)serial->num_ports); serial->num_port_pointers = max_endpoints; - unlock_kernel(); - dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); for (i = 0; i < max_endpoints; ++i) { port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); @@ -976,11 +925,6 @@ int usb_serial_probe(struct usb_interface *interface, } } - if (get_free_serial (serial, num_ports, &minor) == NULL) { - dev_err(&interface->dev, "No more free serial devices\n"); - goto probe_error; - } - /* register all of the individual ports with the driver core */ for (i = 0; i < num_ports; ++i) { port = serial->port[i]; @@ -1058,11 +1002,8 @@ void usb_serial_disconnect(struct usb_interface *interface) if (serial) { for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; - if (port) { - if (port->tty) - tty_hangup(port->tty); - kill_traffic(port); - } + if (port && port->tty) + tty_hangup(port->tty); } /* let the last holder of this object * cause it to be cleaned up */ @@ -1099,7 +1040,6 @@ static int __init usb_serial_init(void) return -ENOMEM; /* Initialize our global data */ - spin_lock_init(&table_lock); for (i = 0; i < SERIAL_TTY_MINORS; ++i) { serial_table[i] = NULL; } @@ -1198,7 +1138,7 @@ static void fixup_generic(struct usb_serial_driver *device) set_to_generic_if_null(device, shutdown); } -int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */ +int usb_serial_register(struct usb_serial_driver *driver) { int retval; @@ -1222,7 +1162,7 @@ int usb_serial_register(struct usb_serial_driver *driver) /* must be called with } -void usb_serial_deregister(struct usb_serial_driver *device) /* must be called with BKL held */ +void usb_serial_deregister(struct usb_serial_driver *device) { info("USB Serial deregistering driver %s", device->description); list_del(&device->driver_list); diff --git a/trunk/drivers/usb/serial/visor.c b/trunk/drivers/usb/serial/visor.c index 2f59ff226e2c..b09f06096056 100644 --- a/trunk/drivers/usb/serial/visor.c +++ b/trunk/drivers/usb/serial/visor.c @@ -90,6 +90,8 @@ static struct usb_device_id id_table [] = { .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID), @@ -149,6 +151,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, + { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, @@ -186,7 +189,6 @@ static struct usb_serial_driver handspring_device = { .name = "visor", }, .description = "Handspring Visor / Palm OS", - .usb_driver = &visor_driver, .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 2, @@ -217,7 +219,6 @@ static struct usb_serial_driver clie_5_device = { .name = "clie_5", }, .description = "Sony Clie 5.0", - .usb_driver = &visor_driver, .id_table = clie_id_5_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 2, @@ -248,7 +249,6 @@ static struct usb_serial_driver clie_3_5_device = { .name = "clie_3.5", }, .description = "Sony Clie 3.5", - .usb_driver = &visor_driver, .id_table = clie_id_3_5_table, .num_interrupt_in = 0, .num_bulk_in = 1, diff --git a/trunk/drivers/usb/serial/visor.h b/trunk/drivers/usb/serial/visor.h index 4ce6f62a6f39..765118d83fb6 100644 --- a/trunk/drivers/usb/serial/visor.h +++ b/trunk/drivers/usb/serial/visor.h @@ -32,6 +32,7 @@ #define PALM_TUNGSTEN_T_ID 0x0060 #define PALM_TREO_650 0x0061 #define PALM_TUNGSTEN_Z_ID 0x0031 +#define PALM_ZIRE31_ID 0x0061 #define PALM_ZIRE_ID 0x0070 #define PALM_M100_ID 0x0080 diff --git a/trunk/drivers/usb/serial/whiteheat.c b/trunk/drivers/usb/serial/whiteheat.c index bf16e9e1d84e..5483d8564c1b 100644 --- a/trunk/drivers/usb/serial/whiteheat.c +++ b/trunk/drivers/usb/serial/whiteheat.c @@ -161,7 +161,6 @@ static struct usb_serial_driver whiteheat_fake_device = { .name = "whiteheatnofirm", }, .description = "Connect Tech - WhiteHEAT - (prerenumeration)", - .usb_driver = &whiteheat_driver, .id_table = id_table_prerenumeration, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -177,7 +176,6 @@ static struct usb_serial_driver whiteheat_device = { .name = "whiteheat", }, .description = "Connect Tech - WhiteHEAT", - .usb_driver = &whiteheat_driver, .id_table = id_table_std, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, diff --git a/trunk/drivers/usb/storage/onetouch.c b/trunk/drivers/usb/storage/onetouch.c index 6d3dad3d1dae..e565d3d2ab29 100644 --- a/trunk/drivers/usb/storage/onetouch.c +++ b/trunk/drivers/usb/storage/onetouch.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "usb.h" #include "onetouch.h" diff --git a/trunk/drivers/usb/storage/scsiglue.c b/trunk/drivers/usb/storage/scsiglue.c index 70234f5dbeeb..e1072d52d641 100644 --- a/trunk/drivers/usb/storage/scsiglue.c +++ b/trunk/drivers/usb/storage/scsiglue.c @@ -110,6 +110,23 @@ static int slave_configure(struct scsi_device *sdev) * the end, scatter-gather buffers follow page boundaries. */ blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); + /* Set the SCSI level to at least 2. We'll leave it at 3 if that's + * what is originally reported. We need this to avoid confusing + * the SCSI layer with devices that report 0 or 1, but need 10-byte + * commands (ala ATAPI devices behind certain bridges, or devices + * which simply have broken INQUIRY data). + * + * NOTE: This means /dev/sg programs (ala cdrecord) will get the + * actual information. This seems to be the preference for + * programs like that. + * + * NOTE: This also means that /proc/scsi/scsi and sysfs may report + * the actual value or the modified one, depending on where the + * data comes from. + */ + if (sdev->scsi_level < SCSI_2) + sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; + /* Many devices have trouble transfering more than 32KB at a time, * while others have trouble with more than 64K. At this time we * are limiting both to 32K (64 sectores). @@ -159,9 +176,7 @@ static int slave_configure(struct scsi_device *sdev) * a Get-Max-LUN request, we won't lose much by setting the * revision level down to 2. The only devices that would be * affected are those with sparse LUNs. */ - if (sdev->scsi_level > SCSI_2) - sdev->sdev_target->scsi_level = - sdev->scsi_level = SCSI_2; + sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable * Hardware Error) when any low-level error occurs, @@ -179,16 +194,6 @@ static int slave_configure(struct scsi_device *sdev) sdev->use_10_for_ms = 1; } - /* The CB and CBI transports have no way to pass LUN values - * other than the bits in the second byte of a CDB. But those - * bits don't get set to the LUN value if the device reports - * scsi_level == 0 (UNKNOWN). Hence such devices must necessarily - * be single-LUN. - */ - if ((us->protocol == US_PR_CB || us->protocol == US_PR_CBI) && - sdev->scsi_level == SCSI_UNKNOWN) - us->max_lun = 0; - /* Some devices choke when they receive a PREVENT-ALLOW MEDIUM * REMOVAL command, so suppress those commands. */ if (us->flags & US_FL_NOT_LOCKABLE) diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index f49a62fc32d2..b49f2a78189e 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -573,7 +573,7 @@ UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110, #endif /* Submitted by Olaf Hering, SuSE Bugzilla #49049 */ -UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000, +UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x0501, "Sony", "USB Floppy Drive", US_SC_DEVICE, US_PR_DEVICE, NULL, @@ -1325,6 +1325,13 @@ UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Jan Mate */ +UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, + "Sony Ericsson", + "P990i", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* Reported by Kevin Cernekee * Tested on hardware version 1.10. * Entry is needed only for the initializer function override. diff --git a/trunk/drivers/usb/storage/usb.c b/trunk/drivers/usb/storage/usb.c index 7e7ec29782f1..70644506651f 100644 --- a/trunk/drivers/usb/storage/usb.c +++ b/trunk/drivers/usb/storage/usb.c @@ -731,27 +731,26 @@ static int get_pipes(struct us_data *us) struct usb_endpoint_descriptor *ep_int = NULL; /* - * Find the first endpoint of each type we need. + * Find the endpoints we need. * We are expecting a minimum of 2 endpoints - in and out (bulk). - * An optional interrupt-in is OK (necessary for CBI protocol). + * An optional interrupt is OK (necessary for CBI protocol). * We will ignore any others. */ for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { ep = &altsetting->endpoint[i].desc; + /* Is it a BULK endpoint? */ if (usb_endpoint_xfer_bulk(ep)) { - if (usb_endpoint_dir_in(ep)) { - if (!ep_in) - ep_in = ep; - } else { - if (!ep_out) - ep_out = ep; - } + /* BULK in or out? */ + if (usb_endpoint_dir_in(ep)) + ep_in = ep; + else + ep_out = ep; } - else if (usb_endpoint_is_int_in(ep)) { - if (!ep_int) - ep_int = ep; + /* Is it an interrupt endpoint? */ + else if (usb_endpoint_xfer_int(ep)) { + ep_int = ep; } } diff --git a/trunk/drivers/video/output.c b/trunk/drivers/video/output.c deleted file mode 100644 index 1473f2c892d2..000000000000 --- a/trunk/drivers/video/output.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * output.c - Display Output Switch driver - * - * Copyright (C) 2006 Luming Yu - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include -#include - - -MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luming Yu "); - -static ssize_t video_output_show_state(struct class_device *dev,char *buf) -{ - ssize_t ret_size = 0; - struct output_device *od = to_output_device(dev); - if (od->props) - ret_size = sprintf(buf,"%.8x\n",od->props->get_status(od)); - return ret_size; -} - -static ssize_t video_output_store_state(struct class_device *dev, - const char *buf,size_t count) -{ - char *endp; - struct output_device *od = to_output_device(dev); - int request_state = simple_strtoul(buf,&endp,0); - size_t size = endp - buf; - - if (*endp && isspace(*endp)) - size++; - if (size != count) - return -EINVAL; - - if (od->props) { - od->request_state = request_state; - od->props->set_state(od); - } - return count; -} - -static void video_output_class_release(struct class_device *dev) -{ - struct output_device *od = to_output_device(dev); - kfree(od); -} - -static struct class_device_attribute video_output_attributes[] = { - __ATTR(state, 0644, video_output_show_state, video_output_store_state), - __ATTR_NULL, -}; - -static struct class video_output_class = { - .name = "video_output", - .release = video_output_class_release, - .class_dev_attrs = video_output_attributes, -}; - -struct output_device *video_output_register(const char *name, - struct device *dev, - void *devdata, - struct output_properties *op) -{ - struct output_device *new_dev; - int ret_code = 0; - - new_dev = kzalloc(sizeof(struct output_device),GFP_KERNEL); - if (!new_dev) { - ret_code = -ENOMEM; - goto error_return; - } - new_dev->props = op; - new_dev->class_dev.class = &video_output_class; - new_dev->class_dev.dev = dev; - strlcpy(new_dev->class_dev.class_id,name,KOBJ_NAME_LEN); - class_set_devdata(&new_dev->class_dev,devdata); - ret_code = class_device_register(&new_dev->class_dev); - if (ret_code) { - kfree(new_dev); - goto error_return; - } - return new_dev; - -error_return: - return ERR_PTR(ret_code); -} -EXPORT_SYMBOL(video_output_register); - -void video_output_unregister(struct output_device *dev) -{ - if (!dev) - return; - class_device_unregister(&dev->class_dev); -} -EXPORT_SYMBOL(video_output_unregister); - -static void __exit video_output_class_exit(void) -{ - class_unregister(&video_output_class); -} - -static int __init video_output_class_init(void) -{ - return class_register(&video_output_class); -} - -postcore_initcall(video_output_class_init); -module_exit(video_output_class_exit); diff --git a/trunk/fs/ocfs2/cluster/tcp_internal.h b/trunk/fs/ocfs2/cluster/tcp_internal.h index b700dc9624d1..775c911342f4 100644 --- a/trunk/fs/ocfs2/cluster/tcp_internal.h +++ b/trunk/fs/ocfs2/cluster/tcp_internal.h @@ -38,6 +38,9 @@ * locking semantics of the file system using the protocol. It should * be somewhere else, I'm sure, but right now it isn't. * + * New in version 6: + * - DLM lockres remote refcount fixes. + * * New in version 5: * - Network timeout checking protocol * @@ -51,7 +54,7 @@ * - full 64 bit i_size in the metadata lock lvbs * - introduction of "rw" lock and pushing meta/data locking down */ -#define O2NET_PROTOCOL_VERSION 5ULL +#define O2NET_PROTOCOL_VERSION 6ULL struct o2net_handshake { __be64 protocol_version; __be64 connector_id; diff --git a/trunk/fs/ocfs2/dlm/dlmcommon.h b/trunk/fs/ocfs2/dlm/dlmcommon.h index 6b6ff76538c5..9fa427119a3c 100644 --- a/trunk/fs/ocfs2/dlm/dlmcommon.h +++ b/trunk/fs/ocfs2/dlm/dlmcommon.h @@ -222,6 +222,7 @@ static inline void __dlm_set_joining_node(struct dlm_ctxt *dlm, #define DLM_LOCK_RES_DIRTY 0x00000008 #define DLM_LOCK_RES_IN_PROGRESS 0x00000010 #define DLM_LOCK_RES_MIGRATING 0x00000020 +#define DLM_LOCK_RES_DROPPING_REF 0x00000040 /* max milliseconds to wait to sync up a network failure with a node death */ #define DLM_NODE_DEATH_WAIT_MAX (5 * 1000) @@ -265,6 +266,8 @@ struct dlm_lock_resource u8 owner; //node which owns the lock resource, or unknown u16 state; char lvb[DLM_LVB_LEN]; + unsigned int inflight_locks; + unsigned long refmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; }; struct dlm_migratable_lock @@ -367,7 +370,7 @@ enum { DLM_CONVERT_LOCK_MSG, /* 504 */ DLM_PROXY_AST_MSG, /* 505 */ DLM_UNLOCK_LOCK_MSG, /* 506 */ - DLM_UNUSED_MSG2, /* 507 */ + DLM_DEREF_LOCKRES_MSG, /* 507 */ DLM_MIGRATE_REQUEST_MSG, /* 508 */ DLM_MIG_LOCKRES_MSG, /* 509 */ DLM_QUERY_JOIN_MSG, /* 510 */ @@ -417,6 +420,9 @@ struct dlm_master_request u8 name[O2NM_MAX_NAME_LEN]; }; +#define DLM_ASSERT_RESPONSE_REASSERT 0x00000001 +#define DLM_ASSERT_RESPONSE_MASTERY_REF 0x00000002 + #define DLM_ASSERT_MASTER_MLE_CLEANUP 0x00000001 #define DLM_ASSERT_MASTER_REQUERY 0x00000002 #define DLM_ASSERT_MASTER_FINISH_MIGRATION 0x00000004 @@ -430,6 +436,8 @@ struct dlm_assert_master u8 name[O2NM_MAX_NAME_LEN]; }; +#define DLM_MIGRATE_RESPONSE_MASTERY_REF 0x00000001 + struct dlm_migrate_request { u8 master; @@ -648,6 +656,16 @@ struct dlm_finalize_reco __be32 pad2; }; +struct dlm_deref_lockres +{ + u32 pad1; + u16 pad2; + u8 node_idx; + u8 namelen; + + u8 name[O2NM_MAX_NAME_LEN]; +}; + static inline enum dlm_status __dlm_lockres_state_to_status(struct dlm_lock_resource *res) { @@ -721,8 +739,8 @@ void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm, struct dlm_lock_resource *res); void dlm_lockres_calc_usage(struct dlm_ctxt *dlm, struct dlm_lock_resource *res); -void dlm_purge_lockres(struct dlm_ctxt *dlm, - struct dlm_lock_resource *lockres); +int dlm_purge_lockres(struct dlm_ctxt *dlm, + struct dlm_lock_resource *lockres); static inline void dlm_lockres_get(struct dlm_lock_resource *res) { /* This is called on every lookup, so it might be worth @@ -733,6 +751,10 @@ void dlm_lockres_put(struct dlm_lock_resource *res); void __dlm_unhash_lockres(struct dlm_lock_resource *res); void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res); +struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm, + const char *name, + unsigned int len, + unsigned int hash); struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, const char *name, unsigned int len, @@ -753,6 +775,47 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm, const char *name, unsigned int namelen); +#define dlm_lockres_set_refmap_bit(bit,res) \ + __dlm_lockres_set_refmap_bit(bit,res,__FILE__,__LINE__) +#define dlm_lockres_clear_refmap_bit(bit,res) \ + __dlm_lockres_clear_refmap_bit(bit,res,__FILE__,__LINE__) + +static inline void __dlm_lockres_set_refmap_bit(int bit, + struct dlm_lock_resource *res, + const char *file, + int line) +{ + //printk("%s:%d:%.*s: setting bit %d\n", file, line, + // res->lockname.len, res->lockname.name, bit); + set_bit(bit, res->refmap); +} + +static inline void __dlm_lockres_clear_refmap_bit(int bit, + struct dlm_lock_resource *res, + const char *file, + int line) +{ + //printk("%s:%d:%.*s: clearing bit %d\n", file, line, + // res->lockname.len, res->lockname.name, bit); + clear_bit(bit, res->refmap); +} + +void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, + const char *file, + int line); +void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, + int new_lockres, + const char *file, + int line); +#define dlm_lockres_drop_inflight_ref(d,r) \ + __dlm_lockres_drop_inflight_ref(d,r,__FILE__,__LINE__) +#define dlm_lockres_grab_inflight_ref(d,r) \ + __dlm_lockres_grab_inflight_ref(d,r,0,__FILE__,__LINE__) +#define dlm_lockres_grab_inflight_ref_new(d,r) \ + __dlm_lockres_grab_inflight_ref(d,r,1,__FILE__,__LINE__) + void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock); void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock); void dlm_do_local_ast(struct dlm_ctxt *dlm, @@ -805,6 +868,7 @@ int dlm_lockres_is_dirty(struct dlm_ctxt *dlm, struct dlm_lock_resource *res); int dlm_migrate_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, u8 target); +int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res); int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, u8 old_master); @@ -814,6 +878,7 @@ void __dlm_lockres_reserve_ast(struct dlm_lock_resource *res); int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data); int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data); +int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data); int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data); int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data); int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data); @@ -856,10 +921,12 @@ static inline void __dlm_wait_on_lockres(struct dlm_lock_resource *res) int dlm_init_mle_cache(void); void dlm_destroy_mle_cache(void); void dlm_hb_event_notify_attached(struct dlm_ctxt *dlm, int idx, int node_up); +int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res); void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node); int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock); - +int __dlm_lockres_has_locks(struct dlm_lock_resource *res); int __dlm_lockres_unused(struct dlm_lock_resource *res); static inline const char * dlm_lock_mode_name(int mode) diff --git a/trunk/fs/ocfs2/dlm/dlmdebug.c b/trunk/fs/ocfs2/dlm/dlmdebug.c index 3f6c8d88f7af..1015cc7bf9cb 100644 --- a/trunk/fs/ocfs2/dlm/dlmdebug.c +++ b/trunk/fs/ocfs2/dlm/dlmdebug.c @@ -53,6 +53,23 @@ void dlm_print_one_lock_resource(struct dlm_lock_resource *res) spin_unlock(&res->spinlock); } +static void dlm_print_lockres_refmap(struct dlm_lock_resource *res) +{ + int bit; + assert_spin_locked(&res->spinlock); + + mlog(ML_NOTICE, " refmap nodes: [ "); + bit = 0; + while (1) { + bit = find_next_bit(res->refmap, O2NM_MAX_NODES, bit); + if (bit >= O2NM_MAX_NODES) + break; + printk("%u ", bit); + bit++; + } + printk("], inflight=%u\n", res->inflight_locks); +} + void __dlm_print_one_lock_resource(struct dlm_lock_resource *res) { struct list_head *iter2; @@ -65,6 +82,7 @@ void __dlm_print_one_lock_resource(struct dlm_lock_resource *res) res->owner, res->state); mlog(ML_NOTICE, " last used: %lu, on purge list: %s\n", res->last_used, list_empty(&res->purge) ? "no" : "yes"); + dlm_print_lockres_refmap(res); mlog(ML_NOTICE, " granted queue: \n"); list_for_each(iter2, &res->granted) { lock = list_entry(iter2, struct dlm_lock, list); diff --git a/trunk/fs/ocfs2/dlm/dlmdomain.c b/trunk/fs/ocfs2/dlm/dlmdomain.c index f0b25f2dd205..3995de360264 100644 --- a/trunk/fs/ocfs2/dlm/dlmdomain.c +++ b/trunk/fs/ocfs2/dlm/dlmdomain.c @@ -125,10 +125,10 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm, hlist_add_head(&res->hash_node, bucket); } -struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, - const char *name, - unsigned int len, - unsigned int hash) +struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm, + const char *name, + unsigned int len, + unsigned int hash) { struct hlist_head *bucket; struct hlist_node *list; @@ -154,6 +154,37 @@ struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, return NULL; } +/* intended to be called by functions which do not care about lock + * resources which are being purged (most net _handler functions). + * this will return NULL for any lock resource which is found but + * currently in the process of dropping its mastery reference. + * use __dlm_lookup_lockres_full when you need the lock resource + * regardless (e.g. dlm_get_lock_resource) */ +struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, + const char *name, + unsigned int len, + unsigned int hash) +{ + struct dlm_lock_resource *res = NULL; + + mlog_entry("%.*s\n", len, name); + + assert_spin_locked(&dlm->spinlock); + + res = __dlm_lookup_lockres_full(dlm, name, len, hash); + if (res) { + spin_lock(&res->spinlock); + if (res->state & DLM_LOCK_RES_DROPPING_REF) { + spin_unlock(&res->spinlock); + dlm_lockres_put(res); + return NULL; + } + spin_unlock(&res->spinlock); + } + + return res; +} + struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm, const char *name, unsigned int len) @@ -330,43 +361,60 @@ static void dlm_complete_dlm_shutdown(struct dlm_ctxt *dlm) wake_up(&dlm_domain_events); } -static void dlm_migrate_all_locks(struct dlm_ctxt *dlm) +static int dlm_migrate_all_locks(struct dlm_ctxt *dlm) { - int i; + int i, num, n, ret = 0; struct dlm_lock_resource *res; + struct hlist_node *iter; + struct hlist_head *bucket; + int dropped; mlog(0, "Migrating locks from domain %s\n", dlm->name); -restart: + + num = 0; spin_lock(&dlm->spinlock); for (i = 0; i < DLM_HASH_BUCKETS; i++) { - while (!hlist_empty(dlm_lockres_hash(dlm, i))) { - res = hlist_entry(dlm_lockres_hash(dlm, i)->first, - struct dlm_lock_resource, hash_node); - /* need reference when manually grabbing lockres */ +redo_bucket: + n = 0; + bucket = dlm_lockres_hash(dlm, i); + iter = bucket->first; + while (iter) { + n++; + res = hlist_entry(iter, struct dlm_lock_resource, + hash_node); dlm_lockres_get(res); - /* this should unhash the lockres - * and exit with dlm->spinlock */ - mlog(0, "purging res=%p\n", res); - if (dlm_lockres_is_dirty(dlm, res)) { - /* HACK! this should absolutely go. - * need to figure out why some empty - * lockreses are still marked dirty */ - mlog(ML_ERROR, "lockres %.*s dirty!\n", - res->lockname.len, res->lockname.name); - - spin_unlock(&dlm->spinlock); - dlm_kick_thread(dlm, res); - wait_event(dlm->ast_wq, !dlm_lockres_is_dirty(dlm, res)); - dlm_lockres_put(res); - goto restart; - } - dlm_purge_lockres(dlm, res); + /* migrate, if necessary. this will drop the dlm + * spinlock and retake it if it does migration. */ + dropped = dlm_empty_lockres(dlm, res); + + spin_lock(&res->spinlock); + __dlm_lockres_calc_usage(dlm, res); + iter = res->hash_node.next; + spin_unlock(&res->spinlock); + dlm_lockres_put(res); + + cond_resched_lock(&dlm->spinlock); + + if (dropped) + goto redo_bucket; } + num += n; + mlog(0, "%s: touched %d lockreses in bucket %d " + "(tot=%d)\n", dlm->name, n, i, num); } spin_unlock(&dlm->spinlock); - + wake_up(&dlm->dlm_thread_wq); + + /* let the dlm thread take care of purging, keep scanning until + * nothing remains in the hash */ + if (num) { + mlog(0, "%s: %d lock resources in hash last pass\n", + dlm->name, num); + ret = -EAGAIN; + } mlog(0, "DONE Migrating locks from domain %s\n", dlm->name); + return ret; } static int dlm_no_joining_node(struct dlm_ctxt *dlm) @@ -571,7 +619,9 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm) /* We changed dlm state, notify the thread */ dlm_kick_thread(dlm, NULL); - dlm_migrate_all_locks(dlm); + while (dlm_migrate_all_locks(dlm)) { + mlog(0, "%s: more migration to do\n", dlm->name); + } dlm_mark_domain_leaving(dlm); dlm_leave_domain(dlm); dlm_complete_dlm_shutdown(dlm); @@ -1082,6 +1132,13 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm) if (status) goto bail; + status = o2net_register_handler(DLM_DEREF_LOCKRES_MSG, dlm->key, + sizeof(struct dlm_deref_lockres), + dlm_deref_lockres_handler, + dlm, &dlm->dlm_domain_handlers); + if (status) + goto bail; + status = o2net_register_handler(DLM_MIGRATE_REQUEST_MSG, dlm->key, sizeof(struct dlm_migrate_request), dlm_migrate_request_handler, diff --git a/trunk/fs/ocfs2/dlm/dlmlock.c b/trunk/fs/ocfs2/dlm/dlmlock.c index e5ca3db197f6..ac91a76b1e78 100644 --- a/trunk/fs/ocfs2/dlm/dlmlock.c +++ b/trunk/fs/ocfs2/dlm/dlmlock.c @@ -163,6 +163,10 @@ static enum dlm_status dlmlock_master(struct dlm_ctxt *dlm, kick_thread = 1; } } + /* reduce the inflight count, this may result in the lockres + * being purged below during calc_usage */ + if (lock->ml.node == dlm->node_num) + dlm_lockres_drop_inflight_ref(dlm, res); spin_unlock(&res->spinlock); wake_up(&res->wq); diff --git a/trunk/fs/ocfs2/dlm/dlmmaster.c b/trunk/fs/ocfs2/dlm/dlmmaster.c index 0ad872055cb3..4645ec2e0fc3 100644 --- a/trunk/fs/ocfs2/dlm/dlmmaster.c +++ b/trunk/fs/ocfs2/dlm/dlmmaster.c @@ -99,9 +99,9 @@ static void dlm_mle_node_up(struct dlm_ctxt *dlm, int idx); static void dlm_assert_master_worker(struct dlm_work_item *item, void *data); -static int dlm_do_assert_master(struct dlm_ctxt *dlm, const char *lockname, - unsigned int namelen, void *nodemap, - u32 flags); +static int dlm_do_assert_master(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, + void *nodemap, u32 flags); static inline int dlm_mle_equal(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle, @@ -237,7 +237,8 @@ static int dlm_find_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry **mle, char *name, unsigned int namelen); -static int dlm_do_master_request(struct dlm_master_list_entry *mle, int to); +static int dlm_do_master_request(struct dlm_lock_resource *res, + struct dlm_master_list_entry *mle, int to); static int dlm_wait_for_lock_mastery(struct dlm_ctxt *dlm, @@ -687,6 +688,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm, INIT_LIST_HEAD(&res->purge); atomic_set(&res->asts_reserved, 0); res->migration_pending = 0; + res->inflight_locks = 0; kref_init(&res->refs); @@ -700,6 +702,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm, res->last_used = 0; memset(res->lvb, 0, DLM_LVB_LEN); + memset(res->refmap, 0, sizeof(res->refmap)); } struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm, @@ -722,6 +725,42 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm, return res; } +void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, + int new_lockres, + const char *file, + int line) +{ + if (!new_lockres) + assert_spin_locked(&res->spinlock); + + if (!test_bit(dlm->node_num, res->refmap)) { + BUG_ON(res->inflight_locks != 0); + dlm_lockres_set_refmap_bit(dlm->node_num, res); + } + res->inflight_locks++; + mlog(0, "%s:%.*s: inflight++: now %u\n", + dlm->name, res->lockname.len, res->lockname.name, + res->inflight_locks); +} + +void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, + const char *file, + int line) +{ + assert_spin_locked(&res->spinlock); + + BUG_ON(res->inflight_locks == 0); + res->inflight_locks--; + mlog(0, "%s:%.*s: inflight--: now %u\n", + dlm->name, res->lockname.len, res->lockname.name, + res->inflight_locks); + if (res->inflight_locks == 0) + dlm_lockres_clear_refmap_bit(dlm->node_num, res); + wake_up(&res->wq); +} + /* * lookup a lock resource by name. * may already exist in the hashtable. @@ -752,6 +791,7 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, unsigned int hash; int tries = 0; int bit, wait_on_recovery = 0; + int drop_inflight_if_nonlocal = 0; BUG_ON(!lockid); @@ -761,9 +801,30 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, lookup: spin_lock(&dlm->spinlock); - tmpres = __dlm_lookup_lockres(dlm, lockid, namelen, hash); + tmpres = __dlm_lookup_lockres_full(dlm, lockid, namelen, hash); if (tmpres) { + int dropping_ref = 0; + + spin_lock(&tmpres->spinlock); + if (tmpres->owner == dlm->node_num) { + BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF); + dlm_lockres_grab_inflight_ref(dlm, tmpres); + } else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) + dropping_ref = 1; + spin_unlock(&tmpres->spinlock); spin_unlock(&dlm->spinlock); + + /* wait until done messaging the master, drop our ref to allow + * the lockres to be purged, start over. */ + if (dropping_ref) { + spin_lock(&tmpres->spinlock); + __dlm_wait_on_lockres_flags(tmpres, DLM_LOCK_RES_DROPPING_REF); + spin_unlock(&tmpres->spinlock); + dlm_lockres_put(tmpres); + tmpres = NULL; + goto lookup; + } + mlog(0, "found in hash!\n"); if (res) dlm_lockres_put(res); @@ -793,6 +854,7 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, spin_lock(&res->spinlock); dlm_change_lockres_owner(dlm, res, dlm->node_num); __dlm_insert_lockres(dlm, res); + dlm_lockres_grab_inflight_ref(dlm, res); spin_unlock(&res->spinlock); spin_unlock(&dlm->spinlock); /* lockres still marked IN_PROGRESS */ @@ -805,29 +867,40 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, /* if we found a block, wait for lock to be mastered by another node */ blocked = dlm_find_mle(dlm, &mle, (char *)lockid, namelen); if (blocked) { + int mig; if (mle->type == DLM_MLE_MASTER) { mlog(ML_ERROR, "master entry for nonexistent lock!\n"); BUG(); - } else if (mle->type == DLM_MLE_MIGRATION) { - /* migration is in progress! */ - /* the good news is that we now know the - * "current" master (mle->master). */ - + } + mig = (mle->type == DLM_MLE_MIGRATION); + /* if there is a migration in progress, let the migration + * finish before continuing. we can wait for the absence + * of the MIGRATION mle: either the migrate finished or + * one of the nodes died and the mle was cleaned up. + * if there is a BLOCK here, but it already has a master + * set, we are too late. the master does not have a ref + * for us in the refmap. detach the mle and drop it. + * either way, go back to the top and start over. */ + if (mig || mle->master != O2NM_MAX_NODES) { + BUG_ON(mig && mle->master == dlm->node_num); + /* we arrived too late. the master does not + * have a ref for us. retry. */ + mlog(0, "%s:%.*s: late on %s\n", + dlm->name, namelen, lockid, + mig ? "MIGRATION" : "BLOCK"); spin_unlock(&dlm->master_lock); - assert_spin_locked(&dlm->spinlock); - - /* set the lockres owner and hash it */ - spin_lock(&res->spinlock); - dlm_set_lockres_owner(dlm, res, mle->master); - __dlm_insert_lockres(dlm, res); - spin_unlock(&res->spinlock); spin_unlock(&dlm->spinlock); /* master is known, detach */ - dlm_mle_detach_hb_events(dlm, mle); + if (!mig) + dlm_mle_detach_hb_events(dlm, mle); dlm_put_mle(mle); mle = NULL; - goto wake_waiters; + /* this is lame, but we cant wait on either + * the mle or lockres waitqueue here */ + if (mig) + msleep(100); + goto lookup; } } else { /* go ahead and try to master lock on this node */ @@ -858,6 +931,13 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, /* finally add the lockres to its hash bucket */ __dlm_insert_lockres(dlm, res); + /* since this lockres is new it doesnt not require the spinlock */ + dlm_lockres_grab_inflight_ref_new(dlm, res); + + /* if this node does not become the master make sure to drop + * this inflight reference below */ + drop_inflight_if_nonlocal = 1; + /* get an extra ref on the mle in case this is a BLOCK * if so, the creator of the BLOCK may try to put the last * ref at this time in the assert master handler, so we @@ -910,7 +990,7 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, ret = -EINVAL; dlm_node_iter_init(mle->vote_map, &iter); while ((nodenum = dlm_node_iter_next(&iter)) >= 0) { - ret = dlm_do_master_request(mle, nodenum); + ret = dlm_do_master_request(res, mle, nodenum); if (ret < 0) mlog_errno(ret); if (mle->master != O2NM_MAX_NODES) { @@ -960,6 +1040,8 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, wake_waiters: spin_lock(&res->spinlock); + if (res->owner != dlm->node_num && drop_inflight_if_nonlocal) + dlm_lockres_drop_inflight_ref(dlm, res); res->state &= ~DLM_LOCK_RES_IN_PROGRESS; spin_unlock(&res->spinlock); wake_up(&res->wq); @@ -998,7 +1080,7 @@ static int dlm_wait_for_lock_mastery(struct dlm_ctxt *dlm, /* this will cause the master to re-assert across * the whole cluster, freeing up mles */ if (res->owner != dlm->node_num) { - ret = dlm_do_master_request(mle, res->owner); + ret = dlm_do_master_request(res, mle, res->owner); if (ret < 0) { /* give recovery a chance to run */ mlog(ML_ERROR, "link to %u went down?: %d\n", res->owner, ret); @@ -1062,6 +1144,8 @@ static int dlm_wait_for_lock_mastery(struct dlm_ctxt *dlm, * now tell other nodes that I am * mastering this. */ mle->master = dlm->node_num; + /* ref was grabbed in get_lock_resource + * will be dropped in dlmlock_master */ assert = 1; sleep = 0; } @@ -1087,7 +1171,8 @@ static int dlm_wait_for_lock_mastery(struct dlm_ctxt *dlm, (atomic_read(&mle->woken) == 1), timeo); if (res->owner == O2NM_MAX_NODES) { - mlog(0, "waiting again\n"); + mlog(0, "%s:%.*s: waiting again\n", dlm->name, + res->lockname.len, res->lockname.name); goto recheck; } mlog(0, "done waiting, master is %u\n", res->owner); @@ -1100,8 +1185,7 @@ static int dlm_wait_for_lock_mastery(struct dlm_ctxt *dlm, m = dlm->node_num; mlog(0, "about to master %.*s here, this=%u\n", res->lockname.len, res->lockname.name, m); - ret = dlm_do_assert_master(dlm, res->lockname.name, - res->lockname.len, mle->vote_map, 0); + ret = dlm_do_assert_master(dlm, res, mle->vote_map, 0); if (ret) { /* This is a failure in the network path, * not in the response to the assert_master @@ -1117,6 +1201,8 @@ static int dlm_wait_for_lock_mastery(struct dlm_ctxt *dlm, /* set the lockres owner */ spin_lock(&res->spinlock); + /* mastery reference obtained either during + * assert_master_handler or in get_lock_resource */ dlm_change_lockres_owner(dlm, res, m); spin_unlock(&res->spinlock); @@ -1283,7 +1369,8 @@ static int dlm_restart_lock_mastery(struct dlm_ctxt *dlm, * */ -static int dlm_do_master_request(struct dlm_master_list_entry *mle, int to) +static int dlm_do_master_request(struct dlm_lock_resource *res, + struct dlm_master_list_entry *mle, int to) { struct dlm_ctxt *dlm = mle->dlm; struct dlm_master_request request; @@ -1339,6 +1426,9 @@ static int dlm_do_master_request(struct dlm_master_list_entry *mle, int to) case DLM_MASTER_RESP_YES: set_bit(to, mle->response_map); mlog(0, "node %u is the master, response=YES\n", to); + mlog(0, "%s:%.*s: master node %u now knows I have a " + "reference\n", dlm->name, res->lockname.len, + res->lockname.name, to); mle->master = to; break; case DLM_MASTER_RESP_NO: @@ -1428,8 +1518,10 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) } if (res->owner == dlm->node_num) { + mlog(0, "%s:%.*s: setting bit %u in refmap\n", + dlm->name, namelen, name, request->node_idx); + dlm_lockres_set_refmap_bit(request->node_idx, res); spin_unlock(&res->spinlock); - // mlog(0, "this node is the master\n"); response = DLM_MASTER_RESP_YES; if (mle) kmem_cache_free(dlm_mle_cache, mle); @@ -1477,7 +1569,6 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) mlog(0, "node %u is master, but trying to migrate to " "node %u.\n", tmpmle->master, tmpmle->new_master); if (tmpmle->master == dlm->node_num) { - response = DLM_MASTER_RESP_YES; mlog(ML_ERROR, "no owner on lockres, but this " "node is trying to migrate it to %u?!\n", tmpmle->new_master); @@ -1494,6 +1585,10 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) * go back and clean the mles on any * other nodes */ dispatch_assert = 1; + dlm_lockres_set_refmap_bit(request->node_idx, res); + mlog(0, "%s:%.*s: setting bit %u in refmap\n", + dlm->name, namelen, name, + request->node_idx); } else response = DLM_MASTER_RESP_NO; } else { @@ -1607,15 +1702,17 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) * can periodically run all locks owned by this node * and re-assert across the cluster... */ -static int dlm_do_assert_master(struct dlm_ctxt *dlm, const char *lockname, - unsigned int namelen, void *nodemap, - u32 flags) +int dlm_do_assert_master(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, + void *nodemap, u32 flags) { struct dlm_assert_master assert; int to, tmpret; struct dlm_node_iter iter; int ret = 0; int reassert; + const char *lockname = res->lockname.name; + unsigned int namelen = res->lockname.len; BUG_ON(namelen > O2NM_MAX_NAME_LEN); again: @@ -1647,6 +1744,7 @@ static int dlm_do_assert_master(struct dlm_ctxt *dlm, const char *lockname, mlog(0, "link to %d went down!\n", to); /* any nonzero status return will do */ ret = tmpret; + r = 0; } else if (r < 0) { /* ok, something horribly messed. kill thyself. */ mlog(ML_ERROR,"during assert master of %.*s to %u, " @@ -1661,12 +1759,29 @@ static int dlm_do_assert_master(struct dlm_ctxt *dlm, const char *lockname, spin_unlock(&dlm->master_lock); spin_unlock(&dlm->spinlock); BUG(); - } else if (r == EAGAIN) { + } + + if (r & DLM_ASSERT_RESPONSE_REASSERT && + !(r & DLM_ASSERT_RESPONSE_MASTERY_REF)) { + mlog(ML_ERROR, "%.*s: very strange, " + "master MLE but no lockres on %u\n", + namelen, lockname, to); + } + + if (r & DLM_ASSERT_RESPONSE_REASSERT) { mlog(0, "%.*s: node %u create mles on other " "nodes and requests a re-assert\n", namelen, lockname, to); reassert = 1; } + if (r & DLM_ASSERT_RESPONSE_MASTERY_REF) { + mlog(0, "%.*s: node %u has a reference to this " + "lockres, set the bit in the refmap\n", + namelen, lockname, to); + spin_lock(&res->spinlock); + dlm_lockres_set_refmap_bit(to, res); + spin_unlock(&res->spinlock); + } } if (reassert) @@ -1693,7 +1808,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data) char *name; unsigned int namelen, hash; u32 flags; - int master_request = 0; + int master_request = 0, have_lockres_ref = 0; int ret = 0; if (!dlm_grab(dlm)) @@ -1864,6 +1979,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data) dlm_change_lockres_owner(dlm, res, mle->master); } spin_unlock(&res->spinlock); + have_lockres_ref = 1; } /* master is known, detach if not already detached. @@ -1918,7 +2034,19 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data) dlm_put(dlm); if (master_request) { mlog(0, "need to tell master to reassert\n"); - ret = EAGAIN; // positive. negative would shoot down the node. + /* positive. negative would shoot down the node. */ + ret |= DLM_ASSERT_RESPONSE_REASSERT; + if (!have_lockres_ref) { + mlog(ML_ERROR, "strange, got assert from %u, MASTER " + "mle present here for %s:%.*s, but no lockres!\n", + assert->node_idx, dlm->name, namelen, name); + } + } + if (have_lockres_ref) { + /* let the master know we have a reference to the lockres */ + ret |= DLM_ASSERT_RESPONSE_MASTERY_REF; + mlog(0, "%s:%.*s: got assert from %u, need a ref\n", + dlm->name, namelen, name, assert->node_idx); } return ret; @@ -2023,9 +2151,7 @@ static void dlm_assert_master_worker(struct dlm_work_item *item, void *data) * even if one or more nodes die */ mlog(0, "worker about to master %.*s here, this=%u\n", res->lockname.len, res->lockname.name, dlm->node_num); - ret = dlm_do_assert_master(dlm, res->lockname.name, - res->lockname.len, - nodemap, flags); + ret = dlm_do_assert_master(dlm, res, nodemap, flags); if (ret < 0) { /* no need to restart, we are done */ if (!dlm_is_host_down(ret)) @@ -2097,6 +2223,104 @@ static int dlm_pre_master_reco_lockres(struct dlm_ctxt *dlm, return ret; } +/* + * DLM_DEREF_LOCKRES_MSG + */ + +int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) +{ + struct dlm_deref_lockres deref; + int ret = 0, r; + const char *lockname; + unsigned int namelen; + + lockname = res->lockname.name; + namelen = res->lockname.len; + BUG_ON(namelen > O2NM_MAX_NAME_LEN); + + mlog(0, "%s:%.*s: sending deref to %d\n", + dlm->name, namelen, lockname, res->owner); + memset(&deref, 0, sizeof(deref)); + deref.node_idx = dlm->node_num; + deref.namelen = namelen; + memcpy(deref.name, lockname, namelen); + + ret = o2net_send_message(DLM_DEREF_LOCKRES_MSG, dlm->key, + &deref, sizeof(deref), res->owner, &r); + if (ret < 0) + mlog_errno(ret); + else if (r < 0) { + /* BAD. other node says I did not have a ref. */ + mlog(ML_ERROR,"while dropping ref on %s:%.*s " + "(master=%u) got %d.\n", dlm->name, namelen, + lockname, res->owner, r); + dlm_print_one_lock_resource(res); + BUG(); + } + return ret; +} + +int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data) +{ + struct dlm_ctxt *dlm = data; + struct dlm_deref_lockres *deref = (struct dlm_deref_lockres *)msg->buf; + struct dlm_lock_resource *res = NULL; + char *name; + unsigned int namelen; + int ret = -EINVAL; + u8 node; + unsigned int hash; + + if (!dlm_grab(dlm)) + return 0; + + name = deref->name; + namelen = deref->namelen; + node = deref->node_idx; + + if (namelen > DLM_LOCKID_NAME_MAX) { + mlog(ML_ERROR, "Invalid name length!"); + goto done; + } + if (deref->node_idx >= O2NM_MAX_NODES) { + mlog(ML_ERROR, "Invalid node number: %u\n", node); + goto done; + } + + hash = dlm_lockid_hash(name, namelen); + + spin_lock(&dlm->spinlock); + res = __dlm_lookup_lockres_full(dlm, name, namelen, hash); + if (!res) { + spin_unlock(&dlm->spinlock); + mlog(ML_ERROR, "%s:%.*s: bad lockres name\n", + dlm->name, namelen, name); + goto done; + } + spin_unlock(&dlm->spinlock); + + spin_lock(&res->spinlock); + BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF); + if (test_bit(node, res->refmap)) { + ret = 0; + dlm_lockres_clear_refmap_bit(node, res); + } else { + mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " + "but it is already dropped!\n", dlm->name, namelen, + name, node); + __dlm_print_one_lock_resource(res); + } + spin_unlock(&res->spinlock); + + if (!ret) + dlm_lockres_calc_usage(dlm, res); +done: + if (res) + dlm_lockres_put(res); + dlm_put(dlm); + return ret; +} + /* * DLM_MIGRATE_LOCKRES @@ -2376,6 +2600,53 @@ int dlm_migrate_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, return ret; } +#define DLM_MIGRATION_RETRY_MS 100 + +/* Should be called only after beginning the domain leave process. + * There should not be any remaining locks on nonlocal lock resources, + * and there should be no local locks left on locally mastered resources. + * + * Called with the dlm spinlock held, may drop it to do migration, but + * will re-acquire before exit. + * + * Returns: 1 if dlm->spinlock was dropped/retaken, 0 if never dropped */ +int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) +{ + int ret; + int lock_dropped = 0; + + if (res->owner != dlm->node_num) { + if (!__dlm_lockres_unused(res)) { + mlog(ML_ERROR, "%s:%.*s: this node is not master, " + "trying to free this but locks remain\n", + dlm->name, res->lockname.len, res->lockname.name); + } + goto leave; + } + + /* Wheee! Migrate lockres here! Will sleep so drop spinlock. */ + spin_unlock(&dlm->spinlock); + lock_dropped = 1; + while (1) { + ret = dlm_migrate_lockres(dlm, res, O2NM_MAX_NODES); + if (ret >= 0) + break; + if (ret == -ENOTEMPTY) { + mlog(ML_ERROR, "lockres %.*s still has local locks!\n", + res->lockname.len, res->lockname.name); + BUG(); + } + + mlog(0, "lockres %.*s: migrate failed, " + "retrying\n", res->lockname.len, + res->lockname.name); + msleep(DLM_MIGRATION_RETRY_MS); + } + spin_lock(&dlm->spinlock); +leave: + return lock_dropped; +} + int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock) { int ret; @@ -2490,7 +2761,7 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm, { struct list_head *iter, *iter2; struct list_head *queue = &res->granted; - int i; + int i, bit; struct dlm_lock *lock; assert_spin_locked(&res->spinlock); @@ -2508,12 +2779,28 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm, BUG_ON(!list_empty(&lock->bast_list)); BUG_ON(lock->ast_pending); BUG_ON(lock->bast_pending); + dlm_lockres_clear_refmap_bit(lock->ml.node, res); list_del_init(&lock->list); dlm_lock_put(lock); } } queue++; } + bit = 0; + while (1) { + bit = find_next_bit(res->refmap, O2NM_MAX_NODES, bit); + if (bit >= O2NM_MAX_NODES) + break; + /* do not clear the local node reference, if there is a + * process holding this, let it drop the ref itself */ + if (bit != dlm->node_num) { + mlog(0, "%s:%.*s: node %u had a ref to this " + "migrating lockres, clearing\n", dlm->name, + res->lockname.len, res->lockname.name, bit); + dlm_lockres_clear_refmap_bit(bit, res); + } + bit++; + } } /* for now this is not too intelligent. we will @@ -2601,6 +2888,16 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm, mlog(0, "migrate request (node %u) returned %d!\n", nodenum, status); ret = status; + } else if (status == DLM_MIGRATE_RESPONSE_MASTERY_REF) { + /* during the migration request we short-circuited + * the mastery of the lockres. make sure we have + * a mastery ref for nodenum */ + mlog(0, "%s:%.*s: need ref for node %u\n", + dlm->name, res->lockname.len, res->lockname.name, + nodenum); + spin_lock(&res->spinlock); + dlm_lockres_set_refmap_bit(nodenum, res); + spin_unlock(&res->spinlock); } } @@ -2745,7 +3042,13 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm, /* remove it from the list so that only one * mle will be found */ list_del_init(&tmp->list); - __dlm_mle_detach_hb_events(dlm, mle); + /* this was obviously WRONG. mle is uninited here. should be tmp. */ + __dlm_mle_detach_hb_events(dlm, tmp); + ret = DLM_MIGRATE_RESPONSE_MASTERY_REF; + mlog(0, "%s:%.*s: master=%u, newmaster=%u, " + "telling master to get ref for cleared out mle " + "during migration\n", dlm->name, namelen, name, + master, new_master); } spin_unlock(&tmp->spinlock); } @@ -2753,6 +3056,8 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm, /* now add a migration mle to the tail of the list */ dlm_init_mle(mle, DLM_MLE_MIGRATION, dlm, res, name, namelen); mle->new_master = new_master; + /* the new master will be sending an assert master for this. + * at that point we will get the refmap reference */ mle->master = master; /* do this for consistency with other mle types */ set_bit(new_master, mle->maybe_map); @@ -2902,6 +3207,13 @@ int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, clear_bit(dlm->node_num, iter.node_map); spin_unlock(&dlm->spinlock); + /* ownership of the lockres is changing. account for the + * mastery reference here since old_master will briefly have + * a reference after the migration completes */ + spin_lock(&res->spinlock); + dlm_lockres_set_refmap_bit(old_master, res); + spin_unlock(&res->spinlock); + mlog(0, "now time to do a migrate request to other nodes\n"); ret = dlm_do_migrate_request(dlm, res, old_master, dlm->node_num, &iter); @@ -2914,8 +3226,7 @@ int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, res->lockname.len, res->lockname.name); /* this call now finishes out the nodemap * even if one or more nodes die */ - ret = dlm_do_assert_master(dlm, res->lockname.name, - res->lockname.len, iter.node_map, + ret = dlm_do_assert_master(dlm, res, iter.node_map, DLM_ASSERT_MASTER_FINISH_MIGRATION); if (ret < 0) { /* no longer need to retry. all living nodes contacted. */ @@ -2927,8 +3238,7 @@ int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, set_bit(old_master, iter.node_map); mlog(0, "doing assert master of %.*s back to %u\n", res->lockname.len, res->lockname.name, old_master); - ret = dlm_do_assert_master(dlm, res->lockname.name, - res->lockname.len, iter.node_map, + ret = dlm_do_assert_master(dlm, res, iter.node_map, DLM_ASSERT_MASTER_FINISH_MIGRATION); if (ret < 0) { mlog(0, "assert master to original master failed " diff --git a/trunk/fs/ocfs2/dlm/dlmrecovery.c b/trunk/fs/ocfs2/dlm/dlmrecovery.c index 367a11e9e2ed..d011a2a22742 100644 --- a/trunk/fs/ocfs2/dlm/dlmrecovery.c +++ b/trunk/fs/ocfs2/dlm/dlmrecovery.c @@ -1129,6 +1129,11 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm, if (total_locks == mres_total_locks) mres->flags |= DLM_MRES_ALL_DONE; + mlog(0, "%s:%.*s: sending mig lockres (%s) to %u\n", + dlm->name, res->lockname.len, res->lockname.name, + orig_flags & DLM_MRES_MIGRATION ? "migrate" : "recovery", + send_to); + /* send it */ ret = o2net_send_message(DLM_MIG_LOCKRES_MSG, dlm->key, mres, sz, send_to, &status); @@ -1213,6 +1218,34 @@ static int dlm_add_lock_to_array(struct dlm_lock *lock, return 0; } +static void dlm_add_dummy_lock(struct dlm_ctxt *dlm, + struct dlm_migratable_lockres *mres) +{ + struct dlm_lock dummy; + memset(&dummy, 0, sizeof(dummy)); + dummy.ml.cookie = 0; + dummy.ml.type = LKM_IVMODE; + dummy.ml.convert_type = LKM_IVMODE; + dummy.ml.highest_blocked = LKM_IVMODE; + dummy.lksb = NULL; + dummy.ml.node = dlm->node_num; + dlm_add_lock_to_array(&dummy, mres, DLM_BLOCKED_LIST); +} + +static inline int dlm_is_dummy_lock(struct dlm_ctxt *dlm, + struct dlm_migratable_lock *ml, + u8 *nodenum) +{ + if (unlikely(ml->cookie == 0 && + ml->type == LKM_IVMODE && + ml->convert_type == LKM_IVMODE && + ml->highest_blocked == LKM_IVMODE && + ml->list == DLM_BLOCKED_LIST)) { + *nodenum = ml->node; + return 1; + } + return 0; +} int dlm_send_one_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, struct dlm_migratable_lockres *mres, @@ -1260,6 +1293,14 @@ int dlm_send_one_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, goto error; } } + if (total_locks == 0) { + /* send a dummy lock to indicate a mastery reference only */ + mlog(0, "%s:%.*s: sending dummy lock to %u, %s\n", + dlm->name, res->lockname.len, res->lockname.name, + send_to, flags & DLM_MRES_RECOVERY ? "recovery" : + "migration"); + dlm_add_dummy_lock(dlm, mres); + } /* flush any remaining locks */ ret = dlm_send_mig_lockres_msg(dlm, mres, send_to, res, total_locks); if (ret < 0) @@ -1386,13 +1427,16 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data) /* add an extra ref for just-allocated lockres * otherwise the lockres will be purged immediately */ dlm_lockres_get(res); - } /* at this point we have allocated everything we need, * and we have a hashed lockres with an extra ref and * the proper res->state flags. */ ret = 0; + spin_lock(&res->spinlock); + /* drop this either when master requery finds a different master + * or when a lock is added by the recovery worker */ + dlm_lockres_grab_inflight_ref(dlm, res); if (mres->master == DLM_LOCK_RES_OWNER_UNKNOWN) { /* migration cannot have an unknown master */ BUG_ON(!(mres->flags & DLM_MRES_RECOVERY)); @@ -1400,10 +1444,11 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data) "unknown owner.. will need to requery: " "%.*s\n", mres->lockname_len, mres->lockname); } else { - spin_lock(&res->spinlock); + /* take a reference now to pin the lockres, drop it + * when locks are added in the worker */ dlm_change_lockres_owner(dlm, res, dlm->node_num); - spin_unlock(&res->spinlock); } + spin_unlock(&res->spinlock); /* queue up work for dlm_mig_lockres_worker */ dlm_grab(dlm); /* get an extra ref for the work item */ @@ -1459,6 +1504,9 @@ static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data) "this node will take it.\n", res->lockname.len, res->lockname.name); } else { + spin_lock(&res->spinlock); + dlm_lockres_drop_inflight_ref(dlm, res); + spin_unlock(&res->spinlock); mlog(0, "master needs to respond to sender " "that node %u still owns %.*s\n", real_master, res->lockname.len, @@ -1666,10 +1714,25 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, int i, bad; struct list_head *iter; struct dlm_lock *lock = NULL; + u8 from = O2NM_MAX_NODES; + unsigned int added = 0; mlog(0, "running %d locks for this lockres\n", mres->num_locks); for (i=0; inum_locks; i++) { ml = &(mres->ml[i]); + + if (dlm_is_dummy_lock(dlm, ml, &from)) { + /* placeholder, just need to set the refmap bit */ + BUG_ON(mres->num_locks != 1); + mlog(0, "%s:%.*s: dummy lock for %u\n", + dlm->name, mres->lockname_len, mres->lockname, + from); + spin_lock(&res->spinlock); + dlm_lockres_set_refmap_bit(from, res); + spin_unlock(&res->spinlock); + added++; + break; + } BUG_ON(ml->highest_blocked != LKM_IVMODE); newlock = NULL; lksb = NULL; @@ -1711,6 +1774,7 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, /* do not alter lock refcount. switching lists. */ list_move_tail(&lock->list, queue); spin_unlock(&res->spinlock); + added++; mlog(0, "just reordered a local lock!\n"); continue; @@ -1817,12 +1881,24 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, if (!bad) { dlm_lock_get(newlock); list_add_tail(&newlock->list, queue); + mlog(0, "%s:%.*s: added lock for node %u, " + "setting refmap bit\n", dlm->name, + res->lockname.len, res->lockname.name, ml->node); + dlm_lockres_set_refmap_bit(ml->node, res); + added++; } spin_unlock(&res->spinlock); } mlog(0, "done running all the locks\n"); leave: + /* balance the ref taken when the work was queued */ + if (added > 0) { + spin_lock(&res->spinlock); + dlm_lockres_drop_inflight_ref(dlm, res); + spin_unlock(&res->spinlock); + } + if (ret < 0) { mlog_errno(ret); if (newlock) @@ -1935,9 +2011,11 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm, if (res->owner == dead_node) { list_del_init(&res->recovering); spin_lock(&res->spinlock); + /* new_master has our reference from + * the lock state sent during recovery */ dlm_change_lockres_owner(dlm, res, new_master); res->state &= ~DLM_LOCK_RES_RECOVERING; - if (!__dlm_lockres_unused(res)) + if (__dlm_lockres_has_locks(res)) __dlm_dirty_lockres(dlm, res); spin_unlock(&res->spinlock); wake_up(&res->wq); @@ -1977,9 +2055,11 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm, dlm_lockres_put(res); } spin_lock(&res->spinlock); + /* new_master has our reference from + * the lock state sent during recovery */ dlm_change_lockres_owner(dlm, res, new_master); res->state &= ~DLM_LOCK_RES_RECOVERING; - if (!__dlm_lockres_unused(res)) + if (__dlm_lockres_has_locks(res)) __dlm_dirty_lockres(dlm, res); spin_unlock(&res->spinlock); wake_up(&res->wq); @@ -2048,6 +2128,7 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, { struct list_head *iter, *tmpiter; struct dlm_lock *lock; + unsigned int freed = 0; /* this node is the lockres master: * 1) remove any stale locks for the dead node @@ -2062,6 +2143,7 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, if (lock->ml.node == dead_node) { list_del_init(&lock->list); dlm_lock_put(lock); + freed++; } } list_for_each_safe(iter, tmpiter, &res->converting) { @@ -2069,6 +2151,7 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, if (lock->ml.node == dead_node) { list_del_init(&lock->list); dlm_lock_put(lock); + freed++; } } list_for_each_safe(iter, tmpiter, &res->blocked) { @@ -2076,9 +2159,23 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, if (lock->ml.node == dead_node) { list_del_init(&lock->list); dlm_lock_put(lock); + freed++; } } + if (freed) { + mlog(0, "%s:%.*s: freed %u locks for dead node %u, " + "dropping ref from lockres\n", dlm->name, + res->lockname.len, res->lockname.name, freed, dead_node); + BUG_ON(!test_bit(dead_node, res->refmap)); + dlm_lockres_clear_refmap_bit(dead_node, res); + } else if (test_bit(dead_node, res->refmap)) { + mlog(0, "%s:%.*s: dead node %u had a ref, but had " + "no locks and had not purged before dying\n", dlm->name, + res->lockname.len, res->lockname.name, dead_node); + dlm_lockres_clear_refmap_bit(dead_node, res); + } + /* do not kick thread yet */ __dlm_dirty_lockres(dlm, res); } @@ -2141,9 +2238,21 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node) spin_lock(&res->spinlock); /* zero the lvb if necessary */ dlm_revalidate_lvb(dlm, res, dead_node); - if (res->owner == dead_node) + if (res->owner == dead_node) { + if (res->state & DLM_LOCK_RES_DROPPING_REF) + mlog(0, "%s:%.*s: owned by " + "dead node %u, this node was " + "dropping its ref when it died. " + "continue, dropping the flag.\n", + dlm->name, res->lockname.len, + res->lockname.name, dead_node); + + /* the wake_up for this will happen when the + * RECOVERING flag is dropped later */ + res->state &= ~DLM_LOCK_RES_DROPPING_REF; + dlm_move_lockres_to_recovery_list(dlm, res); - else if (res->owner == dlm->node_num) { + } else if (res->owner == dlm->node_num) { dlm_free_dead_locks(dlm, res, dead_node); __dlm_lockres_calc_usage(dlm, res); } diff --git a/trunk/fs/ocfs2/dlm/dlmthread.c b/trunk/fs/ocfs2/dlm/dlmthread.c index 0c822f3ffb05..620eb824ce1d 100644 --- a/trunk/fs/ocfs2/dlm/dlmthread.c +++ b/trunk/fs/ocfs2/dlm/dlmthread.c @@ -54,9 +54,6 @@ #include "cluster/masklog.h" static int dlm_thread(void *data); -static void dlm_purge_lockres_now(struct dlm_ctxt *dlm, - struct dlm_lock_resource *lockres); - static void dlm_flush_asts(struct dlm_ctxt *dlm); #define dlm_lock_is_remote(dlm, lock) ((lock)->ml.node != (dlm)->node_num) @@ -82,14 +79,33 @@ void __dlm_wait_on_lockres_flags(struct dlm_lock_resource *res, int flags) current->state = TASK_RUNNING; } - -int __dlm_lockres_unused(struct dlm_lock_resource *res) +int __dlm_lockres_has_locks(struct dlm_lock_resource *res) { if (list_empty(&res->granted) && list_empty(&res->converting) && - list_empty(&res->blocked) && - list_empty(&res->dirty)) - return 1; + list_empty(&res->blocked)) + return 0; + return 1; +} + +/* "unused": the lockres has no locks, is not on the dirty list, + * has no inflight locks (in the gap between mastery and acquiring + * the first lock), and has no bits in its refmap. + * truly ready to be freed. */ +int __dlm_lockres_unused(struct dlm_lock_resource *res) +{ + if (!__dlm_lockres_has_locks(res) && + list_empty(&res->dirty)) { + /* try not to scan the bitmap unless the first two + * conditions are already true */ + int bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); + if (bit >= O2NM_MAX_NODES) { + /* since the bit for dlm->node_num is not + * set, inflight_locks better be zero */ + BUG_ON(res->inflight_locks != 0); + return 1; + } + } return 0; } @@ -106,46 +122,21 @@ void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm, assert_spin_locked(&res->spinlock); if (__dlm_lockres_unused(res)){ - /* For now, just keep any resource we master */ - if (res->owner == dlm->node_num) - { - if (!list_empty(&res->purge)) { - mlog(0, "we master %s:%.*s, but it is on " - "the purge list. Removing\n", - dlm->name, res->lockname.len, - res->lockname.name); - list_del_init(&res->purge); - dlm->purge_count--; - } - return; - } - if (list_empty(&res->purge)) { - mlog(0, "putting lockres %.*s from purge list\n", - res->lockname.len, res->lockname.name); + mlog(0, "putting lockres %.*s:%p onto purge list\n", + res->lockname.len, res->lockname.name, res); res->last_used = jiffies; + dlm_lockres_get(res); list_add_tail(&res->purge, &dlm->purge_list); dlm->purge_count++; - - /* if this node is not the owner, there is - * no way to keep track of who the owner could be. - * unhash it to avoid serious problems. */ - if (res->owner != dlm->node_num) { - mlog(0, "%s:%.*s: doing immediate " - "purge of lockres owned by %u\n", - dlm->name, res->lockname.len, - res->lockname.name, res->owner); - - dlm_purge_lockres_now(dlm, res); - } } } else if (!list_empty(&res->purge)) { - mlog(0, "removing lockres %.*s from purge list, " - "owner=%u\n", res->lockname.len, res->lockname.name, - res->owner); + mlog(0, "removing lockres %.*s:%p from purge list, owner=%u\n", + res->lockname.len, res->lockname.name, res, res->owner); list_del_init(&res->purge); + dlm_lockres_put(res); dlm->purge_count--; } } @@ -163,68 +154,60 @@ void dlm_lockres_calc_usage(struct dlm_ctxt *dlm, spin_unlock(&dlm->spinlock); } -/* TODO: Eventual API: Called with the dlm spinlock held, may drop it - * to do migration, but will re-acquire before exit. */ -void dlm_purge_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *lockres) +int dlm_purge_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { int master; - int ret; - - spin_lock(&lockres->spinlock); - master = lockres->owner == dlm->node_num; - spin_unlock(&lockres->spinlock); - - mlog(0, "purging lockres %.*s, master = %d\n", lockres->lockname.len, - lockres->lockname.name, master); + int ret = 0; - /* Non master is the easy case -- no migration required, just - * quit. */ + spin_lock(&res->spinlock); + if (!__dlm_lockres_unused(res)) { + spin_unlock(&res->spinlock); + mlog(0, "%s:%.*s: tried to purge but not unused\n", + dlm->name, res->lockname.len, res->lockname.name); + return -ENOTEMPTY; + } + master = (res->owner == dlm->node_num); if (!master) - goto finish; - - /* Wheee! Migrate lockres here! */ - spin_unlock(&dlm->spinlock); -again: + res->state |= DLM_LOCK_RES_DROPPING_REF; + spin_unlock(&res->spinlock); - ret = dlm_migrate_lockres(dlm, lockres, O2NM_MAX_NODES); - if (ret == -ENOTEMPTY) { - mlog(ML_ERROR, "lockres %.*s still has local locks!\n", - lockres->lockname.len, lockres->lockname.name); + mlog(0, "purging lockres %.*s, master = %d\n", res->lockname.len, + res->lockname.name, master); - BUG(); - } else if (ret < 0) { - mlog(ML_NOTICE, "lockres %.*s: migrate failed, retrying\n", - lockres->lockname.len, lockres->lockname.name); - msleep(100); - goto again; + if (!master) { + /* drop spinlock to do messaging, retake below */ + spin_unlock(&dlm->spinlock); + /* clear our bit from the master's refmap, ignore errors */ + ret = dlm_drop_lockres_ref(dlm, res); + if (ret < 0) { + mlog_errno(ret); + if (!dlm_is_host_down(ret)) + BUG(); + } + mlog(0, "%s:%.*s: dlm_deref_lockres returned %d\n", + dlm->name, res->lockname.len, res->lockname.name, ret); + spin_lock(&dlm->spinlock); } - spin_lock(&dlm->spinlock); - -finish: - if (!list_empty(&lockres->purge)) { - list_del_init(&lockres->purge); + if (!list_empty(&res->purge)) { + mlog(0, "removing lockres %.*s:%p from purgelist, " + "master = %d\n", res->lockname.len, res->lockname.name, + res, master); + list_del_init(&res->purge); + dlm_lockres_put(res); dlm->purge_count--; } - __dlm_unhash_lockres(lockres); -} - -/* make an unused lockres go away immediately. - * as soon as the dlm spinlock is dropped, this lockres - * will not be found. kfree still happens on last put. */ -static void dlm_purge_lockres_now(struct dlm_ctxt *dlm, - struct dlm_lock_resource *lockres) -{ - assert_spin_locked(&dlm->spinlock); - assert_spin_locked(&lockres->spinlock); - - BUG_ON(!__dlm_lockres_unused(lockres)); + __dlm_unhash_lockres(res); - if (!list_empty(&lockres->purge)) { - list_del_init(&lockres->purge); - dlm->purge_count--; + /* lockres is not in the hash now. drop the flag and wake up + * any processes waiting in dlm_get_lock_resource. */ + if (!master) { + spin_lock(&res->spinlock); + res->state &= ~DLM_LOCK_RES_DROPPING_REF; + spin_unlock(&res->spinlock); + wake_up(&res->wq); } - __dlm_unhash_lockres(lockres); + return 0; } static void dlm_run_purge_list(struct dlm_ctxt *dlm, @@ -268,13 +251,17 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm, break; } + mlog(0, "removing lockres %.*s:%p from purgelist\n", + lockres->lockname.len, lockres->lockname.name, lockres); list_del_init(&lockres->purge); + dlm_lockres_put(lockres); dlm->purge_count--; /* This may drop and reacquire the dlm spinlock if it * has to do migration. */ mlog(0, "calling dlm_purge_lockres!\n"); - dlm_purge_lockres(dlm, lockres); + if (dlm_purge_lockres(dlm, lockres)) + BUG(); mlog(0, "DONE calling dlm_purge_lockres!\n"); /* Avoid adding any scheduling latencies */ diff --git a/trunk/fs/sysfs/bin.c b/trunk/fs/sysfs/bin.c index d3b9f5f07db1..e8f540d38d48 100644 --- a/trunk/fs/sysfs/bin.c +++ b/trunk/fs/sysfs/bin.c @@ -16,7 +16,6 @@ #include #include -#include #include "sysfs.h" @@ -147,7 +146,7 @@ static int open(struct inode * inode, struct file * file) Error: module_put(attr->attr.owner); Done: - if (error) + if (error && kobj) kobject_put(kobj); return error; } @@ -158,7 +157,8 @@ static int release(struct inode * inode, struct file * file) struct bin_attribute * attr = to_bin_attr(file->f_path.dentry); u8 * buffer = file->private_data; - kobject_put(kobj); + if (kobj) + kobject_put(kobj); module_put(attr->attr.owner); kfree(buffer); return 0; diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index 9dcdf556c99c..511edef8b321 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "sysfs.h" DECLARE_RWSEM(sysfs_rename_sem); @@ -33,7 +32,8 @@ static struct dentry_operations sysfs_dentry_ops = { /* * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent */ -static struct sysfs_dirent * __sysfs_new_dirent(void * element) +static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd, + void * element) { struct sysfs_dirent * sd; @@ -45,28 +45,12 @@ static struct sysfs_dirent * __sysfs_new_dirent(void * element) atomic_set(&sd->s_count, 1); atomic_set(&sd->s_event, 1); INIT_LIST_HEAD(&sd->s_children); - INIT_LIST_HEAD(&sd->s_sibling); + list_add(&sd->s_sibling, &parent_sd->s_children); sd->s_element = element; return sd; } -static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd, - struct sysfs_dirent *sd) -{ - if (sd) - list_add(&sd->s_sibling, &parent_sd->s_children); -} - -static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent *parent_sd, - void * element) -{ - struct sysfs_dirent *sd; - sd = __sysfs_new_dirent(element); - __sysfs_list_dirent(parent_sd, sd); - return sd; -} - /* * * Return -EEXIST if there is already a sysfs element with the same name for @@ -93,14 +77,14 @@ int sysfs_dirent_exist(struct sysfs_dirent *parent_sd, } -static struct sysfs_dirent * -__sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type) +int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry, + void * element, umode_t mode, int type) { struct sysfs_dirent * sd; - sd = __sysfs_new_dirent(element); + sd = sysfs_new_dirent(parent_sd, element); if (!sd) - goto out; + return -ENOMEM; sd->s_mode = mode; sd->s_type = type; @@ -110,19 +94,7 @@ __sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type) dentry->d_op = &sysfs_dentry_ops; } -out: - return sd; -} - -int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry, - void * element, umode_t mode, int type) -{ - struct sysfs_dirent *sd; - - sd = __sysfs_make_dirent(dentry, element, mode, type); - __sysfs_list_dirent(parent_sd, sd); - - return sd ? 0 : -ENOMEM; + return 0; } static int init_dir(struct inode * inode) @@ -193,11 +165,11 @@ int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d) /** * sysfs_create_dir - create a directory for an object. + * @parent: parent parent object. * @kobj: object we're creating directory for. - * @shadow_parent: parent parent object. */ -int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent) +int sysfs_create_dir(struct kobject * kobj) { struct dentry * dentry = NULL; struct dentry * parent; @@ -205,9 +177,7 @@ int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent) BUG_ON(!kobj); - if (shadow_parent) - parent = shadow_parent; - else if (kobj->parent) + if (kobj->parent) parent = kobj->parent->dentry; else if (sysfs_mount && sysfs_mount->mnt_sb) parent = sysfs_mount->mnt_sb->s_root; @@ -328,12 +298,21 @@ void sysfs_remove_subdir(struct dentry * d) } -static void __sysfs_remove_dir(struct dentry *dentry) +/** + * sysfs_remove_dir - remove an object's directory. + * @kobj: object. + * + * The only thing special about this is that we remove any files in + * the directory before we remove the directory, and we've inlined + * what used to be sysfs_rmdir() below, instead of calling separately. + */ + +void sysfs_remove_dir(struct kobject * kobj) { + struct dentry * dentry = dget(kobj->dentry); struct sysfs_dirent * parent_sd; struct sysfs_dirent * sd, * tmp; - dget(dentry); if (!dentry) return; @@ -354,60 +333,32 @@ static void __sysfs_remove_dir(struct dentry *dentry) * Drop reference from dget() on entrance. */ dput(dentry); -} - -/** - * sysfs_remove_dir - remove an object's directory. - * @kobj: object. - * - * The only thing special about this is that we remove any files in - * the directory before we remove the directory, and we've inlined - * what used to be sysfs_rmdir() below, instead of calling separately. - */ - -void sysfs_remove_dir(struct kobject * kobj) -{ - __sysfs_remove_dir(kobj->dentry); kobj->dentry = NULL; } -int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent, - const char *new_name) +int sysfs_rename_dir(struct kobject * kobj, const char *new_name) { int error = 0; - struct dentry * new_dentry; + struct dentry * new_dentry, * parent; - if (!new_parent) - return -EFAULT; + if (!strcmp(kobject_name(kobj), new_name)) + return -EINVAL; + + if (!kobj->parent) + return -EINVAL; down_write(&sysfs_rename_sem); - mutex_lock(&new_parent->d_inode->i_mutex); + parent = kobj->parent->dentry; + + mutex_lock(&parent->d_inode->i_mutex); - new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name)); + new_dentry = lookup_one_len(new_name, parent, strlen(new_name)); if (!IS_ERR(new_dentry)) { - /* By allowing two different directories with the - * same d_parent we allow this routine to move - * between different shadows of the same directory - */ - if (kobj->dentry->d_parent->d_inode != new_parent->d_inode) - return -EINVAL; - else if (new_dentry->d_parent->d_inode != new_parent->d_inode) - error = -EINVAL; - else if (new_dentry == kobj->dentry) - error = -EINVAL; - else if (!new_dentry->d_inode) { + if (!new_dentry->d_inode) { error = kobject_set_name(kobj, "%s", new_name); if (!error) { - struct sysfs_dirent *sd, *parent_sd; - d_add(new_dentry, NULL); d_move(kobj->dentry, new_dentry); - - sd = kobj->dentry->d_fsdata; - parent_sd = new_parent->d_fsdata; - - list_del_init(&sd->s_sibling); - list_add(&sd->s_sibling, &parent_sd->s_children); } else d_drop(new_dentry); @@ -415,7 +366,7 @@ int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent, error = -EEXIST; dput(new_dentry); } - mutex_unlock(&new_parent->d_inode->i_mutex); + mutex_unlock(&parent->d_inode->i_mutex); up_write(&sysfs_rename_sem); return error; @@ -427,10 +378,12 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent) struct sysfs_dirent *new_parent_sd, *sd; int error; + if (!new_parent) + return -EINVAL; + old_parent_dentry = kobj->parent ? kobj->parent->dentry : sysfs_mount->mnt_sb->s_root; - new_parent_dentry = new_parent ? - new_parent->dentry : sysfs_mount->mnt_sb->s_root; + new_parent_dentry = new_parent->dentry; again: mutex_lock(&old_parent_dentry->d_inode->i_mutex); @@ -594,95 +547,6 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) return offset; } - -/** - * sysfs_make_shadowed_dir - Setup so a directory can be shadowed - * @kobj: object we're creating shadow of. - */ - -int sysfs_make_shadowed_dir(struct kobject *kobj, - void * (*follow_link)(struct dentry *, struct nameidata *)) -{ - struct inode *inode; - struct inode_operations *i_op; - - inode = kobj->dentry->d_inode; - if (inode->i_op != &sysfs_dir_inode_operations) - return -EINVAL; - - i_op = kmalloc(sizeof(*i_op), GFP_KERNEL); - if (!i_op) - return -ENOMEM; - - memcpy(i_op, &sysfs_dir_inode_operations, sizeof(*i_op)); - i_op->follow_link = follow_link; - - /* Locking of inode->i_op? - * Since setting i_op is a single word write and they - * are atomic we should be ok here. - */ - inode->i_op = i_op; - return 0; -} - -/** - * sysfs_create_shadow_dir - create a shadow directory for an object. - * @kobj: object we're creating directory for. - * - * sysfs_make_shadowed_dir must already have been called on this - * directory. - */ - -struct dentry *sysfs_create_shadow_dir(struct kobject *kobj) -{ - struct sysfs_dirent *sd; - struct dentry *parent, *dir, *shadow; - struct inode *inode; - - dir = kobj->dentry; - inode = dir->d_inode; - parent = dir->d_parent; - shadow = ERR_PTR(-EINVAL); - if (!sysfs_is_shadowed_inode(inode)) - goto out; - - shadow = d_alloc(parent, &dir->d_name); - if (!shadow) - goto nomem; - - sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR); - if (!sd) - goto nomem; - - d_instantiate(shadow, igrab(inode)); - inc_nlink(inode); - inc_nlink(parent->d_inode); - shadow->d_op = &sysfs_dentry_ops; - - dget(shadow); /* Extra count - pin the dentry in core */ - -out: - return shadow; -nomem: - dput(shadow); - shadow = ERR_PTR(-ENOMEM); - goto out; -} - -/** - * sysfs_remove_shadow_dir - remove an object's directory. - * @shadow: dentry of shadow directory - * - * The only thing special about this is that we remove any files in - * the directory before we remove the directory, and we've inlined - * what used to be sysfs_rmdir() below, instead of calling separately. - */ - -void sysfs_remove_shadow_dir(struct dentry *shadow) -{ - __sysfs_remove_dir(shadow); -} - const struct file_operations sysfs_dir_operations = { .open = sysfs_dir_open, .release = sysfs_dir_close, diff --git a/trunk/fs/sysfs/file.c b/trunk/fs/sysfs/file.c index c0e117649a4d..9cfe53e1e00d 100644 --- a/trunk/fs/sysfs/file.c +++ b/trunk/fs/sysfs/file.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -51,29 +50,17 @@ static struct sysfs_ops subsys_sysfs_ops = { .store = subsys_attr_store, }; -/** - * add_to_collection - add buffer to a collection - * @buffer: buffer to be added - * @node inode of set to add to - */ -static inline void -add_to_collection(struct sysfs_buffer *buffer, struct inode *node) -{ - struct sysfs_buffer_collection *set = node->i_private; +struct sysfs_buffer { + size_t count; + loff_t pos; + char * page; + struct sysfs_ops * ops; + struct semaphore sem; + int needs_read_fill; + int event; +}; - mutex_lock(&node->i_mutex); - list_add(&buffer->associates, &set->associates); - mutex_unlock(&node->i_mutex); -} - -static inline void -remove_from_collection(struct sysfs_buffer *buffer, struct inode *node) -{ - mutex_lock(&node->i_mutex); - list_del(&buffer->associates); - mutex_unlock(&node->i_mutex); -} /** * fill_read_buffer - allocate and fill buffer from object. @@ -83,8 +70,7 @@ remove_from_collection(struct sysfs_buffer *buffer, struct inode *node) * Allocate @buffer->page, if it hasn't been already, then call the * kobject's show() method to fill the buffer with this attribute's * data. - * This is called only once, on the file's first read unless an error - * is returned. + * This is called only once, on the file's first read. */ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer) { @@ -102,13 +88,12 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer buffer->event = atomic_read(&sd->s_event); count = ops->show(kobj,attr,buffer->page); + buffer->needs_read_fill = 0; BUG_ON(count > (ssize_t)PAGE_SIZE); - if (count >= 0) { - buffer->needs_read_fill = 0; + if (count >= 0) buffer->count = count; - } else { + else ret = count; - } return ret; } @@ -168,10 +153,6 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) ssize_t retval = 0; down(&buffer->sem); - if (buffer->orphaned) { - retval = -ENODEV; - goto out; - } if (buffer->needs_read_fill) { if ((retval = fill_read_buffer(file->f_path.dentry,buffer))) goto out; @@ -184,6 +165,7 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) return retval; } + /** * fill_write_buffer - copy buffer from userspace. * @buffer: data buffer for file. @@ -261,25 +243,19 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t ssize_t len; down(&buffer->sem); - if (buffer->orphaned) { - len = -ENODEV; - goto out; - } len = fill_write_buffer(buffer, buf, count); if (len > 0) len = flush_write_buffer(file->f_path.dentry, buffer, len); if (len > 0) *ppos += len; -out: up(&buffer->sem); return len; } -static int sysfs_open_file(struct inode *inode, struct file *file) +static int check_perm(struct inode * inode, struct file * file) { struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent); struct attribute * attr = to_attr(file->f_path.dentry); - struct sysfs_buffer_collection *set; struct sysfs_buffer * buffer; struct sysfs_ops * ops = NULL; int error = 0; @@ -309,18 +285,6 @@ static int sysfs_open_file(struct inode *inode, struct file *file) if (!ops) goto Eaccess; - /* make sure we have a collection to add our buffers to */ - mutex_lock(&inode->i_mutex); - if (!(set = inode->i_private)) { - if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL))) { - error = -ENOMEM; - goto Done; - } else { - INIT_LIST_HEAD(&set->associates); - } - } - mutex_unlock(&inode->i_mutex); - /* File needs write support. * The inode's perms must say it's ok, * and we must have a store method. @@ -346,11 +310,9 @@ static int sysfs_open_file(struct inode *inode, struct file *file) */ buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL); if (buffer) { - INIT_LIST_HEAD(&buffer->associates); init_MUTEX(&buffer->sem); buffer->needs_read_fill = 1; buffer->ops = ops; - add_to_collection(buffer, inode); file->private_data = buffer; } else error = -ENOMEM; @@ -363,11 +325,16 @@ static int sysfs_open_file(struct inode *inode, struct file *file) error = -EACCES; module_put(attr->owner); Done: - if (error) + if (error && kobj) kobject_put(kobj); return error; } +static int sysfs_open_file(struct inode * inode, struct file * filp) +{ + return check_perm(inode,filp); +} + static int sysfs_release(struct inode * inode, struct file * filp) { struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent); @@ -375,9 +342,8 @@ static int sysfs_release(struct inode * inode, struct file * filp) struct module * owner = attr->owner; struct sysfs_buffer * buffer = filp->private_data; - if (buffer) - remove_from_collection(buffer, inode); - kobject_put(kobj); + if (kobj) + kobject_put(kobj); /* After this point, attr should not be accessed. */ module_put(owner); @@ -582,7 +548,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file); void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) { - sysfs_hash_and_remove(kobj->dentry, attr->name); + sysfs_hash_and_remove(kobj->dentry,attr->name); } diff --git a/trunk/fs/sysfs/group.c b/trunk/fs/sysfs/group.c index b20951c93761..122145b0895c 100644 --- a/trunk/fs/sysfs/group.c +++ b/trunk/fs/sysfs/group.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include "sysfs.h" diff --git a/trunk/fs/sysfs/inode.c b/trunk/fs/sysfs/inode.c index 542d2bcc73df..e79e38d52c00 100644 --- a/trunk/fs/sysfs/inode.c +++ b/trunk/fs/sysfs/inode.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "sysfs.h" extern struct super_block * sysfs_sb; @@ -33,16 +32,6 @@ static struct inode_operations sysfs_inode_operations ={ .setattr = sysfs_setattr, }; -void sysfs_delete_inode(struct inode *inode) -{ - /* Free the shadowed directory inode operations */ - if (sysfs_is_shadowed_inode(inode)) { - kfree(inode->i_op); - inode->i_op = NULL; - } - return generic_delete_inode(inode); -} - int sysfs_setattr(struct dentry * dentry, struct iattr * iattr) { struct inode * inode = dentry->d_inode; @@ -220,22 +209,6 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd) return NULL; } -static inline void orphan_all_buffers(struct inode *node) -{ - struct sysfs_buffer_collection *set = node->i_private; - struct sysfs_buffer *buf; - - mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD); - if (node->i_private) { - list_for_each_entry(buf, &set->associates, associates) { - down(&buf->sem); - buf->orphaned = 1; - up(&buf->sem); - } - } - mutex_unlock(&node->i_mutex); -} - /* * Unhashes the dentry corresponding to given sysfs_dirent @@ -244,23 +217,16 @@ static inline void orphan_all_buffers(struct inode *node) void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent) { struct dentry * dentry = sd->s_dentry; - struct inode *inode; if (dentry) { spin_lock(&dcache_lock); spin_lock(&dentry->d_lock); if (!(d_unhashed(dentry) && dentry->d_inode)) { - inode = dentry->d_inode; - spin_lock(&inode->i_lock); - __iget(inode); - spin_unlock(&inode->i_lock); dget_locked(dentry); __d_drop(dentry); spin_unlock(&dentry->d_lock); spin_unlock(&dcache_lock); simple_unlink(parent->d_inode, dentry); - orphan_all_buffers(inode); - iput(inode); } else { spin_unlock(&dentry->d_lock); spin_unlock(&dcache_lock); @@ -282,7 +248,7 @@ int sysfs_hash_and_remove(struct dentry * dir, const char * name) return -ENOENT; parent_sd = dir->d_fsdata; - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); + mutex_lock(&dir->d_inode->i_mutex); list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { if (!sd->s_element) continue; diff --git a/trunk/fs/sysfs/mount.c b/trunk/fs/sysfs/mount.c index f6a87a824883..e503f858fba8 100644 --- a/trunk/fs/sysfs/mount.c +++ b/trunk/fs/sysfs/mount.c @@ -8,7 +8,6 @@ #include #include #include -#include #include "sysfs.h" @@ -19,12 +18,9 @@ struct vfsmount *sysfs_mount; struct super_block * sysfs_sb = NULL; struct kmem_cache *sysfs_dir_cachep; -static void sysfs_clear_inode(struct inode *inode); - static struct super_operations sysfs_ops = { .statfs = simple_statfs, - .drop_inode = sysfs_delete_inode, - .clear_inode = sysfs_clear_inode, + .drop_inode = generic_delete_inode, }; static struct sysfs_dirent sysfs_root = { @@ -35,11 +31,6 @@ static struct sysfs_dirent sysfs_root = { .s_iattr = NULL, }; -static void sysfs_clear_inode(struct inode *inode) -{ - kfree(inode->i_private); -} - static int sysfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *inode; diff --git a/trunk/fs/sysfs/symlink.c b/trunk/fs/sysfs/symlink.c index 4869f611192f..f50e3cc2ded8 100644 --- a/trunk/fs/sysfs/symlink.c +++ b/trunk/fs/sysfs/symlink.c @@ -7,7 +7,6 @@ #include #include #include -#include #include "sysfs.h" diff --git a/trunk/fs/sysfs/sysfs.h b/trunk/fs/sysfs/sysfs.h index fe1cbfd208ed..bd7cec295dab 100644 --- a/trunk/fs/sysfs/sysfs.h +++ b/trunk/fs/sysfs/sysfs.h @@ -2,7 +2,6 @@ extern struct vfsmount * sysfs_mount; extern struct kmem_cache *sysfs_dir_cachep; -extern void sysfs_delete_inode(struct inode *inode); extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); @@ -34,22 +33,6 @@ struct sysfs_symlink { struct kobject * target_kobj; }; -struct sysfs_buffer { - struct list_head associates; - size_t count; - loff_t pos; - char * page; - struct sysfs_ops * ops; - struct semaphore sem; - int orphaned; - int needs_read_fill; - int event; -}; - -struct sysfs_buffer_collection { - struct list_head associates; -}; - static inline struct kobject * to_kobj(struct dentry * dentry) { struct sysfs_dirent * sd = dentry->d_fsdata; @@ -113,7 +96,3 @@ static inline void sysfs_put(struct sysfs_dirent * sd) release_sysfs_dirent(sd); } -static inline int sysfs_is_shadowed_inode(struct inode *inode) -{ - return S_ISDIR(inode->i_mode) && inode->i_op->follow_link; -} diff --git a/trunk/include/acpi/acconfig.h b/trunk/include/acpi/acconfig.h index 422f29c06c77..ebc1f697615a 100644 --- a/trunk/include/acpi/acconfig.h +++ b/trunk/include/acpi/acconfig.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20070126 +#define ACPI_CA_VERSION 0x20060707 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, @@ -115,10 +115,6 @@ #define ACPI_NUM_OWNERID_MASKS 8 -/* Size of the root table array is increased by this increment */ - -#define ACPI_ROOT_TABLE_SIZE_INCREMENT 4 - /****************************************************************************** * * ACPI Specification constants (Do not change unless the specification changes) @@ -156,11 +152,6 @@ #define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */ #define ACPI_PATH_SEPARATOR '.' -/* Sizes for ACPI table headers */ - -#define ACPI_OEM_ID_SIZE 6 -#define ACPI_OEM_TABLE_ID_SIZE 8 - /* Constants used in searching for the RSDP in low memory */ #define ACPI_EBDA_PTR_LOCATION 0x0000040E /* Physical Address */ diff --git a/trunk/include/acpi/acdebug.h b/trunk/include/acpi/acdebug.h index d626bb1d2973..d8167095caf3 100644 --- a/trunk/include/acpi/acdebug.h +++ b/trunk/include/acpi/acdebug.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -159,10 +159,6 @@ void acpi_db_create_execution_threads(char *num_threads_arg, char *num_loops_arg, char *method_name_arg); -#ifdef ACPI_DBG_TRACK_ALLOCATIONS -u32 acpi_db_get_cache_info(struct acpi_memory_list *cache); -#endif - /* * dbfileio - Debugger file I/O commands */ @@ -218,6 +214,4 @@ void acpi_db_prep_namestring(char *name); struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name); -void acpi_db_uint32_to_hex_string(u32 value, char *buffer); - #endif /* __ACDEBUG_H__ */ diff --git a/trunk/include/acpi/acdisasm.h b/trunk/include/acpi/acdisasm.h index 389d772c7d5b..9a7d6921f534 100644 --- a/trunk/include/acpi/acdisasm.h +++ b/trunk/include/acpi/acdisasm.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -97,11 +97,9 @@ typedef const struct acpi_dmtable_info { #define ACPI_DMT_CHKSUM 20 #define ACPI_DMT_SPACEID 21 #define ACPI_DMT_GAS 22 -#define ACPI_DMT_DMAR 23 -#define ACPI_DMT_MADT 24 -#define ACPI_DMT_SRAT 25 -#define ACPI_DMT_EXIT 26 -#define ACPI_DMT_SIG 27 +#define ACPI_DMT_MADT 23 +#define ACPI_DMT_SRAT 24 +#define ACPI_DMT_EXIT 25 typedef void (*ACPI_TABLE_HANDLER) (struct acpi_table_header * table); @@ -110,7 +108,6 @@ struct acpi_dmtable_data { char *signature; struct acpi_dmtable_info *table_info; ACPI_TABLE_HANDLER table_handler; - char *name; }; struct acpi_op_walk_info { @@ -142,9 +139,7 @@ extern const char *acpi_gbl_match_ops[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf0[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf1[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf1a[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf2[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf2a[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf3[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf4[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf_hdr[]; @@ -152,11 +147,6 @@ extern struct acpi_dmtable_info acpi_dm_table_info_boot[]; extern struct acpi_dmtable_info acpi_dm_table_info_cpep[]; extern struct acpi_dmtable_info acpi_dm_table_info_cpep0[]; extern struct acpi_dmtable_info acpi_dm_table_info_dbgp[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar_hdr[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar_scope[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[]; extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[]; extern struct acpi_dmtable_info acpi_dm_table_info_facs[]; extern struct acpi_dmtable_info acpi_dm_table_info_fadt1[]; @@ -211,8 +201,6 @@ void acpi_dm_dump_asf(struct acpi_table_header *table); void acpi_dm_dump_cpep(struct acpi_table_header *table); -void acpi_dm_dump_dmar(struct acpi_table_header *table); - void acpi_dm_dump_fadt(struct acpi_table_header *table); void acpi_dm_dump_srat(struct acpi_table_header *table); @@ -326,7 +314,7 @@ acpi_dm_resource_template(struct acpi_op_walk_info *info, union acpi_parse_object *op, u8 * byte_data, u32 byte_count); -acpi_status acpi_dm_is_resource_template(union acpi_parse_object *op); +u8 acpi_dm_is_resource_template(union acpi_parse_object *op); void acpi_dm_indent(u32 level); diff --git a/trunk/include/acpi/acdispat.h b/trunk/include/acpi/acdispat.h index cb8d2868c8ac..a22fe9cf8493 100644 --- a/trunk/include/acpi/acdispat.h +++ b/trunk/include/acpi/acdispat.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -210,7 +210,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state); * dsinit */ acpi_status -acpi_ds_initialize_objects(acpi_native_uint table_index, +acpi_ds_initialize_objects(struct acpi_table_desc *table_desc, struct acpi_namespace_node *start_node); /* diff --git a/trunk/include/acpi/acevents.h b/trunk/include/acpi/acevents.h index d23cdf326808..234142828e1a 100644 --- a/trunk/include/acpi/acevents.h +++ b/trunk/include/acpi/acevents.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acexcep.h b/trunk/include/acpi/acexcep.h index b73f18a48785..797ca1ea5214 100644 --- a/trunk/include/acpi/acexcep.h +++ b/trunk/include/acpi/acexcep.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -178,10 +178,8 @@ #define AE_CTRL_BREAK (acpi_status) (0x0009 | AE_CODE_CONTROL) #define AE_CTRL_CONTINUE (acpi_status) (0x000A | AE_CODE_CONTROL) #define AE_CTRL_SKIP (acpi_status) (0x000B | AE_CODE_CONTROL) -#define AE_CTRL_PARSE_CONTINUE (acpi_status) (0x000C | AE_CODE_CONTROL) -#define AE_CTRL_PARSE_PENDING (acpi_status) (0x000D | AE_CODE_CONTROL) -#define AE_CODE_CTRL_MAX 0x000D +#define AE_CODE_CTRL_MAX 0x000B #ifdef DEFINE_ACPI_GLOBALS @@ -293,9 +291,7 @@ char const *acpi_gbl_exception_names_ctrl[] = { "AE_CTRL_TRANSFER", "AE_CTRL_BREAK", "AE_CTRL_CONTINUE", - "AE_CTRL_SKIP", - "AE_CTRL_PARSE_CONTINUE", - "AE_CTRL_PARSE_PENDING" + "AE_CTRL_SKIP" }; #endif /* ACPI GLOBALS */ diff --git a/trunk/include/acpi/acglobal.h b/trunk/include/acpi/acglobal.h index 24c3f05ab367..06972e6637de 100644 --- a/trunk/include/acpi/acglobal.h +++ b/trunk/include/acpi/acglobal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -58,6 +58,37 @@ #define ACPI_INIT_GLOBAL(a,b) a #endif +/* + * Keep local copies of these FADT-based registers. NOTE: These globals + * are first in this file for alignment reasons on 64-bit systems. + */ +ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; +ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; + +/***************************************************************************** + * + * Debug support + * + ****************************************************************************/ + +/* Runtime configuration of debug print levels */ + +extern u32 acpi_dbg_level; +extern u32 acpi_dbg_layer; + +/* Procedure nesting level for debug output */ + +extern u32 acpi_gbl_nesting_level; + +/* Support for dynamic control method tracing mechanism */ + +ACPI_EXTERN u32 acpi_gbl_original_dbg_level; +ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; +ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; +ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; +ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; +ACPI_EXTERN u32 acpi_gbl_trace_flags; + /***************************************************************************** * * Runtime configuration (static defaults that can be overriden at runtime) @@ -102,34 +133,6 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); */ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); -/***************************************************************************** - * - * Debug support - * - ****************************************************************************/ - -/* Runtime configuration of debug print levels */ - -extern u32 acpi_dbg_level; -extern u32 acpi_dbg_layer; - -/* Procedure nesting level for debug output */ - -extern u32 acpi_gbl_nesting_level; - -/* Event counters */ - -ACPI_EXTERN u32 acpi_gpe_count; - -/* Support for dynamic control method tracing mechanism */ - -ACPI_EXTERN u32 acpi_gbl_original_dbg_level; -ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; -ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; -ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; -ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; -ACPI_EXTERN u32 acpi_gbl_trace_flags; - /***************************************************************************** * * ACPI Table globals @@ -137,29 +140,47 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; ****************************************************************************/ /* - * acpi_gbl_root_table_list is the master list of ACPI tables found in the - * RSDT/XSDT. + * Table pointers. + * Although these pointers are somewhat redundant with the global acpi_table, + * they are convenient because they are typed pointers. * - * acpi_gbl_FADT is a local copy of the FADT, converted to a common format. + * These tables are single-table only; meaning that there can be at most one + * of each in the system. Each global points to the actual table. + */ +ACPI_EXTERN u32 acpi_gbl_table_flags; +ACPI_EXTERN u32 acpi_gbl_rsdt_table_count; +ACPI_EXTERN struct rsdp_descriptor *acpi_gbl_RSDP; +ACPI_EXTERN struct xsdt_descriptor *acpi_gbl_XSDT; +ACPI_EXTERN struct fadt_descriptor *acpi_gbl_FADT; +ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT; +ACPI_EXTERN struct facs_descriptor *acpi_gbl_FACS; +ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS; +/* + * Since there may be multiple SSDTs and PSDTs, a single pointer is not + * sufficient; Therefore, there isn't one! */ -ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; -ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; -extern acpi_native_uint acpi_gbl_permanent_mmap; -/* These addresses are calculated from FADT address values */ +/* The root table can be either an RSDT or an XSDT */ -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; +ACPI_EXTERN u8 acpi_gbl_root_table_type; +#define ACPI_TABLE_TYPE_RSDT 'R' +#define ACPI_TABLE_TYPE_XSDT 'X' /* - * Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is - * determined by the revision of the DSDT: If the DSDT revision is less than - * 2, use only the lower 32 bits of the internal 64-bit Integer. + * Handle both ACPI 1.0 and ACPI 2.0 Integer widths: + * If we are executing a method that exists in a 32-bit ACPI table, + * use only the lower 32 bits of the (internal) 64-bit Integer. */ ACPI_EXTERN u8 acpi_gbl_integer_bit_width; ACPI_EXTERN u8 acpi_gbl_integer_byte_width; ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; +/* + * ACPI Table info arrays + */ +extern struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1]; +extern struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1]; + /***************************************************************************** * * Mutual exlusion within ACPICA subsystem @@ -167,7 +188,7 @@ ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; ****************************************************************************/ /* - * Predefined mutex objects. This array contains the + * Predefined mutex objects. This array contains the * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs. * (The table maps local handles to the real OS handles) */ @@ -176,7 +197,6 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX]; /* * Global lock semaphore works in conjunction with the actual HW global lock */ -ACPI_EXTERN acpi_mutex acpi_gbl_global_lock_mutex; ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; /* @@ -200,7 +220,6 @@ ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE regis ACPI_EXTERN struct acpi_memory_list *acpi_gbl_global_list; ACPI_EXTERN struct acpi_memory_list *acpi_gbl_ns_node_list; -ACPI_EXTERN u8 acpi_gbl_display_final_mem_stats; #endif /* Object caches */ @@ -221,6 +240,7 @@ ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; /* Misc */ +ACPI_EXTERN u32 acpi_gbl_global_lock_thread_count; ACPI_EXTERN u32 acpi_gbl_original_mode; ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; @@ -240,19 +260,12 @@ ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_startup_flags; +extern const u8 acpi_gbl_decode_to8bit[8]; extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; extern const char *acpi_gbl_highest_dstate_names[4]; extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; -/* Exception codes */ - -extern char const *acpi_gbl_exception_names_env[]; -extern char const *acpi_gbl_exception_names_pgm[]; -extern char const *acpi_gbl_exception_names_tbl[]; -extern char const *acpi_gbl_exception_names_aml[]; -extern char const *acpi_gbl_exception_names_ctrl[]; - /***************************************************************************** * * Namespace globals diff --git a/trunk/include/acpi/achware.h b/trunk/include/acpi/achware.h index 9df275cf7bc1..29b60a8c0593 100644 --- a/trunk/include/acpi/achware.h +++ b/trunk/include/acpi/achware.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,6 +61,8 @@ /* * hwacpi - high level functions */ +acpi_status acpi_hw_initialize(void); + acpi_status acpi_hw_set_mode(u32 mode); u32 acpi_hw_get_mode(void); @@ -82,7 +84,7 @@ acpi_hw_low_level_read(u32 width, acpi_status acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address *reg); -acpi_status acpi_hw_clear_acpi_status(void); +acpi_status acpi_hw_clear_acpi_status(u32 flags); /* * hwgpe - GPE support diff --git a/trunk/include/acpi/acinterp.h b/trunk/include/acpi/acinterp.h index ce7c9d653910..91586d0d5bb5 100644 --- a/trunk/include/acpi/acinterp.h +++ b/trunk/include/acpi/acinterp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -277,6 +277,12 @@ acpi_status acpi_ex_system_do_suspend(acpi_integer time); acpi_status acpi_ex_system_do_stall(u32 time); +acpi_status +acpi_ex_system_acquire_mutex(union acpi_operand_object *time, + union acpi_operand_object *obj_desc); + +acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc); + acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc); acpi_status @@ -445,14 +451,10 @@ acpi_ex_copy_integer_to_buffer_field(union acpi_operand_object *source_desc, /* * exutils - interpreter/scanner utilities */ -void acpi_ex_enter_interpreter(void); +acpi_status acpi_ex_enter_interpreter(void); void acpi_ex_exit_interpreter(void); -void acpi_ex_reacquire_interpreter(void); - -void acpi_ex_relinquish_interpreter(void); - void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc); u8 acpi_ex_acquire_global_lock(u32 rule); diff --git a/trunk/include/acpi/aclocal.h b/trunk/include/acpi/aclocal.h index 6f83ddbed3af..063c4b54290f 100644 --- a/trunk/include/acpi/aclocal.h +++ b/trunk/include/acpi/aclocal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,8 +80,8 @@ union acpi_parse_object; * table below also! */ #define ACPI_MTX_INTERPRETER 0 /* AML Interpreter, main lock */ -#define ACPI_MTX_NAMESPACE 1 /* ACPI Namespace */ -#define ACPI_MTX_TABLES 2 /* Data for ACPI tables */ +#define ACPI_MTX_TABLES 1 /* Data for ACPI tables */ +#define ACPI_MTX_NAMESPACE 2 /* ACPI Namespace */ #define ACPI_MTX_EVENTS 3 /* Data for ACPI events */ #define ACPI_MTX_CACHES 4 /* Internal caches, general purposes */ #define ACPI_MTX_MEMORY 5 /* Debug memory tracking lists */ @@ -162,7 +162,7 @@ struct acpi_mutex_info { typedef enum { ACPI_IMODE_LOAD_PASS1 = 0x01, ACPI_IMODE_LOAD_PASS2 = 0x02, - ACPI_IMODE_EXECUTE = 0x03 + ACPI_IMODE_EXECUTE = 0x0E } acpi_interpreter_mode; union acpi_name_union { @@ -204,7 +204,7 @@ struct acpi_namespace_node { /* Namespace Node flags */ #define ANOBJ_END_OF_PEER_LIST 0x01 /* End-of-list, Peer field points to parent */ -#define ANOBJ_TEMPORARY 0x02 /* Node is create by a method and is temporary */ +#define ANOBJ_RESERVED 0x02 /* Available for future use */ #define ANOBJ_METHOD_ARG 0x04 /* Node is a method argument */ #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ @@ -219,42 +219,25 @@ struct acpi_namespace_node { * ACPI Table Descriptor. One per ACPI table */ struct acpi_table_desc { - acpi_physical_address address; + struct acpi_table_desc *prev; + struct acpi_table_desc *next; + struct acpi_table_desc *installed_desc; struct acpi_table_header *pointer; - u32 length; /* Length fixed at 32 bits */ - union acpi_name_union signature; + u8 *aml_start; + u64 physical_address; + acpi_size length; + u32 aml_length; acpi_owner_id owner_id; - u8 flags; + u8 type; + u8 allocation; + u8 loaded_into_namespace; }; -/* Flags for above */ - -#define ACPI_TABLE_ORIGIN_UNKNOWN (0) -#define ACPI_TABLE_ORIGIN_MAPPED (1) -#define ACPI_TABLE_ORIGIN_ALLOCATED (2) -#define ACPI_TABLE_ORIGIN_MASK (3) -#define ACPI_TABLE_IS_LOADED (4) - -/* One internal RSDT for table management */ - -struct acpi_internal_rsdt { - struct acpi_table_desc *tables; +struct acpi_table_list { + struct acpi_table_desc *next; u32 count; - u32 size; - u8 flags; }; -/* Flags for above */ - -#define ACPI_ROOT_ORIGIN_UNKNOWN (0) /* ~ORIGIN_ALLOCATED */ -#define ACPI_ROOT_ORIGIN_ALLOCATED (1) -#define ACPI_ROOT_ALLOW_RESIZE (2) - -/* Predefined (fixed) table indexes */ - -#define ACPI_TABLE_INDEX_DSDT (0) -#define ACPI_TABLE_INDEX_FACS (1) - struct acpi_find_context { char *search_for; acpi_handle *list; @@ -367,7 +350,7 @@ struct acpi_gpe_event_info { union acpi_gpe_dispatch_info dispatch; /* Either Method or Handler */ struct acpi_gpe_register_info *register_info; /* Backpointer to register info */ u8 flags; /* Misc info about this GPE */ - u8 gpe_number; /* This GPE */ + u8 register_bit; /* This GPE bit within the register */ }; /* Information about a GPE register pair, one per each status/enable pair in an array */ @@ -872,30 +855,12 @@ struct acpi_bit_register_info { ****************************************************************************/ struct acpi_db_method_info { - acpi_handle main_thread_gate; - acpi_handle thread_complete_gate; - u32 *threads; - u32 num_threads; - u32 num_created; - u32 num_completed; - + acpi_handle thread_gate; char *name; + char **args; u32 flags; u32 num_loops; char pathname[128]; - char **args; - - /* - * Arguments to be passed to method for the command - * Threads - - * the Number of threads, ID of current thread and - * Index of current thread inside all them created. - */ - char init_args; - char *arguments[4]; - char num_threads_str[11]; - char id_of_thread_str[11]; - char index_of_thread_str[11]; }; struct acpi_integrity_info { @@ -954,8 +919,6 @@ struct acpi_memory_list { u32 total_allocated; u32 total_freed; - u32 max_occupied; - u32 total_size; u32 current_total_size; u32 requests; u32 hits; diff --git a/trunk/include/acpi/acmacros.h b/trunk/include/acpi/acmacros.h index 8948a6461834..192fa095a515 100644 --- a/trunk/include/acpi/acmacros.h +++ b/trunk/include/acpi/acmacros.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,12 +55,25 @@ #define ACPI_SET_BIT(target,bit) ((target) |= (bit)) #define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit)) #define ACPI_MIN(a,b) (((a)<(b))?(a):(b)) -#define ACPI_MAX(a,b) (((a)>(b))?(a):(b)) /* Size calculation */ #define ACPI_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) +#if ACPI_MACHINE_WIDTH == 16 + +/* + * For 16-bit addresses, we have to assume that the upper 32 bits + * (out of 64) are zero. + */ +#define ACPI_LODWORD(l) ((u32)(l)) +#define ACPI_HIDWORD(l) ((u32)(0)) + +#define ACPI_GET_ADDRESS(a) ((a).lo) +#define ACPI_STORE_ADDRESS(a,b) {(a).hi=0;(a).lo=(u32)(b);} +#define ACPI_VALID_ADDRESS(a) ((a).hi | (a).lo) + +#else #ifdef ACPI_NO_INTEGER64_SUPPORT /* * acpi_integer is 32-bits, no 64-bit support on this platform @@ -68,6 +81,10 @@ #define ACPI_LODWORD(l) ((u32)(l)) #define ACPI_HIDWORD(l) ((u32)(0)) +#define ACPI_GET_ADDRESS(a) (a) +#define ACPI_STORE_ADDRESS(a,b) ((a)=(b)) +#define ACPI_VALID_ADDRESS(a) (a) + #else /* @@ -75,6 +92,11 @@ */ #define ACPI_LODWORD(l) ((u32)(u64)(l)) #define ACPI_HIDWORD(l) ((u32)(((*(struct uint64_struct *)(void *)(&l))).hi)) + +#define ACPI_GET_ADDRESS(a) (a) +#define ACPI_STORE_ADDRESS(a,b) ((a)=(acpi_physical_address)(b)) +#define ACPI_VALID_ADDRESS(a) (a) +#endif #endif /* @@ -112,8 +134,15 @@ #define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void,(void *) NULL,(acpi_native_uint) i) #define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL) #define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) + +#if ACPI_MACHINE_WIDTH == 16 +#define ACPI_STORE_POINTER(d,s) ACPI_MOVE_32_TO_32(d,s) +#define ACPI_PHYSADDR_TO_PTR(i) (void *)(i) +#define ACPI_PTR_TO_PHYSADDR(i) (u32) ACPI_CAST_PTR (u8,(i)) +#else #define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) #define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i) +#endif #ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED #define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (u32,(a)) == *ACPI_CAST_PTR (u32,(b))) @@ -194,6 +223,28 @@ /* The hardware supports unaligned transfers, just do the little-endian move */ +#if ACPI_MACHINE_WIDTH == 16 + +/* No 64-bit integers */ +/* 16-bit source, 16/32/64 destination */ + +#define ACPI_MOVE_16_TO_16(d,s) *(u16 *)(void *)(d) = *(u16 *)(void *)(s) +#define ACPI_MOVE_16_TO_32(d,s) *(u32 *)(void *)(d) = *(u16 *)(void *)(s) +#define ACPI_MOVE_16_TO_64(d,s) ACPI_MOVE_16_TO_32(d,s) + +/* 32-bit source, 16/32/64 destination */ + +#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */ +#define ACPI_MOVE_32_TO_32(d,s) *(u32 *)(void *)(d) = *(u32 *)(void *)(s) +#define ACPI_MOVE_32_TO_64(d,s) ACPI_MOVE_32_TO_32(d,s) + +/* 64-bit source, 16/32/64 destination */ + +#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */ +#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */ +#define ACPI_MOVE_64_TO_64(d,s) ACPI_MOVE_32_TO_32(d,s) + +#else /* 16-bit source, 16/32/64 destination */ #define ACPI_MOVE_16_TO_16(d,s) *(u16 *)(void *)(d) = *(u16 *)(void *)(s) @@ -211,6 +262,7 @@ #define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */ #define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */ #define ACPI_MOVE_64_TO_64(d,s) *(u64 *)(void *)(d) = *(u64 *)(void *)(s) +#endif #else /* @@ -255,7 +307,10 @@ /* Macros based on machine integer width */ -#if ACPI_MACHINE_WIDTH == 32 +#if ACPI_MACHINE_WIDTH == 16 +#define ACPI_MOVE_SIZE_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) + +#elif ACPI_MACHINE_WIDTH == 32 #define ACPI_MOVE_SIZE_TO_16(d,s) ACPI_MOVE_32_TO_16(d,s) #elif ACPI_MACHINE_WIDTH == 64 @@ -640,6 +695,16 @@ #define ACPI_DEBUGGER_EXEC(a) #endif +/* + * For 16-bit code, we want to shrink some things even though + * we are using ACPI_DEBUG_OUTPUT to get the debug output + */ +#if ACPI_MACHINE_WIDTH == 16 +#undef ACPI_DEBUG_ONLY_MEMBERS +#undef _VERBOSE_STRUCTURES +#define ACPI_DEBUG_ONLY_MEMBERS(a) +#endif + #ifdef ACPI_DEBUG_OUTPUT /* * 1) Set name to blanks diff --git a/trunk/include/acpi/acnames.h b/trunk/include/acpi/acnames.h index 34bfae8a05f3..b67da3636899 100644 --- a/trunk/include/acpi/acnames.h +++ b/trunk/include/acpi/acnames.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acnamesp.h b/trunk/include/acpi/acnamesp.h index 535b7e1c41bc..83b52f9f899a 100644 --- a/trunk/include/acpi/acnamesp.h +++ b/trunk/include/acpi/acnamesp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,13 +65,9 @@ #define ACPI_NS_ERROR_IF_FOUND 0x08 #define ACPI_NS_PREFIX_IS_SCOPE 0x10 #define ACPI_NS_EXTERNAL 0x20 -#define ACPI_NS_TEMPORARY 0x40 -/* Flags for acpi_ns_walk_namespace */ - -#define ACPI_NS_WALK_NO_UNLOCK 0 -#define ACPI_NS_WALK_UNLOCK 0x01 -#define ACPI_NS_WALK_TEMP_NODES 0x02 +#define ACPI_NS_WALK_UNLOCK TRUE +#define ACPI_NS_WALK_NO_UNLOCK FALSE /* * nsinit - Namespace initialization @@ -86,7 +82,7 @@ acpi_status acpi_ns_initialize_devices(void); acpi_status acpi_ns_load_namespace(void); acpi_status -acpi_ns_load_table(acpi_native_uint table_index, +acpi_ns_load_table(struct acpi_table_desc *table_desc, struct acpi_namespace_node *node); /* @@ -96,7 +92,7 @@ acpi_status acpi_ns_walk_namespace(acpi_object_type type, acpi_handle start_object, u32 max_depth, - u32 flags, + u8 unlock_before_callback, acpi_walk_callback user_function, void *context, void **return_value); @@ -110,12 +106,11 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, * nsparse - table parsing */ acpi_status -acpi_ns_parse_table(acpi_native_uint table_index, - struct acpi_namespace_node *start_node); +acpi_ns_parse_table(struct acpi_table_desc *table_desc, + struct acpi_namespace_node *scope); acpi_status -acpi_ns_one_complete_parse(acpi_native_uint pass_number, - acpi_native_uint table_index); +acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc); /* * nsaccess - Top-level namespace access diff --git a/trunk/include/acpi/acobject.h b/trunk/include/acpi/acobject.h index 04e9735a6742..8fdee31119f3 100644 --- a/trunk/include/acpi/acobject.h +++ b/trunk/include/acpi/acobject.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,15 +52,7 @@ * to the interpreter, and to keep track of the various handlers such as * address space handlers and notify handlers. The object is a constant * size in order to allow it to be cached and reused. - * - * Note: The object is optimized to be aligned and will not work if it is - * byte-packed. */ -#if ACPI_MACHINE_WIDTH == 64 -#pragma pack(8) -#else -#pragma pack(4) -#endif /******************************************************************************* * @@ -109,8 +101,7 @@ struct acpi_object_common { ACPI_OBJECT_COMMON_HEADER}; struct acpi_object_integer { - ACPI_OBJECT_COMMON_HEADER u8 fill[3]; /* Prevent warning on some compilers */ - acpi_integer value; + ACPI_OBJECT_COMMON_HEADER acpi_integer value; }; /* @@ -212,9 +203,7 @@ struct acpi_object_power_resource { }; struct acpi_object_processor { - ACPI_OBJECT_COMMON_HEADER - /* The next two fields take advantage of the 3-byte space before NOTIFY_INFO */ - u8 proc_id; + ACPI_OBJECT_COMMON_HEADER u8 proc_id; u8 length; ACPI_COMMON_NOTIFY_INFO acpi_io_address address; }; @@ -417,6 +406,4 @@ union acpi_descriptor { union acpi_parse_object op; }; -#pragma pack() - #endif /* _ACOBJECT_H */ diff --git a/trunk/include/acpi/acopcode.h b/trunk/include/acpi/acopcode.h index e6f76a280a94..7659a46bc432 100644 --- a/trunk/include/acpi/acopcode.h +++ b/trunk/include/acpi/acopcode.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -257,7 +257,7 @@ #define ARGI_LLESSEQUAL_OP ARGI_INVALID_OPCODE #define ARGI_LNOT_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_LNOTEQUAL_OP ARGI_INVALID_OPCODE -#define ARGI_LOAD_OP ARGI_LIST2 (ARGI_REGION_OR_BUFFER,ARGI_TARGETREF) +#define ARGI_LOAD_OP ARGI_LIST2 (ARGI_REGION_OR_FIELD,ARGI_TARGETREF) #define ARGI_LOAD_TABLE_OP ARGI_LIST6 (ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_ANYTYPE) #define ARGI_LOCAL0 ARG_NONE #define ARGI_LOCAL1 ARG_NONE diff --git a/trunk/include/acpi/acoutput.h b/trunk/include/acpi/acoutput.h index 7812267b577f..8d5039d0b430 100644 --- a/trunk/include/acpi/acoutput.h +++ b/trunk/include/acpi/acoutput.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acparser.h b/trunk/include/acpi/acparser.h index 85c358e21014..9d49d3c41cd9 100644 --- a/trunk/include/acpi/acparser.h +++ b/trunk/include/acpi/acparser.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acpi.h b/trunk/include/acpi/acpi.h index 2e5f00d3ea0d..b9a39d1009bd 100644 --- a/trunk/include/acpi/acpi.h +++ b/trunk/include/acpi/acpi.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index 0d9f984a60a1..fdd10953b2b6 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -59,6 +59,7 @@ acpi_evaluate_reference(acpi_handle handle, #define ACPI_BUS_FILE_ROOT "acpi" extern struct proc_dir_entry *acpi_root_dir; +extern struct fadt_descriptor acpi_fadt; enum acpi_bus_removal_type { ACPI_BUS_REMOVAL_NORMAL = 0, @@ -91,12 +92,13 @@ typedef int (*acpi_op_remove) (struct acpi_device * device, int type); typedef int (*acpi_op_lock) (struct acpi_device * device, int type); typedef int (*acpi_op_start) (struct acpi_device * device); typedef int (*acpi_op_stop) (struct acpi_device * device, int type); -typedef int (*acpi_op_suspend) (struct acpi_device * device, pm_message_t state); -typedef int (*acpi_op_resume) (struct acpi_device * device); +typedef int (*acpi_op_suspend) (struct acpi_device * device, int state); +typedef int (*acpi_op_resume) (struct acpi_device * device, int state); typedef int (*acpi_op_scan) (struct acpi_device * device); typedef int (*acpi_op_bind) (struct acpi_device * device); typedef int (*acpi_op_unbind) (struct acpi_device * device); -typedef int (*acpi_op_shutdown) (struct acpi_device * device); +typedef int (*acpi_op_match) (struct acpi_device * device, + struct acpi_driver * driver); struct acpi_bus_ops { u32 acpi_op_add:1; @@ -109,7 +111,7 @@ struct acpi_bus_ops { u32 acpi_op_scan:1; u32 acpi_op_bind:1; u32 acpi_op_unbind:1; - u32 acpi_op_shutdown:1; + u32 acpi_op_match:1; u32 reserved:21; }; @@ -124,16 +126,16 @@ struct acpi_device_ops { acpi_op_scan scan; acpi_op_bind bind; acpi_op_unbind unbind; - acpi_op_shutdown shutdown; + acpi_op_match match; }; struct acpi_driver { + struct list_head node; char name[80]; char class[80]; + atomic_t references; char *ids; /* Supported Hardware IDs */ struct acpi_device_ops ops; - struct device_driver drv; - struct module *owner; }; /* @@ -183,7 +185,7 @@ struct acpi_device_dir { typedef char acpi_bus_id[5]; typedef unsigned long acpi_bus_address; -typedef char acpi_hardware_id[15]; +typedef char acpi_hardware_id[9]; typedef char acpi_unique_id[9]; typedef char acpi_device_name[40]; typedef char acpi_device_class[20]; @@ -294,14 +296,11 @@ struct acpi_device { struct acpi_device_ops ops; struct acpi_driver *driver; void *driver_data; + struct kobject kobj; struct device dev; - struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */ - enum acpi_bus_removal_type removal_type; /* indicate for different removal type */ }; #define acpi_driver_data(d) ((d)->driver_data) -#define to_acpi_device(d) container_of(d, struct acpi_device, dev) -#define to_acpi_driver(d) container_of(d, struct acpi_driver, drv) /* * Events diff --git a/trunk/include/acpi/acpi_drivers.h b/trunk/include/acpi/acpi_drivers.h index 4dc8a5043ef0..6a5bdcefec64 100644 --- a/trunk/include/acpi/acpi_drivers.h +++ b/trunk/include/acpi/acpi_drivers.h @@ -36,14 +36,13 @@ /* _HID definitions */ -#define ACPI_POWER_HID "power_resource" -#define ACPI_PROCESSOR_HID "ACPI0007" -#define ACPI_SYSTEM_HID "acpi_system" -#define ACPI_THERMAL_HID "thermal" -#define ACPI_BUTTON_HID_POWERF "button_power" -#define ACPI_BUTTON_HID_SLEEPF "button_sleep" -#define ACPI_VIDEO_HID "video" -#define ACPI_BAY_HID "bay" +#define ACPI_POWER_HID "ACPI_PWR" +#define ACPI_PROCESSOR_HID "ACPI_CPU" +#define ACPI_SYSTEM_HID "ACPI_SYS" +#define ACPI_THERMAL_HID "ACPI_THM" +#define ACPI_BUTTON_HID_POWERF "ACPI_FPB" +#define ACPI_BUTTON_HID_SLEEPF "ACPI_FSB" + /* -------------------------------------------------------------------------- PCI -------------------------------------------------------------------------- */ diff --git a/trunk/include/acpi/acpiosxf.h b/trunk/include/acpi/acpiosxf.h index 781394b9efe0..0cd63bce0ae4 100644 --- a/trunk/include/acpi/acpiosxf.h +++ b/trunk/include/acpi/acpiosxf.h @@ -8,7 +8,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -85,7 +85,7 @@ acpi_status acpi_os_terminate(void); /* * ACPI Table interfaces */ -acpi_physical_address acpi_os_get_root_pointer(void); +acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *address); acpi_status acpi_os_predefined_override(const struct acpi_predefined_names *init_val, @@ -143,7 +143,9 @@ void acpi_os_release_mutex(acpi_mutex handle); */ void *acpi_os_allocate(acpi_size size); -void __iomem *acpi_os_map_memory(acpi_physical_address where, acpi_native_uint length); +acpi_status +acpi_os_map_memory(acpi_physical_address physical_address, + acpi_size size, void __iomem ** logical_address); void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size); diff --git a/trunk/include/acpi/acpixf.h b/trunk/include/acpi/acpixf.h index e08f7df85a4f..81458767a90e 100644 --- a/trunk/include/acpi/acpixf.h +++ b/trunk/include/acpi/acpixf.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,10 +51,6 @@ /* * Global interfaces */ -acpi_status -acpi_initialize_tables(struct acpi_table_desc *initial_storage, - u32 initial_table_count, u8 allow_resize); - acpi_status acpi_initialize_subsystem(void); acpi_status acpi_enable_subsystem(u32 flags); @@ -96,28 +92,30 @@ void acpi_free(void *address); /* * ACPI table manipulation interfaces */ -acpi_status acpi_reallocate_root_table(void); - -acpi_status acpi_find_root_pointer(acpi_native_uint * rsdp_address); +acpi_status +acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address); acpi_status acpi_load_tables(void); acpi_status acpi_load_table(struct acpi_table_header *table_ptr); -acpi_status acpi_unload_table_id(acpi_owner_id id); +acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id); +#ifdef ACPI_FUTURE_USAGE +acpi_status acpi_unload_table(acpi_table_type table_type); acpi_status -acpi_get_table_header(acpi_string signature, - acpi_native_uint instance, - struct acpi_table_header *out_table_header); +acpi_get_table_header(acpi_table_type table_type, + u32 instance, struct acpi_table_header *out_table_header); +#endif /* ACPI_FUTURE_USAGE */ acpi_status -acpi_get_table(acpi_string signature, - acpi_native_uint instance, struct acpi_table_header **out_table); +acpi_get_table(acpi_table_type table_type, + u32 instance, struct acpi_buffer *ret_buffer); acpi_status -acpi_get_table_by_index(acpi_native_uint table_index, - struct acpi_table_header **out_table); +acpi_get_firmware_table(acpi_string signature, + u32 instance, + u32 flags, struct acpi_table_header **table_pointer); /* * Namespace and name interfaces @@ -312,9 +310,9 @@ acpi_resource_to_address64(struct acpi_resource *resource, /* * Hardware (ACPI device) interfaces */ -acpi_status acpi_get_register(u32 register_id, u32 * return_value); +acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags); -acpi_status acpi_set_register(u32 register_id, u32 value); +acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags); acpi_status acpi_set_firmware_waking_vector(acpi_physical_address physical_address); diff --git a/trunk/include/acpi/acresrc.h b/trunk/include/acpi/acresrc.h index 9486ab266a5e..80a3b33571b4 100644 --- a/trunk/include/acpi/acresrc.h +++ b/trunk/include/acpi/acresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acstruct.h b/trunk/include/acpi/acstruct.h index aeb4498e5e06..5e8095f0f78f 100644 --- a/trunk/include/acpi/acstruct.h +++ b/trunk/include/acpi/acstruct.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -139,8 +139,7 @@ struct acpi_init_walk_info { u16 buffer_init; u16 package_init; u16 object_count; - acpi_owner_id owner_id; - acpi_native_uint table_index; + struct acpi_table_desc *table_desc; }; struct acpi_get_devices_info { diff --git a/trunk/include/acpi/actables.h b/trunk/include/acpi/actables.h index 2b9f46f9da4d..4dbaf02fe526 100644 --- a/trunk/include/acpi/actables.h +++ b/trunk/include/acpi/actables.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,75 +44,105 @@ #ifndef __ACTABLES_H__ #define __ACTABLES_H__ -acpi_status acpi_allocate_root_table(u32 initial_table_count); +/* Used in acpi_tb_map_acpi_table for size parameter if table header is to be used */ + +#define SIZE_IN_HEADER 0 /* - * tbfadt - FADT parse/convert/validate + * tbconvrt - Table conversion routines */ -void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags); +acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info); + +acpi_status acpi_tb_convert_table_fadt(void); -void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length); +acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info); + +u32 +acpi_tb_get_table_count(struct rsdp_descriptor *RSDP, + struct acpi_table_header *RSDT); /* - * tbfind - find ACPI table + * tbget - Table "get" routines */ acpi_status -acpi_tb_find_table(char *signature, - char *oem_id, - char *oem_table_id, acpi_native_uint * table_index); +acpi_tb_get_table(struct acpi_pointer *address, + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_get_table_header(struct acpi_pointer *address, + struct acpi_table_header *return_header); + +acpi_status +acpi_tb_get_table_body(struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_get_table_ptr(acpi_table_type table_type, + u32 instance, struct acpi_table_header **table_ptr_loc); + +acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address); + +void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address); + +acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr); /* - * tbinstal - Table removal and deletion + * tbgetall - get multiple required tables */ -acpi_status acpi_tb_resize_root_table_list(void); +acpi_status acpi_tb_get_required_tables(void); -acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); +/* + * tbinstall - Table installation + */ +acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info); acpi_status -acpi_tb_add_table(struct acpi_table_desc *table_desc, - acpi_native_uint * table_index); +acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type); acpi_status -acpi_tb_store_table(acpi_physical_address address, - struct acpi_table_header *table, - u32 length, u8 flags, acpi_native_uint * table_index); +acpi_tb_init_table_descriptor(acpi_table_type table_type, + struct acpi_table_desc *table_info); -void acpi_tb_delete_table(struct acpi_table_desc *table_desc); - -void acpi_tb_terminate(void); +/* + * tbremove - Table removal and deletion + */ +void acpi_tb_delete_all_tables(void); -void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index); +void acpi_tb_delete_tables_by_type(acpi_table_type type); -acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index); +void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc); -acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index); +struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc + *table_desc); +/* + * tbxfroot - RSDP, RSDT utilities + */ acpi_status -acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id); +acpi_tb_find_table(char *signature, + char *oem_id, + char *oem_table_id, struct acpi_table_header **table_ptr); -u8 acpi_tb_is_table_loaded(acpi_native_uint table_index); +acpi_status acpi_tb_get_table_rsdt(void); -void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded); +acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp); /* - * tbutils - table manager utilities + * tbutils - common table utilities */ -u8 acpi_tb_tables_loaded(void); +acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc); -void -acpi_tb_print_table_header(acpi_physical_address address, - struct acpi_table_header *header); +acpi_status +acpi_tb_verify_table_checksum(struct acpi_table_header *table_header); -u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length); +u8 acpi_tb_sum_table(void *buffer, u32 length); -acpi_status -acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length); +u8 acpi_tb_generate_checksum(struct acpi_table_header *table); -void -acpi_tb_install_table(acpi_physical_address address, - u8 flags, char *signature, acpi_native_uint table_index); +void acpi_tb_set_checksum(struct acpi_table_header *table); acpi_status -acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags); +acpi_tb_validate_table_header(struct acpi_table_header *table_header); #endif /* __ACTABLES_H__ */ diff --git a/trunk/include/acpi/actbl.h b/trunk/include/acpi/actbl.h index 09469e7db6a5..b125ceed9cb7 100644 --- a/trunk/include/acpi/actbl.h +++ b/trunk/include/acpi/actbl.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,15 +48,15 @@ * Values for description table header signatures. Useful because they make * it more difficult to inadvertently type in the wrong signature. */ -#define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */ -#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */ -#define ACPI_SIG_FACS "FACS" /* Firmware ACPI Control Structure */ -#define ACPI_SIG_PSDT "PSDT" /* Persistent System Description Table */ -#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Pointer */ -#define ACPI_SIG_RSDT "RSDT" /* Root System Description Table */ -#define ACPI_SIG_XSDT "XSDT" /* Extended System Description Table */ -#define ACPI_SIG_SSDT "SSDT" /* Secondary System Description Table */ -#define ACPI_RSDP_NAME "RSDP" /* Short name for RSDP, not signature */ +#define DSDT_SIG "DSDT" /* Differentiated System Description Table */ +#define FADT_SIG "FACP" /* Fixed ACPI Description Table */ +#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */ +#define PSDT_SIG "PSDT" /* Persistent System Description Table */ +#define RSDP_SIG "RSD PTR " /* Root System Description Pointer */ +#define RSDT_SIG "RSDT" /* Root System Description Table */ +#define XSDT_SIG "XSDT" /* Extended System Description Table */ +#define SSDT_SIG "SSDT" /* Secondary System Description Table */ +#define RSDP_NAME "RSDP" /* * All tables and structures must be byte-packed to match the ACPI @@ -83,29 +83,27 @@ * ******************************************************************************/ +#define ACPI_TABLE_HEADER_DEF \ + char signature[4]; /* ASCII table signature */\ + u32 length; /* Length of table in bytes, including this header */\ + u8 revision; /* ACPI Specification minor version # */\ + u8 checksum; /* To make sum of entire table == 0 */\ + char oem_id[6]; /* ASCII OEM identification */\ + char oem_table_id[8]; /* ASCII OEM table identification */\ + u32 oem_revision; /* OEM revision number */\ + char asl_compiler_id[4]; /* ASCII ASL compiler vendor ID */\ + u32 asl_compiler_revision; /* ASL compiler version */ + struct acpi_table_header { - char signature[ACPI_NAME_SIZE]; /* ASCII table signature */ - u32 length; /* Length of table in bytes, including this header */ - u8 revision; /* ACPI Specification minor version # */ - u8 checksum; /* To make sum of entire table == 0 */ - char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */ - char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */ - u32 oem_revision; /* OEM revision number */ - char asl_compiler_id[ACPI_NAME_SIZE]; /* ASCII ASL compiler vendor ID */ - u32 asl_compiler_revision; /* ASL compiler version */ -}; +ACPI_TABLE_HEADER_DEF}; /* * GAS - Generic Address Structure (ACPI 2.0+) - * - * Note: Since this structure is used in the ACPI tables, it is byte aligned. - * If misalignment is not supported, access to the Address field must be - * performed with care. */ struct acpi_generic_address { - u8 space_id; /* Address space where struct or register exists */ - u8 bit_width; /* Size in bits of given register */ - u8 bit_offset; /* Bit offset within the register */ + u8 address_space_id; /* Address space where struct or register exists */ + u8 register_bit_width; /* Size in bits of given register */ + u8 register_bit_offset; /* Bit offset within the register */ u8 access_width; /* Minimum Access size (ACPI 3.0) */ u64 address; /* 64-bit address of struct or register */ }; @@ -116,10 +114,10 @@ struct acpi_generic_address { * ******************************************************************************/ -struct acpi_table_rsdp { +struct rsdp_descriptor { char signature[8]; /* ACPI signature, contains "RSD PTR " */ u8 checksum; /* ACPI 1.0 checksum */ - char oem_id[ACPI_OEM_ID_SIZE]; /* OEM identification */ + char oem_id[6]; /* OEM identification */ u8 revision; /* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */ u32 rsdt_physical_address; /* 32-bit physical address of the RSDT */ u32 length; /* Table length in bytes, including header (ACPI 2.0+) */ @@ -136,14 +134,12 @@ struct acpi_table_rsdp { * ******************************************************************************/ -struct acpi_table_rsdt { - struct acpi_table_header header; /* Common ACPI table header */ - u32 table_offset_entry[1]; /* Array of pointers to ACPI tables */ +struct rsdt_descriptor { + ACPI_TABLE_HEADER_DEF u32 table_offset_entry[1]; /* Array of pointers to ACPI tables */ }; -struct acpi_table_xsdt { - struct acpi_table_header header; /* Common ACPI table header */ - u64 table_offset_entry[1]; /* Array of pointers to ACPI tables */ +struct xsdt_descriptor { + ACPI_TABLE_HEADER_DEF u64 table_offset_entry[1]; /* Array of pointers to ACPI tables */ }; /******************************************************************************* @@ -152,27 +148,36 @@ struct acpi_table_xsdt { * ******************************************************************************/ -struct acpi_table_facs { +struct facs_descriptor { char signature[4]; /* ASCII table signature */ u32 length; /* Length of structure, in bytes */ u32 hardware_signature; /* Hardware configuration signature */ u32 firmware_waking_vector; /* 32-bit physical address of the Firmware Waking Vector */ u32 global_lock; /* Global Lock for shared hardware resources */ - u32 flags; + + /* Flags (32 bits) */ + + u8 S4bios_f:1; /* 00: S4BIOS support is present */ + u8:7; /* 01-07: Reserved, must be zero */ + u8 reserved1[3]; /* 08-31: Reserved, must be zero */ + u64 xfirmware_waking_vector; /* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */ u8 version; /* Version of this table (ACPI 2.0+) */ u8 reserved[31]; /* Reserved, must be zero */ }; -/* Flag macros */ - -#define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */ - -/* Global lock flags */ - #define ACPI_GLOCK_PENDING 0x01 /* 00: Pending global lock ownership */ #define ACPI_GLOCK_OWNED 0x02 /* 01: Global lock is owned */ +/* + * Common FACS - This is a version-independent FACS structure used for internal use only + */ +struct acpi_common_facs { + u32 *global_lock; + u64 *firmware_waking_vector; + u8 vector_width; +}; + /******************************************************************************* * * FADT - Fixed ACPI Description Table (Signature "FACP") @@ -181,98 +186,121 @@ struct acpi_table_facs { /* Fields common to all versions of the FADT */ -struct acpi_table_fadt { - struct acpi_table_header header; /* Common ACPI table header */ - u32 facs; /* 32-bit physical address of FACS */ - u32 dsdt; /* 32-bit physical address of DSDT */ - u8 model; /* System Interrupt Model (ACPI 1.0) - not used in ACPI 2.0+ */ - u8 preferred_profile; /* Conveys preferred power management profile to OSPM. */ - u16 sci_interrupt; /* System vector of SCI interrupt */ - u32 smi_command; /* 32-bit Port address of SMI command port */ - u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ - u8 S4bios_request; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 pstate_control; /* Processor performance state control */ - u32 pm1a_event_block; /* 32-bit Port address of Power Mgt 1a Event Reg Blk */ - u32 pm1b_event_block; /* 32-bit Port address of Power Mgt 1b Event Reg Blk */ - u32 pm1a_control_block; /* 32-bit Port address of Power Mgt 1a Control Reg Blk */ - u32 pm1b_control_block; /* 32-bit Port address of Power Mgt 1b Control Reg Blk */ - u32 pm2_control_block; /* 32-bit Port address of Power Mgt 2 Control Reg Blk */ - u32 pm_timer_block; /* 32-bit Port address of Power Mgt Timer Ctrl Reg Blk */ - u32 gpe0_block; /* 32-bit Port address of General Purpose Event 0 Reg Blk */ - u32 gpe1_block; /* 32-bit Port address of General Purpose Event 1 Reg Blk */ - u8 pm1_event_length; /* Byte Length of ports at pm1x_event_block */ - u8 pm1_control_length; /* Byte Length of ports at pm1x_control_block */ - u8 pm2_control_length; /* Byte Length of ports at pm2_control_block */ - u8 pm_timer_length; /* Byte Length of ports at pm_timer_block */ - u8 gpe0_block_length; /* Byte Length of ports at gpe0_block */ - u8 gpe1_block_length; /* Byte Length of ports at gpe1_block */ - u8 gpe1_base; /* Offset in GPE number space where GPE1 events start */ - u8 cst_control; /* Support for the _CST object and C States change notification */ - u16 C2latency; /* Worst case HW latency to enter/exit C2 state */ - u16 C3latency; /* Worst case HW latency to enter/exit C3 state */ - u16 flush_size; /* Processor's memory cache line width, in bytes */ - u16 flush_stride; /* Number of flush strides that need to be read */ - u8 duty_offset; /* Processor duty cycle index in processor's P_CNT reg */ - u8 duty_width; /* Processor duty cycle value bit width in P_CNT register. */ - u8 day_alarm; /* Index to day-of-month alarm in RTC CMOS RAM */ - u8 month_alarm; /* Index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* Index to century in RTC CMOS RAM */ - u16 boot_flags; /* IA-PC Boot Architecture Flags. See Table 5-10 for description */ - u8 reserved; /* Reserved, must be zero */ - u32 flags; /* Miscellaneous flag bits (see below for individual flags) */ - struct acpi_generic_address reset_register; /* 64-bit address of the Reset register */ +#define ACPI_FADT_COMMON \ + ACPI_TABLE_HEADER_DEF \ + u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ \ + u32 V1_dsdt; /* 32-bit physical address of DSDT */ \ + u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ \ + u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ \ + u16 sci_int; /* System vector of SCI interrupt */ \ + u32 smi_cmd; /* Port address of SMI command port */ \ + u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ \ + u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ \ + u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ \ + u8 pstate_cnt; /* Processor performance state control*/ \ + u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a Event Reg Blk */ \ + u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b Event Reg Blk */ \ + u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ \ + u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ \ + u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ \ + u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ \ + u32 V1_gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ \ + u32 V1_gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ \ + u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ \ + u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ \ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ \ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ \ + u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ \ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ \ + u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ \ + u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ \ + u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ \ + u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ \ + u16 flush_size; /* Processor's memory cache line width, in bytes */ \ + u16 flush_stride; /* Number of flush strides that need to be read */ \ + u8 duty_offset; /* Processor's duty cycle index in processor's P_CNT reg*/ \ + u8 duty_width; /* Processor's duty cycle value bit width in P_CNT register.*/ \ + u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ \ + u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ \ + u8 century; /* Index to century in RTC CMOS RAM */ \ + u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ \ + u8 reserved2; /* Reserved, must be zero */ + +/* + * ACPI 2.0+ FADT + */ +struct fadt_descriptor { + ACPI_FADT_COMMON + /* Flags (32 bits) */ + u8 wb_invd:1; /* 00: The wbinvd instruction works properly */ + u8 wb_invd_flush:1; /* 01: The wbinvd flushes but does not invalidate */ + u8 proc_c1:1; /* 02: All processors support C1 state */ + u8 plvl2_up:1; /* 03: C2 state works on MP system */ + u8 pwr_button:1; /* 04: Power button is handled as a generic feature */ + u8 sleep_button:1; /* 05: Sleep button is handled as a generic feature, or not present */ + u8 fixed_rTC:1; /* 06: RTC wakeup stat not in fixed register space */ + u8 rtcs4:1; /* 07: RTC wakeup stat not possible from S4 */ + u8 tmr_val_ext:1; /* 08: tmr_val is 32 bits 0=24-bits */ + u8 dock_cap:1; /* 09: Docking supported */ + u8 reset_reg_sup:1; /* 10: System reset via the FADT RESET_REG supported */ + u8 sealed_case:1; /* 11: No internal expansion capabilities and case is sealed */ + u8 headless:1; /* 12: No local video capabilities or local input devices */ + u8 cpu_sw_sleep:1; /* 13: Must execute native instruction after writing SLP_TYPx register */ + + u8 pci_exp_wak:1; /* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */ + u8 use_platform_clock:1; /* 15: OSPM should use platform-provided timer (ACPI 3.0) */ + u8 S4rtc_sts_valid:1; /* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */ + u8 remote_power_on_capable:1; /* 17: System is compatible with remote power on (ACPI 3.0) */ + u8 force_apic_cluster_model:1; /* 18: All local APICs must use cluster model (ACPI 3.0) */ + u8 force_apic_physical_destination_mode:1; /* 19: All local x_aPICs must use physical dest mode (ACPI 3.0) */ + u8:4; /* 20-23: Reserved, must be zero */ + u8 reserved3; /* 24-31: Reserved, must be zero */ + + struct acpi_generic_address reset_register; /* Reset register address in GAS format */ u8 reset_value; /* Value to write to the reset_register port to reset the system */ - u8 reserved4[3]; /* Reserved, must be zero */ - u64 Xfacs; /* 64-bit physical address of FACS */ + u8 reserved4[3]; /* These three bytes must be zero */ + u64 xfirmware_ctrl; /* 64-bit physical address of FACS */ u64 Xdsdt; /* 64-bit physical address of DSDT */ - struct acpi_generic_address xpm1a_event_block; /* 64-bit Extended Power Mgt 1a Event Reg Blk address */ - struct acpi_generic_address xpm1b_event_block; /* 64-bit Extended Power Mgt 1b Event Reg Blk address */ - struct acpi_generic_address xpm1a_control_block; /* 64-bit Extended Power Mgt 1a Control Reg Blk address */ - struct acpi_generic_address xpm1b_control_block; /* 64-bit Extended Power Mgt 1b Control Reg Blk address */ - struct acpi_generic_address xpm2_control_block; /* 64-bit Extended Power Mgt 2 Control Reg Blk address */ - struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */ - struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */ - struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ + struct acpi_generic_address xpm1a_evt_blk; /* Extended Power Mgt 1a acpi_event Reg Blk address */ + struct acpi_generic_address xpm1b_evt_blk; /* Extended Power Mgt 1b acpi_event Reg Blk address */ + struct acpi_generic_address xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */ + struct acpi_generic_address xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */ + struct acpi_generic_address xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */ + struct acpi_generic_address xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ + struct acpi_generic_address xgpe0_blk; /* Extended General Purpose acpi_event 0 Reg Blk address */ + struct acpi_generic_address xgpe1_blk; /* Extended General Purpose acpi_event 1 Reg Blk address */ }; -/* FADT flags */ - -#define ACPI_FADT_WBINVD (1) /* 00: The wbinvd instruction works properly */ -#define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: The wbinvd flushes but does not invalidate */ -#define ACPI_FADT_C1_SUPPORTED (1<<2) /* 02: All processors support C1 state */ -#define ACPI_FADT_C2_MP_SUPPORTED (1<<3) /* 03: C2 state works on MP system */ -#define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: Power button is handled as a generic feature */ -#define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: Sleep button is handled as a generic feature, or not present */ -#define ACPI_FADT_FIXED_RTC (1<<6) /* 06: RTC wakeup stat not in fixed register space */ -#define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: RTC wakeup stat not possible from S4 */ -#define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: tmr_val is 32 bits 0=24-bits */ -#define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: Docking supported */ -#define ACPI_FADT_RESET_REGISTER (1<<10) /* 10: System reset via the FADT RESET_REG supported */ -#define ACPI_FADT_SEALED_CASE (1<<11) /* 11: No internal expansion capabilities and case is sealed */ -#define ACPI_FADT_HEADLESS (1<<12) /* 12: No local video capabilities or local input devices */ -#define ACPI_FADT_SLEEP_TYPE (1<<13) /* 13: Must execute native instruction after writing SLP_TYPx register */ -#define ACPI_FADT_PCI_EXPRESS_WAKE (1<<14) /* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */ -#define ACPI_FADT_PLATFORM_CLOCK (1<<15) /* 15: OSPM should use platform-provided timer (ACPI 3.0) */ -#define ACPI_FADT_S4_RTC_VALID (1<<16) /* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */ -#define ACPI_FADT_REMOTE_POWER_ON (1<<17) /* 17: System is compatible with remote power on (ACPI 3.0) */ -#define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: All local APICs must use cluster model (ACPI 3.0) */ -#define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: All local x_aPICs must use physical dest mode (ACPI 3.0) */ +/* + * "Down-revved" ACPI 2.0 FADT descriptor + * Defined here to allow compiler to generate the length of the struct + */ +struct fadt_descriptor_rev2_minus { + ACPI_FADT_COMMON u32 flags; + struct acpi_generic_address reset_register; /* Reset register address in GAS format */ + u8 reset_value; /* Value to write to the reset_register port to reset the system. */ + u8 reserved7[3]; /* Reserved, must be zero */ +}; /* - * FADT Prefered Power Management Profiles + * ACPI 1.0 FADT + * Defined here to allow compiler to generate the length of the struct */ -enum acpi_prefered_pm_profiles { - PM_UNSPECIFIED = 0, - PM_DESKTOP = 1, - PM_MOBILE = 2, - PM_WORKSTATION = 3, - PM_ENTERPRISE_SERVER = 4, - PM_SOHO_SERVER = 5, - PM_APPLIANCE_PC = 6 +struct fadt_descriptor_rev1 { + ACPI_FADT_COMMON u32 flags; }; -/* FADT Boot Arch Flags */ +/* FADT: Prefered Power Management Profiles */ + +#define PM_UNSPECIFIED 0 +#define PM_DESKTOP 1 +#define PM_MOBILE 2 +#define PM_WORKSTATION 3 +#define PM_ENTERPRISE_SERVER 4 +#define PM_SOHO_SERVER 5 +#define PM_APPLIANCE_PC 6 + +/* FADT: Boot Arch Flags */ #define BAF_LEGACY_DEVICES 0x0001 #define BAF_8042_KEYBOARD_CONTROLLER 0x0002 @@ -284,12 +312,59 @@ enum acpi_prefered_pm_profiles { #pragma pack() -#define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_fadt, f) - +/* + * This macro is temporary until the table bitfield flag definitions + * are removed and replaced by a Flags field. + */ +#define ACPI_FLAG_OFFSET(d,f,o) (u8) (ACPI_OFFSET (d,f) + \ + sizeof(((d *)0)->f) + o) /* * Get the remaining ACPI tables */ +#include "actbl1.h" + +/* + * ACPI Table information. We save the table address, length, + * and type of memory allocation (mapped or allocated) for each + * table for 1) when we exit, and 2) if a new table is installed + */ +#define ACPI_MEM_NOT_ALLOCATED 0 +#define ACPI_MEM_ALLOCATED 1 +#define ACPI_MEM_MAPPED 2 + +/* Definitions for the Flags bitfield member of struct acpi_table_support */ + +#define ACPI_TABLE_SINGLE 0x00 +#define ACPI_TABLE_MULTIPLE 0x01 +#define ACPI_TABLE_EXECUTABLE 0x02 + +#define ACPI_TABLE_ROOT 0x00 +#define ACPI_TABLE_PRIMARY 0x10 +#define ACPI_TABLE_SECONDARY 0x20 +#define ACPI_TABLE_ALL 0x30 +#define ACPI_TABLE_TYPE_MASK 0x30 + +/* Data about each known table type */ + +struct acpi_table_support { + char *name; + char *signature; + void **global_ptr; + u8 sig_length; + u8 flags; +}; + +extern u8 acpi_fadt_is_v1; /* is set to 1 if FADT is revision 1, + * needed for certain workarounds */ +/* Macros used to generate offsets to specific table fields */ + +#define ACPI_FACS_OFFSET(f) (u8) ACPI_OFFSET (struct facs_descriptor,f) +#define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct fadt_descriptor, f) +#define ACPI_GAS_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_generic_address,f) +#define ACPI_HDR_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_header,f) +#define ACPI_RSDP_OFFSET(f) (u8) ACPI_OFFSET (struct rsdp_descriptor,f) -#include +#define ACPI_FADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct fadt_descriptor,f,o) +#define ACPI_FACS_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct facs_descriptor,f,o) #endif /* __ACTBL_H__ */ diff --git a/trunk/include/acpi/actbl1.h b/trunk/include/acpi/actbl1.h index 4e5d3ca53a8e..745a6445a4f9 100644 --- a/trunk/include/acpi/actbl1.h +++ b/trunk/include/acpi/actbl1.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,7 +61,6 @@ #define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ #define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ #define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ -#define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ #define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */ #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ @@ -74,6 +73,12 @@ #define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ #define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ +/* Legacy names */ + +#define APIC_SIG "APIC" /* Multiple APIC Description Table */ +#define BOOT_SIG "BOOT" /* Simple Boot Flag Table */ +#define SBST_SIG "SBST" /* Smart Battery Specification Table */ + /* * All tables must be byte-packed to match the ACPI specification, since * the tables are provided by the system BIOS. @@ -86,43 +91,31 @@ * portable, so do not use any other bitfield types. */ -/* Common Sub-table header (used in MADT, SRAT, etc.) */ - -struct acpi_subtable_header { - u8 type; - u8 length; -}; - /******************************************************************************* * * ASF - Alert Standard Format table (Signature "ASF!") * - * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003 - * ******************************************************************************/ struct acpi_table_asf { - struct acpi_table_header header; /* Common ACPI table header */ -}; +ACPI_TABLE_HEADER_DEF}; -/* ASF subtable header */ +#define ACPI_ASF_HEADER_DEF \ + u8 type; \ + u8 reserved; \ + u16 length; struct acpi_asf_header { - u8 type; - u8 reserved; - u16 length; -}; +ACPI_ASF_HEADER_DEF}; -/* Values for Type field above */ +/* Values for Type field */ -enum acpi_asf_type { - ACPI_ASF_TYPE_INFO = 0, - ACPI_ASF_TYPE_ALERT = 1, - ACPI_ASF_TYPE_CONTROL = 2, - ACPI_ASF_TYPE_BOOT = 3, - ACPI_ASF_TYPE_ADDRESS = 4, - ACPI_ASF_TYPE_RESERVED = 5 -}; +#define ASF_INFO 0 +#define ASF_ALERT 1 +#define ASF_CONTROL 2 +#define ASF_BOOT 3 +#define ASF_ADDRESS 4 +#define ASF_RESERVED 5 /* * ASF subtables @@ -131,8 +124,7 @@ enum acpi_asf_type { /* 0: ASF Information */ struct acpi_asf_info { - struct acpi_asf_header header; - u8 min_reset_value; + ACPI_ASF_HEADER_DEF u8 min_reset_value; u8 min_poll_interval; u16 system_id; u32 mfg_id; @@ -143,49 +135,26 @@ struct acpi_asf_info { /* 1: ASF Alerts */ struct acpi_asf_alert { - struct acpi_asf_header header; - u8 assert_mask; + ACPI_ASF_HEADER_DEF u8 assert_mask; u8 deassert_mask; u8 alerts; u8 data_length; -}; - -struct acpi_asf_alert_data { - u8 address; - u8 command; - u8 mask; - u8 value; - u8 sensor_type; - u8 type; - u8 offset; - u8 source_type; - u8 severity; - u8 sensor_number; - u8 entity; - u8 instance; + u8 array[1]; }; /* 2: ASF Remote Control */ struct acpi_asf_remote { - struct acpi_asf_header header; - u8 controls; + ACPI_ASF_HEADER_DEF u8 controls; u8 data_length; u16 reserved2; -}; - -struct acpi_asf_control_data { - u8 function; - u8 address; - u8 command; - u8 value; + u8 array[1]; }; /* 3: ASF RMCP Boot Options */ struct acpi_asf_rmcp { - struct acpi_asf_header header; - u8 capabilities[7]; + ACPI_ASF_HEADER_DEF u8 capabilities[7]; u8 completion_code; u32 enterprise_id; u8 command; @@ -197,9 +166,9 @@ struct acpi_asf_rmcp { /* 4: ASF Address */ struct acpi_asf_address { - struct acpi_asf_header header; - u8 eprom_address; + ACPI_ASF_HEADER_DEF u8 eprom_address; u8 devices; + u8 smbus_addresses[1]; }; /******************************************************************************* @@ -209,8 +178,7 @@ struct acpi_asf_address { ******************************************************************************/ struct acpi_table_boot { - struct acpi_table_header header; /* Common ACPI table header */ - u8 cmos_index; /* Index in CMOS RAM for the boot register */ + ACPI_TABLE_HEADER_DEF u8 cmos_index; /* Index in CMOS RAM for the boot register */ u8 reserved[3]; }; @@ -221,8 +189,7 @@ struct acpi_table_boot { ******************************************************************************/ struct acpi_table_cpep { - struct acpi_table_header header; /* Common ACPI table header */ - u64 reserved; + ACPI_TABLE_HEADER_DEF u64 reserved; }; /* Subtable */ @@ -230,9 +197,9 @@ struct acpi_table_cpep { struct acpi_cpep_polling { u8 type; u8 length; - u8 id; /* Processor ID */ - u8 eid; /* Processor EID */ - u32 interval; /* Polling interval (msec) */ + u8 processor_id; /* Processor ID */ + u8 processor_eid; /* Processor EID */ + u32 polling_interval; /* Polling interval (msec) */ }; /******************************************************************************* @@ -242,97 +209,23 @@ struct acpi_cpep_polling { ******************************************************************************/ struct acpi_table_dbgp { - struct acpi_table_header header; /* Common ACPI table header */ - u8 type; /* 0=full 16550, 1=subset of 16550 */ + ACPI_TABLE_HEADER_DEF u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ u8 reserved[3]; struct acpi_generic_address debug_port; }; -/******************************************************************************* - * - * DMAR - DMA Remapping table - * - ******************************************************************************/ - -struct acpi_table_dmar { - struct acpi_table_header header; /* Common ACPI table header */ - u8 width; /* Host Address Width */ - u8 reserved[11]; -}; - -/* DMAR subtable header */ - -struct acpi_dmar_header { - u16 type; - u16 length; - u8 flags; - u8 reserved[3]; -}; - -/* Values for subtable type in struct acpi_dmar_header */ - -enum acpi_dmar_type { - ACPI_DMAR_TYPE_HARDWARE_UNIT = 0, - ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, - ACPI_DMAR_TYPE_RESERVED = 2 /* 2 and greater are reserved */ -}; - -struct acpi_dmar_device_scope { - u8 entry_type; - u8 length; - u8 segment; - u8 bus; -}; - -/* Values for entry_type in struct acpi_dmar_device_scope */ - -enum acpi_dmar_scope_type { - ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0, - ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1, - ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2, - ACPI_DMAR_SCOPE_TYPE_RESERVED = 3 /* 3 and greater are reserved */ -}; - -/* - * DMAR Sub-tables, correspond to Type in struct acpi_dmar_header - */ - -/* 0: Hardware Unit Definition */ - -struct acpi_dmar_hardware_unit { - struct acpi_dmar_header header; - u64 address; /* Register Base Address */ -}; - -/* Flags */ - -#define ACPI_DMAR_INCLUDE_ALL (1) - -/* 1: Reserved Memory Defininition */ - -struct acpi_dmar_reserved_memory { - struct acpi_dmar_header header; - u64 address; /* 4_k aligned base address */ - u64 end_address; /* 4_k aligned limit address */ -}; - -/* Flags */ - -#define ACPI_DMAR_ALLOW_ALL (1) - /******************************************************************************* * * ECDT - Embedded Controller Boot Resources Table * ******************************************************************************/ -struct acpi_table_ecdt { - struct acpi_table_header header; /* Common ACPI table header */ - struct acpi_generic_address control; /* Address of EC command/status register */ - struct acpi_generic_address data; /* Address of EC data register */ +struct ec_boot_resources { + ACPI_TABLE_HEADER_DEF struct acpi_generic_address ec_control; /* Address of EC command/status register */ + struct acpi_generic_address ec_data; /* Address of EC data register */ u32 uid; /* Unique ID - must be same as the EC _UID method */ - u8 gpe; /* The GPE for the EC */ - u8 id[1]; /* Full namepath of the EC in the ACPI namespace */ + u8 gpe_bit; /* The GPE for the EC */ + u8 ec_id[1]; /* Full namepath of the EC in the ACPI namespace */ }; /******************************************************************************* @@ -341,22 +234,22 @@ struct acpi_table_ecdt { * ******************************************************************************/ -struct acpi_table_hpet { - struct acpi_table_header header; /* Common ACPI table header */ - u32 id; /* Hardware ID of event timer block */ - struct acpi_generic_address address; /* Address of event timer block */ - u8 sequence; /* HPET sequence number */ - u16 minimum_tick; /* Main counter min tick, periodic mode */ - u8 flags; +struct acpi_hpet_table { + ACPI_TABLE_HEADER_DEF u32 hardware_id; /* Hardware ID of event timer block */ + struct acpi_generic_address base_address; /* Address of event timer block */ + u8 hpet_number; /* HPET sequence number */ + u16 clock_tick; /* Main counter min tick, periodic mode */ + u8 attributes; }; -/*! Flags */ - -#define ACPI_HPET_PAGE_PROTECT (1) /* 00: No page protection */ -#define ACPI_HPET_PAGE_PROTECT_4 (1<<1) /* 01: 4KB page protected */ -#define ACPI_HPET_PAGE_PROTECT_64 (1<<2) /* 02: 64KB page protected */ - -/*! [End] no source code translation !*/ +#if 0 /* HPET flags to be converted to macros */ +struct { /* Flags (8 bits) */ + u8 page_protect:1; /* 00: No page protection */ + u8 page_protect4:1; /* 01: 4_kB page protected */ + u8 page_protect64:1; /* 02: 64_kB page protected */ + u8:5; /* 03-07: Reserved, must be zero */ +} flags; +#endif /******************************************************************************* * @@ -364,159 +257,148 @@ struct acpi_table_hpet { * ******************************************************************************/ -struct acpi_table_madt { - struct acpi_table_header header; /* Common ACPI table header */ - u32 address; /* Physical address of local APIC */ - u32 flags; +struct multiple_apic_table { + ACPI_TABLE_HEADER_DEF u32 local_apic_address; /* Physical address of local APIC */ + + /* Flags (32 bits) */ + + u8 PCATcompat:1; /* 00: System also has dual 8259s */ + u8:7; /* 01-07: Reserved, must be zero */ + u8 reserved1[3]; /* 08-31: Reserved, must be zero */ }; -/* Flags */ +/* Values for MADT PCATCompat */ -#define ACPI_MADT_PCAT_COMPAT (1) /* 00: System also has dual 8259s */ +#define DUAL_PIC 0 +#define MULTIPLE_APIC 1 -/* Values for PCATCompat flag */ +/* Common MADT Sub-table header */ -#define ACPI_MADT_DUAL_PIC 0 -#define ACPI_MADT_MULTIPLE_APIC 1 +#define APIC_HEADER_DEF \ + u8 type; \ + u8 length; -/* Values for subtable type in struct acpi_subtable_header */ +struct apic_header { +APIC_HEADER_DEF}; -enum acpi_madt_type { - ACPI_MADT_TYPE_LOCAL_APIC = 0, - ACPI_MADT_TYPE_IO_APIC = 1, - ACPI_MADT_TYPE_INTERRUPT_OVERRIDE = 2, - ACPI_MADT_TYPE_NMI_SOURCE = 3, - ACPI_MADT_TYPE_LOCAL_APIC_NMI = 4, - ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE = 5, - ACPI_MADT_TYPE_IO_SAPIC = 6, - ACPI_MADT_TYPE_LOCAL_SAPIC = 7, - ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8, - ACPI_MADT_TYPE_RESERVED = 9 /* 9 and greater are reserved */ -}; +/* Values for Type in struct apic_header */ + +#define APIC_PROCESSOR 0 +#define APIC_IO 1 +#define APIC_XRUPT_OVERRIDE 2 +#define APIC_NMI 3 +#define APIC_LOCAL_NMI 4 +#define APIC_ADDRESS_OVERRIDE 5 +#define APIC_IO_SAPIC 6 +#define APIC_LOCAL_SAPIC 7 +#define APIC_XRUPT_SOURCE 8 +#define APIC_RESERVED 9 /* 9 and greater are reserved */ + +/* Flag definitions for MADT sub-tables */ + +#define ACPI_MADT_IFLAGS /* INTI flags (16 bits) */ \ + u8 polarity : 2; /* 00-01: Polarity of APIC I/O input signals */\ + u8 trigger_mode : 2; /* 02-03: Trigger mode of APIC input signals */\ + u8 : 4; /* 04-07: Reserved, must be zero */\ + u8 reserved1; /* 08-15: Reserved, must be zero */ + +#define ACPI_MADT_LFLAGS /* Local Sapic flags (32 bits) */ \ + u8 processor_enabled: 1; /* 00: Processor is usable if set */\ + u8 : 7; /* 01-07: Reserved, must be zero */\ + u8 reserved2[3]; /* 08-31: Reserved, must be zero */ + +/* Values for MPS INTI flags */ + +#define POLARITY_CONFORMS 0 +#define POLARITY_ACTIVE_HIGH 1 +#define POLARITY_RESERVED 2 +#define POLARITY_ACTIVE_LOW 3 + +#define TRIGGER_CONFORMS 0 +#define TRIGGER_EDGE 1 +#define TRIGGER_RESERVED 2 +#define TRIGGER_LEVEL 3 /* - * MADT Sub-tables, correspond to Type in struct acpi_subtable_header + * MADT Sub-tables, correspond to Type in struct apic_header */ -/* 0: Processor Local APIC */ +/* 0: processor APIC */ -struct acpi_madt_local_apic { - struct acpi_subtable_header header; - u8 processor_id; /* ACPI processor id */ - u8 id; /* Processor's local APIC id */ - u32 lapic_flags; -}; +struct madt_processor_apic { + APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ + u8 local_apic_id; /* Processor's local APIC id */ + ACPI_MADT_LFLAGS}; /* 1: IO APIC */ -struct acpi_madt_io_apic { - struct acpi_subtable_header header; - u8 id; /* I/O APIC ID */ +struct madt_io_apic { + APIC_HEADER_DEF u8 io_apic_id; /* I/O APIC ID */ u8 reserved; /* Reserved - must be zero */ u32 address; /* APIC physical address */ - u32 global_irq_base; /* Global system interrupt where INTI lines start */ + u32 interrupt; /* Global system interrupt where INTI lines start */ }; /* 2: Interrupt Override */ -struct acpi_madt_interrupt_override { - struct acpi_subtable_header header; - u8 bus; /* 0 - ISA */ - u8 source_irq; /* Interrupt source (IRQ) */ - u32 global_irq; /* Global system interrupt */ - u16 inti_flags; -}; +struct madt_interrupt_override { + APIC_HEADER_DEF u8 bus; /* 0 - ISA */ + u8 source; /* Interrupt source (IRQ) */ + u32 interrupt; /* Global system interrupt */ + ACPI_MADT_IFLAGS}; -/* 3: NMI Source */ +/* 3: NMI Sources */ -struct acpi_madt_nmi_source { - struct acpi_subtable_header header; - u16 inti_flags; - u32 global_irq; /* Global system interrupt */ +struct madt_nmi_source { + APIC_HEADER_DEF ACPI_MADT_IFLAGS u32 interrupt; /* Global system interrupt */ }; /* 4: Local APIC NMI */ -struct acpi_madt_local_apic_nmi { - struct acpi_subtable_header header; - u8 processor_id; /* ACPI processor id */ - u16 inti_flags; - u8 lint; /* LINTn to which NMI is connected */ +struct madt_local_apic_nmi { + APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ + ACPI_MADT_IFLAGS u8 lint; /* LINTn to which NMI is connected */ }; /* 5: Address Override */ -struct acpi_madt_local_apic_override { - struct acpi_subtable_header header; - u16 reserved; /* Reserved, must be zero */ +struct madt_address_override { + APIC_HEADER_DEF u16 reserved; /* Reserved, must be zero */ u64 address; /* APIC physical address */ }; /* 6: I/O Sapic */ -struct acpi_madt_io_sapic { - struct acpi_subtable_header header; - u8 id; /* I/O SAPIC ID */ +struct madt_io_sapic { + APIC_HEADER_DEF u8 io_sapic_id; /* I/O SAPIC ID */ u8 reserved; /* Reserved, must be zero */ - u32 global_irq_base; /* Global interrupt for SAPIC start */ + u32 interrupt_base; /* Glocal interrupt for SAPIC start */ u64 address; /* SAPIC physical address */ }; /* 7: Local Sapic */ -struct acpi_madt_local_sapic { - struct acpi_subtable_header header; - u8 processor_id; /* ACPI processor id */ - u8 id; /* SAPIC ID */ - u8 eid; /* SAPIC EID */ +struct madt_local_sapic { + APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ + u8 local_sapic_id; /* SAPIC ID */ + u8 local_sapic_eid; /* SAPIC EID */ u8 reserved[3]; /* Reserved, must be zero */ - u32 lapic_flags; - u32 uid; /* Numeric UID - ACPI 3.0 */ - char uid_string[1]; /* String UID - ACPI 3.0 */ + ACPI_MADT_LFLAGS u32 processor_uID; /* Numeric UID - ACPI 3.0 */ + char processor_uIDstring[1]; /* String UID - ACPI 3.0 */ }; /* 8: Platform Interrupt Source */ -struct acpi_madt_interrupt_source { - struct acpi_subtable_header header; - u16 inti_flags; - u8 type; /* 1=PMI, 2=INIT, 3=corrected */ - u8 id; /* Processor ID */ - u8 eid; /* Processor EID */ +struct madt_interrupt_source { + APIC_HEADER_DEF ACPI_MADT_IFLAGS u8 interrupt_type; /* 1=PMI, 2=INIT, 3=corrected */ + u8 processor_id; /* Processor ID */ + u8 processor_eid; /* Processor EID */ u8 io_sapic_vector; /* Vector value for PMI interrupts */ - u32 global_irq; /* Global system interrupt */ + u32 interrupt; /* Global system interrupt */ u32 flags; /* Interrupt Source Flags */ }; -/* Flags field above */ - -#define ACPI_MADT_CPEI_OVERRIDE (1) - -/* - * Common flags fields for MADT subtables - */ - -/* MADT Local APIC flags (lapic_flags) */ - -#define ACPI_MADT_ENABLED (1) /* 00: Processor is usable if set */ - -/* MADT MPS INTI flags (inti_flags) */ - -#define ACPI_MADT_POLARITY_MASK (3) /* 00-01: Polarity of APIC I/O input signals */ -#define ACPI_MADT_TRIGGER_MASK (3<<2) /* 02-03: Trigger mode of APIC input signals */ - -/* Values for MPS INTI flags */ - -#define ACPI_MADT_POLARITY_CONFORMS 0 -#define ACPI_MADT_POLARITY_ACTIVE_HIGH 1 -#define ACPI_MADT_POLARITY_RESERVED 2 -#define ACPI_MADT_POLARITY_ACTIVE_LOW 3 - -#define ACPI_MADT_TRIGGER_CONFORMS (0) -#define ACPI_MADT_TRIGGER_EDGE (1<<2) -#define ACPI_MADT_TRIGGER_RESERVED (2<<2) -#define ACPI_MADT_TRIGGER_LEVEL (3<<2) - +#ifdef DUPLICATE_DEFINITION_WITH_LINUX_ACPI_H /******************************************************************************* * * MCFG - PCI Memory Mapped Configuration table and sub-table @@ -524,19 +406,17 @@ struct acpi_madt_interrupt_source { ******************************************************************************/ struct acpi_table_mcfg { - struct acpi_table_header header; /* Common ACPI table header */ - u8 reserved[8]; + ACPI_TABLE_HEADER_DEF u8 reserved[8]; }; -/* Subtable */ - struct acpi_mcfg_allocation { - u64 address; /* Base address, processor-relative */ + u64 base_address; /* Base address, processor-relative */ u16 pci_segment; /* PCI segment group number */ u8 start_bus_number; /* Starting PCI Bus number */ u8 end_bus_number; /* Final PCI Bus number */ u32 reserved; }; +#endif /******************************************************************************* * @@ -544,9 +424,8 @@ struct acpi_mcfg_allocation { * ******************************************************************************/ -struct acpi_table_sbst { - struct acpi_table_header header; /* Common ACPI table header */ - u32 warning_level; +struct smart_battery_table { + ACPI_TABLE_HEADER_DEF u32 warning_level; u32 low_level; u32 critical_level; }; @@ -557,10 +436,9 @@ struct acpi_table_sbst { * ******************************************************************************/ -struct acpi_table_slit { - struct acpi_table_header header; /* Common ACPI table header */ - u64 locality_count; - u8 entry[1]; /* Real size = localities^2 */ +struct system_locality_info { + ACPI_TABLE_HEADER_DEF u64 locality_count; + u8 entry[1][1]; }; /******************************************************************************* @@ -570,8 +448,7 @@ struct acpi_table_slit { ******************************************************************************/ struct acpi_table_spcr { - struct acpi_table_header header; /* Common ACPI table header */ - u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ + ACPI_TABLE_HEADER_DEF u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ u8 reserved[3]; struct acpi_generic_address serial_port; u8 interrupt_type; @@ -582,7 +459,7 @@ struct acpi_table_spcr { u8 stop_bits; u8 flow_control; u8 terminal_type; - u8 reserved1; + u8 reserved2; u16 pci_device_id; u16 pci_vendor_id; u8 pci_bus; @@ -590,7 +467,7 @@ struct acpi_table_spcr { u8 pci_function; u32 pci_flags; u8 pci_segment; - u32 reserved2; + u32 reserved3; }; /******************************************************************************* @@ -600,13 +477,12 @@ struct acpi_table_spcr { ******************************************************************************/ struct acpi_table_spmi { - struct acpi_table_header header; /* Common ACPI table header */ - u8 reserved; + ACPI_TABLE_HEADER_DEF u8 reserved; u8 interface_type; u16 spec_revision; /* Version of IPMI */ u8 interrupt_type; u8 gpe_number; /* GPE assigned */ - u8 reserved1; + u8 reserved2; u8 pci_device_flag; u32 interrupt; struct acpi_generic_address ipmi_register; @@ -622,52 +498,57 @@ struct acpi_table_spmi { * ******************************************************************************/ -struct acpi_table_srat { - struct acpi_table_header header; /* Common ACPI table header */ - u32 table_revision; /* Must be value '1' */ - u64 reserved; /* Reserved, must be zero */ +struct system_resource_affinity { + ACPI_TABLE_HEADER_DEF u32 reserved1; /* Must be value '1' */ + u64 reserved2; /* Reserved, must be zero */ }; -/* Values for subtable type in struct acpi_subtable_header */ +/* SRAT common sub-table header */ -enum acpi_srat_type { - ACPI_SRAT_TYPE_CPU_AFFINITY = 0, - ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1, - ACPI_SRAT_TYPE_RESERVED = 2 -}; +#define SRAT_SUBTABLE_HEADER \ + u8 type; \ + u8 length; + +/* Values for Type above */ + +#define SRAT_CPU_AFFINITY 0 +#define SRAT_MEMORY_AFFINITY 1 +#define SRAT_RESERVED 2 /* SRAT sub-tables */ -struct acpi_srat_cpu_affinity { - struct acpi_subtable_header header; - u8 proximity_domain_lo; +struct static_resource_alloc { + SRAT_SUBTABLE_HEADER u8 proximity_domain_lo; u8 apic_id; - u32 flags; + + /* Flags (32 bits) */ + + u8 enabled:1; /* 00: Use affinity structure */ + u8:7; /* 01-07: Reserved, must be zero */ + u8 reserved3[3]; /* 08-31: Reserved, must be zero */ + u8 local_sapic_eid; u8 proximity_domain_hi[3]; - u32 reserved; /* Reserved, must be zero */ + u32 reserved4; /* Reserved, must be zero */ }; -/* Flags */ - -#define ACPI_SRAT_CPU_ENABLED (1) /* 00: Use affinity structure */ - -struct acpi_srat_mem_affinity { - struct acpi_subtable_header header; - u32 proximity_domain; - u16 reserved; /* Reserved, must be zero */ +struct memory_affinity { + SRAT_SUBTABLE_HEADER u32 proximity_domain; + u16 reserved3; u64 base_address; - u64 length; - u32 memory_type; /* See acpi_address_range_id */ - u32 flags; - u64 reserved1; /* Reserved, must be zero */ -}; + u64 address_length; + u32 reserved4; -/* Flags */ + /* Flags (32 bits) */ -#define ACPI_SRAT_MEM_ENABLED (1) /* 00: Use affinity structure */ -#define ACPI_SRAT_MEM_HOT_PLUGGABLE (1<<1) /* 01: Memory region is hot pluggable */ -#define ACPI_SRAT_MEM_NON_VOLATILE (1<<2) /* 02: Memory region is non-volatile */ + u8 enabled:1; /* 00: Use affinity structure */ + u8 hot_pluggable:1; /* 01: Memory region is hot pluggable */ + u8 non_volatile:1; /* 02: Memory is non-volatile */ + u8:5; /* 03-07: Reserved, must be zero */ + u8 reserved5[3]; /* 08-31: Reserved, must be zero */ + + u64 reserved6; /* Reserved, must be zero */ +}; /******************************************************************************* * @@ -676,8 +557,7 @@ struct acpi_srat_mem_affinity { ******************************************************************************/ struct acpi_table_tcpa { - struct acpi_table_header header; /* Common ACPI table header */ - u16 reserved; + ACPI_TABLE_HEADER_DEF u16 reserved; u32 max_log_length; /* Maximum length for the event log area */ u64 log_address; /* Address of the event log area */ }; @@ -689,8 +569,7 @@ struct acpi_table_tcpa { ******************************************************************************/ struct acpi_table_wdrt { - struct acpi_table_header header; /* Common ACPI table header */ - u32 header_length; /* Watchdog Header Length */ + ACPI_TABLE_HEADER_DEF u32 header_length; /* Watchdog Header Length */ u8 pci_segment; /* PCI Segment number */ u8 pci_bus; /* PCI Bus number */ u8 pci_device; /* PCI Device number */ @@ -703,9 +582,58 @@ struct acpi_table_wdrt { u32 entries; /* Number of watchdog entries that follow */ }; -/* Flags */ - -#define ACPI_WDRT_TIMER_ENABLED (1) /* 00: Timer enabled */ +#if 0 /* Flags, will be converted to macros */ +u8 enabled:1; /* 00: Timer enabled */ +u8:6; /* 01-06: Reserved */ +u8 sleep_stop:1; /* 07: Timer stopped in sleep state */ +#endif + +/* Macros used to generate offsets to specific table fields */ + +#define ACPI_ASF0_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_info,f) +#define ACPI_ASF1_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_alert,f) +#define ACPI_ASF2_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_remote,f) +#define ACPI_ASF3_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_rmcp,f) +#define ACPI_ASF4_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_address,f) +#define ACPI_BOOT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_boot,f) +#define ACPI_CPEP_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_cpep,f) +#define ACPI_CPEP0_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_cpep_polling,f) +#define ACPI_DBGP_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_dbgp,f) +#define ACPI_ECDT_OFFSET(f) (u8) ACPI_OFFSET (struct ec_boot_resources,f) +#define ACPI_HPET_OFFSET(f) (u8) ACPI_OFFSET (struct hpet_table,f) +#define ACPI_MADT_OFFSET(f) (u8) ACPI_OFFSET (struct multiple_apic_table,f) +#define ACPI_MADT0_OFFSET(f) (u8) ACPI_OFFSET (struct madt_processor_apic,f) +#define ACPI_MADT1_OFFSET(f) (u8) ACPI_OFFSET (struct madt_io_apic,f) +#define ACPI_MADT2_OFFSET(f) (u8) ACPI_OFFSET (struct madt_interrupt_override,f) +#define ACPI_MADT3_OFFSET(f) (u8) ACPI_OFFSET (struct madt_nmi_source,f) +#define ACPI_MADT4_OFFSET(f) (u8) ACPI_OFFSET (struct madt_local_apic_nmi,f) +#define ACPI_MADT5_OFFSET(f) (u8) ACPI_OFFSET (struct madt_address_override,f) +#define ACPI_MADT6_OFFSET(f) (u8) ACPI_OFFSET (struct madt_io_sapic,f) +#define ACPI_MADT7_OFFSET(f) (u8) ACPI_OFFSET (struct madt_local_sapic,f) +#define ACPI_MADT8_OFFSET(f) (u8) ACPI_OFFSET (struct madt_interrupt_source,f) +#define ACPI_MADTH_OFFSET(f) (u8) ACPI_OFFSET (struct apic_header,f) +#define ACPI_MCFG_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_mcfg,f) +#define ACPI_MCFG0_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_mcfg_allocation,f) +#define ACPI_SBST_OFFSET(f) (u8) ACPI_OFFSET (struct smart_battery_table,f) +#define ACPI_SLIT_OFFSET(f) (u8) ACPI_OFFSET (struct system_locality_info,f) +#define ACPI_SPCR_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_spcr,f) +#define ACPI_SPMI_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_spmi,f) +#define ACPI_SRAT_OFFSET(f) (u8) ACPI_OFFSET (struct system_resource_affinity,f) +#define ACPI_SRAT0_OFFSET(f) (u8) ACPI_OFFSET (struct static_resource_alloc,f) +#define ACPI_SRAT1_OFFSET(f) (u8) ACPI_OFFSET (struct memory_affinity,f) +#define ACPI_TCPA_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_tcpa,f) +#define ACPI_WDRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_wdrt,f) + +#define ACPI_HPET_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct hpet_table,f,o) +#define ACPI_SRAT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct static_resource_alloc,f,o) +#define ACPI_SRAT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct memory_affinity,f,o) +#define ACPI_MADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct multiple_apic_table,f,o) +#define ACPI_MADT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_processor_apic,f,o) +#define ACPI_MADT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_interrupt_override,f,o) +#define ACPI_MADT3_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_nmi_source,f,o) +#define ACPI_MADT4_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_local_apic_nmi,f,o) +#define ACPI_MADT7_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_local_sapic,f,o) +#define ACPI_MADT8_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_interrupt_source,f,o) /* Reset to default packing */ diff --git a/trunk/include/acpi/actbl2.h b/trunk/include/acpi/actbl2.h new file mode 100644 index 000000000000..67efe6cad27b --- /dev/null +++ b/trunk/include/acpi/actbl2.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * Name: actbl2.h - ACPI Specification Revision 2.0 Tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#ifndef __ACTBL2_H__ +#define __ACTBL2_H__ + +/* Code moved to both actbl.h and actbl1.h */ + +#endif /* __ACTBL2_H__ */ diff --git a/trunk/include/acpi/actbl71.h b/trunk/include/acpi/actbl71.h new file mode 100644 index 000000000000..10ac05bb36bc --- /dev/null +++ b/trunk/include/acpi/actbl71.h @@ -0,0 +1,134 @@ +/****************************************************************************** + * + * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71 + * This file includes tables specific to this + * specification revision. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACTBL71_H__ +#define __ACTBL71_H__ + +/* 0.71 FADT address_space data item bitmasks defines */ +/* If the associated bit is zero then it is in memory space else in io space */ + +#define SMI_CMD_ADDRESS_SPACE 0x01 +#define PM1_BLK_ADDRESS_SPACE 0x02 +#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 +#define PM_TMR_BLK_ADDRESS_SPACE 0x08 +#define GPE0_BLK_ADDRESS_SPACE 0x10 +#define GPE1_BLK_ADDRESS_SPACE 0x20 + +/* Only for clarity in declarations */ + +typedef u64 IO_ADDRESS; + +#pragma pack(1) +struct { /* Root System Descriptor Pointer */ + NATIVE_CHAR signature[8]; /* contains "RSD PTR " */ + u8 checksum; /* to make sum of struct == 0 */ + NATIVE_CHAR oem_id[6]; /* OEM identification */ + u8 reserved; /* Must be 0 for 1.0, 2 for 2.0 */ + u64 rsdt_physical_address; /* 64-bit physical address of RSDT */ +}; + +/*****************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Root System Description Table */ +/*****************************************/ +struct { + struct acpi_table_header header; /* Table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + u64 table_offset_entry[1]; /* Array of pointers to other */ + /* tables' headers */ +}; + +/*******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Firmware ACPI Control Structure */ +/*******************************************/ +struct { + NATIVE_CHAR signature[4]; /* signature "FACS" */ + u32 length; /* length of structure, in bytes */ + u32 hardware_signature; /* hardware configuration signature */ + u32 reserved4; /* must be 0 */ + u64 firmware_waking_vector; /* ACPI OS waking vector */ + u64 global_lock; /* Global Lock */ + u32 S4bios_f:1; /* Indicates if S4BIOS support is present */ + u32 reserved1:31; /* must be 0 */ + u8 reserved3[28]; /* reserved - must be zero */ +}; + +/******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Fixed ACPI Description Table */ +/******************************************/ +struct { + struct acpi_table_header header; /* table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + u64 firmware_ctrl; /* 64-bit Physical address of FACS */ + u64 dsdt; /* 64-bit Physical address of DSDT */ + u8 model; /* System Interrupt Model */ + u8 address_space; /* Address Space Bitmask */ + u16 sci_int; /* System vector of SCI interrupt */ + u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ + u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ + u8 reserved2; /* reserved - must be zero */ + u64 smi_cmd; /* Port address of SMI command port */ + u64 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ + u64 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ + u64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + u64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + u64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + u64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + u64 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ + u64 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* offset in gpe model where gpe1 events start */ + u8 reserved3; /* reserved */ + u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ + u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* index to century in RTC CMOS RAM */ + u8 reserved4; /* reserved */ + u32 flush_cash:1; /* PAL_FLUSH_CACHE is correctly supported */ + u32 reserved5:1; /* reserved - must be zero */ + u32 proc_c1:1; /* all processors support C1 state */ + u32 plvl2_up:1; /* C2 state works on MP system */ + u32 pwr_button:1; /* Power button is handled as a generic feature */ + u32 sleep_button:1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC:1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4:1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext:1; /* tmr_val is 32 bits */ + u32 dock_cap:1; /* Supports Docking */ + u32 reserved6:22; /* reserved - must be zero */ +}; + +#pragma pack() + +#endif /* __ACTBL71_H__ */ diff --git a/trunk/include/acpi/actypes.h b/trunk/include/acpi/actypes.h index 72a6e2c3a536..64b603cfe92e 100644 --- a/trunk/include/acpi/actypes.h +++ b/trunk/include/acpi/actypes.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,8 +48,7 @@ /* * ACPI_MACHINE_WIDTH must be specified in an OS- or compiler-dependent header - * and must be either 32 or 64. 16-bit ACPICA is no longer supported, as of - * 12/2006. + * and must be either 16, 32, or 64 */ #ifndef ACPI_MACHINE_WIDTH #error ACPI_MACHINE_WIDTH not defined @@ -150,6 +149,7 @@ typedef int INT32; typedef u64 acpi_native_uint; typedef s64 acpi_native_int; +typedef u64 acpi_table_ptr; typedef u64 acpi_io_address; typedef u64 acpi_physical_address; @@ -189,15 +189,48 @@ typedef int INT32; typedef u32 acpi_native_uint; typedef s32 acpi_native_int; +typedef u64 acpi_table_ptr; typedef u32 acpi_io_address; -typedef u32 acpi_physical_address; +typedef u64 acpi_physical_address; #define ACPI_MAX_PTR ACPI_UINT32_MAX #define ACPI_SIZE_MAX ACPI_UINT32_MAX +/******************************************************************************* + * + * Types specific to 16-bit targets + * + ******************************************************************************/ + +#elif ACPI_MACHINE_WIDTH == 16 + +/*! [Begin] no source code translation (keep the typedefs as-is) */ + +typedef unsigned long UINT32; +typedef short INT16; +typedef long INT32; + +/*! [End] no source code translation !*/ + +typedef u16 acpi_native_uint; +typedef s16 acpi_native_int; + +typedef u32 acpi_table_ptr; +typedef u32 acpi_io_address; +typedef char *acpi_physical_address; + +#define ACPI_MAX_PTR ACPI_UINT16_MAX +#define ACPI_SIZE_MAX ACPI_UINT16_MAX + +#define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */ + +/* 64-bit integers cannot be supported */ + +#define ACPI_NO_INTEGER64_SUPPORT + #else -/* ACPI_MACHINE_WIDTH must be either 64 or 32 */ +/* ACPI_MACHINE_WIDTH must be either 64, 32, or 16 */ #error unknown ACPI_MACHINE_WIDTH #endif @@ -278,6 +311,36 @@ typedef acpi_native_uint acpi_size; * ******************************************************************************/ +/* + * Pointer overlays to avoid lots of typecasting for + * code that accepts both physical and logical pointers. + */ +union acpi_pointers { + acpi_physical_address physical; + void *logical; + acpi_table_ptr value; +}; + +struct acpi_pointer { + u32 pointer_type; + union acpi_pointers pointer; +}; + +/* pointer_types for above */ + +#define ACPI_PHYSICAL_POINTER 0x01 +#define ACPI_LOGICAL_POINTER 0x02 + +/* Processor mode */ + +#define ACPI_PHYSICAL_ADDRESSING 0x04 +#define ACPI_LOGICAL_ADDRESSING 0x08 +#define ACPI_MEMORY_MODE 0x0C + +#define ACPI_PHYSMODE_PHYSPTR ACPI_PHYSICAL_ADDRESSING | ACPI_PHYSICAL_POINTER +#define ACPI_LOGMODE_PHYSPTR ACPI_LOGICAL_ADDRESSING | ACPI_PHYSICAL_POINTER +#define ACPI_LOGMODE_LOGPTR ACPI_LOGICAL_ADDRESSING | ACPI_LOGICAL_POINTER + /* Logical defines and NULL */ #ifdef FALSE @@ -379,8 +442,7 @@ typedef u64 acpi_integer; /* * Initialization state */ -#define ACPI_SUBSYSTEM_INITIALIZE 0x01 -#define ACPI_INITIALIZED_OK 0x02 +#define ACPI_INITIALIZED_OK 0x01 /* * Power state values @@ -428,6 +490,21 @@ typedef u64 acpi_integer; #define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 6 #define ACPI_NOTIFY_POWER_FAULT (u8) 7 +/* + * Table types. These values are passed to the table related APIs + */ +typedef u32 acpi_table_type; + +#define ACPI_TABLE_ID_RSDP (acpi_table_type) 0 +#define ACPI_TABLE_ID_DSDT (acpi_table_type) 1 +#define ACPI_TABLE_ID_FADT (acpi_table_type) 2 +#define ACPI_TABLE_ID_FACS (acpi_table_type) 3 +#define ACPI_TABLE_ID_PSDT (acpi_table_type) 4 +#define ACPI_TABLE_ID_SSDT (acpi_table_type) 5 +#define ACPI_TABLE_ID_XSDT (acpi_table_type) 6 +#define ACPI_TABLE_ID_MAX 6 +#define ACPI_NUM_TABLE_TYPES (ACPI_TABLE_ID_MAX+1) + /* * Types associated with ACPI names and objects. The first group of * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition @@ -560,7 +637,7 @@ typedef u32 acpi_event_status; * | | | +--- Type of dispatch -- to method, handler, or none * | | +--- Enabled for runtime? * | +--- Enabled for wake? - * +--- Unused + * +--- System state when GPE ocurred (running/waking) */ #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 #define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01 @@ -586,6 +663,10 @@ typedef u32 acpi_event_status; #define ACPI_GPE_ENABLE_MASK (u8) 0x60 /* Both run/wake */ +#define ACPI_GPE_SYSTEM_MASK (u8) 0x80 +#define ACPI_GPE_SYSTEM_RUNNING (u8) 0x80 +#define ACPI_GPE_SYSTEM_WAKING (u8) 0x00 + /* * Flags for GPE and Lock interfaces */ @@ -734,6 +815,13 @@ struct acpi_buffer { #define ACPI_SYS_MODE_LEGACY 0x0002 #define ACPI_SYS_MODES_MASK 0x0003 +/* + * ACPI Table Info. One per ACPI table _type_ + */ +struct acpi_table_info { + u32 count; +}; + /* * System info returned by acpi_get_system_info() */ @@ -745,6 +833,8 @@ struct acpi_system_info { u32 reserved2; u32 debug_level; u32 debug_layer; + u32 num_table_types; + struct acpi_table_info table_info[ACPI_TABLE_ID_MAX + 1]; }; /* diff --git a/trunk/include/acpi/acutils.h b/trunk/include/acpi/acutils.h index 883ffe92148f..ba039ea1a057 100644 --- a/trunk/include/acpi/acutils.h +++ b/trunk/include/acpi/acutils.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -141,6 +141,8 @@ acpi_status acpi_ut_hardware_initialize(void); void acpi_ut_subsystem_shutdown(void); +acpi_status acpi_ut_validate_fadt(void); + /* * utclib - Local implementations of C library functions */ @@ -451,8 +453,6 @@ acpi_ut_short_divide(acpi_integer in_dividend, /* * utmisc */ -const char *acpi_ut_validate_exception(acpi_status status); - u8 acpi_ut_is_aml_table(struct acpi_table_header *table); acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); @@ -470,7 +470,7 @@ void acpi_ut_print_string(char *string, u8 max_length); u8 acpi_ut_valid_acpi_name(u32 name); -acpi_name acpi_ut_repair_name(char *name); +acpi_name acpi_ut_repair_name(acpi_name name); u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position); diff --git a/trunk/include/acpi/amlcode.h b/trunk/include/acpi/amlcode.h index da53a4ef287a..cf18426a87b1 100644 --- a/trunk/include/acpi/amlcode.h +++ b/trunk/include/acpi/amlcode.h @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -273,7 +273,7 @@ #define ARGI_DATAOBJECT 0x12 /* Buffer, String, package or reference to a Node - Used only by size_of operator */ #define ARGI_COMPLEXOBJ 0x13 /* Buffer, String, or package (Used by INDEX op only) */ #define ARGI_REF_OR_STRING 0x14 /* Reference or String (Used by DEREFOF op only) */ -#define ARGI_REGION_OR_BUFFER 0x15 /* Used by LOAD op only */ +#define ARGI_REGION_OR_FIELD 0x15 /* Used by LOAD op only */ #define ARGI_DATAREFOBJ 0x16 /* Note: types above can expand to 0x1F maximum */ diff --git a/trunk/include/acpi/amlresrc.h b/trunk/include/acpi/amlresrc.h index f7d541239da4..be03818af9d1 100644 --- a/trunk/include/acpi/amlresrc.h +++ b/trunk/include/acpi/amlresrc.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/platform/acenv.h b/trunk/include/acpi/platform/acenv.h index dab2ec59a3b0..453a469fd397 100644 --- a/trunk/include/acpi/platform/acenv.h +++ b/trunk/include/acpi/platform/acenv.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/platform/acgcc.h b/trunk/include/acpi/platform/acgcc.h index 3bb50494a38a..da80933963db 100644 --- a/trunk/include/acpi/platform/acgcc.h +++ b/trunk/include/acpi/platform/acgcc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/platform/aclinux.h b/trunk/include/acpi/platform/aclinux.h index 5f532d2ac180..7f1e92930b62 100644 --- a/trunk/include/acpi/platform/aclinux.h +++ b/trunk/include/acpi/platform/aclinux.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/asm-alpha/pci.h b/trunk/include/asm-alpha/pci.h index 85aa1127c903..4e115f368d5f 100644 --- a/trunk/include/asm-alpha/pci.h +++ b/trunk/include/asm-alpha/pci.h @@ -293,6 +293,4 @@ struct pci_dev *alpha_gendev_to_pci(struct device *dev); #define IOBASE_ROOT_BUS 5 #define IOBASE_FROM_HOSE 0x10000 -extern struct pci_dev *isa_bridge; - #endif /* __ALPHA_PCI_H */ diff --git a/trunk/include/asm-i386/acpi.h b/trunk/include/asm-i386/acpi.h index 5e657eb8946c..7cfad93edf10 100644 --- a/trunk/include/asm-i386/acpi.h +++ b/trunk/include/asm-i386/acpi.h @@ -39,7 +39,7 @@ * Calling conventions: * * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_EXTERNAL_XFACE - External ACPI interfaces * ACPI_INTERNAL_XFACE - Internal ACPI interfaces * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces */ @@ -59,11 +59,11 @@ int __acpi_acquire_global_lock(unsigned int *lock); int __acpi_release_global_lock(unsigned int *lock); -#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr)) -#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_release_global_lock(&facs->global_lock)) +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = __acpi_release_global_lock((unsigned int *) GLptr)) /* * Math helper asm macros @@ -87,7 +87,7 @@ extern void check_acpi_pci(void); static inline void check_acpi_pci(void) { } #endif -#ifdef CONFIG_ACPI +#ifdef CONFIG_ACPI extern int acpi_lapic; extern int acpi_ioapic; extern int acpi_noirq; @@ -95,9 +95,9 @@ extern int acpi_strict; extern int acpi_disabled; extern int acpi_ht; extern int acpi_pci_disabled; -static inline void disable_acpi(void) -{ - acpi_disabled = 1; +static inline void disable_acpi(void) +{ + acpi_disabled = 1; acpi_ht = 0; acpi_pci_disabled = 1; acpi_noirq = 1; @@ -114,9 +114,9 @@ extern int acpi_use_timer_override; #endif static inline void acpi_noirq_set(void) { acpi_noirq = 1; } -static inline void acpi_disable_pci(void) +static inline void acpi_disable_pci(void) { - acpi_pci_disabled = 1; + acpi_pci_disabled = 1; acpi_noirq_set(); } extern int acpi_irq_balance_set(char *str); @@ -144,6 +144,8 @@ extern void acpi_reserve_bootmem(void); #endif /*CONFIG_ACPI_SLEEP*/ +extern u8 x86_acpiid_to_apicid[]; + #define ARCH_HAS_POWER_INIT 1 #endif /*__KERNEL__*/ diff --git a/trunk/include/asm-i386/mach-es7000/mach_mpparse.h b/trunk/include/asm-i386/mach-es7000/mach_mpparse.h index 24990e546da3..99f66be240be 100644 --- a/trunk/include/asm-i386/mach-es7000/mach_mpparse.h +++ b/trunk/include/asm-i386/mach-es7000/mach_mpparse.h @@ -3,13 +3,13 @@ #include -static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, +static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, struct mpc_config_translation *translation) { Dprintk("Bus #%d is %s\n", m->mpc_busid, name); } -static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, +static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, struct mpc_config_translation *translation) { } @@ -22,7 +22,7 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid) { if (mpc->mpc_oemptr) { - struct mp_config_oemtable *oem_table = + struct mp_config_oemtable *oem_table = (struct mp_config_oemtable *)mpc->mpc_oemptr; if (!strncmp(oem, "UNISYS", 6)) return parse_unisys_oem((char *)oem_table); @@ -31,13 +31,12 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, } #ifdef CONFIG_ACPI - static inline int es7000_check_dsdt(void) { - struct acpi_table_header header; - memcpy(&header, 0, sizeof(struct acpi_table_header)); - acpi_get_table_header(ACPI_SIG_DSDT, 0, &header); - if (!strncmp(header.oem_id, "UNISYS", 6)) + struct acpi_table_header *header = NULL; + if(!acpi_get_table_header_early(ACPI_DSDT, &header)) + acpi_table_print(header, 0); + if (!strncmp(header->oem_id, "UNISYS", 6)) return 1; return 0; } @@ -45,7 +44,7 @@ static inline int es7000_check_dsdt(void) /* Hook from generic ACPI tables.c */ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { - unsigned long oem_addr; + unsigned long oem_addr; if (!find_unisys_acpi_oem_table(&oem_addr)) { if (es7000_check_dsdt()) return parse_unisys_oem((char *)oem_addr); diff --git a/trunk/include/asm-ia64/acpi.h b/trunk/include/asm-ia64/acpi.h index 5d03792d4f65..09a5dd0e44a8 100644 --- a/trunk/include/asm-ia64/acpi.h +++ b/trunk/include/asm-ia64/acpi.h @@ -82,11 +82,11 @@ ia64_acpi_release_global_lock (unsigned int *lock) return old & 0x1; } -#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = ia64_acpi_acquire_global_lock(&facs->global_lock)) +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = ia64_acpi_acquire_global_lock((unsigned int *) GLptr)) -#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = ia64_acpi_release_global_lock(&facs->global_lock)) +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = ia64_acpi_release_global_lock((unsigned int *) GLptr)) #define acpi_disabled 0 /* ACPI always enabled on IA64 */ #define acpi_noirq 0 /* ACPI always enabled on IA64 */ @@ -119,6 +119,8 @@ extern int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS]; extern int __initdata nid_to_pxm_map[MAX_NUMNODES]; #endif +extern u16 ia64_acpiid_to_sapicid[]; + /* * Refer Intel ACPI _PDC support document for bit definitions */ diff --git a/trunk/include/asm-ia64/machvec.h b/trunk/include/asm-ia64/machvec.h index 3c96ac19154e..a3891eb3f217 100644 --- a/trunk/include/asm-ia64/machvec.h +++ b/trunk/include/asm-ia64/machvec.h @@ -21,7 +21,6 @@ struct mm_struct; struct pci_bus; struct task_struct; struct pci_dev; -struct msi_desc; typedef void ia64_mv_setup_t (char **); typedef void ia64_mv_cpu_init_t (void); @@ -80,7 +79,7 @@ typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *); typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *); typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *); -typedef int ia64_mv_setup_msi_irq_t (struct pci_dev *pdev, struct msi_desc *); +typedef int ia64_mv_setup_msi_irq_t (unsigned int irq, struct pci_dev *pdev); typedef void ia64_mv_teardown_msi_irq_t (unsigned int irq); static inline void diff --git a/trunk/include/asm-ia64/sn/acpi.h b/trunk/include/asm-ia64/sn/acpi.h index 9ce2801cbd57..2850a7ef5e71 100644 --- a/trunk/include/asm-ia64/sn/acpi.h +++ b/trunk/include/asm-ia64/sn/acpi.h @@ -11,7 +11,6 @@ #include "acpi/acglobal.h" -extern int sn_acpi_rev; -#define SN_ACPI_BASE_SUPPORT() (sn_acpi_rev >= 0x20101) +#define SN_ACPI_BASE_SUPPORT() (acpi_gbl_DSDT->oem_revision >= 0x20101) #endif /* _ASM_IA64_SN_ACPI_H */ diff --git a/trunk/include/asm-ia64/sn/pcibr_provider.h b/trunk/include/asm-ia64/sn/pcibr_provider.h index 17cb6cc3f21a..da3eade0cae2 100644 --- a/trunk/include/asm-ia64/sn/pcibr_provider.h +++ b/trunk/include/asm-ia64/sn/pcibr_provider.h @@ -142,7 +142,7 @@ extern int pcibr_ate_alloc(struct pcibus_info *, int); extern void pcibr_ate_free(struct pcibus_info *, int); extern void ate_write(struct pcibus_info *, int, int, u64); extern int sal_pcibr_slot_enable(struct pcibus_info *soft, int device, - void *resp, char **ssdt); + void *resp); extern int sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action, void *resp); extern u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus); diff --git a/trunk/include/asm-ia64/sn/pcidev.h b/trunk/include/asm-ia64/sn/pcidev.h index 1c2382cea807..9fe89a93d880 100644 --- a/trunk/include/asm-ia64/sn/pcidev.h +++ b/trunk/include/asm-ia64/sn/pcidev.h @@ -70,16 +70,10 @@ extern void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info); extern void sn_irq_unfixup(struct pci_dev *pci_dev); extern struct pcidev_info * sn_pcidev_info_get(struct pci_dev *); -extern void sn_bus_fixup(struct pci_bus *); -extern void sn_acpi_bus_fixup(struct pci_bus *); -extern void sn_common_bus_fixup(struct pci_bus *, struct pcibus_bussoft *); extern void sn_bus_store_sysdata(struct pci_dev *dev); extern void sn_bus_free_sysdata(void); extern void sn_generate_path(struct pci_bus *pci_bus, char *address); -extern void sn_io_slot_fixup(struct pci_dev *); -extern void sn_acpi_slot_fixup(struct pci_dev *); -extern void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *, - struct sn_irq_info *); +extern void sn_pci_fixup_slot(struct pci_dev *dev); extern void sn_pci_unfixup_slot(struct pci_dev *dev); extern void sn_irq_lh_init(void); #endif /* _ASM_IA64_SN_PCI_PCIDEV_H */ diff --git a/trunk/include/asm-powerpc/cputable.h b/trunk/include/asm-powerpc/cputable.h index e870b5393175..7384b8086b75 100644 --- a/trunk/include/asm-powerpc/cputable.h +++ b/trunk/include/asm-powerpc/cputable.h @@ -50,12 +50,6 @@ enum powerpc_oprofile_type { PPC_OPROFILE_CELL = 5, }; -enum powerpc_pmc_type { - PPC_PMC_DEFAULT = 0, - PPC_PMC_IBM = 1, - PPC_PMC_PA6T = 2, -}; - struct cpu_spec { /* CPU is matched via (PVR & pvr_mask) == pvr_value */ unsigned int pvr_mask; @@ -71,7 +65,6 @@ struct cpu_spec { /* number of performance monitor counters */ unsigned int num_pmcs; - enum powerpc_pmc_type pmc_type; /* this is called to initialize various CPU bits like L1 cache, * BHT, SPD, etc... from head.S before branching to identify_machine @@ -344,6 +337,12 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start, CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ CPU_FTR_DSCR) +#define CPU_FTRS_POWER6X (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ + CPU_FTR_MMCRA | CPU_FTR_SMT | \ + CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ + CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE | \ + CPU_FTR_SPURR | CPU_FTR_REAL_LE | CPU_FTR_DSCR) #define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ diff --git a/trunk/include/asm-powerpc/dcr.h b/trunk/include/asm-powerpc/dcr.h index 9338d50538f1..b66c5e6941f0 100644 --- a/trunk/include/asm-powerpc/dcr.h +++ b/trunk/include/asm-powerpc/dcr.h @@ -33,7 +33,6 @@ * base from the device-tree */ #ifdef CONFIG_PPC_MERGE -struct device_node; extern unsigned int dcr_resource_start(struct device_node *np, unsigned int index); extern unsigned int dcr_resource_len(struct device_node *np, diff --git a/trunk/include/asm-powerpc/elf.h b/trunk/include/asm-powerpc/elf.h index de507995c7b1..d36426c01b6b 100644 --- a/trunk/include/asm-powerpc/elf.h +++ b/trunk/include/asm-powerpc/elf.h @@ -173,7 +173,7 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32]; the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. */ -#define ELF_ET_DYN_BASE (0x20000000) +#define ELF_ET_DYN_BASE (0x08000000) /* Common routine for both 32-bit and 64-bit processes */ static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs, diff --git a/trunk/include/asm-powerpc/firmware.h b/trunk/include/asm-powerpc/firmware.h index 3671c128f271..98f7b62422c9 100644 --- a/trunk/include/asm-powerpc/firmware.h +++ b/trunk/include/asm-powerpc/firmware.h @@ -43,8 +43,6 @@ #define FW_FEATURE_ISERIES ASM_CONST(0x0000000000200000) #define FW_FEATURE_LPAR ASM_CONST(0x0000000000400000) #define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000) -#define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000) -#define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000002000000) #ifndef __ASSEMBLY__ @@ -63,8 +61,6 @@ enum { FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, - FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT, - FW_FEATURE_CELLEB_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_BEAT, FW_FEATURE_NATIVE_POSSIBLE = 0, FW_FEATURE_NATIVE_ALWAYS = 0, FW_FEATURE_POSSIBLE = @@ -77,9 +73,6 @@ enum { #ifdef CONFIG_PPC_PS3 FW_FEATURE_PS3_POSSIBLE | #endif -#ifdef CONFIG_PPC_CELLEB - FW_FEATURE_CELLEB_POSSIBLE | -#endif #ifdef CONFIG_PPC_NATIVE FW_FEATURE_NATIVE_ALWAYS | #endif @@ -94,9 +87,6 @@ enum { #ifdef CONFIG_PPC_PS3 FW_FEATURE_PS3_ALWAYS & #endif -#ifdef CONFIG_PPC_CELLEB - FW_FEATURE_CELLEB_ALWAYS & -#endif #ifdef CONFIG_PPC_NATIVE FW_FEATURE_NATIVE_ALWAYS & #endif diff --git a/trunk/include/asm-powerpc/fs_pd.h b/trunk/include/asm-powerpc/fs_pd.h index c624915b757e..3d0e819d37f1 100644 --- a/trunk/include/asm-powerpc/fs_pd.h +++ b/trunk/include/asm-powerpc/fs_pd.h @@ -11,17 +11,19 @@ #ifndef FS_PD_H #define FS_PD_H +#include #include #include -#ifdef CONFIG_CPM2 -#include +static inline int uart_baudrate(void) +{ + return get_baudrate(); +} -#if defined(CONFIG_8260) -#include -#elif defined(CONFIG_85xx) -#include -#endif +static inline int uart_clock(void) +{ + return ppc_proc_freq; +} #define cpm2_map(member) \ ({ \ @@ -39,38 +41,5 @@ }) #define cpm2_unmap(addr) iounmap(addr) -#endif - -#ifdef CONFIG_8xx -#include -#include - -#define immr_map(member) \ -({ \ - u32 offset = offsetof(immap_t, member); \ - void *addr = ioremap (IMAP_ADDR + offset, \ - sizeof( ((immap_t*)0)->member)); \ - addr; \ -}) - -#define immr_map_size(member, size) \ -({ \ - u32 offset = offsetof(immap_t, member); \ - void *addr = ioremap (IMAP_ADDR + offset, size); \ - addr; \ -}) - -#define immr_unmap(addr) iounmap(addr) -#endif - -static inline int uart_baudrate(void) -{ - return get_baudrate(); -} - -static inline int uart_clock(void) -{ - return ppc_proc_freq; -} #endif diff --git a/trunk/include/asm-powerpc/hvcall.h b/trunk/include/asm-powerpc/hvcall.h index 60977806d2f4..7a500732b671 100644 --- a/trunk/include/asm-powerpc/hvcall.h +++ b/trunk/include/asm-powerpc/hvcall.h @@ -168,7 +168,6 @@ #define H_FREE_LOGICAL_LAN 0x118 #define H_ADD_LOGICAL_LAN_BUFFER 0x11C #define H_SEND_LOGICAL_LAN 0x120 -#define H_BULK_REMOVE 0x124 #define H_MULTICAST_CTRL 0x130 #define H_SET_XDABR 0x134 #define H_STUFF_TCE 0x138 diff --git a/trunk/include/asm-powerpc/io.h b/trunk/include/asm-powerpc/io.h index 301c9bb308b1..1cd532379c30 100644 --- a/trunk/include/asm-powerpc/io.h +++ b/trunk/include/asm-powerpc/io.h @@ -732,12 +732,6 @@ static inline void * bus_to_virt(unsigned long address) #endif /* CONFIG_PPC32 */ -/* access ports */ -#define setbits32(_addr, _v) out_be32((_addr), in_be32(_addr) | (_v)) -#define clrbits32(_addr, _v) out_be32((_addr), in_be32(_addr) & ~(_v)) - -#define setbits16(_addr, _v) out_be16((_addr), in_be16(_addr) | (_v)) -#define clrbits16(_addr, _v) out_be16((_addr), in_be16(_addr) & ~(_v)) #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-powerpc/iommu.h b/trunk/include/asm-powerpc/iommu.h index b2e56b30306a..f85dbd305558 100644 --- a/trunk/include/asm-powerpc/iommu.h +++ b/trunk/include/asm-powerpc/iommu.h @@ -99,7 +99,6 @@ extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, extern void iommu_init_early_pSeries(void); extern void iommu_init_early_iSeries(void); extern void iommu_init_early_dart(void); -extern void iommu_init_early_pasemi(void); #ifdef CONFIG_PCI extern void pci_iommu_init(void); diff --git a/trunk/include/asm-powerpc/ipic.h b/trunk/include/asm-powerpc/ipic.h index edec79dcb7c1..9fbb03415860 100644 --- a/trunk/include/asm-powerpc/ipic.h +++ b/trunk/include/asm-powerpc/ipic.h @@ -78,7 +78,7 @@ extern u32 ipic_get_mcp_status(void); extern void ipic_clear_mcp_status(u32 mask); #ifdef CONFIG_PPC_MERGE -extern struct ipic * ipic_init(struct device_node *node, unsigned int flags); +extern void ipic_init(struct device_node *node, unsigned int flags); extern unsigned int ipic_get_irq(void); #else extern void ipic_init(phys_addr_t phys_addr, unsigned int flags, diff --git a/trunk/include/asm-powerpc/irq.h b/trunk/include/asm-powerpc/irq.h index 4734cc178db5..46476e9a494a 100644 --- a/trunk/include/asm-powerpc/irq.h +++ b/trunk/include/asm-powerpc/irq.h @@ -89,9 +89,6 @@ struct irq_host_ops { /* Dispose of such a mapping */ void (*unmap)(struct irq_host *h, unsigned int virq); - /* Update of such a mapping */ - void (*remap)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw); - /* Translate device-tree interrupt specifier from raw format coming * from the firmware to a irq_hw_number_t (interrupt line number) and * type (sense) that can be passed to set_irq_type(). In the absence diff --git a/trunk/include/asm-powerpc/kprobes.h b/trunk/include/asm-powerpc/kprobes.h index 3a5dd492588f..2dafa376a63f 100644 --- a/trunk/include/asm-powerpc/kprobes.h +++ b/trunk/include/asm-powerpc/kprobes.h @@ -44,7 +44,6 @@ typedef unsigned int kprobe_opcode_t; #define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) #define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) -#ifdef CONFIG_PPC64 /* * 64bit powerpc uses function descriptors. * Handle cases where: @@ -68,13 +67,9 @@ typedef unsigned int kprobe_opcode_t; } #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry) + #define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ IS_TWI(instr) || IS_TDI(instr)) -#else -/* Use stock kprobe_lookup_name since ppc32 doesn't use function descriptors */ -#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)(pentry) -#define is_trap(instr) (IS_TW(instr) || IS_TWI(instr)) -#endif #define ARCH_SUPPORTS_KRETPROBES #define ARCH_INACTIVE_KPROBE_COUNT 1 diff --git a/trunk/include/asm-powerpc/mmu.h b/trunk/include/asm-powerpc/mmu.h index 200055a4b82b..41c8c9c5a254 100644 --- a/trunk/include/asm-powerpc/mmu.h +++ b/trunk/include/asm-powerpc/mmu.h @@ -247,7 +247,6 @@ extern void htab_initialize_secondary(void); extern void hpte_init_native(void); extern void hpte_init_lpar(void); extern void hpte_init_iSeries(void); -extern void hpte_init_beat(void); extern void stabs_alloc(void); extern void slb_initialize(void); diff --git a/trunk/include/asm-powerpc/mpc52xx.h b/trunk/include/asm-powerpc/mpc52xx.h index 7afd5bf94528..4560d72fc758 100644 --- a/trunk/include/asm-powerpc/mpc52xx.h +++ b/trunk/include/asm-powerpc/mpc52xx.h @@ -249,8 +249,6 @@ extern void mpc52xx_declare_of_platform_devices(void); extern void mpc52xx_init_irq(void); extern unsigned int mpc52xx_get_irq(void); -extern int __init mpc52xx_add_bridge(struct device_node *node); - #endif /* __ASSEMBLY__ */ #endif /* __ASM_POWERPC_MPC52xx_H__ */ diff --git a/trunk/include/asm-powerpc/mpc8260.h b/trunk/include/asm-powerpc/mpc8260.h deleted file mode 100644 index f1b83b09ab2e..000000000000 --- a/trunk/include/asm-powerpc/mpc8260.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Since there are many different boards and no standard configuration, - * we have a unique include file for each. Rather than change every - * file that has to include MPC8260 configuration, they all include - * this one and the configuration switching is done here. - */ -#ifdef __KERNEL__ -#ifndef __ASM_PPC_MPC8260_H__ -#define __ASM_PPC_MPC8260_H__ - - -#ifdef CONFIG_8260 - -#if defined(CONFIG_PQ2ADS) || defined (CONFIG_PQ2FADS) -#include -#endif - -#ifdef CONFIG_PCI_8260 -#include -#endif - -#endif /* CONFIG_8260 */ -#endif /* !__ASM_PPC_MPC8260_H__ */ -#endif /* __KERNEL__ */ diff --git a/trunk/include/asm-powerpc/mpc8xx.h b/trunk/include/asm-powerpc/mpc8xx.h deleted file mode 100644 index 580371120e1a..000000000000 --- a/trunk/include/asm-powerpc/mpc8xx.h +++ /dev/null @@ -1,28 +0,0 @@ -/* This is the single file included by all MPC8xx build options. - * Since there are many different boards and no standard configuration, - * we have a unique include file for each. Rather than change every - * file that has to include MPC8xx configuration, they all include - * this one and the configuration switching is done here. - */ -#ifdef __KERNEL__ -#ifndef __CONFIG_8xx_DEFS -#define __CONFIG_8xx_DEFS - - -#ifdef CONFIG_8xx - -#ifdef CONFIG_FADS -#include -#endif - -#if defined(CONFIG_MPC86XADS) -#include -#endif - -#if defined(CONFIG_MPC885ADS) -#include -#endif - -#endif /* CONFIG_8xx */ -#endif /* __CONFIG_8xx_DEFS */ -#endif /* __KERNEL__ */ diff --git a/trunk/include/asm-powerpc/mpic.h b/trunk/include/asm-powerpc/mpic.h index cb204a71e912..b71e7b32a555 100644 --- a/trunk/include/asm-powerpc/mpic.h +++ b/trunk/include/asm-powerpc/mpic.h @@ -102,6 +102,21 @@ #define MPIC_MAX_CPUS 32 #define MPIC_MAX_ISU 32 +/* + * Special vector numbers (internal use only) + */ +#define MPIC_VEC_SPURRIOUS 255 +#define MPIC_VEC_IPI_3 254 +#define MPIC_VEC_IPI_2 253 +#define MPIC_VEC_IPI_1 252 +#define MPIC_VEC_IPI_0 251 + +/* unused */ +#define MPIC_VEC_TIMER_3 250 +#define MPIC_VEC_TIMER_2 249 +#define MPIC_VEC_TIMER_1 248 +#define MPIC_VEC_TIMER_0 247 + /* * Tsi108 implementation of MPIC has many differences from the original one */ @@ -261,13 +276,6 @@ struct mpic unsigned char *senses; unsigned int senses_count; - /* vector numbers used for internal sources (ipi/timers) */ - unsigned int ipi_vecs[4]; - unsigned int timer_vecs[4]; - - /* Spurious vector to program into unused sources */ - unsigned int spurious_vec; - #ifdef CONFIG_MPIC_BROKEN_U3 /* The fixup table */ struct mpic_irq_fixup *fixups; @@ -324,8 +332,6 @@ struct mpic #define MPIC_NO_PTHROU_DIS 0x00000040 /* DCR based MPIC */ #define MPIC_USES_DCR 0x00000080 -/* MPIC has 11-bit vector fields (or larger) */ -#define MPIC_LARGE_VECTORS 0x00000100 /* MPIC HW modification ID */ #define MPIC_REGSET_MASK 0xf0000000 diff --git a/trunk/include/asm-powerpc/oprofile_impl.h b/trunk/include/asm-powerpc/oprofile_impl.h index 94c0ad2bff96..71043bf3641f 100644 --- a/trunk/include/asm-powerpc/oprofile_impl.h +++ b/trunk/include/asm-powerpc/oprofile_impl.h @@ -58,8 +58,10 @@ extern struct op_powerpc_model op_model_power4; extern struct op_powerpc_model op_model_7450; extern struct op_powerpc_model op_model_cell; +#ifndef CONFIG_FSL_BOOKE + /* All the classic PPC parts use these */ -static inline unsigned int classic_ctr_read(unsigned int i) +static inline unsigned int ctr_read(unsigned int i) { switch(i) { case 0: @@ -87,7 +89,7 @@ static inline unsigned int classic_ctr_read(unsigned int i) } } -static inline void classic_ctr_write(unsigned int i, unsigned int val) +static inline void ctr_write(unsigned int i, unsigned int val) { switch(i) { case 0: @@ -122,6 +124,89 @@ static inline void classic_ctr_write(unsigned int i, unsigned int val) break; } } +#else /* CONFIG_FSL_BOOKE */ +static inline u32 get_pmlca(int ctr) +{ + u32 pmlca; + + switch (ctr) { + case 0: + pmlca = mfpmr(PMRN_PMLCA0); + break; + case 1: + pmlca = mfpmr(PMRN_PMLCA1); + break; + case 2: + pmlca = mfpmr(PMRN_PMLCA2); + break; + case 3: + pmlca = mfpmr(PMRN_PMLCA3); + break; + default: + panic("Bad ctr number\n"); + } + + return pmlca; +} + +static inline void set_pmlca(int ctr, u32 pmlca) +{ + switch (ctr) { + case 0: + mtpmr(PMRN_PMLCA0, pmlca); + break; + case 1: + mtpmr(PMRN_PMLCA1, pmlca); + break; + case 2: + mtpmr(PMRN_PMLCA2, pmlca); + break; + case 3: + mtpmr(PMRN_PMLCA3, pmlca); + break; + default: + panic("Bad ctr number\n"); + } +} + +static inline unsigned int ctr_read(unsigned int i) +{ + switch(i) { + case 0: + return mfpmr(PMRN_PMC0); + case 1: + return mfpmr(PMRN_PMC1); + case 2: + return mfpmr(PMRN_PMC2); + case 3: + return mfpmr(PMRN_PMC3); + default: + return 0; + } +} + +static inline void ctr_write(unsigned int i, unsigned int val) +{ + switch(i) { + case 0: + mtpmr(PMRN_PMC0, val); + break; + case 1: + mtpmr(PMRN_PMC1, val); + break; + case 2: + mtpmr(PMRN_PMC2, val); + break; + case 3: + mtpmr(PMRN_PMC3, val); + break; + default: + break; + } +} + + +#endif /* CONFIG_FSL_BOOKE */ extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth); diff --git a/trunk/include/asm-powerpc/pci-bridge.h b/trunk/include/asm-powerpc/pci-bridge.h index d9bf5aba96cb..cb02c9d1ef93 100644 --- a/trunk/include/asm-powerpc/pci-bridge.h +++ b/trunk/include/asm-powerpc/pci-bridge.h @@ -53,8 +53,6 @@ struct pci_controller { unsigned long buid; unsigned long dma_window_base_cur; unsigned long dma_window_size; - - void *private_data; }; /* diff --git a/trunk/include/asm-powerpc/ps3.h b/trunk/include/asm-powerpc/ps3.h index 4f5a1e01fdac..52a69ed0d90a 100644 --- a/trunk/include/asm-powerpc/ps3.h +++ b/trunk/include/asm-powerpc/ps3.h @@ -21,33 +21,11 @@ #if !defined(_ASM_POWERPC_PS3_H) #define _ASM_POWERPC_PS3_H +#include /* for __deprecated */ #include #include #include -union ps3_firmware_version { - u64 raw; - struct { - u16 pad; - u16 major; - u16 minor; - u16 rev; - }; -}; - -int ps3_get_firmware_version(union ps3_firmware_version *v); - -/* 'Other OS' area */ - -enum ps3_param_av_multi_out { - PS3_PARAM_AV_MULTI_OUT_NTSC = 0, - PS3_PARAM_AV_MULTI_OUT_PAL_RGB = 1, - PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR = 2, - PS3_PARAM_AV_MULTI_OUT_SECAM = 3, -}; - -enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void); - /** * struct ps3_device_id - HV bus device identifier from the system repository * @bus_id: HV bus id, {1..} (zero invalid) @@ -161,32 +139,20 @@ unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr); /* inrerrupt routines */ -enum ps3_cpu_binding { - PS3_BINDING_CPU_ANY = -1, - PS3_BINDING_CPU_0 = 0, - PS3_BINDING_CPU_1 = 1, -}; - -int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, - unsigned int *virq); +int ps3_alloc_io_irq(unsigned int interrupt_id, unsigned int *virq); int ps3_free_io_irq(unsigned int virq); -int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq); +int ps3_alloc_event_irq(unsigned int *virq); int ps3_free_event_irq(unsigned int virq); int ps3_send_event_locally(unsigned int virq); -int ps3_connect_event_irq(enum ps3_cpu_binding cpu, - const struct ps3_device_id *did, unsigned int interrupt_id, - unsigned int *virq); +int ps3_connect_event_irq(const struct ps3_device_id *did, + unsigned int interrupt_id, unsigned int *virq); int ps3_disconnect_event_irq(const struct ps3_device_id *did, unsigned int interrupt_id, unsigned int virq); -int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp, - unsigned int *virq); +int ps3_alloc_vuart_irq(void* virt_addr_bmp, unsigned int *virq); int ps3_free_vuart_irq(unsigned int virq); -int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id, - unsigned int class, unsigned int *virq); -int ps3_free_spe_irq(unsigned int virq); -int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet, +int ps3_alloc_spe_irq(unsigned long spe_id, unsigned int class, unsigned int *virq); -int ps3_free_irq(unsigned int virq); +int ps3_free_spe_irq(unsigned int virq); /* lv1 result codes */ @@ -281,6 +247,146 @@ static inline const char* ps3_result(int result) #endif } +/* repository bus info */ + +enum ps3_bus_type { + PS3_BUS_TYPE_SB = 4, + PS3_BUS_TYPE_STORAGE = 5, +}; + +enum ps3_dev_type { + PS3_DEV_TYPE_SB_GELIC = 3, + PS3_DEV_TYPE_SB_USB = 4, + PS3_DEV_TYPE_SB_GPIO = 6, +}; + +int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, + u64 *value); +int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id); +int ps3_repository_read_bus_type(unsigned int bus_index, + enum ps3_bus_type *bus_type); +int ps3_repository_read_bus_num_dev(unsigned int bus_index, + unsigned int *num_dev); + +/* repository bus device info */ + +enum ps3_interrupt_type { + PS3_INTERRUPT_TYPE_EVENT_PORT = 2, + PS3_INTERRUPT_TYPE_SB_OHCI = 3, + PS3_INTERRUPT_TYPE_SB_EHCI = 4, + PS3_INTERRUPT_TYPE_OTHER = 5, +}; + +enum ps3_region_type { + PS3_REGION_TYPE_SB_OHCI = 3, + PS3_REGION_TYPE_SB_EHCI = 4, + PS3_REGION_TYPE_SB_GPIO = 5, +}; + +int ps3_repository_read_dev_str(unsigned int bus_index, + unsigned int dev_index, const char *dev_str, u64 *value); +int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, + unsigned int *dev_id); +int ps3_repository_read_dev_type(unsigned int bus_index, + unsigned int dev_index, enum ps3_dev_type *dev_type); +int ps3_repository_read_dev_intr(unsigned int bus_index, + unsigned int dev_index, unsigned int intr_index, + enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id); +int ps3_repository_read_dev_reg_type(unsigned int bus_index, + unsigned int dev_index, unsigned int reg_index, + enum ps3_region_type *reg_type); +int ps3_repository_read_dev_reg_addr(unsigned int bus_index, + unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, + u64 *len); +int ps3_repository_read_dev_reg(unsigned int bus_index, + unsigned int dev_index, unsigned int reg_index, + enum ps3_region_type *reg_type, u64 *bus_addr, u64 *len); + +/* repository bus enumerators */ + +struct ps3_repository_device { + unsigned int bus_index; + unsigned int dev_index; + struct ps3_device_id did; +}; + +int ps3_repository_find_device(enum ps3_bus_type bus_type, + enum ps3_dev_type dev_type, + const struct ps3_repository_device *start_dev, + struct ps3_repository_device *dev); +static inline int ps3_repository_find_first_device( + enum ps3_bus_type bus_type, enum ps3_dev_type dev_type, + struct ps3_repository_device *dev) +{ + return ps3_repository_find_device(bus_type, dev_type, NULL, dev); +} +int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, + enum ps3_interrupt_type intr_type, unsigned int *interrupt_id); +int ps3_repository_find_region(const struct ps3_repository_device *dev, + enum ps3_region_type reg_type, u64 *bus_addr, u64 *len); + +/* repository block device info */ + +int ps3_repository_read_dev_port(unsigned int bus_index, + unsigned int dev_index, u64 *port); +int ps3_repository_read_dev_blk_size(unsigned int bus_index, + unsigned int dev_index, u64 *blk_size); +int ps3_repository_read_dev_num_blocks(unsigned int bus_index, + unsigned int dev_index, u64 *num_blocks); +int ps3_repository_read_dev_num_regions(unsigned int bus_index, + unsigned int dev_index, unsigned int *num_regions); +int ps3_repository_read_dev_region_id(unsigned int bus_index, + unsigned int dev_index, unsigned int region_index, + unsigned int *region_id); +int ps3_repository_read_dev_region_size(unsigned int bus_index, + unsigned int dev_index, unsigned int region_index, u64 *region_size); +int ps3_repository_read_dev_region_start(unsigned int bus_index, + unsigned int dev_index, unsigned int region_index, u64 *region_start); + +/* repository pu and memory info */ + +int ps3_repository_read_num_pu(unsigned int *num_pu); +int ps3_repository_read_ppe_id(unsigned int *pu_index, unsigned int *ppe_id); +int ps3_repository_read_rm_base(unsigned int ppe_id, u64 *rm_base); +int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size); +int ps3_repository_read_region_total(u64 *region_total); +int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, + u64 *region_total); + +/* repository pme info */ + +int ps3_repository_read_num_be(unsigned int *num_be); +int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id); +int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq); +int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq); + +/* repository 'Other OS' area */ + +int ps3_repository_read_boot_dat_addr(u64 *lpar_addr); +int ps3_repository_read_boot_dat_size(unsigned int *size); +int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size); + +/* repository spu info */ + +/** + * enum spu_resource_type - Type of spu resource. + * @spu_resource_type_shared: Logical spu is shared with other partions. + * @spu_resource_type_exclusive: Logical spu is not shared with other partions. + * + * Returned by ps3_repository_read_spu_resource_id(). + */ + +enum ps3_spu_resource_type { + PS3_SPU_RESOURCE_TYPE_SHARED = 0, + PS3_SPU_RESOURCE_TYPE_EXCLUSIVE = 0x8000000000000000UL, +}; + +int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved); +int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id); +int ps3_repository_read_spu_resource_id(unsigned int res_index, + enum ps3_spu_resource_type* resource_type, unsigned int *resource_id); + + /* system bus routines */ enum ps3_match_id { @@ -353,39 +459,4 @@ static inline void *ps3_system_bus_get_driver_data( extern struct bus_type ps3_system_bus_type; -/* vuart routines */ - -struct ps3_vuart_stats { - unsigned long bytes_written; - unsigned long bytes_read; - unsigned long tx_interrupts; - unsigned long rx_interrupts; - unsigned long disconnect_interrupts; -}; - -/** - * struct ps3_vuart_port_device - a device on a vuart port - */ - -struct ps3_vuart_port_device { - enum ps3_match_id match_id; - struct device core; - - /* private driver variables */ - unsigned int port_number; - u64 interrupt_mask; - struct { - spinlock_t lock; - struct list_head head; - } tx_list; - struct { - unsigned long bytes_held; - spinlock_t lock; - struct list_head head; - } rx_list; - struct ps3_vuart_stats stats; -}; - -int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev); - #endif diff --git a/trunk/include/asm-powerpc/reg.h b/trunk/include/asm-powerpc/reg.h index 0d7f0164ed81..a3631b15754c 100644 --- a/trunk/include/asm-powerpc/reg.h +++ b/trunk/include/asm-powerpc/reg.h @@ -166,7 +166,6 @@ #define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */ #define SPRN_SPURR 0x134 /* Scaled PURR */ #define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ -#define SPRN_LPCR 0x13E /* LPAR Control Register */ #define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */ #define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */ #define SPRN_DBAT1L 0x21B /* Data BAT 1 Lower Register */ @@ -392,12 +391,6 @@ #define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */ #define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */ -#define SPRN_TBCTL 0x35f /* PA6T Timebase control register */ -#define TBCTL_FREEZE 0x0000000000000000ull /* Freeze all tbs */ -#define TBCTL_RESTART 0x0000000100000000ull /* Restart all tbs */ -#define TBCTL_UPDATE_UPPER 0x0000000200000000ull /* Set upper 32 bits */ -#define TBCTL_UPDATE_LOWER 0x0000000300000000ull /* Set lower 32 bits */ - #ifndef SPRN_SVR #define SPRN_SVR 0x11E /* System Version Register */ #endif @@ -469,13 +462,6 @@ #define SPRN_SIAR 780 #define SPRN_SDAR 781 -#define PA6T_SPRN_PMC0 787 -#define PA6T_SPRN_PMC1 788 -#define PA6T_SPRN_PMC2 789 -#define PA6T_SPRN_PMC3 790 -#define PA6T_SPRN_PMC4 791 -#define PA6T_SPRN_PMC5 792 - #else /* 32-bit */ #define SPRN_MMCR0 952 /* Monitor Mode Control Register 0 */ #define MMCR0_FC 0x80000000UL /* freeze counters */ diff --git a/trunk/include/asm-powerpc/smp.h b/trunk/include/asm-powerpc/smp.h index 01717f266dc9..20ea7c70bc38 100644 --- a/trunk/include/asm-powerpc/smp.h +++ b/trunk/include/asm-powerpc/smp.h @@ -75,7 +75,6 @@ extern cpumask_t cpu_sibling_map[NR_CPUS]; void smp_init_iSeries(void); void smp_init_pSeries(void); void smp_init_cell(void); -void smp_init_celleb(void); void smp_setup_cpu_maps(void); extern int __cpu_disable(void); diff --git a/trunk/include/asm-powerpc/spu.h b/trunk/include/asm-powerpc/spu.h index b634e16575f2..3d90264e9d36 100644 --- a/trunk/include/asm-powerpc/spu.h +++ b/trunk/include/asm-powerpc/spu.h @@ -104,7 +104,6 @@ struct spu_context; struct spu_runqueue; -struct device_node; struct spu { const char *name; @@ -143,19 +142,7 @@ struct spu { char irq_c1[8]; char irq_c2[8]; - u64 spe_id; - void* pdata; /* platform private data */ - - /* of based platforms only */ - struct device_node *devnode; - - /* native only */ - struct spu_priv1 __iomem *priv1; - - /* beat only */ - u64 shadow_int_mask_RW[3]; - struct sys_device sysdev; }; diff --git a/trunk/include/asm-powerpc/spu_priv1.h b/trunk/include/asm-powerpc/spu_priv1.h index 7e78f6a1ab8b..69dcb0c53884 100644 --- a/trunk/include/asm-powerpc/spu_priv1.h +++ b/trunk/include/asm-powerpc/spu_priv1.h @@ -206,8 +206,6 @@ spu_destroy_spu (struct spu *spu) */ extern const struct spu_priv1_ops spu_priv1_mmio_ops; -extern const struct spu_priv1_ops spu_priv1_beat_ops; - extern const struct spu_management_ops spu_management_of_ops; #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-powerpc/sstep.h b/trunk/include/asm-powerpc/sstep.h index f593b0f9b627..630a9889c07c 100644 --- a/trunk/include/asm-powerpc/sstep.h +++ b/trunk/include/asm-powerpc/sstep.h @@ -21,7 +21,6 @@ struct pt_regs; */ #define IS_MTMSRD(instr) (((instr) & 0xfc0007be) == 0x7c000124) #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024) -#define IS_RFI(instr) (((instr) & 0xfc0007fe) == 0x4c000064) /* Emulate instructions that cause a transfer of control. */ extern int emulate_step(struct pt_regs *regs, unsigned int instr); diff --git a/trunk/include/asm-powerpc/time.h b/trunk/include/asm-powerpc/time.h index 3fd57c048f59..4cff977ad526 100644 --- a/trunk/include/asm-powerpc/time.h +++ b/trunk/include/asm-powerpc/time.h @@ -39,8 +39,6 @@ extern void generic_calibrate_decr(void); extern void wakeup_decrementer(void); extern void snapshot_timebase(void); -extern void set_dec_cpu6(unsigned int val); - /* Some sane defaults: 125 MHz timebase, 1GHz processor */ extern unsigned long ppc_proc_freq; #define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) diff --git a/trunk/include/asm-powerpc/udbg.h b/trunk/include/asm-powerpc/udbg.h index 4cbc313aa02a..55e57844fa78 100644 --- a/trunk/include/asm-powerpc/udbg.h +++ b/trunk/include/asm-powerpc/udbg.h @@ -41,11 +41,9 @@ extern void __init udbg_early_init(void); extern void __init udbg_init_debug_lpar(void); extern void __init udbg_init_pmac_realmode(void); extern void __init udbg_init_maple_realmode(void); -extern void __init udbg_init_pas_realmode(void); extern void __init udbg_init_iseries(void); extern void __init udbg_init_rtas_panel(void); extern void __init udbg_init_rtas_console(void); -extern void __init udbg_init_debug_beat(void); #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_UDBG_H */ diff --git a/trunk/include/asm-ppc/commproc.h b/trunk/include/asm-ppc/commproc.h index 4f99df1bafd7..7b06b4e6bf30 100644 --- a/trunk/include/asm-ppc/commproc.h +++ b/trunk/include/asm-ppc/commproc.h @@ -77,7 +77,6 @@ extern int cpm_dpfree(uint offset); extern uint cpm_dpalloc_fixed(uint offset, uint size, uint align); extern void cpm_dpdump(void); extern void *cpm_dpram_addr(uint offset); -extern uint cpm_dpram_phys(u8* addr); extern void cpm_setbrg(uint brg, uint rate); extern uint m8xx_cpm_hostalloc(uint size); diff --git a/trunk/include/asm-ppc/ibm4xx.h b/trunk/include/asm-ppc/ibm4xx.h index 7a64ede53bb6..499c14691c71 100644 --- a/trunk/include/asm-ppc/ibm4xx.h +++ b/trunk/include/asm-ppc/ibm4xx.h @@ -15,7 +15,6 @@ #define __ASM_IBM4XX_H__ #include -#include #ifdef CONFIG_40x diff --git a/trunk/include/asm-ppc/m48t35.h b/trunk/include/asm-ppc/m48t35.h new file mode 100644 index 000000000000..a5277ea4b194 --- /dev/null +++ b/trunk/include/asm-ppc/m48t35.h @@ -0,0 +1,77 @@ +/* + * Registers for the SGS-Thomson M48T35 Timekeeper RAM chip + * and + * Registers for the SGS-Thomson M48T37 Timekeeper RAM chip + * The 37 is the 35 plus alarm and century thus the offsets + * are shifted by the extra registers. + */ + +#ifndef __PPC_M48T35_H +#define __PPC_M48T35_H + +/* RTC offsets */ +#define M48T35_RTC_FLAGS (-8) /* the negative regs are really T37 only */ +#define M48T35_RTC_CENTURY (-7) +#define M48T35_RTC_AL_SEC (-6) +#define M48T35_RTC_AL_MIN (-5) +#define M48T35_RTC_AL_HRS (-4) +#define M48T35_RTC_AL_DOM (-3) +#define M48T35_RTC_INTERRUPT (-2) +#define M48T35_RTC_WATCHDOG (-1) +#define M48T35_RTC_CONTROL 0 /* T35 starts here */ +#define M48T35_RTC_SECONDS 1 +#define M48T35_RTC_MINUTES 2 +#define M48T35_RTC_HOURS 3 +#define M48T35_RTC_DAY 4 +#define M48T35_RTC_DOM 5 +#define M48T35_RTC_MONTH 6 +#define M48T35_RTC_YEAR 7 + +/* this way help us know which bits go with which regs */ +#define M48T35_RTC_FLAGS_BL 0x10 +#define M48T35_RTC_FLAGS_AF 0x40 +#define M48T35_RTC_FLAGS_WDF 0x80 + +#define M48T35_RTC_INTERRUPT_AFE 0x80 +#define M48T35_RTC_INTERRUPT_ABE 0x20 +#define M48T35_RTC_INTERRUPT_ALL (M48T35_RTC_INTERRUPT_AFE|M48T35_RTC_INTERRUPT_ABE) + +#define M48T35_RTC_WATCHDOG_RB 0x03 +#define M48T35_RTC_WATCHDOG_BMB 0x7c +#define M48T35_RTC_WATCHDOG_WDS 0x80 +#define M48T35_RTC_WATCHDOG_ALL (M48T35_RTC_WATCHDOG_RB|M48T35_RTC_WATCHDOG_BMB|M48T35_RTC_W) + +#define M48T35_RTC_CONTROL_WRITE 0x80 +#define M48T35_RTC_CONTROL_READ 0x40 +#define M48T35_RTC_CONTROL_CAL_SIGN 0x20 +#define M48T35_RTC_CONTROL_CAL_VALUE 0x1f +#define M48T35_RTC_CONTROL_LOCKED (M48T35_RTC_WRITE|M48T35_RTC_READ) +#define M48T35_RTC_CONTROL_CALIBRATION (M48T35_RTC_CONTROL_CAL_SIGN|M48T35_RTC_CONTROL_CAL_VALUE) + +#define M48T35_RTC_SECONDS_SEC_1 0x0f +#define M48T35_RTC_SECONDS_SEC_10 0x70 +#define M48T35_RTC_SECONDS_ST 0x80 +#define M48T35_RTC_SECONDS_SEC_ALL (M48T35_RTC_SECONDS_SEC_1|M48T35_RTC_SECONDS_SEC_10) + +#define M48T35_RTC_MINUTES_MIN_1 0x0f +#define M48T35_RTC_MINUTES_MIN_10 0x70 +#define M48T35_RTC_MINUTES_MIN_ALL (M48T35_RTC_MINUTES_MIN_1|M48T35_RTC_MINUTES_MIN_10) + +#define M48T35_RTC_HOURS_HRS_1 0x0f +#define M48T35_RTC_HOURS_HRS_10 0x30 +#define M48T35_RTC_HOURS_HRS_ALL (M48T35_RTC_HOURS_HRS_1|M48T35_RTC_HOURS_HRS_10) + +#define M48T35_RTC_DAY_DAY_1 0x03 +#define M48T35_RTC_DAY_FT 0x40 + +#define M48T35_RTC_ALARM_OFF 0x00 +#define M48T35_RTC_WATCHDOG_OFF 0x00 + + +/* legacy */ +#define M48T35_RTC_SET 0x80 +#define M48T35_RTC_STOPPED 0x80 +#define M48T35_RTC_READ 0x40 + + +#endif diff --git a/trunk/include/asm-ppc/reg_booke.h b/trunk/include/asm-ppc/reg_booke.h index 82948ed2744a..a263fc1e65c4 100644 --- a/trunk/include/asm-ppc/reg_booke.h +++ b/trunk/include/asm-ppc/reg_booke.h @@ -9,6 +9,8 @@ #ifndef __ASM_PPC_REG_BOOKE_H__ #define __ASM_PPC_REG_BOOKE_H__ +#include + #ifndef __ASSEMBLY__ /* Performance Monitor Registers */ #define mfpmr(rn) ({unsigned int rval; \ diff --git a/trunk/include/asm-ppc/serial.h b/trunk/include/asm-ppc/serial.h index 8fc1b546613d..8a59f8871f32 100644 --- a/trunk/include/asm-ppc/serial.h +++ b/trunk/include/asm-ppc/serial.h @@ -11,6 +11,8 @@ #include #elif defined(CONFIG_CHESTNUT) #include +#elif defined(CONFIG_GEMINI) +#include #elif defined(CONFIG_POWERPMC250) #include #elif defined(CONFIG_LOPEC) diff --git a/trunk/include/asm-x86_64/acpi.h b/trunk/include/asm-x86_64/acpi.h index a29f05087a31..6b6fc6f8be7e 100644 --- a/trunk/include/asm-x86_64/acpi.h +++ b/trunk/include/asm-x86_64/acpi.h @@ -37,7 +37,7 @@ * Calling conventions: * * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_EXTERNAL_XFACE - External ACPI interfaces * ACPI_INTERNAL_XFACE - Internal ACPI interfaces * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces */ @@ -57,11 +57,11 @@ int __acpi_acquire_global_lock(unsigned int *lock); int __acpi_release_global_lock(unsigned int *lock); -#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr)) -#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_release_global_lock(&facs->global_lock)) +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = __acpi_release_global_lock((unsigned int *) GLptr)) /* * Math helper asm macros @@ -87,10 +87,10 @@ extern int acpi_strict; extern int acpi_disabled; extern int acpi_pci_disabled; extern int acpi_ht; -static inline void disable_acpi(void) -{ - acpi_disabled = 1; - acpi_ht = 0; +static inline void disable_acpi(void) +{ + acpi_disabled = 1; + acpi_ht = 0; acpi_pci_disabled = 1; acpi_noirq = 1; } @@ -100,9 +100,9 @@ static inline void disable_acpi(void) extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); static inline void acpi_noirq_set(void) { acpi_noirq = 1; } -static inline void acpi_disable_pci(void) +static inline void acpi_disable_pci(void) { - acpi_pci_disabled = 1; + acpi_pci_disabled = 1; acpi_noirq_set(); } extern int acpi_irq_balance_set(char *str); @@ -136,6 +136,8 @@ extern void acpi_reserve_bootmem(void); extern int acpi_disabled; extern int acpi_pci_disabled; +extern u8 x86_acpiid_to_apicid[]; + #define ARCH_HAS_POWER_INIT 1 extern int acpi_skip_timer_override; diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index 683513e310de..157db77a7170 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -11,7 +11,6 @@ header-y += netfilter_arp/ header-y += netfilter_bridge/ header-y += netfilter_ipv4/ header-y += netfilter_ipv6/ -header-y += usb/ header-y += affs_hardblocks.h header-y += aio_abi.h @@ -327,6 +326,7 @@ unifdef-y += udp.h unifdef-y += uinput.h unifdef-y += uio.h unifdef-y += unistd.h +unifdef-y += usb_ch9.h unifdef-y += usbdevice_fs.h unifdef-y += user.h unifdef-y += utsname.h diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 815f1fb4ce21..91f1f2363870 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -53,6 +53,166 @@ enum acpi_irq_model_id { extern enum acpi_irq_model_id acpi_irq_model; + +/* Root System Description Pointer (RSDP) */ + +struct acpi_table_rsdp { + char signature[8]; + u8 checksum; + char oem_id[6]; + u8 revision; + u32 rsdt_address; +} __attribute__ ((packed)); + +struct acpi20_table_rsdp { + char signature[8]; + u8 checksum; + char oem_id[6]; + u8 revision; + u32 rsdt_address; + u32 length; + u64 xsdt_address; + u8 ext_checksum; + u8 reserved[3]; +} __attribute__ ((packed)); + +typedef struct { + u8 type; + u8 length; +} __attribute__ ((packed)) acpi_table_entry_header; + +/* Root System Description Table (RSDT) */ + +struct acpi_table_rsdt { + struct acpi_table_header header; + u32 entry[8]; +} __attribute__ ((packed)); + +/* Extended System Description Table (XSDT) */ + +struct acpi_table_xsdt { + struct acpi_table_header header; + u64 entry[1]; +} __attribute__ ((packed)); + +/* Fixed ACPI Description Table (FADT) */ + +struct acpi_table_fadt { + struct acpi_table_header header; + u32 facs_addr; + u32 dsdt_addr; + /* ... */ +} __attribute__ ((packed)); + +/* Multiple APIC Description Table (MADT) */ + +struct acpi_table_madt { + struct acpi_table_header header; + u32 lapic_address; + struct { + u32 pcat_compat:1; + u32 reserved:31; + } flags; +} __attribute__ ((packed)); + +enum acpi_madt_entry_id { + ACPI_MADT_LAPIC = 0, + ACPI_MADT_IOAPIC, + ACPI_MADT_INT_SRC_OVR, + ACPI_MADT_NMI_SRC, + ACPI_MADT_LAPIC_NMI, + ACPI_MADT_LAPIC_ADDR_OVR, + ACPI_MADT_IOSAPIC, + ACPI_MADT_LSAPIC, + ACPI_MADT_PLAT_INT_SRC, + ACPI_MADT_ENTRY_COUNT +}; + +typedef struct { + u16 polarity:2; + u16 trigger:2; + u16 reserved:12; +} __attribute__ ((packed)) acpi_interrupt_flags; + +struct acpi_table_lapic { + acpi_table_entry_header header; + u8 acpi_id; + u8 id; + struct { + u32 enabled:1; + u32 reserved:31; + } flags; +} __attribute__ ((packed)); + +struct acpi_table_ioapic { + acpi_table_entry_header header; + u8 id; + u8 reserved; + u32 address; + u32 global_irq_base; +} __attribute__ ((packed)); + +struct acpi_table_int_src_ovr { + acpi_table_entry_header header; + u8 bus; + u8 bus_irq; + u32 global_irq; + acpi_interrupt_flags flags; +} __attribute__ ((packed)); + +struct acpi_table_nmi_src { + acpi_table_entry_header header; + acpi_interrupt_flags flags; + u32 global_irq; +} __attribute__ ((packed)); + +struct acpi_table_lapic_nmi { + acpi_table_entry_header header; + u8 acpi_id; + acpi_interrupt_flags flags; + u8 lint; +} __attribute__ ((packed)); + +struct acpi_table_lapic_addr_ovr { + acpi_table_entry_header header; + u8 reserved[2]; + u64 address; +} __attribute__ ((packed)); + +struct acpi_table_iosapic { + acpi_table_entry_header header; + u8 id; + u8 reserved; + u32 global_irq_base; + u64 address; +} __attribute__ ((packed)); + +struct acpi_table_lsapic { + acpi_table_entry_header header; + u8 acpi_id; + u8 id; + u8 eid; + u8 reserved[3]; + struct { + u32 enabled:1; + u32 reserved:31; + } flags; +} __attribute__ ((packed)); + +struct acpi_table_plat_int_src { + acpi_table_entry_header header; + acpi_interrupt_flags flags; + u8 type; /* See acpi_interrupt_type */ + u8 id; + u8 eid; + u8 iosapic_vector; + u32 global_irq; + struct { + u32 cpei_override_flag:1; + u32 reserved:31; + } plint_flags; +} __attribute__ ((packed)); + enum acpi_interrupt_id { ACPI_INTERRUPT_PMI = 1, ACPI_INTERRUPT_INIT, @@ -62,6 +222,89 @@ enum acpi_interrupt_id { #define ACPI_SPACE_MEM 0 +struct acpi_gen_regaddr { + u8 space_id; + u8 bit_width; + u8 bit_offset; + u8 resv; + u32 addrl; + u32 addrh; +} __attribute__ ((packed)); + +struct acpi_table_hpet { + struct acpi_table_header header; + u32 id; + struct acpi_gen_regaddr addr; + u8 number; + u16 min_tick; + u8 page_protect; +} __attribute__ ((packed)); + +/* + * Simple Boot Flags + * http://www.microsoft.com/whdc/hwdev/resources/specs/simp_bios.mspx + */ +struct acpi_table_sbf +{ + u8 sbf_signature[4]; + u32 sbf_len; + u8 sbf_revision; + u8 sbf_csum; + u8 sbf_oemid[6]; + u8 sbf_oemtable[8]; + u8 sbf_revdata[4]; + u8 sbf_creator[4]; + u8 sbf_crearev[4]; + u8 sbf_cmos; + u8 sbf_spare[3]; +} __attribute__ ((packed)); + +/* + * System Resource Affinity Table (SRAT) + * http://www.microsoft.com/whdc/hwdev/platform/proc/SRAT.mspx + */ + +struct acpi_table_srat { + struct acpi_table_header header; + u32 table_revision; + u64 reserved; +} __attribute__ ((packed)); + +enum acpi_srat_entry_id { + ACPI_SRAT_PROCESSOR_AFFINITY = 0, + ACPI_SRAT_MEMORY_AFFINITY, + ACPI_SRAT_ENTRY_COUNT +}; + +struct acpi_table_processor_affinity { + acpi_table_entry_header header; + u8 proximity_domain; + u8 apic_id; + struct { + u32 enabled:1; + u32 reserved:31; + } flags; + u8 lsapic_eid; + u8 reserved[7]; +} __attribute__ ((packed)); + +struct acpi_table_memory_affinity { + acpi_table_entry_header header; + u8 proximity_domain; + u8 reserved1[5]; + u32 base_addr_lo; + u32 base_addr_hi; + u32 length_lo; + u32 length_hi; + u32 memory_type; /* See acpi_address_range_id */ + struct { + u32 enabled:1; + u32 hot_pluggable:1; + u32 reserved:30; + } flags; + u64 reserved2; +} __attribute__ ((packed)); + enum acpi_address_range_id { ACPI_ADDRESS_RANGE_MEMORY = 1, ACPI_ADDRESS_RANGE_RESERVED = 2, @@ -70,12 +313,84 @@ enum acpi_address_range_id { ACPI_ADDRESS_RANGE_COUNT }; +/* + * System Locality Information Table (SLIT) + * see http://devresource.hp.com/devresource/docs/techpapers/ia64/slit.pdf + */ + +struct acpi_table_slit { + struct acpi_table_header header; + u64 localities; + u8 entry[1]; /* real size = localities^2 */ +} __attribute__ ((packed)); + +/* Smart Battery Description Table (SBST) */ + +struct acpi_table_sbst { + struct acpi_table_header header; + u32 warning; /* Warn user */ + u32 low; /* Critical sleep */ + u32 critical; /* Critical shutdown */ +} __attribute__ ((packed)); + +/* Embedded Controller Boot Resources Table (ECDT) */ + +struct acpi_table_ecdt { + struct acpi_table_header header; + struct acpi_generic_address ec_control; + struct acpi_generic_address ec_data; + u32 uid; + u8 gpe_bit; + char ec_id[0]; +} __attribute__ ((packed)); + +/* PCI MMCONFIG */ + +/* Defined in PCI Firmware Specification 3.0 */ +struct acpi_table_mcfg_config { + u32 base_address; + u32 base_reserved; + u16 pci_segment_group_number; + u8 start_bus_number; + u8 end_bus_number; + u8 reserved[4]; +} __attribute__ ((packed)); +struct acpi_table_mcfg { + struct acpi_table_header header; + u8 reserved[8]; + struct acpi_table_mcfg_config config[0]; +} __attribute__ ((packed)); /* Table Handlers */ -typedef int (*acpi_table_handler) (struct acpi_table_header *table); +enum acpi_table_id { + ACPI_TABLE_UNKNOWN = 0, + ACPI_APIC, + ACPI_BOOT, + ACPI_DBGP, + ACPI_DSDT, + ACPI_ECDT, + ACPI_ETDT, + ACPI_FADT, + ACPI_FACS, + ACPI_OEMX, + ACPI_PSDT, + ACPI_SBST, + ACPI_SLIT, + ACPI_SPCR, + ACPI_SRAT, + ACPI_SSDT, + ACPI_SPMI, + ACPI_HPET, + ACPI_MCFG, + ACPI_TABLE_COUNT +}; + +typedef int (*acpi_table_handler) (unsigned long phys_addr, unsigned long size); + +extern acpi_table_handler acpi_table_ops[ACPI_TABLE_COUNT]; -typedef int (*acpi_madt_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); +typedef int (*acpi_madt_entry_handler) (acpi_table_entry_header *header, const unsigned long end); char * __acpi_map_table (unsigned long phys_addr, unsigned long size); unsigned long acpi_find_rsdp (void); @@ -84,12 +399,14 @@ int acpi_boot_table_init (void); int acpi_numa_init (void); int acpi_table_init (void); -int acpi_table_parse (char *id, acpi_table_handler handler); -int acpi_table_parse_madt (enum acpi_madt_type id, acpi_madt_entry_handler handler, unsigned int max_entries); -int acpi_table_parse_srat (enum acpi_srat_type id, acpi_madt_entry_handler handler, unsigned int max_entries); -int acpi_parse_mcfg (struct acpi_table_header *header); -void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); -void acpi_table_print_srat_entry (struct acpi_subtable_header *srat); +int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler); +int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); +int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); +int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); +int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size); +void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); +void acpi_table_print_madt_entry (acpi_table_entry_header *madt); +void acpi_table_print_srat_entry (acpi_table_entry_header *srat); /* the following four functions are architecture-dependent */ #ifdef CONFIG_HAVE_ARCH_PARSE_SRAT @@ -100,8 +417,8 @@ void acpi_table_print_srat_entry (struct acpi_subtable_header *srat); #define acpi_numa_arch_fixup() do {} while (0) #else void acpi_numa_slit_init (struct acpi_table_slit *slit); -void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); -void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); +void acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa); +void acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma); void acpi_numa_arch_fixup(void); #endif @@ -116,7 +433,7 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); extern int acpi_mp_config; -extern struct acpi_mcfg_allocation *pci_mmcfg_config; +extern struct acpi_table_mcfg_config *pci_mmcfg_config; extern int pci_mmcfg_config_num; extern int sbf_port; diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 5ca1cdba563a..f44247fe8135 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -126,7 +126,6 @@ struct device_driver { struct klist_node knode_bus; struct module * owner; - const char * mod_name; /* used for built-in modules */ int (*probe) (struct device * dev); int (*remove) (struct device * dev); @@ -328,13 +327,6 @@ extern struct class_device *class_device_create(struct class *cls, __attribute__((format(printf,5,6))); extern void class_device_destroy(struct class *cls, dev_t devt); -struct device_type { - struct device_attribute *attrs; - int (*uevent)(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size); - void (*release)(struct device *dev); -}; - /* interface for exporting device attributes */ struct device_attribute { struct attribute attr; @@ -363,7 +355,6 @@ struct device { struct kobject kobj; char bus_id[BUS_ID_SIZE]; /* position on parent bus */ - struct device_type *type; unsigned is_registered:1; struct device_attribute uevent_attr; struct device_attribute *devt_attr; @@ -399,10 +390,9 @@ struct device { /* class_device migration path */ struct list_head node; - struct class *class; + struct class *class; /* optional*/ dev_t devt; /* dev_t, creates the sysfs "dev" */ struct attribute_group **groups; /* optional groups */ - int uevent_suppress; void (*release)(struct device * dev); }; diff --git a/trunk/include/linux/hid.h b/trunk/include/linux/hid.h index d26b08f461f2..93173fe45634 100644 --- a/trunk/include/linux/hid.h +++ b/trunk/include/linux/hid.h @@ -266,7 +266,6 @@ struct hid_item { #define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000 #define HID_QUIRK_IGNORE_MOUSE 0x00040000 -#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000 /* * This is the global environment of the parser. This information is diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index 04e0fa97ac99..e26a03981a94 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -18,9 +18,6 @@ #include #include #include -#ifdef CONFIG_BLK_DEV_IDEACPI -#include -#endif #include #include #include @@ -544,11 +541,6 @@ typedef enum { struct ide_driver_s; struct ide_settings_s; -#ifdef CONFIG_BLK_DEV_IDEACPI -struct ide_acpi_drive_link; -struct ide_acpi_hwif_link; -#endif - typedef struct ide_drive_s { char name[4]; /* drive name, such as "hda" */ char driver_req[10]; /* requests specific driver */ @@ -645,9 +637,6 @@ typedef struct ide_drive_s { int lun; /* logical unit */ int crc_count; /* crc counter to reduce drive speed */ -#ifdef CONFIG_BLK_DEV_IDEACPI - struct ide_acpi_drive_link *acpidata; -#endif struct list_head list; struct device gendev; struct completion gendev_rel_comp; /* to deal with device release() */ @@ -815,10 +804,6 @@ typedef struct hwif_s { void *hwif_data; /* extra hwif data */ unsigned dma; - -#ifdef CONFIG_BLK_DEV_IDEACPI - struct ide_acpi_hwif_link *acpidata; -#endif } ____cacheline_internodealigned_in_smp ide_hwif_t; /* @@ -1207,8 +1192,8 @@ void ide_init_disk(struct gendisk *, ide_drive_t *); extern int ideprobe_init(void); extern void ide_scan_pcibus(int scan_direction) __init; -extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name); -#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME) +extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner); +#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE) void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *); extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d); @@ -1313,18 +1298,6 @@ static inline void ide_dma_verbose(ide_drive_t *drive) { ; } static inline void ide_release_dma(ide_hwif_t *drive) {;} #endif -#ifdef CONFIG_BLK_DEV_IDEACPI -extern int ide_acpi_exec_tfs(ide_drive_t *drive); -extern void ide_acpi_get_timing(ide_hwif_t *hwif); -extern void ide_acpi_push_timing(ide_hwif_t *hwif); -extern void ide_acpi_init(ide_hwif_t *hwif); -#else -static inline int ide_acpi_exec_tfs(ide_drive_t *drive) { return 0; } -static inline void ide_acpi_get_timing(ide_hwif_t *hwif) { ; } -static inline void ide_acpi_push_timing(ide_hwif_t *hwif) { ; } -static inline void ide_acpi_init(ide_hwif_t *hwif) { ; } -#endif - extern int ide_hwif_request_regions(ide_hwif_t *hwif); extern void ide_hwif_release_regions(ide_hwif_t* hwif); extern void ide_unregister (unsigned int index); diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 5504b671357f..52fc4052a0ae 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -68,7 +68,6 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, #define IRQ_MOVE_PENDING 0x40000000 /* need to re-target IRQ destination */ struct proc_dir_entry; -struct msi_desc; /** * struct irq_chip - hardware interrupt chip descriptor @@ -149,7 +148,6 @@ struct irq_chip { struct irq_desc { irq_flow_handler_t handle_irq; struct irq_chip *chip; - struct msi_desc *msi_desc; void *handler_data; void *chip_data; struct irqaction *action; /* IRQ action list */ @@ -375,12 +373,10 @@ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); extern int set_irq_data(unsigned int irq, void *data); extern int set_irq_chip_data(unsigned int irq, void *data); extern int set_irq_type(unsigned int irq, unsigned int type); -extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); #define get_irq_chip(irq) (irq_desc[irq].chip) #define get_irq_chip_data(irq) (irq_desc[irq].chip_data) #define get_irq_data(irq) (irq_desc[irq].handler_data) -#define get_irq_msi(irq) (irq_desc[irq].msi_desc) #endif /* CONFIG_GENERIC_HARDIRQS */ diff --git a/trunk/include/linux/kobject.h b/trunk/include/linux/kobject.h index b850e0310538..76538fcf2c4e 100644 --- a/trunk/include/linux/kobject.h +++ b/trunk/include/linux/kobject.h @@ -74,13 +74,9 @@ extern void kobject_init(struct kobject *); extern void kobject_cleanup(struct kobject *); extern int __must_check kobject_add(struct kobject *); -extern int __must_check kobject_shadow_add(struct kobject *, struct dentry *); extern void kobject_del(struct kobject *); extern int __must_check kobject_rename(struct kobject *, const char *new_name); -extern int __must_check kobject_shadow_rename(struct kobject *kobj, - struct dentry *new_parent, - const char *new_name); extern int __must_check kobject_move(struct kobject *, struct kobject *); extern int __must_check kobject_register(struct kobject *); diff --git a/trunk/include/linux/log2.h b/trunk/include/linux/log2.h index 99922bedfcc9..d02e1a547a7e 100644 --- a/trunk/include/linux/log2.h +++ b/trunk/include/linux/log2.h @@ -43,17 +43,6 @@ int __ilog2_u64(u64 n) } #endif -/* - * Determine whether some value is a power of two, where zero is - * *not* considered a power of two. - */ - -static inline __attribute__((const)) -bool is_power_of_2(unsigned long n) -{ - return (n != 0 && ((n & (n - 1)) == 0)); -} - /* * round up to nearest power of two */ diff --git a/trunk/include/linux/module.h b/trunk/include/linux/module.h index 419d3ef293dd..10f771a49997 100644 --- a/trunk/include/linux/module.h +++ b/trunk/include/linux/module.h @@ -58,7 +58,6 @@ struct module_kobject { struct kobject kobj; struct module *mod; - struct kobject *drivers_dir; }; /* These are either module local, or the kernel's dummy ones. */ @@ -264,7 +263,7 @@ struct module struct module_attribute *modinfo_attrs; const char *version; const char *srcversion; - struct kobject *holders_dir; + struct kobject *drivers_dir; /* Exported symbols */ const struct kernel_symbol *syms; diff --git a/trunk/include/linux/msi.h b/trunk/include/linux/msi.h index 74c8a2ecc9dd..c7ef94343673 100644 --- a/trunk/include/linux/msi.h +++ b/trunk/include/linux/msi.h @@ -7,10 +7,11 @@ struct msi_msg { u32 data; /* 16 bits of msi message data */ }; -/* Helper functions */ +/* Heper functions */ extern void mask_msi_irq(unsigned int irq); extern void unmask_msi_irq(unsigned int irq); extern void read_msi_msg(unsigned int irq, struct msi_msg *msg); + extern void write_msi_msg(unsigned int irq, struct msi_msg *msg); struct msi_desc { @@ -41,7 +42,7 @@ struct msi_desc { /* * The arch hook for setup up msi irqs */ -int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); +int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev); void arch_teardown_msi_irq(unsigned int irq); diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 2e37f5012788..fea0d9db6846 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -529,11 +529,10 @@ struct net_device struct net_bridge_port *br_port; /* class/net/name entry */ - struct device dev; + struct class_device class_dev; /* space for optional statistics and wireless sysfs groups */ struct attribute_group *sysfs_groups[3]; }; -#define to_net_dev(d) container_of(d, struct net_device, dev) #define NETDEV_ALIGN 32 #define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1) @@ -549,7 +548,7 @@ static inline void *netdev_priv(struct net_device *dev) /* Set the sysfs physical device reference for the network logical device * if set prior to registration will cause a symlink during initialization. */ -#define SET_NETDEV_DEV(net, pdev) ((net)->dev.parent = (pdev)) +#define SET_NETDEV_DEV(net, pdev) ((net)->class_dev.dev = (pdev)) struct packet_type { __be16 type; /* This is really htons(ether_type). */ diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 805412cc6875..f3c617eabd8d 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -174,9 +174,6 @@ struct pci_dev { struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ int rom_attr_enabled; /* has display of the rom attribute been enabled? */ struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ -#ifdef CONFIG_PCI_MSI - unsigned int first_msi_irq; -#endif }; #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list) @@ -184,11 +181,6 @@ struct pci_dev { #define to_pci_dev(n) container_of(n, struct pci_dev, dev) #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) -static inline int pci_channel_offline(struct pci_dev *pdev) -{ - return (pdev->error_state != pci_channel_io_normal); -} - static inline struct pci_cap_saved_state *pci_find_saved_cap( struct pci_dev *pci_dev,char cap) { @@ -471,7 +463,8 @@ extern void pci_sort_breadthfirst(void); /* Generic PCI functions exported to card drivers */ -struct pci_dev __deprecated *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); +struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); +struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from); struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); int pci_find_capability (struct pci_dev *dev, int cap); int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); @@ -540,7 +533,6 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); int __must_check pci_assign_resource(struct pci_dev *dev, int i); int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i); void pci_restore_bars(struct pci_dev *dev); -int pci_select_bars(struct pci_dev *dev, unsigned long flags); /* ROM control related routines */ void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); @@ -569,8 +561,6 @@ int __must_check pci_request_regions(struct pci_dev *, const char *); void pci_release_regions(struct pci_dev *); int __must_check pci_request_region(struct pci_dev *, int, const char *); void pci_release_region(struct pci_dev *, int); -int pci_request_selected_regions(struct pci_dev *, int, const char *); -void pci_release_selected_regions(struct pci_dev *, int); /* drivers/pci/bus.c */ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, @@ -583,11 +573,10 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, void pci_enable_bridges(struct pci_bus *bus); /* Proper probing supporting hot-pluggable devices */ -int __must_check __pci_register_driver(struct pci_driver *, struct module *, - const char *mod_name); +int __must_check __pci_register_driver(struct pci_driver *, struct module *); static inline int __must_check pci_register_driver(struct pci_driver *driver) { - return __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); + return __pci_register_driver(driver, THIS_MODULE); } void pci_unregister_driver(struct pci_driver *); @@ -622,6 +611,10 @@ enum pci_dma_burst_strategy { strategy_parameter byte boundaries */ }; +#if defined(CONFIG_ISA) || defined(CONFIG_EISA) +extern struct pci_dev *isa_bridge; +#endif + struct msix_entry { u16 vector; /* kernel uses to write allocated vector */ u16 entry; /* driver uses to specify entry, OS writes */ @@ -629,6 +622,7 @@ struct msix_entry { #ifndef CONFIG_PCI_MSI +static inline void pci_scan_msi_device(struct pci_dev *dev) {} static inline int pci_enable_msi(struct pci_dev *dev) {return -1;} static inline void pci_disable_msi(struct pci_dev *dev) {} static inline int pci_enable_msix(struct pci_dev* dev, @@ -636,6 +630,7 @@ static inline int pci_enable_msix(struct pci_dev* dev, static inline void pci_disable_msix(struct pci_dev *dev) {} static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} #else +extern void pci_scan_msi_device(struct pci_dev *dev); extern int pci_enable_msi(struct pci_dev *dev); extern void pci_disable_msi(struct pci_dev *dev); extern int pci_enable_msix(struct pci_dev* dev, @@ -727,6 +722,8 @@ static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { static inline pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) { return PCI_D0; } static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { return 0; } +#define isa_bridge ((struct pci_dev *)NULL) + #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index defdeed20641..ccd706f876ec 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1454,7 +1454,6 @@ #define PCI_VENDOR_ID_TOSHIBA_2 0x102f #define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030 -#define PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE 0x0105 #define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108 #define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3 @@ -2071,8 +2070,6 @@ #define PCI_VENDOR_ID_TDI 0x192E #define PCI_DEVICE_ID_TDI_EHCI 0x0101 -#define PCI_VENDOR_ID_PASEMI 0x1959 - #define PCI_VENDOR_ID_JMICRON 0x197B #define PCI_DEVICE_ID_JMICRON_JMB360 0x2360 #define PCI_DEVICE_ID_JMICRON_JMB361 0x2361 diff --git a/trunk/include/linux/serio.h b/trunk/include/linux/serio.h index ac2c70e7f760..0f478a8791a2 100644 --- a/trunk/include/linux/serio.h +++ b/trunk/include/linux/serio.h @@ -86,11 +86,6 @@ static inline void serio_register_port(struct serio *serio) void serio_unregister_port(struct serio *serio); void serio_unregister_child_port(struct serio *serio); -int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name); -static inline int serio_register_driver(struct serio_driver *drv) -{ - return __serio_register_driver(drv, THIS_MODULE, KBUILD_MODNAME); -} int serio_register_driver(struct serio_driver *drv); void serio_unregister_driver(struct serio_driver *drv); diff --git a/trunk/include/linux/sysdev.h b/trunk/include/linux/sysdev.h index 389ccf858d37..166a2e58c287 100644 --- a/trunk/include/linux/sysdev.h +++ b/trunk/include/linux/sysdev.h @@ -98,16 +98,12 @@ struct sysdev_attribute { }; -#define _SYSDEV_ATTR(_name,_mode,_show,_store) \ -{ \ - .attr = { .name = __stringify(_name), .mode = _mode, \ - .owner = THIS_MODULE }, \ +#define SYSDEV_ATTR(_name,_mode,_show,_store) \ +struct sysdev_attribute attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ -} - -#define SYSDEV_ATTR(_name,_mode,_show,_store) \ -struct sysdev_attribute attr_##_name = _SYSDEV_ATTR(_name,_mode,_show,_store); +}; extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *); extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *); diff --git a/trunk/include/linux/sysfs.h b/trunk/include/linux/sysfs.h index 192de3afa96b..2129d1b6c874 100644 --- a/trunk/include/linux/sysfs.h +++ b/trunk/include/linux/sysfs.h @@ -11,12 +11,10 @@ #define _SYSFS_H_ #include -#include #include struct kobject; struct module; -struct nameidata; struct attribute { const char * name; @@ -90,13 +88,13 @@ struct sysfs_dirent { #ifdef CONFIG_SYSFS extern int __must_check -sysfs_create_dir(struct kobject *, struct dentry *); +sysfs_create_dir(struct kobject *); extern void sysfs_remove_dir(struct kobject *); extern int __must_check -sysfs_rename_dir(struct kobject *, struct dentry *, const char *new_name); +sysfs_rename_dir(struct kobject *, const char *new_name); extern int __must_check sysfs_move_dir(struct kobject *, struct kobject *); @@ -128,17 +126,11 @@ int __must_check sysfs_create_group(struct kobject *, void sysfs_remove_group(struct kobject *, const struct attribute_group *); void sysfs_notify(struct kobject * k, char *dir, char *attr); - -extern int sysfs_make_shadowed_dir(struct kobject *kobj, - void * (*follow_link)(struct dentry *, struct nameidata *)); -extern struct dentry *sysfs_create_shadow_dir(struct kobject *kobj); -extern void sysfs_remove_shadow_dir(struct dentry *dir); - extern int __must_check sysfs_init(void); #else /* CONFIG_SYSFS */ -static inline int sysfs_create_dir(struct kobject * k, struct dentry *shadow) +static inline int sysfs_create_dir(struct kobject * k) { return 0; } @@ -148,9 +140,7 @@ static inline void sysfs_remove_dir(struct kobject * k) ; } -static inline int sysfs_rename_dir(struct kobject * k, - struct dentry *new_parent, - const char *new_name) +static inline int sysfs_rename_dir(struct kobject * k, const char *new_name) { return 0; } @@ -214,12 +204,6 @@ static inline void sysfs_notify(struct kobject * k, char *dir, char *attr) { } -static inline int sysfs_make_shadowed_dir(struct kobject *kobj, - void * (*follow_link)(struct dentry *, struct nameidata *)) -{ - return 0; -} - static inline int __must_check sysfs_init(void) { return 0; diff --git a/trunk/include/linux/usb.h b/trunk/include/linux/usb.h index b5c226a87ed8..aab5b1b72021 100644 --- a/trunk/include/linux/usb.h +++ b/trunk/include/linux/usb.h @@ -2,7 +2,7 @@ #define __LINUX_USB_H #include -#include +#include #define USB_MAJOR 180 #define USB_DEVICE_MAJOR 189 @@ -107,8 +107,7 @@ enum usb_interface_condition { * @needs_remote_wakeup: flag set when the driver requires remote-wakeup * capability during autosuspend. * @dev: driver model's view of this device - * @usb_dev: if an interface is bound to the USB major, this will point - * to the sysfs representation for that device. + * @class_dev: driver model's class view of this device. * @pm_usage_cnt: PM usage counter for this interface; autosuspend is not * allowed unless the counter is 0. * @@ -153,7 +152,7 @@ struct usb_interface { unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ struct device dev; /* interface specific device info */ - struct device *usb_dev; /* pointer to the usb class's device, if any */ + struct class_device *class_dev; int pm_usage_cnt; /* usage counter for autosuspend */ }; #define to_usb_interface(d) container_of(d, struct usb_interface, dev) @@ -373,7 +372,7 @@ struct usb_device { char *serial; /* iSerialNumber string, if present */ struct list_head filelist; - struct device *usbfs_dev; + struct class_device *class_dev; struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ /* @@ -476,8 +475,6 @@ extern void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface); const struct usb_device_id *usb_match_id(struct usb_interface *interface, const struct usb_device_id *id); -extern int usb_match_one_id(struct usb_interface *interface, - const struct usb_device_id *id); extern struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor); @@ -556,18 +553,6 @@ static inline int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *e USB_ENDPOINT_XFER_BULK); } -/** - * usb_endpoint_xfer_control - check if the endpoint has control transfer type - * @epd: endpoint to be checked - * - * Returns true if the endpoint is of type control, otherwise it returns false. - */ -static inline int usb_endpoint_xfer_control(const struct usb_endpoint_descriptor *epd) -{ - return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_CONTROL); -} - /** * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type * @epd: endpoint to be checked @@ -738,21 +723,11 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor /* ----------------------------------------------------------------------- */ -/* Stuff for dynamic usb ids */ struct usb_dynids { spinlock_t lock; struct list_head list; }; -struct usb_dynid { - struct list_head node; - struct usb_device_id id; -}; - -extern ssize_t usb_store_new_id(struct usb_dynids *dynids, - struct device_driver *driver, - const char *buf, size_t count); - /** * struct usbdrv_wrap - wrapper for driver-model structure * @driver: The driver-model core driver structure. @@ -893,11 +868,10 @@ struct usb_class_driver { * use these in module_init()/module_exit() * and don't forget MODULE_DEVICE_TABLE(usb, ...) */ -extern int usb_register_driver(struct usb_driver *, struct module *, - const char *); +extern int usb_register_driver(struct usb_driver *, struct module *); static inline int usb_register(struct usb_driver *driver) { - return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); + return usb_register_driver(driver, THIS_MODULE); } extern void usb_deregister(struct usb_driver *); @@ -1111,6 +1085,7 @@ struct urb struct kref kref; /* reference count of the URB */ spinlock_t lock; /* lock for the URB */ void *hcpriv; /* private data for host controller */ + int bandwidth; /* bandwidth for INT/ISO request */ atomic_t use_count; /* concurrent submissions counter */ u8 reject; /* submissions will fail */ diff --git a/trunk/include/linux/usb/Kbuild b/trunk/include/linux/usb/Kbuild deleted file mode 100644 index 43f160cfe003..000000000000 --- a/trunk/include/linux/usb/Kbuild +++ /dev/null @@ -1,5 +0,0 @@ -unifdef-y += audio.h -unifdef-y += cdc.h -unifdef-y += ch9.h -unifdef-y += midi.h - diff --git a/trunk/include/linux/usb/serial.h b/trunk/include/linux/usb/serial.h index 33dcd8576696..10f99e5f1a97 100644 --- a/trunk/include/linux/usb/serial.h +++ b/trunk/include/linux/usb/serial.h @@ -179,9 +179,6 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) * memory structure allocation at this point in time. * @shutdown: pointer to the driver's shutdown function. This will be * called when the device is removed from the system. - * @usb_driver: pointer to the struct usb_driver that controls this - * device. This is necessary to allow dynamic ids to be added to - * the driver from sysfs. * * This structure is defines a USB Serial driver. It provides all of * the information that the USB serial core code needs. If the function @@ -205,8 +202,6 @@ struct usb_serial_driver { struct list_head driver_list; struct device_driver driver; - struct usb_driver *usb_driver; - struct usb_dynids dynids; int (*probe) (struct usb_serial *serial, const struct usb_device_id *id); int (*attach) (struct usb_serial *serial); diff --git a/trunk/include/linux/usb/ch9.h b/trunk/include/linux/usb_ch9.h similarity index 99% rename from trunk/include/linux/usb/ch9.h rename to trunk/include/linux/usb_ch9.h index ae7833749fa2..c720d107ff29 100644 --- a/trunk/include/linux/usb/ch9.h +++ b/trunk/include/linux/usb_ch9.h @@ -224,7 +224,6 @@ struct usb_device_descriptor { #define USB_CLASS_CONTENT_SEC 0x0d /* content security */ #define USB_CLASS_VIDEO 0x0e #define USB_CLASS_WIRELESS_CONTROLLER 0xe0 -#define USB_CLASS_MISC 0xef #define USB_CLASS_APP_SPEC 0xfe #define USB_CLASS_VENDOR_SPEC 0xff diff --git a/trunk/include/linux/usb_gadgetfs.h b/trunk/include/linux/usb_gadgetfs.h index 8086d5a9b94e..b53d6ae8e55e 100644 --- a/trunk/include/linux/usb_gadgetfs.h +++ b/trunk/include/linux/usb_gadgetfs.h @@ -2,7 +2,7 @@ #include #include -#include +#include /* * Filesystem based user-mode API to USB Gadget controller hardware diff --git a/trunk/include/linux/video_output.h b/trunk/include/linux/video_output.h deleted file mode 100644 index e63e0c03ee0d..000000000000 --- a/trunk/include/linux/video_output.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright (C) 2006 Luming Yu - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#ifndef _LINUX_VIDEO_OUTPUT_H -#define _LINUX_VIDEO_OUTPUT_H -#include -struct output_device; -struct output_properties { - int (*set_state)(struct output_device *); - int (*get_status)(struct output_device *); -}; -struct output_device { - int request_state; - struct output_properties *props; - struct class_device class_dev; -}; -#define to_output_device(obj) container_of(obj, struct output_device, class_dev) -struct output_device *video_output_register(const char *name, - struct device *dev, - void *devdata, - struct output_properties *op); -void video_output_unregister(struct output_device *dev); -#endif diff --git a/trunk/include/pcmcia/ss.h b/trunk/include/pcmcia/ss.h index 6e84258b94de..623a0fc0dae1 100644 --- a/trunk/include/pcmcia/ss.h +++ b/trunk/include/pcmcia/ss.h @@ -284,7 +284,7 @@ struct pcmcia_socket { #endif /* socket device */ - struct device dev; + struct class_device dev; void *driver_data; /* data internal to the socket driver */ }; diff --git a/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index 475e8a71bcdc..d27b25855743 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -39,7 +39,6 @@ void dynamic_irq_init(unsigned int irq) desc->chip = &no_irq_chip; desc->handle_irq = handle_bad_irq; desc->depth = 1; - desc->msi_desc = NULL; desc->handler_data = NULL; desc->chip_data = NULL; desc->action = NULL; @@ -75,9 +74,6 @@ void dynamic_irq_cleanup(unsigned int irq) WARN_ON(1); return; } - desc->msi_desc = NULL; - desc->handler_data = NULL; - desc->chip_data = NULL; desc->handle_irq = handle_bad_irq; desc->chip = &no_irq_chip; spin_unlock_irqrestore(&desc->lock, flags); @@ -165,30 +161,6 @@ int set_irq_data(unsigned int irq, void *data) } EXPORT_SYMBOL(set_irq_data); -/** - * set_irq_data - set irq type data for an irq - * @irq: Interrupt number - * @data: Pointer to interrupt specific data - * - * Set the hardware irq controller data for an irq - */ -int set_irq_msi(unsigned int irq, struct msi_desc *entry) -{ - struct irq_desc *desc; - unsigned long flags; - - if (irq >= NR_IRQS) { - printk(KERN_ERR - "Trying to install msi data for IRQ%d\n", irq); - return -EINVAL; - } - desc = irq_desc + irq; - spin_lock_irqsave(&desc->lock, flags); - desc->msi_desc = entry; - spin_unlock_irqrestore(&desc->lock, flags); - return 0; -} - /** * set_irq_chip_data - set irq chip data for an irq * @irq: Interrupt number diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 8a94e054230c..d0f2260a0210 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -537,8 +537,6 @@ static int already_uses(struct module *a, struct module *b) static int use_module(struct module *a, struct module *b) { struct module_use *use; - int no_warn; - if (b == NULL || already_uses(a, b)) return 1; if (!strong_try_module_get(b)) @@ -554,7 +552,6 @@ static int use_module(struct module *a, struct module *b) use->module_which_uses = a; list_add(&use->list, &b->modules_which_use_me); - no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name); return 1; } @@ -572,7 +569,6 @@ static void module_unload_free(struct module *mod) module_put(i); list_del(&use->list); kfree(use); - sysfs_remove_link(i->holders_dir, mod->name); /* There can be at most one match. */ break; } @@ -1110,7 +1106,9 @@ static void module_remove_modinfo_attrs(struct module *mod) kfree(mod->modinfo_attrs); } -static int mod_sysfs_init(struct module *mod) +static int mod_sysfs_setup(struct module *mod, + struct kernel_param *kparam, + unsigned int num_params) { int err; @@ -1127,30 +1125,21 @@ static int mod_sysfs_init(struct module *mod) kobj_set_kset_s(&mod->mkobj, module_subsys); mod->mkobj.mod = mod; - kobject_init(&mod->mkobj.kobj); - -out: - return err; -} - -static int mod_sysfs_setup(struct module *mod, - struct kernel_param *kparam, - unsigned int num_params) -{ - int err; - /* delay uevent until full sysfs population */ + kobject_init(&mod->mkobj.kobj); err = kobject_add(&mod->mkobj.kobj); if (err) goto out; - mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders"); - if (!mod->holders_dir) + mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); + if (!mod->drivers_dir) { + err = -ENOMEM; goto out_unreg; + } err = module_param_sysfs_setup(mod, kparam, num_params); if (err) - goto out_unreg_holders; + goto out_unreg_drivers; err = module_add_modinfo_attrs(mod); if (err) @@ -1161,8 +1150,8 @@ static int mod_sysfs_setup(struct module *mod, out_unreg_param: module_param_sysfs_remove(mod); -out_unreg_holders: - kobject_unregister(mod->holders_dir); +out_unreg_drivers: + kobject_unregister(mod->drivers_dir); out_unreg: kobject_del(&mod->mkobj.kobj); kobject_put(&mod->mkobj.kobj); @@ -1174,10 +1163,7 @@ static void mod_kobject_remove(struct module *mod) { module_remove_modinfo_attrs(mod); module_param_sysfs_remove(mod); - if (mod->mkobj.drivers_dir) - kobject_unregister(mod->mkobj.drivers_dir); - if (mod->holders_dir) - kobject_unregister(mod->holders_dir); + kobject_unregister(mod->drivers_dir); kobject_unregister(&mod->mkobj.kobj); } @@ -1782,10 +1768,6 @@ static struct module *load_module(void __user *umod, /* Now we've moved module, initialize linked lists, etc. */ module_unload_init(mod); - /* Initialize kobject, so we can reference it. */ - if (mod_sysfs_init(mod) != 0) - goto cleanup; - /* Set up license info based on the info section */ set_license(mod, get_modinfo(sechdrs, infoindex, "license")); @@ -2358,43 +2340,19 @@ static char *make_driver_name(struct device_driver *drv) return driver_name; } -static void module_create_drivers_dir(struct module_kobject *mk) -{ - if (!mk || mk->drivers_dir) - return; - - mk->drivers_dir = kobject_add_dir(&mk->kobj, "drivers"); -} - void module_add_driver(struct module *mod, struct device_driver *drv) { char *driver_name; int no_warn; - struct module_kobject *mk = NULL; - - if (!drv) - return; - - if (mod) - mk = &mod->mkobj; - else if (drv->mod_name) { - struct kobject *mkobj; - - /* Lookup built-in module entry in /sys/modules */ - mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name); - if (mkobj) - mk = container_of(mkobj, struct module_kobject, kobj); - } - if (!mk) + if (!mod || !drv) return; /* Don't check return codes; these calls are idempotent */ - no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module"); + no_warn = sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); driver_name = make_driver_name(drv); if (driver_name) { - module_create_drivers_dir(mk); - no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj, + no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, driver_name); kfree(driver_name); } @@ -2409,10 +2367,10 @@ void module_remove_driver(struct device_driver *drv) return; sysfs_remove_link(&drv->kobj, "module"); - if (drv->owner && drv->owner->mkobj.drivers_dir) { + if (drv->owner && drv->owner->drivers_dir) { driver_name = make_driver_name(drv); if (driver_name) { - sysfs_remove_link(drv->owner->mkobj.drivers_dir, + sysfs_remove_link(drv->owner->drivers_dir, driver_name); kfree(driver_name); } diff --git a/trunk/kernel/params.c b/trunk/kernel/params.c index 553cf7d6a4be..718945da8f58 100644 --- a/trunk/kernel/params.c +++ b/trunk/kernel/params.c @@ -30,8 +30,6 @@ #define DEBUGP(fmt, a...) #endif -static struct kobj_type module_ktype; - static inline char dash2underscore(char c) { if (c == '-') @@ -563,11 +561,14 @@ static void __init kernel_param_sysfs_setup(const char *name, mk->mod = THIS_MODULE; kobj_set_kset_s(mk, module_subsys); kobject_set_name(&mk->kobj, name); - kobject_init(&mk->kobj); - ret = kobject_add(&mk->kobj); + ret = kobject_register(&mk->kobj); BUG_ON(ret < 0); - param_sysfs_setup(mk, kparam, num_params, name_skip); - kobject_uevent(&mk->kobj, KOBJ_ADD); + + /* no need to keep the kobject if no parameter is exported */ + if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) { + kobject_unregister(&mk->kobj); + kfree(mk); + } } /* @@ -673,19 +674,6 @@ static struct sysfs_ops module_sysfs_ops = { .store = module_attr_store, }; -static int uevent_filter(struct kset *kset, struct kobject *kobj) -{ - struct kobj_type *ktype = get_ktype(kobj); - - if (ktype == &module_ktype) - return 1; - return 0; -} - -static struct kset_uevent_ops module_uevent_ops = { - .filter = uevent_filter, -}; - #else static struct sysfs_ops module_sysfs_ops = { .show = NULL, @@ -697,7 +685,7 @@ static struct kobj_type module_ktype = { .sysfs_ops = &module_sysfs_ops, }; -decl_subsys(module, &module_ktype, &module_uevent_ops); +decl_subsys(module, &module_ktype, NULL); /* * param_sysfs_init - wrapper for built-in params support diff --git a/trunk/lib/kobject.c b/trunk/lib/kobject.c index c2917ffe8bf1..7ce6dc138e90 100644 --- a/trunk/lib/kobject.c +++ b/trunk/lib/kobject.c @@ -44,11 +44,11 @@ static int populate_dir(struct kobject * kobj) return error; } -static int create_dir(struct kobject * kobj, struct dentry *shadow_parent) +static int create_dir(struct kobject * kobj) { int error = 0; if (kobject_name(kobj)) { - error = sysfs_create_dir(kobj, shadow_parent); + error = sysfs_create_dir(kobj); if (!error) { if ((error = populate_dir(kobj))) sysfs_remove_dir(kobj); @@ -126,8 +126,6 @@ EXPORT_SYMBOL_GPL(kobject_get_path); */ void kobject_init(struct kobject * kobj) { - if (!kobj) - return; kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); init_waitqueue_head(&kobj->poll); @@ -158,10 +156,9 @@ static void unlink(struct kobject * kobj) /** * kobject_add - add an object to the hierarchy. * @kobj: object. - * @shadow_parent: sysfs directory to add to. */ -int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent) +int kobject_add(struct kobject * kobj) { int error = 0; struct kobject * parent; @@ -192,11 +189,12 @@ int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent) } kobj->parent = parent; - error = create_dir(kobj, shadow_parent); + error = create_dir(kobj); if (error) { /* unlink does the kobject_put() for us */ unlink(kobj); - kobject_put(parent); + if (parent) + kobject_put(parent); /* be noisy on error issues */ if (error == -EEXIST) @@ -213,15 +211,6 @@ int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent) return error; } -/** - * kobject_add - add an object to the hierarchy. - * @kobj: object. - */ -int kobject_add(struct kobject * kobj) -{ - return kobject_shadow_add(kobj, NULL); -} - /** * kobject_register - initialize and add an object. @@ -314,29 +303,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name) kobj = kobject_get(kobj); if (!kobj) return -EINVAL; - if (!kobj->parent) - return -EINVAL; - error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name); - kobject_put(kobj); - - return error; -} - -/** - * kobject_rename - change the name of an object - * @kobj: object in question. - * @new_name: object's new name - */ - -int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent, - const char *new_name) -{ - int error = 0; - - kobj = kobject_get(kobj); - if (!kobj) - return -EINVAL; - error = sysfs_rename_dir(kobj, new_parent, new_name); + error = sysfs_rename_dir(kobj, new_name); kobject_put(kobj); return error; @@ -345,7 +312,7 @@ int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent, /** * kobject_move - move object to another parent * @kobj: object in question. - * @new_parent: object's new parent (can be NULL) + * @new_parent: object's new parent */ int kobject_move(struct kobject *kobj, struct kobject *new_parent) @@ -361,8 +328,8 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent) return -EINVAL; new_parent = kobject_get(new_parent); if (!new_parent) { - if (kobj->kset) - new_parent = kobject_get(&kobj->kset->kobj); + error = -EINVAL; + goto out; } /* old object path */ devpath = kobject_get_path(kobj, GFP_KERNEL); @@ -399,8 +366,6 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent) void kobject_del(struct kobject * kobj) { - if (!kobj) - return; sysfs_remove_dir(kobj); unlink(kobj); } @@ -412,8 +377,6 @@ void kobject_del(struct kobject * kobj) void kobject_unregister(struct kobject * kobj) { - if (!kobj) - return; pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); kobject_uevent(kobj, KOBJ_REMOVE); kobject_del(kobj); @@ -451,7 +414,8 @@ void kobject_cleanup(struct kobject * kobj) t->release(kobj); if (s) kset_put(s); - kobject_put(parent); + if (parent) + kobject_put(parent); } static void kobject_release(struct kref *kref) @@ -559,8 +523,6 @@ int kset_add(struct kset * k) int kset_register(struct kset * k) { - if (!k) - return -EINVAL; kset_init(k); return kset_add(k); } @@ -573,8 +535,6 @@ int kset_register(struct kset * k) void kset_unregister(struct kset * k) { - if (!k) - return; kobject_unregister(&k->kobj); } @@ -626,9 +586,6 @@ int subsystem_register(struct subsystem * s) { int error; - if (!s) - return -EINVAL; - subsystem_init(s); pr_debug("subsystem %s: registering\n",s->kset.kobj.name); @@ -641,8 +598,6 @@ int subsystem_register(struct subsystem * s) void subsystem_unregister(struct subsystem * s) { - if (!s) - return; pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name); kset_unregister(&s->kset); } @@ -657,10 +612,6 @@ void subsystem_unregister(struct subsystem * s) int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) { int error = 0; - - if (!s || !a) - return -EINVAL; - if (subsys_get(s)) { error = sysfs_create_file(&s->kset.kobj,&a->attr); subsys_put(s); diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index 2b7c2c7dad48..55bb2634c088 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -286,7 +286,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, kobject_init(&p->kobj); kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR); p->kobj.ktype = &brport_ktype; - p->kobj.parent = &(dev->dev.kobj); + p->kobj.parent = &(dev->class_dev.kobj); p->kobj.kset = NULL; return p; diff --git a/trunk/net/bridge/br_sysfs_br.c b/trunk/net/bridge/br_sysfs_br.c index ce10464716a7..de9d1a9473f2 100644 --- a/trunk/net/bridge/br_sysfs_br.c +++ b/trunk/net/bridge/br_sysfs_br.c @@ -21,17 +21,18 @@ #include "br_private.h" -#define to_dev(obj) container_of(obj, struct device, kobj) +#define to_class_dev(obj) container_of(obj,struct class_device,kobj) +#define to_net_dev(class) container_of(class, struct net_device, class_dev) #define to_bridge(cd) ((struct net_bridge *)(to_net_dev(cd)->priv)) /* * Common code for storing bridge parameters. */ -static ssize_t store_bridge_parm(struct device *d, +static ssize_t store_bridge_parm(struct class_device *cd, const char *buf, size_t len, void (*set)(struct net_bridge *, unsigned long)) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); char *endp; unsigned long val; @@ -49,10 +50,9 @@ static ssize_t store_bridge_parm(struct device *d, } -static ssize_t show_forward_delay(struct device *d, - struct device_attribute *attr, char *buf) +static ssize_t show_forward_delay(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay)); } @@ -64,20 +64,18 @@ static void set_forward_delay(struct net_bridge *br, unsigned long val) br->bridge_forward_delay = delay; } -static ssize_t store_forward_delay(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_forward_delay(struct class_device *cd, const char *buf, + size_t len) { - return store_bridge_parm(d, buf, len, set_forward_delay); + return store_bridge_parm(cd, buf, len, set_forward_delay); } -static DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR, - show_forward_delay, store_forward_delay); +static CLASS_DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR, + show_forward_delay, store_forward_delay); -static ssize_t show_hello_time(struct device *d, struct device_attribute *attr, - char *buf) +static ssize_t show_hello_time(struct class_device *cd, char *buf) { return sprintf(buf, "%lu\n", - jiffies_to_clock_t(to_bridge(d)->hello_time)); + jiffies_to_clock_t(to_bridge(cd)->hello_time)); } static void set_hello_time(struct net_bridge *br, unsigned long val) @@ -88,20 +86,19 @@ static void set_hello_time(struct net_bridge *br, unsigned long val) br->bridge_hello_time = t; } -static ssize_t store_hello_time(struct device *d, - struct device_attribute *attr, const char *buf, +static ssize_t store_hello_time(struct class_device *cd, const char *buf, size_t len) { - return store_bridge_parm(d, buf, len, set_hello_time); + return store_bridge_parm(cd, buf, len, set_hello_time); } -static DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time, - store_hello_time); -static ssize_t show_max_age(struct device *d, struct device_attribute *attr, - char *buf) +static CLASS_DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time, + store_hello_time); + +static ssize_t show_max_age(struct class_device *cd, char *buf) { return sprintf(buf, "%lu\n", - jiffies_to_clock_t(to_bridge(d)->max_age)); + jiffies_to_clock_t(to_bridge(cd)->max_age)); } static void set_max_age(struct net_bridge *br, unsigned long val) @@ -112,17 +109,18 @@ static void set_max_age(struct net_bridge *br, unsigned long val) br->bridge_max_age = t; } -static ssize_t store_max_age(struct device *d, struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_max_age(struct class_device *cd, const char *buf, + size_t len) { - return store_bridge_parm(d, buf, len, set_max_age); + return store_bridge_parm(cd, buf, len, set_max_age); } -static DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, store_max_age); -static ssize_t show_ageing_time(struct device *d, - struct device_attribute *attr, char *buf) +static CLASS_DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, + store_max_age); + +static ssize_t show_ageing_time(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->ageing_time)); } @@ -131,19 +129,17 @@ static void set_ageing_time(struct net_bridge *br, unsigned long val) br->ageing_time = clock_t_to_jiffies(val); } -static ssize_t store_ageing_time(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_ageing_time(struct class_device *cd, const char *buf, + size_t len) { - return store_bridge_parm(d, buf, len, set_ageing_time); + return store_bridge_parm(cd, buf, len, set_ageing_time); } -static DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time, - store_ageing_time); -static ssize_t show_stp_state(struct device *d, - struct device_attribute *attr, char *buf) +static CLASS_DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time, + store_ageing_time); +static ssize_t show_stp_state(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%d\n", br->stp_enabled); } @@ -152,19 +148,18 @@ static void set_stp_state(struct net_bridge *br, unsigned long val) br->stp_enabled = val; } -static ssize_t store_stp_state(struct device *d, - struct device_attribute *attr, const char *buf, - size_t len) +static ssize_t store_stp_state(struct class_device *cd, + const char *buf, size_t len) { - return store_bridge_parm(d, buf, len, set_stp_state); + return store_bridge_parm(cd, buf, len, set_stp_state); } -static DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state, - store_stp_state); -static ssize_t show_priority(struct device *d, struct device_attribute *attr, - char *buf) +static CLASS_DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state, + store_stp_state); + +static ssize_t show_priority(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%d\n", (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]); } @@ -174,107 +169,92 @@ static void set_priority(struct net_bridge *br, unsigned long val) br_stp_set_bridge_priority(br, (u16) val); } -static ssize_t store_priority(struct device *d, struct device_attribute *attr, +static ssize_t store_priority(struct class_device *cd, const char *buf, size_t len) { - return store_bridge_parm(d, buf, len, set_priority); + return store_bridge_parm(cd, buf, len, set_priority); } -static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority, store_priority); +static CLASS_DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority, + store_priority); -static ssize_t show_root_id(struct device *d, struct device_attribute *attr, - char *buf) +static ssize_t show_root_id(struct class_device *cd, char *buf) { - return br_show_bridge_id(buf, &to_bridge(d)->designated_root); + return br_show_bridge_id(buf, &to_bridge(cd)->designated_root); } -static DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL); +static CLASS_DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL); -static ssize_t show_bridge_id(struct device *d, struct device_attribute *attr, - char *buf) +static ssize_t show_bridge_id(struct class_device *cd, char *buf) { - return br_show_bridge_id(buf, &to_bridge(d)->bridge_id); + return br_show_bridge_id(buf, &to_bridge(cd)->bridge_id); } -static DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL); +static CLASS_DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL); -static ssize_t show_root_port(struct device *d, struct device_attribute *attr, - char *buf) +static ssize_t show_root_port(struct class_device *cd, char *buf) { - return sprintf(buf, "%d\n", to_bridge(d)->root_port); + return sprintf(buf, "%d\n", to_bridge(cd)->root_port); } -static DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL); +static CLASS_DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL); -static ssize_t show_root_path_cost(struct device *d, - struct device_attribute *attr, char *buf) +static ssize_t show_root_path_cost(struct class_device *cd, char *buf) { - return sprintf(buf, "%d\n", to_bridge(d)->root_path_cost); + return sprintf(buf, "%d\n", to_bridge(cd)->root_path_cost); } -static DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL); +static CLASS_DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL); -static ssize_t show_topology_change(struct device *d, - struct device_attribute *attr, char *buf) +static ssize_t show_topology_change(struct class_device *cd, char *buf) { - return sprintf(buf, "%d\n", to_bridge(d)->topology_change); + return sprintf(buf, "%d\n", to_bridge(cd)->topology_change); } -static DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL); +static CLASS_DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL); -static ssize_t show_topology_change_detected(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t show_topology_change_detected(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%d\n", br->topology_change_detected); } -static DEVICE_ATTR(topology_change_detected, S_IRUGO, - show_topology_change_detected, NULL); +static CLASS_DEVICE_ATTR(topology_change_detected, S_IRUGO, show_topology_change_detected, NULL); -static ssize_t show_hello_timer(struct device *d, - struct device_attribute *attr, char *buf) +static ssize_t show_hello_timer(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%ld\n", br_timer_value(&br->hello_timer)); } -static DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL); +static CLASS_DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL); -static ssize_t show_tcn_timer(struct device *d, struct device_attribute *attr, - char *buf) +static ssize_t show_tcn_timer(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%ld\n", br_timer_value(&br->tcn_timer)); } -static DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL); +static CLASS_DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL); -static ssize_t show_topology_change_timer(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t show_topology_change_timer(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%ld\n", br_timer_value(&br->topology_change_timer)); } -static DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer, - NULL); +static CLASS_DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer, NULL); -static ssize_t show_gc_timer(struct device *d, struct device_attribute *attr, - char *buf) +static ssize_t show_gc_timer(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%ld\n", br_timer_value(&br->gc_timer)); } -static DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL); +static CLASS_DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL); -static ssize_t show_group_addr(struct device *d, - struct device_attribute *attr, char *buf) +static ssize_t show_group_addr(struct class_device *cd, char *buf) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); return sprintf(buf, "%x:%x:%x:%x:%x:%x\n", br->group_addr[0], br->group_addr[1], br->group_addr[2], br->group_addr[3], br->group_addr[4], br->group_addr[5]); } -static ssize_t store_group_addr(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_group_addr(struct class_device *cd, const char *buf, + size_t len) { - struct net_bridge *br = to_bridge(d); + struct net_bridge *br = to_bridge(cd); unsigned new_addr[6]; int i; @@ -306,28 +286,28 @@ static ssize_t store_group_addr(struct device *d, return len; } -static DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR, - show_group_addr, store_group_addr); +static CLASS_DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR, + show_group_addr, store_group_addr); static struct attribute *bridge_attrs[] = { - &dev_attr_forward_delay.attr, - &dev_attr_hello_time.attr, - &dev_attr_max_age.attr, - &dev_attr_ageing_time.attr, - &dev_attr_stp_state.attr, - &dev_attr_priority.attr, - &dev_attr_bridge_id.attr, - &dev_attr_root_id.attr, - &dev_attr_root_path_cost.attr, - &dev_attr_root_port.attr, - &dev_attr_topology_change.attr, - &dev_attr_topology_change_detected.attr, - &dev_attr_hello_timer.attr, - &dev_attr_tcn_timer.attr, - &dev_attr_topology_change_timer.attr, - &dev_attr_gc_timer.attr, - &dev_attr_group_addr.attr, + &class_device_attr_forward_delay.attr, + &class_device_attr_hello_time.attr, + &class_device_attr_max_age.attr, + &class_device_attr_ageing_time.attr, + &class_device_attr_stp_state.attr, + &class_device_attr_priority.attr, + &class_device_attr_bridge_id.attr, + &class_device_attr_root_id.attr, + &class_device_attr_root_path_cost.attr, + &class_device_attr_root_port.attr, + &class_device_attr_topology_change.attr, + &class_device_attr_topology_change_detected.attr, + &class_device_attr_hello_timer.attr, + &class_device_attr_tcn_timer.attr, + &class_device_attr_topology_change_timer.attr, + &class_device_attr_gc_timer.attr, + &class_device_attr_group_addr.attr, NULL }; @@ -345,8 +325,8 @@ static struct attribute_group bridge_group = { static ssize_t brforward_read(struct kobject *kobj, char *buf, loff_t off, size_t count) { - struct device *dev = to_dev(kobj); - struct net_bridge *br = to_bridge(dev); + struct class_device *cdev = to_class_dev(kobj); + struct net_bridge *br = to_bridge(cdev); int n; /* must read whole records */ @@ -383,7 +363,7 @@ static struct bin_attribute bridge_forward = { */ int br_sysfs_addbr(struct net_device *dev) { - struct kobject *brobj = &dev->dev.kobj; + struct kobject *brobj = &dev->class_dev.kobj; struct net_bridge *br = netdev_priv(dev); int err; @@ -415,9 +395,9 @@ int br_sysfs_addbr(struct net_device *dev) } return 0; out3: - sysfs_remove_bin_file(&dev->dev.kobj, &bridge_forward); + sysfs_remove_bin_file(&dev->class_dev.kobj, &bridge_forward); out2: - sysfs_remove_group(&dev->dev.kobj, &bridge_group); + sysfs_remove_group(&dev->class_dev.kobj, &bridge_group); out1: return err; @@ -425,7 +405,7 @@ int br_sysfs_addbr(struct net_device *dev) void br_sysfs_delbr(struct net_device *dev) { - struct kobject *kobj = &dev->dev.kobj; + struct kobject *kobj = &dev->class_dev.kobj; struct net_bridge *br = netdev_priv(dev); kobject_unregister(&br->ifobj); diff --git a/trunk/net/bridge/br_sysfs_if.c b/trunk/net/bridge/br_sysfs_if.c index 0bc2aef8f9f3..c51c9e42aeb3 100644 --- a/trunk/net/bridge/br_sysfs_if.c +++ b/trunk/net/bridge/br_sysfs_if.c @@ -211,7 +211,7 @@ int br_sysfs_addif(struct net_bridge_port *p) struct brport_attribute **a; int err; - err = sysfs_create_link(&p->kobj, &br->dev->dev.kobj, + err = sysfs_create_link(&p->kobj, &br->dev->class_dev.kobj, SYSFS_BRIDGE_PORT_LINK); if (err) goto out2; diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 455d589683e8..e660cb57e42a 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -751,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname) else strlcpy(dev->name, newname, IFNAMSIZ); - err = device_rename(&dev->dev, dev->name); + err = class_device_rename(&dev->class_dev, dev->name); if (!err) { hlist_del(&dev->name_hlist); hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); @@ -3221,8 +3221,8 @@ void free_netdev(struct net_device *dev) BUG_ON(dev->reg_state != NETREG_UNREGISTERED); dev->reg_state = NETREG_RELEASED; - /* will free via device release */ - put_device(&dev->dev); + /* will free via class release */ + class_device_put(&dev->class_dev); #else kfree((char *)dev - dev->padded); #endif diff --git a/trunk/net/core/net-sysfs.c b/trunk/net/core/net-sysfs.c index 44db095a8f7e..f47f319bb7dc 100644 --- a/trunk/net/core/net-sysfs.c +++ b/trunk/net/core/net-sysfs.c @@ -18,6 +18,9 @@ #include #include +#define to_class_dev(obj) container_of(obj,struct class_device,kobj) +#define to_net_dev(class) container_of(class, struct net_device, class_dev) + static const char fmt_hex[] = "%#x\n"; static const char fmt_long_hex[] = "%#lx\n"; static const char fmt_dec[] = "%d\n"; @@ -29,11 +32,10 @@ static inline int dev_isalive(const struct net_device *dev) } /* use same locking rules as GIF* ioctl's */ -static ssize_t netdev_show(const struct device *dev, - struct device_attribute *attr, char *buf, +static ssize_t netdev_show(const struct class_device *cd, char *buf, ssize_t (*format)(const struct net_device *, char *)) { - struct net_device *net = to_net_dev(dev); + struct net_device *net = to_net_dev(cd); ssize_t ret = -EINVAL; read_lock(&dev_base_lock); @@ -50,15 +52,14 @@ static ssize_t format_##field(const struct net_device *net, char *buf) \ { \ return sprintf(buf, format_string, net->field); \ } \ -static ssize_t show_##field(struct device *dev, \ - struct device_attribute *attr, char *buf) \ +static ssize_t show_##field(struct class_device *cd, char *buf) \ { \ - return netdev_show(dev, attr, buf, format_##field); \ + return netdev_show(cd, buf, format_##field); \ } /* use same locking and permission rules as SIF* ioctl's */ -static ssize_t netdev_store(struct device *dev, struct device_attribute *attr, +static ssize_t netdev_store(struct class_device *dev, const char *buf, size_t len, int (*set)(struct net_device *, unsigned long)) { @@ -103,8 +104,7 @@ static ssize_t format_addr(char *buf, const unsigned char *addr, int len) return cp - buf; } -static ssize_t show_address(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t show_address(struct class_device *dev, char *buf) { struct net_device *net = to_net_dev(dev); ssize_t ret = -EINVAL; @@ -116,8 +116,7 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, return ret; } -static ssize_t show_broadcast(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_broadcast(struct class_device *dev, char *buf) { struct net_device *net = to_net_dev(dev); if (dev_isalive(net)) @@ -125,8 +124,7 @@ static ssize_t show_broadcast(struct device *dev, return -EINVAL; } -static ssize_t show_carrier(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_carrier(struct class_device *dev, char *buf) { struct net_device *netdev = to_net_dev(dev); if (netif_running(netdev)) { @@ -135,8 +133,7 @@ static ssize_t show_carrier(struct device *dev, return -EINVAL; } -static ssize_t show_dormant(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_dormant(struct class_device *dev, char *buf) { struct net_device *netdev = to_net_dev(dev); @@ -156,8 +153,7 @@ static const char *operstates[] = { "up" }; -static ssize_t show_operstate(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_operstate(struct class_device *dev, char *buf) { const struct net_device *netdev = to_net_dev(dev); unsigned char operstate; @@ -182,10 +178,9 @@ static int change_mtu(struct net_device *net, unsigned long new_mtu) return dev_set_mtu(net, (int) new_mtu); } -static ssize_t store_mtu(struct device *dev, struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_mtu(struct class_device *dev, const char *buf, size_t len) { - return netdev_store(dev, attr, buf, len, change_mtu); + return netdev_store(dev, buf, len, change_mtu); } NETDEVICE_SHOW(flags, fmt_hex); @@ -195,10 +190,9 @@ static int change_flags(struct net_device *net, unsigned long new_flags) return dev_change_flags(net, (unsigned) new_flags); } -static ssize_t store_flags(struct device *dev, struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_flags(struct class_device *dev, const char *buf, size_t len) { - return netdev_store(dev, attr, buf, len, change_flags); + return netdev_store(dev, buf, len, change_flags); } NETDEVICE_SHOW(tx_queue_len, fmt_ulong); @@ -209,11 +203,9 @@ static int change_tx_queue_len(struct net_device *net, unsigned long new_len) return 0; } -static ssize_t store_tx_queue_len(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, size_t len) { - return netdev_store(dev, attr, buf, len, change_tx_queue_len); + return netdev_store(dev, buf, len, change_tx_queue_len); } NETDEVICE_SHOW(weight, fmt_dec); @@ -224,13 +216,12 @@ static int change_weight(struct net_device *net, unsigned long new_weight) return 0; } -static ssize_t store_weight(struct device *dev, struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_weight(struct class_device *dev, const char *buf, size_t len) { - return netdev_store(dev, attr, buf, len, change_weight); + return netdev_store(dev, buf, len, change_weight); } -static struct device_attribute net_class_attributes[] = { +static struct class_device_attribute net_class_attributes[] = { __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), __ATTR(iflink, S_IRUGO, show_iflink, NULL), __ATTR(ifindex, S_IRUGO, show_ifindex, NULL), @@ -251,11 +242,10 @@ static struct device_attribute net_class_attributes[] = { }; /* Show a given an attribute in the statistics group */ -static ssize_t netstat_show(const struct device *d, - struct device_attribute *attr, char *buf, +static ssize_t netstat_show(const struct class_device *cd, char *buf, unsigned long offset) { - struct net_device *dev = to_net_dev(d); + struct net_device *dev = to_net_dev(cd); struct net_device_stats *stats; ssize_t ret = -EINVAL; @@ -275,13 +265,12 @@ static ssize_t netstat_show(const struct device *d, /* generate a read-only statistics attribute */ #define NETSTAT_ENTRY(name) \ -static ssize_t show_##name(struct device *d, \ - struct device_attribute *attr, char *buf) \ +static ssize_t show_##name(struct class_device *cd, char *buf) \ { \ - return netstat_show(d, attr, buf, \ + return netstat_show(cd, buf, \ offsetof(struct net_device_stats, name)); \ } \ -static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) NETSTAT_ENTRY(rx_packets); NETSTAT_ENTRY(tx_packets); @@ -308,29 +297,29 @@ NETSTAT_ENTRY(rx_compressed); NETSTAT_ENTRY(tx_compressed); static struct attribute *netstat_attrs[] = { - &dev_attr_rx_packets.attr, - &dev_attr_tx_packets.attr, - &dev_attr_rx_bytes.attr, - &dev_attr_tx_bytes.attr, - &dev_attr_rx_errors.attr, - &dev_attr_tx_errors.attr, - &dev_attr_rx_dropped.attr, - &dev_attr_tx_dropped.attr, - &dev_attr_multicast.attr, - &dev_attr_collisions.attr, - &dev_attr_rx_length_errors.attr, - &dev_attr_rx_over_errors.attr, - &dev_attr_rx_crc_errors.attr, - &dev_attr_rx_frame_errors.attr, - &dev_attr_rx_fifo_errors.attr, - &dev_attr_rx_missed_errors.attr, - &dev_attr_tx_aborted_errors.attr, - &dev_attr_tx_carrier_errors.attr, - &dev_attr_tx_fifo_errors.attr, - &dev_attr_tx_heartbeat_errors.attr, - &dev_attr_tx_window_errors.attr, - &dev_attr_rx_compressed.attr, - &dev_attr_tx_compressed.attr, + &class_device_attr_rx_packets.attr, + &class_device_attr_tx_packets.attr, + &class_device_attr_rx_bytes.attr, + &class_device_attr_tx_bytes.attr, + &class_device_attr_rx_errors.attr, + &class_device_attr_tx_errors.attr, + &class_device_attr_rx_dropped.attr, + &class_device_attr_tx_dropped.attr, + &class_device_attr_multicast.attr, + &class_device_attr_collisions.attr, + &class_device_attr_rx_length_errors.attr, + &class_device_attr_rx_over_errors.attr, + &class_device_attr_rx_crc_errors.attr, + &class_device_attr_rx_frame_errors.attr, + &class_device_attr_rx_fifo_errors.attr, + &class_device_attr_rx_missed_errors.attr, + &class_device_attr_tx_aborted_errors.attr, + &class_device_attr_tx_carrier_errors.attr, + &class_device_attr_tx_fifo_errors.attr, + &class_device_attr_tx_heartbeat_errors.attr, + &class_device_attr_tx_window_errors.attr, + &class_device_attr_rx_compressed.attr, + &class_device_attr_tx_compressed.attr, NULL }; @@ -342,11 +331,11 @@ static struct attribute_group netstat_group = { #ifdef WIRELESS_EXT /* helper function that does all the locking etc for wireless stats */ -static ssize_t wireless_show(struct device *d, char *buf, +static ssize_t wireless_show(struct class_device *cd, char *buf, ssize_t (*format)(const struct iw_statistics *, char *)) { - struct net_device *dev = to_net_dev(d); + struct net_device *dev = to_net_dev(cd); const struct iw_statistics *iw = NULL; ssize_t ret = -EINVAL; @@ -369,12 +358,11 @@ static ssize_t format_iw_##name(const struct iw_statistics *iw, char *buf) \ { \ return sprintf(buf, format_string, iw->field); \ } \ -static ssize_t show_iw_##name(struct device *d, \ - struct device_attribute *attr, char *buf) \ +static ssize_t show_iw_##name(struct class_device *cd, char *buf) \ { \ - return wireless_show(d, buf, format_iw_##name); \ + return wireless_show(cd, buf, format_iw_##name); \ } \ -static DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL) +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL) WIRELESS_SHOW(status, status, fmt_hex); WIRELESS_SHOW(link, qual.qual, fmt_dec); @@ -388,16 +376,16 @@ WIRELESS_SHOW(retries, discard.retries, fmt_dec); WIRELESS_SHOW(beacon, miss.beacon, fmt_dec); static struct attribute *wireless_attrs[] = { - &dev_attr_status.attr, - &dev_attr_link.attr, - &dev_attr_level.attr, - &dev_attr_noise.attr, - &dev_attr_nwid.attr, - &dev_attr_crypt.attr, - &dev_attr_fragment.attr, - &dev_attr_retries.attr, - &dev_attr_misc.attr, - &dev_attr_beacon.attr, + &class_device_attr_status.attr, + &class_device_attr_link.attr, + &class_device_attr_level.attr, + &class_device_attr_noise.attr, + &class_device_attr_nwid.attr, + &class_device_attr_crypt.attr, + &class_device_attr_fragment.attr, + &class_device_attr_retries.attr, + &class_device_attr_misc.attr, + &class_device_attr_beacon.attr, NULL }; @@ -408,10 +396,10 @@ static struct attribute_group wireless_group = { #endif #ifdef CONFIG_HOTPLUG -static int netdev_uevent(struct device *d, char **envp, +static int netdev_uevent(struct class_device *cd, char **envp, int num_envp, char *buf, int size) { - struct net_device *dev = to_net_dev(d); + struct net_device *dev = to_net_dev(cd); int i = 0; int n; @@ -431,11 +419,12 @@ static int netdev_uevent(struct device *d, char **envp, /* * netdev_release -- destroy and free a dead device. - * Called when last reference to device kobject is gone. + * Called when last reference to class_device kobject is gone. */ -static void netdev_release(struct device *d) +static void netdev_release(struct class_device *cd) { - struct net_device *dev = to_net_dev(d); + struct net_device *dev + = container_of(cd, struct net_device, class_dev); BUG_ON(dev->reg_state != NETREG_RELEASED); @@ -444,31 +433,31 @@ static void netdev_release(struct device *d) static struct class net_class = { .name = "net", - .dev_release = netdev_release, - .dev_attrs = net_class_attributes, + .release = netdev_release, + .class_dev_attrs = net_class_attributes, #ifdef CONFIG_HOTPLUG - .dev_uevent = netdev_uevent, + .uevent = netdev_uevent, #endif }; void netdev_unregister_sysfs(struct net_device * net) { - device_del(&(net->dev)); + class_device_del(&(net->class_dev)); } /* Create sysfs entries for network device. */ int netdev_register_sysfs(struct net_device *net) { - struct device *dev = &(net->dev); + struct class_device *class_dev = &(net->class_dev); struct attribute_group **groups = net->sysfs_groups; - device_initialize(dev); - dev->class = &net_class; - dev->platform_data = net; - dev->groups = groups; + class_device_initialize(class_dev); + class_dev->class = &net_class; + class_dev->class_data = net; + class_dev->groups = groups; BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ); - strlcpy(dev->bus_id, net->name, BUS_ID_SIZE); + strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE); if (net->get_stats) *groups++ = &netstat_group; @@ -478,7 +467,7 @@ int netdev_register_sysfs(struct net_device *net) *groups++ = &wireless_group; #endif - return device_add(dev); + return class_device_add(class_dev); } int netdev_sysfs_init(void) diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index f3404ae9f190..de7801d589e7 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -268,7 +268,7 @@ struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp, struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int length, gfp_t gfp_mask) { - int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; + int node = dev->class_dev.dev ? dev_to_node(dev->class_dev.dev) : -1; struct sk_buff *skb; skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node); diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c b/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c index fb58e03b3fbd..fa2f7da606a9 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -265,12 +265,6 @@ ieee80211softmac_wx_get_rate(struct net_device *net_dev, int err = -EINVAL; spin_lock_irqsave(&mac->lock, flags); - - if (unlikely(!mac->running)) { - err = -ENODEV; - goto out_unlock; - } - switch (mac->txrates.default_rate) { case IEEE80211_CCK_RATE_1MB: data->bitrate.value = 1000000; diff --git a/trunk/scripts/Kbuild.include b/trunk/scripts/Kbuild.include index a1880e854dce..96926eb13b0a 100644 --- a/trunk/scripts/Kbuild.include +++ b/trunk/scripts/Kbuild.include @@ -57,38 +57,40 @@ endef # See documentation in Documentation/kbuild/makefiles.txt # checker-shell -# Usage: option = $(call checker-shell,$(CC)...-o $$OUT,option-ok,otherwise) +# Usage: option = $(call checker-shell, $(CC)...-o $$OUT, option-ok, otherwise) # Exit code chooses option. $$OUT is safe location for needless output. define checker-shell -$(shell set -e; \ - DIR=$(KBUILD_EXTMOD); \ - cd $${DIR:-$(objtree)}; \ - OUT=$$PWD/.$$$$.null; \ - if $(1) >/dev/null 2>&1; \ - then echo "$(2)"; \ - else echo "$(3)"; \ - fi; \ - rm -f $$OUT) + $(shell set -e; \ + DIR=$(KBUILD_EXTMOD); \ + cd $${DIR:-$(objtree)}; \ + OUT=$$PWD/.$$$$.null; \ + \ + ln -s /dev/null $$OUT; \ + if $(1) >/dev/null 2>&1; \ + then echo "$(2)"; \ + else echo "$(3)"; \ + fi; \ + rm -f $$OUT) endef # as-option -# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) -as-option = $(call checker-shell,\ - $(CC) $(CFLAGS) $(1) -c -xassembler /dev/null -o $$OUT,$(1),$(2)) +# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,) +as-option = $(call checker-shell, \ + $(CC) $(CFLAGS) $(1) -c -xassembler /dev/null -o $$OUT, $(1), $(2)) # as-instr -# Usage: cflags-y += $(call as-instr,instr,option1,option2) -as-instr = $(call checker-shell,\ - printf "$(1)" | $(CC) $(AFLAGS) -c -xassembler -o $$OUT -,$(2),$(3)) +# Usage: cflags-y += $(call as-instr, instr, option1, option2) +as-instr = $(call checker-shell, \ + printf "$(1)" | $(CC) $(AFLAGS) -c -xassembler -o $$OUT -, $(2), $(3)) # cc-option -# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) -cc-option = $(call checker-shell,\ - $(CC) $(CFLAGS) $(if $(3),$(3),$(1)) -S -xc /dev/null -o $$OUT,$(1),$(2)) +# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586) +cc-option = $(call checker-shell, \ + $(CC) $(CFLAGS) $(if $(3),$(3),$(1)) -S -xc /dev/null -o $$OUT, $(1), $(2)) # cc-option-yn -# Usage: flag := $(call cc-option-yn,-march=winchip-c6) -cc-option-yn = $(call cc-option,"y","n",$(1)) +# Usage: flag := $(call cc-option-yn, -march=winchip-c6) +cc-option-yn = $(call cc-option, "y", "n", $(1)) # cc-option-align # Prefix align with either -falign or -malign @@ -96,7 +98,7 @@ cc-option-align = $(subst -functions=0,,\ $(call cc-option,-falign-functions=0,-malign-functions=0)) # cc-version -# Usage gcc-ver := $(call cc-version,$(CC)) +# Usage gcc-ver := $(call cc-version, $(CC)) cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) # cc-ifversion @@ -105,8 +107,8 @@ cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3)) # ld-option # Usage: ldflags += $(call ld-option, -Wl$(comma)--hash-style=both) -ld-option = $(call checker-shell,\ - $(CC) $(1) -nostdlib -xc /dev/null -o $$OUT,$(1),$(2)) +ld-option = $(call checker-shell, \ + $(CC) $(1) -nostdlib -xc /dev/null -o $$OUT, $(1), $(2)) ###### @@ -118,22 +120,22 @@ build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj # Prefix -I with $(srctree) if it is not an absolute path, # add original to the end addtree = $(if \ - $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1) + $(filter-out -I/%, $(1)), $(patsubst -I%,-I$(srctree)/%,$(1))) $(1) # Find all -I options and call addtree -flags = $(foreach o,$($(1)),\ - $(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) +flags = $(foreach o,$($(1)), \ + $(if $(filter -I%,$(o)), $(call addtree, $(o)), $(o))) # echo command. # Short version is used, if $(quiet) equals `quiet_', otherwise full one. -echo-cmd = $(if $($(quiet)cmd_$(1)),\ +echo-cmd = $(if $($(quiet)cmd_$(1)), \ echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';) # printing commands cmd = @$(echo-cmd) $(cmd_$(1)) # Add $(obj)/ for paths that are not absolute -objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) +objectify = $(foreach o,$(1), $(if $(filter /%,$(o)), $(o), $(obj)/$(o))) ### # if_changed - execute command if any prerequisite is newer than