diff --git a/[refs] b/[refs] index 0ec34eac2e0f..96b87173b7e4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6ed14254cb6e269030ff09bed8673473b7be0283 +refs/heads/master: aad61439e6a00bdb72cb649e11f6e166590c5f66 diff --git a/trunk/CREDITS b/trunk/CREDITS index 9bf714a1c7d9..6f50be37fa0f 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -3241,9 +3241,14 @@ S: 12725 SW Millikan Way, Suite 400 S: Beaverton, Oregon 97005 S: USA -N: Marcelo Tosatti -E: marcelo@kvack.org +N: Marcelo W. Tosatti +E: marcelo.tosatti@cyclades.com +D: Miscellaneous kernel hacker D: v2.4 kernel maintainer +D: Current pc300/cyclades maintainer +S: Cyclades Corporation +S: Av Cristovao Colombo, 462. Floresta. +S: Porto Alegre S: Brazil N: Stefan Traby diff --git a/trunk/Documentation/devices.txt b/trunk/Documentation/devices.txt index b369a8c46a73..3c406acd4dfa 100644 --- a/trunk/Documentation/devices.txt +++ b/trunk/Documentation/devices.txt @@ -1721,6 +1721,11 @@ Your cooperation is appreciated. These devices support the same API as the generic SCSI devices. + 97 block Packet writing for CD/DVD devices + 0 = /dev/pktcdvd0 First packet-writing module + 1 = /dev/pktcdvd1 Second packet-writing module + ... + 98 char Control and Measurement Device (comedi) 0 = /dev/comedi0 First comedi device 1 = /dev/comedi1 Second comedi device diff --git a/trunk/Documentation/dvb/get_dvb_firmware b/trunk/Documentation/dvb/get_dvb_firmware index 4820366b6ae8..15fc8fbef67e 100644 --- a/trunk/Documentation/dvb/get_dvb_firmware +++ b/trunk/Documentation/dvb/get_dvb_firmware @@ -259,9 +259,9 @@ sub dibusb { } sub nxt2002 { - my $sourcefile = "Technisat_DVB-PC_4_4_COMPACT.zip"; + my $sourcefile = "Broadband4PC_4_2_11.zip"; my $url = "http://www.bbti.us/download/windows/$sourcefile"; - my $hash = "476befae8c7c1bb9648954060b1eec1f"; + my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a"; my $outfile = "dvb-fe-nxt2002.fw"; my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); @@ -269,8 +269,8 @@ sub nxt2002 { wgetfile($sourcefile, $url); unzip($sourcefile, $tmpdir); - verify("$tmpdir/SkyNET.sys", $hash); - extract("$tmpdir/SkyNET.sys", 331624, 5908, $outfile); + verify("$tmpdir/SkyNETU.sys", $hash); + extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile); $outfile; } diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 43ab119963d5..421bcfff6ad2 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -57,15 +57,6 @@ Who: Jody McIntyre --------------------------- -What: sbp2: module parameter "force_inquiry_hack" -When: July 2006 -Why: Superceded by parameter "workarounds". Both parameters are meant to be - used ad-hoc and for single devices only, i.e. not in modprobe.conf, - therefore the impact of this feature replacement should be low. -Who: Stefan Richter - ---------------------------- - What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. When: July 2006 Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6 diff --git a/trunk/Documentation/firmware_class/README b/trunk/Documentation/firmware_class/README index e9cc8bb26f7d..43e836c07ae8 100644 --- a/trunk/Documentation/firmware_class/README +++ b/trunk/Documentation/firmware_class/README @@ -105,3 +105,20 @@ on the setup, so I think that the choice on what firmware to make persistent should be left to userspace. + - Why register_firmware()+__init can be useful: + - For boot devices needing firmware. + - To make the transition easier: + The firmware can be declared __init and register_firmware() + called on module_init. Then the firmware is warranted to be + there even if "firmware hotplug userspace" is not there yet or + it doesn't yet provide the needed firmware. + Once the firmware is widely available in userspace, it can be + removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE). + + In either case, if firmware hotplug support is there, it can move the + firmware out of kernel memory into the real filesystem for later + usage. + + Note: If persistence is implemented on top of initramfs, + register_firmware() may not be appropriate. + diff --git a/trunk/Documentation/firmware_class/firmware_sample_driver.c b/trunk/Documentation/firmware_class/firmware_sample_driver.c index 87feccdb5c9f..ad3edaba4533 100644 --- a/trunk/Documentation/firmware_class/firmware_sample_driver.c +++ b/trunk/Documentation/firmware_class/firmware_sample_driver.c @@ -5,6 +5,8 @@ * * Sample code on how to use request_firmware() from drivers. * + * Note that register_firmware() is currently useless. + * */ #include @@ -15,6 +17,11 @@ #include "linux/firmware.h" +#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE +#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE +char __init inkernel_firmware[] = "let's say that this is firmware\n"; +#endif + static struct device ghost_device = { .bus_id = "ghost0", }; @@ -97,6 +104,10 @@ static void sample_probe_async(void) static int sample_init(void) { +#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE + register_firmware("sample_driver_fw", inkernel_firmware, + sizeof(inkernel_firmware)); +#endif device_initialize(&ghost_device); /* since there is no real hardware insertion I just call the * sample probe functions here */ diff --git a/trunk/Documentation/memory-barriers.txt b/trunk/Documentation/memory-barriers.txt index c61d8b876fdb..92f0056d928c 100644 --- a/trunk/Documentation/memory-barriers.txt +++ b/trunk/Documentation/memory-barriers.txt @@ -1031,7 +1031,7 @@ conflict on any particular lock. LOCKS VS MEMORY ACCESSES ------------------------ -Consider the following: the system has a pair of spinlocks (M) and (Q), and +Consider the following: the system has a pair of spinlocks (N) and (Q), and three CPUs; then should the following sequence of events occur: CPU 1 CPU 2 @@ -1678,7 +1678,7 @@ CPU's caches by some other cache event: smp_wmb(); - p = &v; q = p; + p = &b; q = p; diff --git a/trunk/Documentation/networking/operstates.txt b/trunk/Documentation/networking/operstates.txt deleted file mode 100644 index 4a21d9bb836b..000000000000 --- a/trunk/Documentation/networking/operstates.txt +++ /dev/null @@ -1,161 +0,0 @@ - -1. Introduction - -Linux distinguishes between administrative and operational state of an -interface. Admininstrative state is the result of "ip link set dev - up or down" and reflects whether the administrator wants to use -the device for traffic. - -However, an interface is not usable just because the admin enabled it -- ethernet requires to be plugged into the switch and, depending on -a site's networking policy and configuration, an 802.1X authentication -to be performed before user data can be transferred. Operational state -shows the ability of an interface to transmit this user data. - -Thanks to 802.1X, userspace must be granted the possibility to -influence operational state. To accommodate this, operational state is -split into two parts: Two flags that can be set by the driver only, and -a RFC2863 compatible state that is derived from these flags, a policy, -and changeable from userspace under certain rules. - - -2. Querying from userspace - -Both admin and operational state can be queried via the netlink -operation RTM_GETLINK. It is also possible to subscribe to RTMGRP_LINK -to be notified of updates. This is important for setting from userspace. - -These values contain interface state: - -ifinfomsg::if_flags & IFF_UP: - Interface is admin up -ifinfomsg::if_flags & IFF_RUNNING: - Interface is in RFC2863 operational state UP or UNKNOWN. This is for - backward compatibility, routing daemons, dhcp clients can use this - flag to determine whether they should use the interface. -ifinfomsg::if_flags & IFF_LOWER_UP: - Driver has signaled netif_carrier_on() -ifinfomsg::if_flags & IFF_DORMANT: - Driver has signaled netif_dormant_on() - -These interface flags can also be queried without netlink using the -SIOCGIFFLAGS ioctl. - -TLV IFLA_OPERSTATE - -contains RFC2863 state of the interface in numeric representation: - -IF_OPER_UNKNOWN (0): - Interface is in unknown state, neither driver nor userspace has set - operational state. Interface must be considered for user data as - setting operational state has not been implemented in every driver. -IF_OPER_NOTPRESENT (1): - Unused in current kernel (notpresent interfaces normally disappear), - just a numerical placeholder. -IF_OPER_DOWN (2): - Interface is unable to transfer data on L1, f.e. ethernet is not - plugged or interface is ADMIN down. -IF_OPER_LOWERLAYERDOWN (3): - Interfaces stacked on an interface that is IF_OPER_DOWN show this - state (f.e. VLAN). -IF_OPER_TESTING (4): - Unused in current kernel. -IF_OPER_DORMANT (5): - Interface is L1 up, but waiting for an external event, f.e. for a - protocol to establish. (802.1X) -IF_OPER_UP (6): - Interface is operational up and can be used. - -This TLV can also be queried via sysfs. - -TLV IFLA_LINKMODE - -contains link policy. This is needed for userspace interaction -described below. - -This TLV can also be queried via sysfs. - - -3. Kernel driver API - -Kernel drivers have access to two flags that map to IFF_LOWER_UP and -IFF_DORMANT. These flags can be set from everywhere, even from -interrupts. It is guaranteed that only the driver has write access, -however, if different layers of the driver manipulate the same flag, -the driver has to provide the synchronisation needed. - -__LINK_STATE_NOCARRIER, maps to !IFF_LOWER_UP: - -The driver uses netif_carrier_on() to clear and netif_carrier_off() to -set this flag. On netif_carrier_off(), the scheduler stops sending -packets. The name 'carrier' and the inversion are historical, think of -it as lower layer. - -netif_carrier_ok() can be used to query that bit. - -__LINK_STATE_DORMANT, maps to IFF_DORMANT: - -Set by the driver to express that the device cannot yet be used -because some driver controlled protocol establishment has to -complete. Corresponding functions are netif_dormant_on() to set the -flag, netif_dormant_off() to clear it and netif_dormant() to query. - -On device allocation, networking core sets the flags equivalent to -netif_carrier_ok() and !netif_dormant(). - - -Whenever the driver CHANGES one of these flags, a workqueue event is -scheduled to translate the flag combination to IFLA_OPERSTATE as -follows: - -!netif_carrier_ok(): - IF_OPER_LOWERLAYERDOWN if the interface is stacked, IF_OPER_DOWN - otherwise. Kernel can recognise stacked interfaces because their - ifindex != iflink. - -netif_carrier_ok() && netif_dormant(): - IF_OPER_DORMANT - -netif_carrier_ok() && !netif_dormant(): - IF_OPER_UP if userspace interaction is disabled. Otherwise - IF_OPER_DORMANT with the possibility for userspace to initiate the - IF_OPER_UP transition afterwards. - - -4. Setting from userspace - -Applications have to use the netlink interface to influence the -RFC2863 operational state of an interface. Setting IFLA_LINKMODE to 1 -via RTM_SETLINK instructs the kernel that an interface should go to -IF_OPER_DORMANT instead of IF_OPER_UP when the combination -netif_carrier_ok() && !netif_dormant() is set by the -driver. Afterwards, the userspace application can set IFLA_OPERSTATE -to IF_OPER_DORMANT or IF_OPER_UP as long as the driver does not set -netif_carrier_off() or netif_dormant_on(). Changes made by userspace -are multicasted on the netlink group RTMGRP_LINK. - -So basically a 802.1X supplicant interacts with the kernel like this: - --subscribe to RTMGRP_LINK --set IFLA_LINKMODE to 1 via RTM_SETLINK --query RTM_GETLINK once to get initial state --if initial flags are not (IFF_LOWER_UP && !IFF_DORMANT), wait until - netlink multicast signals this state --do 802.1X, eventually abort if flags go down again --send RTM_SETLINK to set operstate to IF_OPER_UP if authentication - succeeds, IF_OPER_DORMANT otherwise --see how operstate and IFF_RUNNING is echoed via netlink multicast --set interface back to IF_OPER_DORMANT if 802.1X reauthentication - fails --restart if kernel changes IFF_LOWER_UP or IFF_DORMANT flag - -if supplicant goes down, bring back IFLA_LINKMODE to 0 and -IFLA_OPERSTATE to a sane value. - -A routing daemon or dhcp client just needs to care for IFF_RUNNING or -waiting for operstate to go IF_OPER_UP/IF_OPER_UNKNOWN before -considering the interface / querying a DHCP address. - - -For technical questions and/or comments please e-mail to Stefan Rompf -(stefan at loplof.de). diff --git a/trunk/Documentation/scsi/ChangeLog.megaraid b/trunk/Documentation/scsi/ChangeLog.megaraid index c173806c91fa..09f6300eda4b 100644 --- a/trunk/Documentation/scsi/ChangeLog.megaraid +++ b/trunk/Documentation/scsi/ChangeLog.megaraid @@ -1,28 +1,3 @@ -Release Date : Mon Apr 11 12:27:22 EST 2006 - Seokmann Ju -Current Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module) -Older Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module) - -1. Fixed a bug in megaraid_reset_handler(). - Customer reported "Unable to handle kernel NULL pointer dereference - at virtual address 00000000" when system goes to reset condition - for some reason. It happened randomly. - Root Cause: in the megaraid_reset_handler(), there is possibility not - returning pending packets in the pend_list if there are multiple - pending packets. - Fix: Made the change in the driver so that it will return all packets - in the pend_list. - -2. Added change request. - As found in the following URL, rmb() only didn't help the - problem. I had to increase the loop counter to 0xFFFFFF. (6 F's) - http://marc.theaimsgroup.com/?l=linux-scsi&m=110971060502497&w=2 - - I attached a patch for your reference, too. - Could you check and get this fix in your driver? - - Best Regards, - Jun'ichi Nomura - Release Date : Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module) Older Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module) diff --git a/trunk/Documentation/spi/pxa2xx b/trunk/Documentation/spi/pxa2xx deleted file mode 100644 index 9c45f3df2e18..000000000000 --- a/trunk/Documentation/spi/pxa2xx +++ /dev/null @@ -1,234 +0,0 @@ -PXA2xx SPI on SSP driver HOWTO -=================================================== -This a mini howto on the pxa2xx_spi driver. The driver turns a PXA2xx -synchronous serial port into a SPI master controller -(see Documentation/spi/spi_summary). The driver has the following features - -- Support for any PXA2xx SSP -- SSP PIO and SSP DMA data transfers. -- External and Internal (SSPFRM) chip selects. -- Per slave device (chip) configuration. -- Full suspend, freeze, resume support. - -The driver is built around a "spi_message" fifo serviced by workqueue and a -tasklet. The workqueue, "pump_messages", drives message fifo and the tasklet -(pump_transfer) is responsible for queuing SPI transactions and setting up and -launching the dma/interrupt driven transfers. - -Declaring PXA2xx Master Controllers ------------------------------------ -Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a -"platform device". The master configuration is passed to the driver via a table -found in include/asm-arm/arch-pxa/pxa2xx_spi.h: - -struct pxa2xx_spi_master { - enum pxa_ssp_type ssp_type; - u32 clock_enable; - u16 num_chipselect; - u8 enable_dma; -}; - -The "pxa2xx_spi_master.ssp_type" field must have a value between 1 and 3 and -informs the driver which features a particular SSP supports. - -The "pxa2xx_spi_master.clock_enable" field is used to enable/disable the -corresponding SSP peripheral block in the "Clock Enable Register (CKEN"). See -the "PXA2xx Developer Manual" section "Clocks and Power Management". - -The "pxa2xx_spi_master.num_chipselect" field is used to determine the number of -slave device (chips) attached to this SPI master. - -The "pxa2xx_spi_master.enable_dma" field informs the driver that SSP DMA should -be used. This caused the driver to acquire two DMA channels: rx_channel and -tx_channel. The rx_channel has a higher DMA service priority the tx_channel. -See the "PXA2xx Developer Manual" section "DMA Controller". - -NSSP MASTER SAMPLE ------------------- -Below is a sample configuration using the PXA255 NSSP. - -static struct resource pxa_spi_nssp_resources[] = { - [0] = { - .start = __PREG(SSCR0_P(2)), /* Start address of NSSP */ - .end = __PREG(SSCR0_P(2)) + 0x2c, /* Range of registers */ - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_NSSP, /* NSSP IRQ */ - .end = IRQ_NSSP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct pxa2xx_spi_master pxa_nssp_master_info = { - .ssp_type = PXA25x_NSSP, /* Type of SSP */ - .clock_enable = CKEN9_NSSP, /* NSSP Peripheral clock */ - .num_chipselect = 1, /* Matches the number of chips attached to NSSP */ - .enable_dma = 1, /* Enables NSSP DMA */ -}; - -static struct platform_device pxa_spi_nssp = { - .name = "pxa2xx-spi", /* MUST BE THIS VALUE, so device match driver */ - .id = 2, /* Bus number, MUST MATCH SSP number 1..n */ - .resource = pxa_spi_nssp_resources, - .num_resources = ARRAY_SIZE(pxa_spi_nssp_resources), - .dev = { - .platform_data = &pxa_nssp_master_info, /* Passed to driver */ - }, -}; - -static struct platform_device *devices[] __initdata = { - &pxa_spi_nssp, -}; - -static void __init board_init(void) -{ - (void)platform_add_device(devices, ARRAY_SIZE(devices)); -} - -Declaring Slave Devices ------------------------ -Typically each SPI slave (chip) is defined in the arch/.../mach-*/board-*.c -using the "spi_board_info" structure found in "linux/spi/spi.h". See -"Documentation/spi/spi_summary" for additional information. - -Each slave device attached to the PXA must provide slave specific configuration -information via the structure "pxa2xx_spi_chip" found in -"include/asm-arm/arch-pxa/pxa2xx_spi.h". The pxa2xx_spi master controller driver -will uses the configuration whenever the driver communicates with the slave -device. - -struct pxa2xx_spi_chip { - u8 tx_threshold; - u8 rx_threshold; - u8 dma_burst_size; - u32 timeout_microsecs; - u8 enable_loopback; - void (*cs_control)(u32 command); -}; - -The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are -used to configure the SSP hardware fifo. These fields are critical to the -performance of pxa2xx_spi driver and misconfiguration will result in rx -fifo overruns (especially in PIO mode transfers). Good default values are - - .tx_threshold = 12, - .rx_threshold = 4, - -The "pxa2xx_spi_chip.dma_burst_size" field is used to configure PXA2xx DMA -engine and is related the "spi_device.bits_per_word" field. Read and understand -the PXA2xx "Developer Manual" sections on the DMA controller and SSP Controllers -to determine the correct value. An SSP configured for byte-wide transfers would -use a value of 8. - -The "pxa2xx_spi_chip.timeout_microsecs" fields is used to efficiently handle -trailing bytes in the SSP receiver fifo. The correct value for this field is -dependent on the SPI bus speed ("spi_board_info.max_speed_hz") and the specific -slave device. Please note the the PXA2xx SSP 1 does not support trailing byte -timeouts and must busy-wait any trailing bytes. - -The "pxa2xx_spi_chip.enable_loopback" field is used to place the SSP porting -into internal loopback mode. In this mode the SSP controller internally -connects the SSPTX pin the the SSPRX pin. This is useful for initial setup -testing. - -The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific -function for asserting/deasserting a slave device chip select. If the field is -NULL, the pxa2xx_spi master controller driver assumes that the SSP port is -configured to use SSPFRM instead. - -NSSP SALVE SAMPLE ------------------ -The pxa2xx_spi_chip structure is passed to the pxa2xx_spi driver in the -"spi_board_info.controller_data" field. Below is a sample configuration using -the PXA255 NSSP. - -/* Chip Select control for the CS8415A SPI slave device */ -static void cs8415a_cs_control(u32 command) -{ - if (command & PXA2XX_CS_ASSERT) - GPCR(2) = GPIO_bit(2); - else - GPSR(2) = GPIO_bit(2); -} - -/* Chip Select control for the CS8405A SPI slave device */ -static void cs8405a_cs_control(u32 command) -{ - if (command & PXA2XX_CS_ASSERT) - GPCR(3) = GPIO_bit(3); - else - GPSR(3) = GPIO_bit(3); -} - -static struct pxa2xx_spi_chip cs8415a_chip_info = { - .tx_threshold = 12, /* SSP hardward FIFO threshold */ - .rx_threshold = 4, /* SSP hardward FIFO threshold */ - .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */ - .timeout_microsecs = 64, /* Wait at least 64usec to handle trailing */ - .cs_control = cs8415a_cs_control, /* Use external chip select */ -}; - -static struct pxa2xx_spi_chip cs8405a_chip_info = { - .tx_threshold = 12, /* SSP hardward FIFO threshold */ - .rx_threshold = 4, /* SSP hardward FIFO threshold */ - .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */ - .timeout_microsecs = 64, /* Wait at least 64usec to handle trailing */ - .cs_control = cs8405a_cs_control, /* Use external chip select */ -}; - -static struct spi_board_info streetracer_spi_board_info[] __initdata = { - { - .modalias = "cs8415a", /* Name of spi_driver for this device */ - .max_speed_hz = 3686400, /* Run SSP as fast a possbile */ - .bus_num = 2, /* Framework bus number */ - .chip_select = 0, /* Framework chip select */ - .platform_data = NULL; /* No spi_driver specific config */ - .controller_data = &cs8415a_chip_info, /* Master chip config */ - .irq = STREETRACER_APCI_IRQ, /* Slave device interrupt */ - }, - { - .modalias = "cs8405a", /* Name of spi_driver for this device */ - .max_speed_hz = 3686400, /* Run SSP as fast a possbile */ - .bus_num = 2, /* Framework bus number */ - .chip_select = 1, /* Framework chip select */ - .controller_data = &cs8405a_chip_info, /* Master chip config */ - .irq = STREETRACER_APCI_IRQ, /* Slave device interrupt */ - }, -}; - -static void __init streetracer_init(void) -{ - spi_register_board_info(streetracer_spi_board_info, - ARRAY_SIZE(streetracer_spi_board_info)); -} - - -DMA and PIO I/O Support ------------------------ -The pxa2xx_spi driver support both DMA and interrupt driven PIO message -transfers. The driver defaults to PIO mode and DMA transfers must enabled by -setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and and -ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero. The DMA -mode support both coherent and stream based DMA mappings. - -The following logic is used to determine the type of I/O to be used on -a per "spi_transfer" basis: - -if !enable_dma or dma_burst_size == 0 then - always use PIO transfers - -if spi_message.is_dma_mapped and rx_dma_buf != 0 and tx_dma_buf != 0 then - use coherent DMA mode - -if rx_buf and tx_buf are aligned on 8 byte boundary then - use streaming DMA mode - -otherwise - use PIO transfer - -THANKS TO ---------- - -David Brownell and others for mentoring the development of this driver. - diff --git a/trunk/Documentation/spi/spi-summary b/trunk/Documentation/spi/spi-summary index 068732d32276..a5ffba33a351 100644 --- a/trunk/Documentation/spi/spi-summary +++ b/trunk/Documentation/spi/spi-summary @@ -414,33 +414,7 @@ to get the driver-private data allocated for that device. The driver will initialize the fields of that spi_master, including the bus number (maybe the same as the platform device ID) and three methods used to interact with the SPI core and SPI protocol drivers. It will -also initialize its own internal state. (See below about bus numbering -and those methods.) - -After you initialize the spi_master, then use spi_register_master() to -publish it to the rest of the system. At that time, device nodes for -the controller and any predeclared spi devices will be made available, -and the driver model core will take care of binding them to drivers. - -If you need to remove your SPI controller driver, spi_unregister_master() -will reverse the effect of spi_register_master(). - - -BUS NUMBERING - -Bus numbering is important, since that's how Linux identifies a given -SPI bus (shared SCK, MOSI, MISO). Valid bus numbers start at zero. On -SOC systems, the bus numbers should match the numbers defined by the chip -manufacturer. For example, hardware controller SPI2 would be bus number 2, -and spi_board_info for devices connected to it would use that number. - -If you don't have such hardware-assigned bus number, and for some reason -you can't just assign them, then provide a negative bus number. That will -then be replaced by a dynamically assigned number. You'd then need to treat -this as a non-static configuration (see above). - - -SPI MASTER METHODS +also initialize its own internal state. master->setup(struct spi_device *spi) This sets up the device clock rate, SPI mode, and word sizes. @@ -457,9 +431,6 @@ SPI MASTER METHODS state it dynamically associates with that device. If you do that, be sure to provide the cleanup() method to free that state. - -SPI MESSAGE QUEUE - The bulk of the driver will be managing the I/O queue fed by transfer(). That queue could be purely conceptual. For example, a driver used only @@ -469,9 +440,6 @@ But the queue will probably be very real, using message->queue, PIO, often DMA (especially if the root filesystem is in SPI flash), and execution contexts like IRQ handlers, tasklets, or workqueues (such as keventd). Your driver can be as fancy, or as simple, as you need. -Such a transfer() method would normally just add the message to a -queue, and then start some asynchronous transfer engine (unless it's -already running). THANKS TO diff --git a/trunk/Documentation/watchdog/watchdog-api.txt b/trunk/Documentation/watchdog/watchdog-api.txt index 21ed51173662..c5beb548cfc4 100644 --- a/trunk/Documentation/watchdog/watchdog-api.txt +++ b/trunk/Documentation/watchdog/watchdog-api.txt @@ -36,9 +36,6 @@ timeout or margin. The simplest way to ping the watchdog is to write some data to the device. So a very simple watchdog daemon would look like this: -#include -#include - int main(int argc, const char *argv[]) { int fd=open("/dev/watchdog",O_WRONLY); if (fd==-1) { diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index aa2cfe2b6f24..d6a8e5b434ec 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -40,20 +40,11 @@ trivial patch so apply some common sense. PLEASE document known bugs. If it doesn't work for everything or does something very odd once a month document it. - PLEASE remember that submissions must be made under the terms - of the OSDL certificate of contribution - (http://www.osdl.org/newsroom/press_releases/2004/2004_05_24_dco.html) - and should include a Signed-off-by: line. - 6. Make sure you have the right to send any changes you make. If you do changes at work you may find your employer owns the patch not you. -7. When sending security related changes or reports to a maintainer - please Cc: security@kernel.org, especially if the maintainer - does not respond. - -8. Happy hacking. +7. Happy hacking. ----------------------------------- @@ -978,7 +969,7 @@ S: Maintained EXT3 FILE SYSTEM P: Stephen Tweedie, Andrew Morton M: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com -L: ext2-devel@lists.sourceforge.net +L: ext3-users@redhat.com S: Maintained F71805F HARDWARE MONITORING DRIVER @@ -1413,8 +1404,6 @@ P: Jesse Brandeburg M: jesse.brandeburg@intel.com P: Jeff Kirsher M: jeffrey.t.kirsher@intel.com -P: Auke Kok -M: auke-jan.h.kok@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported @@ -1427,8 +1416,6 @@ P: Jesse Brandeburg M: jesse.brandeburg@intel.com P: Jeff Kirsher M: jeffrey.t.kirsher@intel.com -P: Auke Kok -M: auke-jan.h.kok@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported @@ -1441,8 +1428,6 @@ P: John Ronciak M: john.ronciak@intel.com P: Jesse Brandeburg M: jesse.brandeburg@intel.com -P: Auke Kok -M: auke-jan.h.kok@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported @@ -1495,11 +1480,10 @@ L: netdev@vger.kernel.org S: Maintained IRDA SUBSYSTEM -P: Samuel Ortiz -M: samuel@sortiz.org +P: Jean Tourrilhes L: irda-users@lists.sourceforge.net (subscribers-only) W: http://irda.sourceforge.net/ -S: Maintained +S: Odd Fixes ISAPNP P: Jaroslav Kysela @@ -1545,28 +1529,12 @@ W: http://jfs.sourceforge.net/ T: git kernel.org:/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git S: Supported -JOURNALLING LAYER FOR BLOCK DEVICS (JBD) -P: Stephen Tweedie, Andrew Morton -M: sct@redhat.com, akpm@osdl.org -L: ext2-devel@lists.sourceforge.net -S: Maintained - KCONFIG P: Roman Zippel M: zippel@linux-m68k.org L: kbuild-devel@lists.sourceforge.net S: Maintained -KDUMP -P: Vivek Goyal -M: vgoyal@in.ibm.com -P: Haren Myneni -M: hbabu@us.ibm.com -L: fastboot@lists.osdl.org -L: linux-kernel@vger.kernel.org -W: http://lse.sourceforge.net/kdump/ -S: Maintained - KERNEL AUTOMOUNTER (AUTOFS) P: H. Peter Anvin M: hpa@zytor.com @@ -1634,11 +1602,6 @@ M: James.Bottomley@HansenPartnership.com L: linux-scsi@vger.kernel.org S: Maintained -LED SUBSYSTEM -P: Richard Purdie -M: rpurdie@rpsys.net -S: Maintained - LEGO USB Tower driver P: Juergen Stuber M: starblue@users.sourceforge.net @@ -1698,7 +1661,7 @@ S: Maintained LINUX FOR POWERPC EMBEDDED PPC8XX P: Marcelo Tosatti -M: marcelo@kvack.org +M: marcelo.tosatti@cyclades.com W: http://www.penguinppc.org/ L: linuxppc-embedded@ozlabs.org S: Maintained @@ -2549,12 +2512,6 @@ M: perex@suse.cz L: alsa-devel@alsa-project.org S: Maintained -SPI SUBSYSTEM -P: David Brownell -M: dbrownell@users.sourceforge.net -L: spi-devel-general@lists.sourceforge.net -S: Maintained - TPM DEVICE DRIVER P: Kylene Hall M: kjhall@us.ibm.com diff --git a/trunk/Makefile b/trunk/Makefile index 3494c17c9fb9..6bf99624bd4c 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 17 -EXTRAVERSION =-rc4 +EXTRAVERSION =-rc3 NAME=Sliding Snow Leopard # *DOCUMENTATION* @@ -344,14 +344,16 @@ scripts_basic: scripts/basic/%: scripts_basic ; PHONY += outputmakefile -# outputmakefile generates a Makefile in the output directory, if using a -# separate output directory. This allows convenient use of make in the -# output directory. +# outputmakefile generate a Makefile to be placed in output directory, if +# using a seperate output directory. This allows convinient use +# of make in output directory outputmakefile: -ifneq ($(KBUILD_SRC),) - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ - $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) -endif + $(Q)if test ! $(srctree) -ef $(objtree); then \ + $(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ + $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) \ + > $(objtree)/Makefile; \ + echo ' GEN $(objtree)/Makefile'; \ + fi # To make sure we do not include .config for any of the *config targets # catch them early, and hand them over to scripts/kconfig/Makefile @@ -794,8 +796,8 @@ prepare2: prepare3 outputmakefile prepare1: prepare2 include/linux/version.h include/asm \ include/config/MARKER ifneq ($(KBUILD_MODULES),) + $(Q)rm -rf $(MODVERDIR) $(Q)mkdir -p $(MODVERDIR) - $(Q)rm -f $(MODVERDIR)/* endif archprepare: prepare1 scripts_basic @@ -1084,8 +1086,8 @@ else # KBUILD_EXTMOD KBUILD_MODULES := 1 PHONY += crmodverdir crmodverdir: + $(Q)rm -rf $(MODVERDIR) $(Q)mkdir -p $(MODVERDIR) - $(Q)rm -f $(MODVERDIR)/* PHONY += $(objtree)/Module.symvers $(objtree)/Module.symvers: diff --git a/trunk/arch/arm/configs/collie_defconfig b/trunk/arch/arm/configs/collie_defconfig index 074c47a4fb2e..c9aa878e610a 100644 --- a/trunk/arch/arm/configs/collie_defconfig +++ b/trunk/arch/arm/configs/collie_defconfig @@ -1,21 +1,21 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc1 -# Fri Apr 14 19:09:52 2006 +# Linux kernel version: 2.6.14-rc3 +# Sun Oct 9 16:55:14 2005 # CONFIG_ARM=y CONFIG_MMU=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ARCH_MTD_XIP=y -CONFIG_VECTORS_BASE=0xffff0000 # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 # @@ -23,58 +23,45 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set +CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=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 is not set +CONFIG_BASE_FULL=y CONFIG_FUTEX=y -# CONFIG_EPOLL is not set +CONFIG_EPOLL=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y -# CONFIG_SLAB is not set -CONFIG_DOUBLEFAULT=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 -CONFIG_SLOB=y -CONFIG_OBSOLETE_INTERMODULE=y +CONFIG_BASE_SMALL=0 # # Loadable module support # -# CONFIG_MODULES is not set - -# -# Block layer -# -# 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" +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y # # System Type @@ -83,13 +70,11 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -99,11 +84,9 @@ CONFIG_ARCH_SA1100=y # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_AT91RM9200 is not set # # SA11x0 Implementations @@ -145,32 +128,20 @@ CONFIG_SHARP_SCOOP=y # Bus support # CONFIG_ISA=y +CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support # -CONFIG_PCCARD=y -CONFIG_PCMCIA_DEBUG=y -CONFIG_PCMCIA=y -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y - -# -# PC-card bridges -# -# CONFIG_I82365 is not set -# CONFIG_TCIC is not set -CONFIG_PCMCIA_SA1100=y +# CONFIG_PCCARD is not set # # Kernel Features # -# CONFIG_PREEMPT is not set +# CONFIG_SMP is not set +CONFIG_PREEMPT=y # CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set CONFIG_ARCH_DISCONTIGMEM_ENABLE=y -CONFIG_NODES_SHIFT=2 CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_FLATMEM_MANUAL is not set CONFIG_DISCONTIGMEM_MANUAL=y @@ -179,7 +150,6 @@ CONFIG_DISCONTIGMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 # CONFIG_LEDS is not set CONFIG_ALIGNMENT_TRAP=y @@ -188,7 +158,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="noinitrd root=/dev/mtdblock2 rootfstype=jffs2 fbcon=rotate:1" +CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug" # CONFIG_XIP_KERNEL is not set # @@ -211,16 +181,14 @@ CONFIG_FPE_NWFPE=y # Userspace binary formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m # CONFIG_ARTHUR is not set # # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y -# CONFIG_PM_DEBUG is not set CONFIG_APM=y # @@ -231,7 +199,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -244,19 +211,16 @@ CONFIG_IP_FIB_HASH=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES 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 # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set # @@ -268,11 +232,6 @@ CONFIG_TCP_CONG_BIC=y # 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 @@ -285,11 +244,8 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_NET_DIVERT 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 +# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -309,14 +265,9 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y +CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - # # Memory Technology Devices (MTD) # @@ -336,49 +287,32 @@ 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 # # RAM/ROM/Flash chip drivers # -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set +# 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 is not set -# CONFIG_MTD_CFI_I2 is not set -CONFIG_MTD_CFI_I4=y +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_OTP is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set CONFIG_MTD_OBSOLETE_CHIPS=y CONFIG_MTD_SHARP=y -# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -CONFIG_MTD_SA1100=y -# CONFIG_MTD_IMPA7 is not set # CONFIG_MTD_PLATRAM is not set # @@ -387,6 +321,7 @@ CONFIG_MTD_SA1100=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -401,11 +336,6 @@ CONFIG_MTD_SA1100=y # # CONFIG_MTD_NAND is not set -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - # # Parallel port support # @@ -419,6 +349,7 @@ CONFIG_MTD_SA1100=y # # Block devices # +# CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set @@ -428,35 +359,20 @@ CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=1024 CONFIG_BLK_DEV_INITRD=y # 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 +# IO Schedulers # -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -CONFIG_BLK_DEV_IDECS=y -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_ATA_OVER_ETH=m # -# IDE chipset support/bugfixes +# ATA/ATAPI/MFM/RLL support # -CONFIG_IDE_GENERIC=y -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set +# CONFIG_IDE is not set # # SCSI device support @@ -486,39 +402,6 @@ CONFIG_IDE_GENERIC=y # Network device support # # CONFIG_NETDEVICES is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=y -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_MPPE is not set -# CONFIG_PPPOE 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 @@ -541,7 +424,7 @@ CONFIG_INPUT_TSDEV=y CONFIG_INPUT_TSDEV_SCREEN_X=240 CONFIG_INPUT_TSDEV_SCREEN_Y=320 CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set +CONFIG_INPUT_EVBUG=y # # Input Device Drivers @@ -555,11 +438,7 @@ CONFIG_KEYBOARD_LOCOMO=y # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set # @@ -582,16 +461,7 @@ CONFIG_HW_CONSOLE=y # # Serial drivers # -CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_CONSOLE is not set -CONFIG_SERIAL_8250_CS=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_SHARE_IRQ is not set -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set +# CONFIG_SERIAL_8250 is not set # # Non-8250 serial port support @@ -613,48 +483,94 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # # Ftape, the floppy tape device driver # - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_CARDMAN_4000 is not set -# CONFIG_CARDMAN_4040 is not set # CONFIG_RAW_DRIVER is not set # # TPM devices # -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=m +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set # -# SPI support +# I2C Hardware Bus support # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +# CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set # -# Dallas's 1-wire bus +# Miscellaneous I2C Chip support # -# CONFIG_W1 is not set +# 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_RTC8564 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 # # Hardware Monitoring support # -# CONFIG_HWMON is not set +CONFIG_HWMON=y # CONFIG_HWMON_VID 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_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_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D 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 # # Misc devices @@ -663,33 +579,42 @@ CONFIG_UNIX98_PTYS=y # # Multimedia Capabilities Port drivers # -CONFIG_MCP=y -CONFIG_MCP_SA11X0=y -CONFIG_MCP_UCB1200=y -CONFIG_MCP_UCB1200_TS=y +# CONFIG_MCP_SA11X0 is not set # -# LED devices +# Multimedia devices # -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y +CONFIG_VIDEO_DEV=m # -# LED drivers +# Video For Linux # -CONFIG_LEDS_LOCOMO=y # -# LED Triggers +# Video Adapters # -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_IDE_DISK=y +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_OVCAMCHIP is not set # -# Multimedia devices +# Radio Adapters # -# CONFIG_VIDEO_DEV is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set # # Digital Video Broadcasting Devices @@ -703,8 +628,8 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MACMODES is not set -# CONFIG_FB_FIRMWARE_EDID is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set CONFIG_FB_SA1100=y @@ -718,15 +643,14 @@ CONFIG_FB_SA1100=y # CONFIG_MDA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y -# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x8=y # CONFIG_FONT_8x16 is not set # CONFIG_FONT_6x11 is not set # CONFIG_FONT_7x14 is not set # CONFIG_FONT_PEARL_8x8 is not set # CONFIG_FONT_ACORN_8x8 is not set -CONFIG_FONT_MINI_4x6=y +# CONFIG_FONT_MINI_4x6 is not set # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set @@ -735,11 +659,7 @@ CONFIG_FONT_MINI_4x6=y # Logo configuration # # CONFIG_LOGO is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_DEVICE=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_LCD_DEVICE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -751,42 +671,44 @@ CONFIG_LCD_DEVICE=y # CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - # # USB Gadget Support # -# CONFIG_USB_GADGET is not set +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_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set # # MMC/SD Card support # # CONFIG_MMC is not set -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set - # # File systems # -# CONFIG_EXT2_FS is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set +# CONFIG_JBD 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_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y -# CONFIG_INOTIFY is not set +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set # CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set @@ -803,7 +725,7 @@ CONFIG_ROMFS_FS=y # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set +CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" @@ -817,7 +739,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -833,12 +755,11 @@ CONFIG_RAMFS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set +CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set @@ -868,7 +789,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS=y CONFIG_NLS_DEFAULT="cp437" -CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -892,7 +813,7 @@ CONFIG_NLS_CODEPAGE_437=y # 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_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -905,7 +826,7 @@ CONFIG_NLS_ISO8859_1=y # 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_UTF8=m # # Profiling support @@ -916,23 +837,20 @@ CONFIG_NLS_ISO8859_1=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DETECT_SOFTLOCKUP is not set +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y @@ -956,7 +874,7 @@ CONFIG_DEBUG_ERRORS=y # # Library routines # -CONFIG_CRC_CCITT=y +# CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set diff --git a/trunk/arch/arm/configs/versatile_defconfig b/trunk/arch/arm/configs/versatile_defconfig index 96b7a7762426..2687a225aa6a 100644 --- a/trunk/arch/arm/configs/versatile_defconfig +++ b/trunk/arch/arm/configs/versatile_defconfig @@ -1,55 +1,50 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc3 -# Mon May 8 20:15:57 2006 +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:20:50 2005 # CONFIG_ARM=y CONFIG_MMU=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_GENERIC_IOMAP=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set 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_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_SLAB=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set -CONFIG_OBSOLETE_INTERMODULE=y # # Loadable module support @@ -57,28 +52,11 @@ CONFIG_OBSOLETE_INTERMODULE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y -# -# Block layer -# -# 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" - # # System Type # @@ -86,13 +64,11 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -102,17 +78,14 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set CONFIG_ARCH_VERSATILE=y -# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_AT91RM9200 is not set # # Versatile platform type # CONFIG_ARCH_VERSATILE_PB=y -CONFIG_MACH_VERSATILE_AB=y +# CONFIG_MACH_VERSATILE_AB is not set # # Processor Type @@ -133,14 +106,12 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_DCACHE_WRITETHROUGH is not set # CONFIG_CPU_CACHE_ROUND_ROBIN is not set -CONFIG_ARM_VIC=y CONFIG_ICST307=y # # Bus support # CONFIG_ARM_AMBA=y -# CONFIG_PCI is not set # # PCCARD (PCMCIA/CardBus) support @@ -151,18 +122,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -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=4096 CONFIG_LEDS=y CONFIG_LEDS_TIMER=y CONFIG_LEDS_CPU=y @@ -186,7 +145,7 @@ CONFIG_CMDLINE="root=1f03 mem=32M" CONFIG_FPE_NWFPE=y # CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set -CONFIG_VFP=y +# CONFIG_VFP is not set # # Userspace binary formats @@ -200,91 +159,8 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y -# CONFIG_PM_DEBUG is not set # CONFIG_APM is not set -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -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 is not set -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 is not set -# 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 is not set -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL 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_NET_DIVERT 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 # @@ -297,11 +173,6 @@ 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) # @@ -321,7 +192,6 @@ 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 # # RAM/ROM/Flash chip drivers @@ -344,7 +214,6 @@ 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_OTP is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set @@ -352,7 +221,7 @@ CONFIG_MTD_CFI_UTIL=y # 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 +# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access @@ -360,7 +229,7 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set CONFIG_MTD_ARM_INTEGRATOR=y -# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_EDB7312 is not set # # Self-contained MTD device drivers @@ -368,6 +237,7 @@ CONFIG_MTD_ARM_INTEGRATOR=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -382,11 +252,6 @@ CONFIG_MTD_ARM_INTEGRATOR=y # # CONFIG_MTD_NAND is not set -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - # # Parallel port support # @@ -399,6 +264,7 @@ CONFIG_MTD_ARM_INTEGRATOR=y # # Block devices # +# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -406,13 +272,21 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # # SCSI device support # -# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # @@ -423,7 +297,6 @@ CONFIG_BLK_DEV_INITRD=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -434,26 +307,83 @@ CONFIG_BLK_DEV_INITRD=y # # -# Network device support +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV 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_PNP=y +# CONFIG_IP_PNP_DHCP is not set +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 is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP 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_NET_DIVERT 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 +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing # +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set 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 is not set - # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y -# CONFIG_DM9000 is not set # # Ethernet (1000 Mbit) @@ -480,8 +410,6 @@ CONFIG_SMC91X=y # 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 @@ -531,6 +459,7 @@ CONFIG_SERIO_AMBAKMI=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -545,16 +474,17 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=m CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_MULTIPORT=y CONFIG_SERIAL_8250_RSA=y # # Non-8250 serial port support # +# CONFIG_SERIAL_AMBA_PL010 is not set CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_CORE=y @@ -573,19 +503,20 @@ CONFIG_LEGACY_PTY_COUNT=16 # # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # # Ftape, the floppy tape device driver # +# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -603,59 +534,59 @@ CONFIG_I2C_ALGOBIT=y # # I2C Hardware Bus support # +# CONFIG_I2C_ISA is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_STUB is not set # CONFIG_I2C_PCA_ISA is not set # -# Miscellaneous I2C Chip support +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +# 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_ASB100 is not set +# CONFIG_SENSORS_DS1621 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_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set CONFIG_SENSORS_EEPROM=m # 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_SENSORS_RTC8564 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 - # # Misc devices # -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - # # Multimedia devices # @@ -673,31 +604,27 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_FIRMWARE_EDID is not set +CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set CONFIG_FB_ARMCLCD=y -# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # # Console display driver support # +# CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set # CONFIG_FONT_8x16 is not set # CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set # CONFIG_FONT_PEARL_8x8 is not set CONFIG_FONT_ACORN_8x8=y # CONFIG_FONT_MINI_4x6 is not set # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_10x18 is not set # # Logo configuration @@ -720,18 +647,12 @@ CONFIG_SND_PCM=m CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_PCM_OSS_PLUGINS=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_AC97_CODEC=m -CONFIG_SND_AC97_BUS=m # CONFIG_SND_DUMMY is not set # CONFIG_SND_MTPAV is not set # CONFIG_SND_SERIAL_U16550 is not set @@ -740,7 +661,6 @@ CONFIG_SND_AC97_BUS=m # # ALSA ARM devices # -CONFIG_SND_ARMAACI=m # # Open Sound System @@ -752,13 +672,8 @@ CONFIG_SND_ARMAACI=m # CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - # # USB Gadget Support # @@ -772,32 +687,26 @@ CONFIG_MMC=y CONFIG_MMC_BLOCK=y CONFIG_MMC_ARMMMCI=m -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set - # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP 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_FS_POSIX_ACL is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set CONFIG_MINIX_FS=y CONFIG_ROMFS_FS=y -# CONFIG_INOTIFY is not set # 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 @@ -820,10 +729,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -838,8 +748,8 @@ CONFIG_RAMFS=y # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -856,19 +766,16 @@ CONFIG_CRAMFS=y # 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=y CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set @@ -877,7 +784,6 @@ CONFIG_SUNRPC=y # 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 @@ -897,7 +803,6 @@ CONFIG_MSDOS_PARTITION=y # 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 # @@ -953,24 +858,18 @@ CONFIG_NLS_ISO8859_1=m # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=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_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y @@ -996,7 +895,6 @@ CONFIG_DEBUG_LL=y # Library routines # # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y diff --git a/trunk/arch/arm/kernel/asm-offsets.c b/trunk/arch/arm/kernel/asm-offsets.c index 396efba9bacd..b324dcac1c56 100644 --- a/trunk/arch/arm/kernel/asm-offsets.c +++ b/trunk/arch/arm/kernel/asm-offsets.c @@ -95,13 +95,5 @@ int main(void) DEFINE(SYS_ERROR0, 0x9f0000); BLANK(); DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc)); - DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr)); - DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name)); - DEFINE(MACHINFO_PHYSIO, offsetof(struct machine_desc, phys_io)); - DEFINE(MACHINFO_PGOFFIO, offsetof(struct machine_desc, io_pg_offst)); - BLANK(); - DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list)); - DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush)); - DEFINE(PROCINFO_MMUFLAGS, offsetof(struct proc_info_list, __cpu_mmu_flags)); return 0; } diff --git a/trunk/arch/arm/kernel/dma-isa.c b/trunk/arch/arm/kernel/dma-isa.c index 0a3e9ad297d8..03532769a97f 100644 --- a/trunk/arch/arm/kernel/dma-isa.c +++ b/trunk/arch/arm/kernel/dma-isa.c @@ -143,23 +143,12 @@ static struct dma_ops isa_dma_ops = { .residue = isa_get_dma_residue, }; -static struct resource dma_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x000f -}, { - .name = "dma low page", - .start = 0x0080, - .end = 0x008f -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df -}, { - .name = "dma high page", - .start = 0x0480, - .end = 0x048f -} }; +static struct resource dma_resources[] = { + { "dma1", 0x0000, 0x000f }, + { "dma low page", 0x0080, 0x008f }, + { "dma2", 0x00c0, 0x00df }, + { "dma high page", 0x0480, 0x048f } +}; void __init isa_init_dma(dma_t *dma) { diff --git a/trunk/arch/arm/kernel/head-nommu.S b/trunk/arch/arm/kernel/head-nommu.S index adf62e5eaad7..0bea65864051 100644 --- a/trunk/arch/arm/kernel/head-nommu.S +++ b/trunk/arch/arm/kernel/head-nommu.S @@ -20,10 +20,12 @@ #include #include #include -#include #include #include +#define PROCINFO_INITFUNC 12 +#define MACHINFO_TYPE 0 + /* * Kernel startup entry point. * --------------------------- diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index 04f7344e356a..04b66a9328ef 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -24,6 +24,14 @@ #include #include +#define PROCINFO_MMUFLAGS 8 +#define PROCINFO_INITFUNC 12 + +#define MACHINFO_TYPE 0 +#define MACHINFO_PHYSIO 4 +#define MACHINFO_PGOFFIO 8 +#define MACHINFO_NAME 12 + #define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET) /* diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 7df6e1aaa323..1ff75cee4b0d 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -264,12 +264,8 @@ void show_fpregs(struct user_fp *regs) /* * Task structure and kernel stack allocation. */ -struct thread_info_list { - unsigned long *head; - unsigned int nr; -}; - -static DEFINE_PER_CPU(struct thread_info_list, thread_info_list) = { NULL, 0 }; +static unsigned long *thread_info_head; +static unsigned int nr_thread_info; #define EXTRA_TASK_STRUCT 4 @@ -278,15 +274,12 @@ struct thread_info *alloc_thread_info(struct task_struct *task) struct thread_info *thread = NULL; if (EXTRA_TASK_STRUCT) { - struct thread_info_list *th = &get_cpu_var(thread_info_list); - unsigned long *p = th->head; + unsigned long *p = thread_info_head; if (p) { - th->head = (unsigned long *)p[0]; - th->nr -= 1; + thread_info_head = (unsigned long *)p[0]; + nr_thread_info -= 1; } - put_cpu_var(thread_info_list); - thread = (struct thread_info *)p; } @@ -307,19 +300,13 @@ struct thread_info *alloc_thread_info(struct task_struct *task) void free_thread_info(struct thread_info *thread) { - if (EXTRA_TASK_STRUCT) { - struct thread_info_list *th = &get_cpu_var(thread_info_list); - if (th->nr < EXTRA_TASK_STRUCT) { - unsigned long *p = (unsigned long *)thread; - p[0] = (unsigned long)th->head; - th->head = p; - th->nr += 1; - put_cpu_var(thread_info_list); - return; - } - put_cpu_var(thread_info_list); - } - free_pages((unsigned long)thread, THREAD_SIZE_ORDER); + if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) { + unsigned long *p = (unsigned long *)thread; + p[0] = (unsigned long)thread_info_head; + thread_info_head = p; + nr_thread_info += 1; + } else + free_pages((unsigned long)thread, THREAD_SIZE_ORDER); } /* diff --git a/trunk/arch/arm/lib/backtrace.S b/trunk/arch/arm/lib/backtrace.S index 16153c86c3f8..3bdc8c6949c5 100644 --- a/trunk/arch/arm/lib/backtrace.S +++ b/trunk/arch/arm/lib/backtrace.S @@ -122,7 +122,7 @@ ENTRY(c_backtrace) #define reg r5 #define stack r6 -.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr} +.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} mov stack, r0 mov instr, r1 mov reg, #9 @@ -145,7 +145,7 @@ ENTRY(c_backtrace) adrne r0, .Lcr blne printk mov r0, stack - LOADREGS(fd, sp!, {instr, reg, stack, r7, r8, pc}) + LOADREGS(fd, sp!, {instr, reg, stack, r7, pc}) .Lfp: .asciz " r%d = %08X%c" .Lcr: .asciz "\n" diff --git a/trunk/arch/arm/lib/div64.S b/trunk/arch/arm/lib/div64.S index 58eef6607629..ec9a1cd6176f 100644 --- a/trunk/arch/arm/lib/div64.S +++ b/trunk/arch/arm/lib/div64.S @@ -189,12 +189,12 @@ ENTRY(__do_div64) moveq pc, lr @ Division by 0: - str lr, [sp, #-8]! + str lr, [sp, #-4]! bl __div0 @ as wrong as it could be... mov yl, #0 mov yh, #0 mov xh, #0 - ldr pc, [sp], #8 + ldr pc, [sp], #4 diff --git a/trunk/arch/arm/mach-aaec2000/aaed2000.c b/trunk/arch/arm/mach-aaec2000/aaed2000.c index 83f57da3184c..dc5fa8e5ebef 100644 --- a/trunk/arch/arm/mach-aaec2000/aaed2000.c +++ b/trunk/arch/arm/mach-aaec2000/aaed2000.c @@ -79,12 +79,7 @@ static void __init aaed2000_init(void) } static struct map_desc aaed2000_io_desc[] __initdata = { - { - .virtual = EXT_GPIO_VBASE, - .pfn = __phys_to_pfn(EXT_GPIO_PBASE), - .length = EXT_GPIO_LENGTH, - .type = MT_DEVICE - }, + { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */ }; static void __init aaed2000_map_io(void) diff --git a/trunk/arch/arm/mach-aaec2000/core.c b/trunk/arch/arm/mach-aaec2000/core.c index 65be5efd633c..dce4815cf53c 100644 --- a/trunk/arch/arm/mach-aaec2000/core.c +++ b/trunk/arch/arm/mach-aaec2000/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -49,12 +50,12 @@ static struct map_desc standard_io_desc[] __initdata = { { .virtual = VIO_APB_BASE, - .pfn = __phys_to_pfn(PIO_APB_BASE), + .physical = __phys_to_pfn(PIO_APB_BASE), .length = IO_APB_LENGTH, .type = MT_DEVICE }, { .virtual = VIO_AHB_BASE, - .pfn = __phys_to_pfn(PIO_AHB_BASE), + .physical = __phys_to_pfn(PIO_AHB_BASE), .length = IO_AHB_LENGTH, .type = MT_DEVICE } diff --git a/trunk/arch/arm/mach-aaec2000/core.h b/trunk/arch/arm/mach-aaec2000/core.h index 59501b573167..b6029a95f19c 100644 --- a/trunk/arch/arm/mach-aaec2000/core.h +++ b/trunk/arch/arm/mach-aaec2000/core.h @@ -9,7 +9,6 @@ * */ -#include #include struct sys_timer; diff --git a/trunk/arch/arm/mach-imx/mx1ads.c b/trunk/arch/arm/mach-imx/mx1ads.c index da893c80d471..e1f6c0bbe1e7 100644 --- a/trunk/arch/arm/mach-imx/mx1ads.c +++ b/trunk/arch/arm/mach-imx/mx1ads.c @@ -161,7 +161,7 @@ mx1ads_map_io(void) MACHINE_START(MX1ADS, "Motorola MX1ADS") /* Maintainer: Sascha Hauer, Pengutronix */ .phys_io = 0x00200000, - .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, .boot_params = 0x08000100, .map_io = mx1ads_map_io, .init_irq = imx_init_irq, diff --git a/trunk/arch/arm/mach-pxa/dma.c b/trunk/arch/arm/mach-pxa/dma.c index 7d8c85486c66..458112b21e25 100644 --- a/trunk/arch/arm/mach-pxa/dma.c +++ b/trunk/arch/arm/mach-pxa/dma.c @@ -45,16 +45,23 @@ int pxa_request_dma (char *name, pxa_dma_prio prio, local_irq_save(flags); - do { - /* try grabbing a DMA channel with the requested priority */ - pxa_for_each_dma_prio (i, prio) { + /* try grabbing a DMA channel with the requested priority */ + for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) { + if (!dma_channels[i].name) { + found = 1; + break; + } + } + + if (!found) { + /* requested prio group is full, try hier priorities */ + for (i = prio-1; i >= 0; i--) { if (!dma_channels[i].name) { found = 1; break; } } - /* if requested prio group is full, try a hier priority */ - } while (!found && prio--); + } if (found) { DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; diff --git a/trunk/arch/arm/mach-pxa/mainstone.c b/trunk/arch/arm/mach-pxa/mainstone.c index 02e188d98e7d..98356f810007 100644 --- a/trunk/arch/arm/mach-pxa/mainstone.c +++ b/trunk/arch/arm/mach-pxa/mainstone.c @@ -95,10 +95,7 @@ static void __init mainstone_init_irq(void) for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { set_irq_chip(irq, &mainstone_irq_chip); set_irq_handler(irq, do_level_IRQ); - if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14)) - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN); - else - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } set_irq_flags(MAINSTONE_IRQ(8), 0); set_irq_flags(MAINSTONE_IRQ(12), 0); diff --git a/trunk/arch/arm/mach-realview/realview_eb.c b/trunk/arch/arm/mach-realview/realview_eb.c index 693fb1e396e0..d4a586e38d5b 100644 --- a/trunk/arch/arm/mach-realview/realview_eb.c +++ b/trunk/arch/arm/mach-realview/realview_eb.c @@ -137,11 +137,8 @@ static struct amba_device *amba_devs[] __initdata = { static void __init gic_init_irq(void) { #ifdef CONFIG_REALVIEW_MPCORE - unsigned int pldctrl; writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK)); - pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + 0xd8); - pldctrl |= 0x00800000; /* New irq mode */ - writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + 0xd8); + writel(0x008003c0, __io_address(REALVIEW_SYS_BASE) + 0xd8); writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); #endif gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); diff --git a/trunk/arch/arm/mach-s3c2410/sleep.S b/trunk/arch/arm/mach-s3c2410/sleep.S index 73de2eaca22a..832fb86a03b4 100644 --- a/trunk/arch/arm/mach-s3c2410/sleep.S +++ b/trunk/arch/arm/mach-s3c2410/sleep.S @@ -59,7 +59,8 @@ ENTRY(s3c2410_cpu_suspend) mrc p15, 0, r5, c13, c0, 0 @ PID mrc p15, 0, r6, c3, c0, 0 @ Domain ID mrc p15, 0, r7, c2, c0, 0 @ translation table base address - mrc p15, 0, r8, c1, c0, 0 @ control register + mrc p15, 0, r8, c2, c0, 0 @ auxiliary control register + mrc p15, 0, r9, c1, c0, 0 @ control register stmia r0, { r4 - r13 } @@ -164,6 +165,7 @@ ENTRY(s3c2410_cpu_resume) mcr p15, 0, r5, c13, c0, 0 @ PID mcr p15, 0, r6, c3, c0, 0 @ Domain ID mcr p15, 0, r7, c2, c0, 0 @ translation table base + mcr p15, 0, r8, c1, c1, 0 @ auxilliary control #ifdef CONFIG_DEBUG_RESUME mov r3, #'R' @@ -171,7 +173,7 @@ ENTRY(s3c2410_cpu_resume) #endif ldr r2, =resume_with_mmu - mcr p15, 0, r8, c1, c0, 0 @ turn on MMU, etc + mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc nop @ second-to-last before mmu mov pc, r2 @ go back to virtual address diff --git a/trunk/arch/arm/mach-sa1100/irq.c b/trunk/arch/arm/mach-sa1100/irq.c index b3a56024182e..c131a5201b5b 100644 --- a/trunk/arch/arm/mach-sa1100/irq.c +++ b/trunk/arch/arm/mach-sa1100/irq.c @@ -199,26 +199,10 @@ static void sa1100_unmask_irq(unsigned int irq) ICMR |= (1 << irq); } -/* - * Apart form GPIOs, only the RTC alarm can be a wakeup event. - */ -static int sa1100_set_wake(unsigned int irq, unsigned int on) -{ - if (irq == IRQ_RTCAlrm) { - if (on) - PWER |= PWER_RTC; - else - PWER &= ~PWER_RTC; - return 0; - } - return -EINVAL; -} - static struct irqchip sa1100_normal_chip = { .ack = sa1100_mask_irq, .mask = sa1100_mask_irq, .unmask = sa1100_unmask_irq, - .set_wake = sa1100_set_wake, }; static struct resource irq_resource = { diff --git a/trunk/arch/arm/mm/ioremap.c b/trunk/arch/arm/mm/ioremap.c index c1f7180c7bed..25e0ca3e598c 100644 --- a/trunk/arch/arm/mm/ioremap.c +++ b/trunk/arch/arm/mm/ioremap.c @@ -141,7 +141,7 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, return NULL; addr = (unsigned long)area->addr; if (remap_area_pages(addr, pfn, size, flags)) { - vunmap((void *)addr); + vfree((void *)addr); return NULL; } return (void __iomem *) (offset + (char *)addr); @@ -173,7 +173,7 @@ EXPORT_SYMBOL(__ioremap); void __iounmap(void __iomem *addr) { - vunmap((void *)(PAGE_MASK & (unsigned long)addr)); + vfree((void *) (PAGE_MASK & (unsigned long) addr)); } EXPORT_SYMBOL(__iounmap); diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types index 6d7de9c0412f..8ab5300dcb94 100644 --- a/trunk/arch/arm/tools/mach-types +++ b/trunk/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Mon May 8 20:11:05 2006 +# Last update: Mon Feb 20 10:18:02 2006 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -566,8 +566,8 @@ switchgrass MACH_SWITCHGRASS SWITCHGRASS 549 ens_cmu MACH_ENS_CMU ENS_CMU 550 mm6_sdb MACH_MM6_SDB MM6_SDB 551 saturn MACH_SATURN SATURN 552 -i30030evb MACH_ARGONPLUSEVB ARGONPLUSEVB 553 -mxc27530evb MACH_SCMA11EVB SCMA11EVB 554 +argonplusevb MACH_ARGONPLUSEVB ARGONPLUSEVB 553 +scma11evb MACH_SCMA11EVB SCMA11EVB 554 smdk2800 MACH_SMDK2800 SMDK2800 555 mtwilson MACH_MTWILSON MTWILSON 556 ziti MACH_ZITI ZITI 557 @@ -647,7 +647,7 @@ sendt MACH_SENDT SENDT 630 mx2jazz MACH_MX2JAZZ MX2JAZZ 631 multiio MACH_MULTIIO MULTIIO 632 hrdisplay MACH_HRDISPLAY HRDISPLAY 633 -mxc27530ads MACH_SCMA11BB SCMA11BB 634 +scma11bb MACH_SCMA11BB SCMA11BB 634 trizeps3 MACH_TRIZEPS3 TRIZEPS3 635 zefeerdza MACH_ZEFEERDZA ZEFEERDZA 636 zefeerdzb MACH_ZEFEERDZB ZEFEERDZB 637 @@ -721,7 +721,7 @@ gp32 MACH_GP32 GP32 706 gem MACH_GEM GEM 707 i858 MACH_I858 I858 708 hx2750 MACH_HX2750 HX2750 709 -mxc91131evb MACH_ZEUSEVB ZEUSEVB 710 +zeusevb MACH_ZEUSEVB ZEUSEVB 710 p700 MACH_P700 P700 711 cpe MACH_CPE CPE 712 spitz MACH_SPITZ SPITZ 713 @@ -802,7 +802,7 @@ cpuat91 MACH_CPUAT91 CPUAT91 787 rea9200 MACH_REA9200 REA9200 788 acts_pune_sa1110 MACH_ACTS_PUNE_SA1110 ACTS_PUNE_SA1110 789 ixp425 MACH_IXP425 IXP425 790 -i30030ads MACH_ARGONPLUSODYSSEY ARGONPLUSODYSSEY 791 +argonplusodyssey MACH_ARGONPLUSODYSSEY ARGONPLUSODYSSEY 791 perch MACH_PERCH PERCH 792 eis05r1 MACH_EIS05R1 EIS05R1 793 pepperpad MACH_PEPPERPAD PEPPERPAD 794 @@ -827,7 +827,7 @@ micro9l MACH_MICRO9L MICRO9L 812 uc5471dsp MACH_UC5471DSP UC5471DSP 813 sj5471eng MACH_SJ5471ENG SJ5471ENG 814 none MACH_CMPXA26X CMPXA26X 815 -nc1 MACH_NC NC 816 +nc MACH_NC NC 816 omap_palmte MACH_OMAP_PALMTE OMAP_PALMTE 817 ajax52x MACH_AJAX52X AJAX52X 818 siriustar MACH_SIRIUSTAR SIRIUSTAR 819 @@ -930,7 +930,7 @@ netclient MACH_NETCLIENT NETCLIENT 916 xscale_palmtt5 MACH_XSCALE_PALMTT5 XSCALE_PALMTT5 917 xscale_palmtc MACH_OMAP_PALMTC OMAP_PALMTC 918 omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 -mxc30030evb MACH_ARGONLVEVB ARGONLVEVB 920 +argonlvevb MACH_ARGONLVEVB ARGONLVEVB 920 rea_2d MACH_REA_2D REA_2D 921 eti3e524 MACH_TI3E524 TI3E524 922 ateb9200 MACH_ATEB9200 ATEB9200 923 @@ -965,78 +965,7 @@ sisteron MACH_SISTERON SISTERON 951 rx1950 MACH_RX1950 RX1950 952 tsc_venus MACH_TSC_VENUS TSC_VENUS 953 ds101j MACH_DS101J DS101J 954 -mxc30030ads MACH_MXC30030ADS MXC30030ADS 955 +mxc300_30ads MACH_MXC30030ADS MXC30030ADS 955 fujitsu_wimaxsoc MACH_FUJITSU_WIMAXSOC FUJITSU_WIMAXSOC 956 dualpcmodem MACH_DUALPCMODEM DUALPCMODEM 957 gesbc9312 MACH_GESBC9312 GESBC9312 958 -htcapache MACH_HTCAPACHE HTCAPACHE 959 -ixdp435 MACH_IXDP435 IXDP435 960 -catprovt100 MACH_CATPROVT100 CATPROVT100 961 -picotux1xx MACH_PICOTUX1XX PICOTUX1XX 962 -picotux2xx MACH_PICOTUX2XX PICOTUX2XX 963 -dsmg600 MACH_DSMG600 DSMG600 964 -empc2 MACH_EMPC2 EMPC2 965 -ventura MACH_VENTURA VENTURA 966 -phidget_sbc MACH_PHIDGET_SBC PHIDGET_SBC 967 -ij3k MACH_IJ3K IJ3K 968 -pisgah MACH_PISGAH PISGAH 969 -omap_fsample MACH_OMAP_FSAMPLE OMAP_FSAMPLE 970 -sg720 MACH_SG720 SG720 971 -redfox MACH_REDFOX REDFOX 972 -mysh_ep9315_1 MACH_MYSH_EP9315_1 MYSH_EP9315_1 973 -tpf106 MACH_TPF106 TPF106 974 -at91rm9200kg MACH_AT91RM9200KG AT91RM9200KG 975 -racemt2 MACH_SLEDB SLEDB 976 -ontrack MACH_ONTRACK ONTRACK 977 -pm1200 MACH_PM1200 PM1200 978 -ess24562 MACH_ESS24XXX ESS24XXX 979 -coremp7 MACH_COREMP7 COREMP7 980 -nexcoder_6446 MACH_NEXCODER_6446 NEXCODER_6446 981 -stvc8380 MACH_STVC8380 STVC8380 982 -teklynx MACH_TEKLYNX TEKLYNX 983 -carbonado MACH_CARBONADO CARBONADO 984 -sysmos_mp730 MACH_SYSMOS_MP730 SYSMOS_MP730 985 -snapper_cl15 MACH_SNAPPER_CL15 SNAPPER_CL15 986 -pgigim MACH_PGIGIM PGIGIM 987 -ptx9160p2 MACH_PTX9160P2 PTX9160P2 988 -dcore1 MACH_DCORE1 DCORE1 989 -victorpxa MACH_VICTORPXA VICTORPXA 990 -mx2dtb MACH_MX2DTB MX2DTB 991 -pxa_irex_er0100 MACH_PXA_IREX_ER0100 PXA_IREX_ER0100 992 -omap_palmz71 MACH_OMAP_PALMZ71 OMAP_PALMZ71 993 -bartec_deg MACH_BARTEC_DEG BARTEC_DEG 994 -hw50251 MACH_HW50251 HW50251 995 -ibox MACH_IBOX IBOX 996 -atlaslh7a404 MACH_ATLASLH7A404 ATLASLH7A404 997 -pt2026 MACH_PT2026 PT2026 998 -htcalpine MACH_HTCALPINE HTCALPINE 999 -bartec_vtu MACH_BARTEC_VTU BARTEC_VTU 1000 -vcoreii MACH_VCOREII VCOREII 1001 -pdnb3 MACH_PDNB3 PDNB3 1002 -htcbeetles MACH_HTCBEETLES HTCBEETLES 1003 -s3c6400 MACH_S3C6400 S3C6400 1004 -s3c2443 MACH_S3C2443 S3C2443 1005 -omap_ldk MACH_OMAP_LDK OMAP_LDK 1006 -smdk2460 MACH_SMDK2460 SMDK2460 1007 -smdk2440 MACH_SMDK2440 SMDK2440 1008 -smdk2412 MACH_SMDK2412 SMDK2412 1009 -webbox MACH_WEBBOX WEBBOX 1010 -cwwndp MACH_CWWNDP CWWNDP 1011 -dragon MACH_DRAGON DRAGON 1012 -opendo_cpu_board MACH_OPENDO_CPU_BOARD OPENDO_CPU_BOARD 1013 -ccm2200 MACH_CCM2200 CCM2200 1014 -etwarm MACH_ETWARM ETWARM 1015 -m93030 MACH_M93030 M93030 1016 -cc7u MACH_CC7U CC7U 1017 -mtt_ranger MACH_MTT_RANGER MTT_RANGER 1018 -nexus MACH_NEXUS NEXUS 1019 -desman MACH_DESMAN DESMAN 1020 -bkde303 MACH_BKDE303 BKDE303 1021 -smdk2413 MACH_SMDK2413 SMDK2413 1022 -aml_m7200 MACH_AML_M7200 AML_M7200 1023 -aml_m5900 MACH_AML_M5900 AML_M5900 1024 -sg640 MACH_SG640 SG640 1025 -edg79524 MACH_EDG79524 EDG79524 1026 -ai2410 MACH_AI2410 AI2410 1027 -ixp465 MACH_IXP465 IXP465 1028 -balloon3 MACH_BALLOON3 BALLOON3 1029 diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index 03486be04193..37ff8145b5b5 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -245,7 +245,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) */ barrier(); trigger = fmrx(FPINST2); - orig_fpscr = fpscr = fmrx(FPSCR); + fpscr = fmrx(FPSCR); emulate: exceptions = vfp_emulate_instruction(trigger, fpscr, regs); diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index 8dfa3054f10f..c6fe99e57a05 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -758,10 +758,10 @@ config HOTPLUG_CPU bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER ---help--- - Say Y here to experiment with turning CPUs off and on, and to - enable suspend on SMP systems. CPUs can be controlled through - /sys/devices/system/cpu. + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu. + Say N. endmenu diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index daee69579b1c..40e5aba3ad3d 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -1066,14 +1066,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), }, }, - { - .callback = disable_acpi_pci, - .ident = "HP xw9300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP xw9300 Workstation"), - }, - }, {} }; diff --git a/trunk/arch/i386/kernel/apic.c b/trunk/arch/i386/kernel/apic.c index 3d4b2f3d116a..013b85df18c6 100644 --- a/trunk/arch/i386/kernel/apic.c +++ b/trunk/arch/i386/kernel/apic.c @@ -1341,14 +1341,6 @@ int __init APIC_init_uniprocessor (void) connect_bsp_APIC(); - /* - * Hack: In case of kdump, after a crash, kernel might be booting - * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid - * might be zero if read from MP tables. Get it from LAPIC. - */ -#ifdef CONFIG_CRASH_DUMP - boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); -#endif phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); setup_local_APIC(); diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index d70f2ade5cde..f8f132aa5472 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -2238,8 +2238,6 @@ static inline void unlock_ExtINT_logic(void) spin_unlock_irqrestore(&ioapic_lock, flags); } -int timer_uses_ioapic_pin_0; - /* * This code may look a bit paranoid, but it's supposed to cooperate with * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ @@ -2276,9 +2274,6 @@ static inline void check_timer(void) pin2 = ioapic_i8259.pin; apic2 = ioapic_i8259.apic; - if (pin1 == 0) - timer_uses_ioapic_pin_0 = 1; - printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", vector, apic1, pin1, apic2, pin2); diff --git a/trunk/arch/i386/kernel/mpparse.c b/trunk/arch/i386/kernel/mpparse.c index 6b1392d33ed5..34d21e21e012 100644 --- a/trunk/arch/i386/kernel/mpparse.c +++ b/trunk/arch/i386/kernel/mpparse.c @@ -1130,17 +1130,7 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity) */ int irq = gsi; if (gsi < MAX_GSI_NUM) { - /* - * Retain the VIA chipset work-around (gsi > 15), but - * avoid a problem where the 8254 timer (IRQ0) is setup - * via an override (so it's not on pin 0 of the ioapic), - * and at the same time, the pin 0 interrupt is a PCI - * type. The gsi > 15 test could cause these two pins - * to be shared as IRQ0, and they are not shareable. - * So test for this condition, and if necessary, avoid - * the pin collision. - */ - if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0)) + if (gsi > 15) gsi = pci_irq++; /* * Don't assign IRQ used by ACPI SCI diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 846e1639ef7c..d77e89ac0d54 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -1320,8 +1320,6 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat probe_roms(); for (i = 0; i < e820.nr_map; i++) { struct resource *res; - if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) - continue; res = kzalloc(sizeof(struct resource), GFP_ATOMIC); switch (e820.map[i].type) { case E820_RAM: res->name = "System RAM"; break; diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 0e498369f35e..2d22f5761b1d 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -130,8 +130,9 @@ static inline int print_addr_and_symbol(unsigned long addr, char *log_lvl, print_symbol("%s", addr); printed = (printed + 1) % CONFIG_STACK_BACKTRACE_COLS; + if (printed) - printk(" "); + printk(" "); else printk("\n"); @@ -211,6 +212,7 @@ static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp, } stack = esp; + printk(log_lvl); for(i = 0; i < kstack_depth_to_print; i++) { if (kstack_end(stack)) break; diff --git a/trunk/arch/i386/mm/init.c b/trunk/arch/i386/mm/init.c index 3df1371d4520..ae6534ad8161 100644 --- a/trunk/arch/i386/mm/init.c +++ b/trunk/arch/i386/mm/init.c @@ -651,7 +651,7 @@ void __init mem_init(void) * Specifically, in the case of x86, we will always add * memory to the highmem for now. */ -#ifdef CONFIG_MEMORY_HOTPLUG +#ifdef CONFIG_HOTPLUG_MEMORY #ifndef CONFIG_NEED_MULTIPLE_NODES int add_memory(u64 start, u64 size) { diff --git a/trunk/arch/i386/oprofile/nmi_int.c b/trunk/arch/i386/oprofile/nmi_int.c index ec0fd3cfa774..1a2076ce6f6a 100644 --- a/trunk/arch/i386/oprofile/nmi_int.c +++ b/trunk/arch/i386/oprofile/nmi_int.c @@ -332,11 +332,10 @@ static int __init ppro_init(char ** cpu_type) { __u8 cpu_model = boot_cpu_data.x86_model; - if (cpu_model == 14) - *cpu_type = "i386/core"; - else if (cpu_model > 0xd) + if (cpu_model > 0xd) return 0; - else if (cpu_model == 9) { + + if (cpu_model == 9) { *cpu_type = "i386/p6_mobile"; } else if (cpu_model > 5) { *cpu_type = "i386/piii"; diff --git a/trunk/arch/i386/power/cpu.c b/trunk/arch/i386/power/cpu.c index 79b2370c7fac..50a0bef8c85f 100644 --- a/trunk/arch/i386/power/cpu.c +++ b/trunk/arch/i386/power/cpu.c @@ -92,7 +92,7 @@ void __restore_processor_state(struct saved_context *ctxt) write_cr4(ctxt->cr4); write_cr3(ctxt->cr3); write_cr2(ctxt->cr2); - write_cr0(ctxt->cr0); + write_cr2(ctxt->cr0); /* * now restore the descriptor tables to their proper values diff --git a/trunk/arch/ia64/configs/sn2_defconfig b/trunk/arch/ia64/configs/sn2_defconfig index 9ea35398e10d..f6a8853cd1b4 100644 --- a/trunk/arch/ia64/configs/sn2_defconfig +++ b/trunk/arch/ia64/configs/sn2_defconfig @@ -134,7 +134,7 @@ CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y CONFIG_NUMA=y -CONFIG_NODES_SHIFT=10 +CONFIG_NODES_SHIFT=8 CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y @@ -1159,7 +1159,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set CONFIG_DEBUG_PREEMPT=y -# CONFIG_DEBUG_MUTEXES is not set +CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index d58c1c5c903a..7956eb9058fc 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -416,7 +416,7 @@ iosapic_end_level_irq (unsigned int irq) ia64_vector vec = irq_to_vector(irq); struct iosapic_rte_info *rte; - move_native_irq(irq); + move_irq(irq); list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) iosapic_eoi(rte->addr, vec); } @@ -458,7 +458,7 @@ iosapic_ack_edge_irq (unsigned int irq) { irq_desc_t *idesc = irq_descp(irq); - move_native_irq(irq); + move_irq(irq); /* * Once we have recorded IRQ_PENDING already, we can mask the * interrupt for real. This prevents IRQ storms from unhandled diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index 9c72ea3f6432..5ce908ef9c95 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -101,6 +101,7 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir) if (irq < NR_IRQS) { irq_affinity[irq] = mask; + set_irq_info(irq, mask); irq_redir[irq] = (char) (redir & 0xff); } } diff --git a/trunk/arch/ia64/lib/memcpy_mck.S b/trunk/arch/ia64/lib/memcpy_mck.S index 9e534d52b1d5..46c9331e7ab5 100644 --- a/trunk/arch/ia64/lib/memcpy_mck.S +++ b/trunk/arch/ia64/lib/memcpy_mck.S @@ -6,9 +6,7 @@ * in1: source address * in2: number of bytes to copy * Output: - * for memcpy: return dest - * for copy_user: return 0 if success, - * or number of byte NOT copied if error occurred. + * 0 if success, or number of byte NOT copied if error occurred. * * Copyright (C) 2002 Intel Corp. * Copyright (C) 2002 Ken Chen @@ -75,7 +73,6 @@ GLOBAL_ENTRY(memcpy) and r28=0x7,in0 and r29=0x7,in1 mov f6=f0 - mov retval=in0 br.cond.sptk .common_code ;; END(memcpy) @@ -87,7 +84,7 @@ GLOBAL_ENTRY(__copy_user) mov f6=f1 mov saved_in0=in0 // save dest pointer mov saved_in1=in1 // save src pointer - mov retval=r0 // initialize return value + mov saved_in2=in2 // save len ;; .common_code: cmp.gt p15,p0=8,in2 // check for small size @@ -95,7 +92,7 @@ GLOBAL_ENTRY(__copy_user) cmp.ne p14,p0=0,r29 // check src alignment add src0=0,in1 sub r30=8,r28 // for .align_dest - mov saved_in2=in2 // save len + mov retval=r0 // initialize return value ;; add dst0=0,in0 add dst1=1,in0 // dest odd index diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index 2d80653aa2af..078fb5533541 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -1636,7 +1636,7 @@ static int __init prom_find_machine_type(void) compat, sizeof(compat)-1); if (len <= 0) return PLATFORM_GENERIC; - if (strcmp(compat, RELOC("chrp"))) + if (strncmp(compat, RELOC("chrp"), 4)) return PLATFORM_GENERIC; /* Default to pSeries. We need to know if we are running LPAR */ diff --git a/trunk/arch/powerpc/kernel/systbl.S b/trunk/arch/powerpc/kernel/systbl.S index 26ed1f5ef16e..cf56a1d499ff 100644 --- a/trunk/arch/powerpc/kernel/systbl.S +++ b/trunk/arch/powerpc/kernel/systbl.S @@ -338,8 +338,6 @@ SYSCALL(symlinkat) SYSCALL(readlinkat) SYSCALL(fchmodat) SYSCALL(faccessat) -COMPAT_SYS(get_robust_list) -COMPAT_SYS(set_robust_list) /* * please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c diff --git a/trunk/arch/powerpc/platforms/cell/spu_callbacks.c b/trunk/arch/powerpc/platforms/cell/spu_callbacks.c index b47fcc5ddb78..95b36430aa0f 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_callbacks.c +++ b/trunk/arch/powerpc/platforms/cell/spu_callbacks.c @@ -258,7 +258,6 @@ void *spu_syscall_table[] = { [__NR_futex] sys_futex, [__NR_sched_setaffinity] sys_sched_setaffinity, [__NR_sched_getaffinity] sys_sched_getaffinity, - [224] sys_ni_syscall, [__NR_tuxcall] sys_ni_syscall, [226] sys_ni_syscall, [__NR_io_setup] sys_io_setup, @@ -333,21 +332,19 @@ void *spu_syscall_table[] = { [__NR_readlinkat] sys_readlinkat, [__NR_fchmodat] sys_fchmodat, [__NR_faccessat] sys_faccessat, - [__NR_get_robust_list] sys_get_robust_list, - [__NR_set_robust_list] sys_set_robust_list, }; long spu_sys_callback(struct spu_syscall_block *s) { long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6); + syscall = spu_syscall_table[s->nr_ret]; + if (s->nr_ret >= ARRAY_SIZE(spu_syscall_table)) { pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret); return -ENOSYS; } - syscall = spu_syscall_table[s->nr_ret]; - #ifdef DEBUG print_symbol(KERN_DEBUG "SPU-syscall %s:", (unsigned long)syscall); printk("syscall%ld(%lx, %lx, %lx, %lx, %lx, %lx)\n", diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 5f79f01c44f2..5eb55ef1c91c 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -255,7 +255,7 @@ static int __init pSeries_init_panel(void) { /* Manually leave the kernel version on the panel. */ ppc_md.progress("Linux ppc64\n", 0); - ppc_md.progress(system_utsname.release, 0); + ppc_md.progress(system_utsname.version, 0); return 0; } diff --git a/trunk/arch/ppc/kernel/head_8xx.S b/trunk/arch/ppc/kernel/head_8xx.S index 7a2f20583be4..ec53c7d65f2b 100644 --- a/trunk/arch/ppc/kernel/head_8xx.S +++ b/trunk/arch/ppc/kernel/head_8xx.S @@ -355,7 +355,9 @@ InstructionTLBMiss: . = 0x1200 DataStoreTLBMiss: +#ifdef CONFIG_8xx_CPU6 stw r3, 8(r0) +#endif DO_8xx_CPU6(0x3f80, r3) mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ mfcr r10 @@ -415,7 +417,9 @@ DataStoreTLBMiss: lwz r11, 0(r0) mtcr r11 lwz r11, 4(r0) +#ifdef CONFIG_8xx_CPU6 lwz r3, 8(r0) +#endif rfi /* This is an instruction TLB error on the MPC8xx. This could be due diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index 4d53b2739357..ef5b9c44b86b 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -1650,11 +1650,3 @@ sys_tee_wrapper: llgfr %r4,%r4 # size_t llgfr %r5,%r5 # unsigned int jg sys_tee - - .globl compat_sys_vmsplice_wrapper -compat_sys_vmsplice_wrapper: - lgfr %r2,%r2 # int - llgtr %r3,%r3 # compat_iovec * - llgfr %r4,%r4 # unsigned int - llgfr %r5,%r5 # unsigned int - jg compat_sys_vmsplice diff --git a/trunk/arch/s390/kernel/syscalls.S b/trunk/arch/s390/kernel/syscalls.S index 93be1d56c036..fc2c0767202b 100644 --- a/trunk/arch/s390/kernel/syscalls.S +++ b/trunk/arch/s390/kernel/syscalls.S @@ -317,4 +317,3 @@ SYSCALL(sys_get_robust_list,sys_get_robust_list,compat_sys_get_robust_list_wrapp SYSCALL(sys_splice,sys_splice,sys_splice_wrapper) SYSCALL(sys_sync_file_range,sys_sync_file_range,sys_sync_file_range_wrapper) SYSCALL(sys_tee,sys_tee,sys_tee_wrapper) -SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper) diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c index ce19ad4e92ec..fea043b69b91 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -249,19 +249,18 @@ static inline void stop_hz_timer(void) unsigned long flags; unsigned long seq, next; __u64 timer, todval; - int cpu = smp_processor_id(); if (sysctl_hz_timer != 0) return; - cpu_set(cpu, nohz_cpu_mask); + cpu_set(smp_processor_id(), nohz_cpu_mask); /* * Leave the clock comparator set up for the next timer * tick if either rcu or a softirq is pending. */ - if (rcu_needs_cpu(cpu) || local_softirq_pending()) { - cpu_clear(cpu, nohz_cpu_mask); + if (rcu_pending(smp_processor_id()) || local_softirq_pending()) { + cpu_clear(smp_processor_id(), nohz_cpu_mask); return; } @@ -272,7 +271,7 @@ static inline void stop_hz_timer(void) next = next_timer_interrupt(); do { seq = read_seqbegin_irqsave(&xtime_lock, flags); - timer = (__u64 next) - (__u64 jiffies) + jiffies_64; + timer = (__u64)(next - jiffies) + jiffies_64; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); todval = -1ULL; /* Be careful about overflows. */ diff --git a/trunk/arch/sparc/kernel/ioport.c b/trunk/arch/sparc/kernel/ioport.c index f9ff29734848..460f72e640e6 100644 --- a/trunk/arch/sparc/kernel/ioport.c +++ b/trunk/arch/sparc/kernel/ioport.c @@ -274,11 +274,6 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) if (mmu_map_dma_area(dma_addrp, va, res->start, len_total) != 0) goto err_noiommu; - /* Set the resource name, if known. */ - if (sdev) { - res->name = sdev->prom_name; - } - return (void *)res->start; err_noiommu: diff --git a/trunk/arch/sparc/kernel/module.c b/trunk/arch/sparc/kernel/module.c index 598682f31ebf..787d5f1347ec 100644 --- a/trunk/arch/sparc/kernel/module.c +++ b/trunk/arch/sparc/kernel/module.c @@ -113,7 +113,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, switch (ELF32_R_TYPE(rel[i].r_info)) { case R_SPARC_32: - case R_SPARC_UA32: location[0] = v >> 24; location[1] = v >> 16; location[2] = v >> 8; diff --git a/trunk/arch/sparc/kernel/sparc_ksyms.c b/trunk/arch/sparc/kernel/sparc_ksyms.c index 4b376fae752c..ec1c9687d679 100644 --- a/trunk/arch/sparc/kernel/sparc_ksyms.c +++ b/trunk/arch/sparc/kernel/sparc_ksyms.c @@ -251,9 +251,19 @@ EXPORT_SYMBOL(__prom_getchild); EXPORT_SYMBOL(__prom_getsibling); /* sparc library symbols */ +EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strncat); +EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(page_kernel); /* Special internal versions of library functions. */ @@ -307,3 +317,6 @@ EXPORT_SYMBOL(do_BUG); /* Sun Power Management Idle Handler */ EXPORT_SYMBOL(pm_idle); + +/* Binfmt_misc needs this */ +EXPORT_SYMBOL(sys_close); diff --git a/trunk/arch/sparc/kernel/systbls.S b/trunk/arch/sparc/kernel/systbls.S index 2856551bddf1..6e1135cc03b0 100644 --- a/trunk/arch/sparc/kernel/systbls.S +++ b/trunk/arch/sparc/kernel/systbls.S @@ -79,7 +79,6 @@ sys_call_table: /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare -/*300*/ .long sys_set_robust_list, sys_get_robust_list #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -191,6 +190,6 @@ sunos_sys_table: /*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys - .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys #endif diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig index f09a70b8aabd..1317380fa937 100644 --- a/trunk/arch/sparc64/defconfig +++ b/trunk/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc3 -# Fri May 12 12:43:49 2006 +# Linux kernel version: 2.6.16 +# Sun Apr 2 19:31:04 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -114,7 +114,6 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_HUGETLB_PAGE_SIZE_4MB=y # CONFIG_HUGETLB_PAGE_SIZE_512K is not set # CONFIG_HUGETLB_PAGE_SIZE_64K is not set -CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_LARGE_ALLOCS=y @@ -431,6 +430,7 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLOGICPTI is not set # CONFIG_SCSI_QLA_FC is not set @@ -1042,7 +1042,9 @@ CONFIG_USB_HIDDEV=y # 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_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1112,14 +1114,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_NEW_LEDS is not set -# -# LED drivers -# - -# -# LED Triggers -# - # # InfiniBand support # @@ -1309,7 +1303,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set -# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_STACK_USAGE is not set diff --git a/trunk/arch/sparc64/kernel/module.c b/trunk/arch/sparc64/kernel/module.c index 579871527699..6c83e372f75d 100644 --- a/trunk/arch/sparc64/kernel/module.c +++ b/trunk/arch/sparc64/kernel/module.c @@ -143,11 +143,6 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, location[3] = v >> 0; break; - case R_SPARC_DISP32: - v -= (Elf64_Addr) location; - *loc32 = v; - break; - case R_SPARC_WDISP30: v -= (Elf64_Addr) location; *loc32 = (*loc32 & ~0x3fffffff) | diff --git a/trunk/arch/sparc64/kernel/pci_iommu.c b/trunk/arch/sparc64/kernel/pci_iommu.c index 82e5455134c6..8efbc139769d 100644 --- a/trunk/arch/sparc64/kernel/pci_iommu.c +++ b/trunk/arch/sparc64/kernel/pci_iommu.c @@ -218,7 +218,7 @@ static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx) * DMA for PCI device PDEV. Return non-NULL cpu-side address if * successful and set *DMA_ADDRP to the PCI side dma address. */ -static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp) +static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp) { struct pcidev_cookie *pcp; struct pci_iommu *iommu; @@ -232,7 +232,7 @@ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr if (order >= 10) return NULL; - first_page = __get_free_pages(gfp, order); + first_page = __get_free_pages(GFP_ATOMIC, order); if (first_page == 0UL) return NULL; memset((char *)first_page, 0, PAGE_SIZE << order); diff --git a/trunk/arch/sparc64/kernel/pci_sun4v.c b/trunk/arch/sparc64/kernel/pci_sun4v.c index 2b7a1f316a93..9e94db2573a2 100644 --- a/trunk/arch/sparc64/kernel/pci_sun4v.c +++ b/trunk/arch/sparc64/kernel/pci_sun4v.c @@ -154,7 +154,7 @@ static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, un __clear_bit(i, arena->map); } -static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp) +static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp) { struct pcidev_cookie *pcp; struct pci_iommu *iommu; @@ -169,7 +169,7 @@ static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr npages = size >> IO_PAGE_SHIFT; - first_page = __get_free_pages(gfp, order); + first_page = __get_free_pages(GFP_ATOMIC, order); if (unlikely(first_page == 0UL)) return NULL; diff --git a/trunk/arch/sparc64/kernel/systbls.S b/trunk/arch/sparc64/kernel/systbls.S index 1136fc465e37..d4b39cd30310 100644 --- a/trunk/arch/sparc64/kernel/systbls.S +++ b/trunk/arch/sparc64/kernel/systbls.S @@ -78,9 +78,8 @@ sys_call_table32: .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid /*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 -/*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat +/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare -/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list #endif /* CONFIG_COMPAT */ @@ -148,9 +147,8 @@ sys_call_table: .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid /*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 -/*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat +/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare -/*300*/ .word sys_set_robust_list, sys_get_robust_list #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -263,5 +261,5 @@ sunos_sys_table: /*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys #endif diff --git a/trunk/arch/x86_64/kernel/e820.c b/trunk/arch/x86_64/kernel/e820.c index 222b5b46d2b2..62776c07cff1 100644 --- a/trunk/arch/x86_64/kernel/e820.c +++ b/trunk/arch/x86_64/kernel/e820.c @@ -76,12 +76,6 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) *addrp = __pa_symbol(&_end); return 1; } - - if (last >= ebda_addr && addr < ebda_addr + ebda_size) { - *addrp = ebda_addr + ebda_size; - return 1; - } - /* XXX ramdisk image here? */ return 0; } diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c index 0de3ea938830..77b4c608cca0 100644 --- a/trunk/arch/x86_64/kernel/io_apic.c +++ b/trunk/arch/x86_64/kernel/io_apic.c @@ -1777,8 +1777,6 @@ static inline void unlock_ExtINT_logic(void) spin_unlock_irqrestore(&ioapic_lock, flags); } -int timer_uses_ioapic_pin_0; - /* * This code may look a bit paranoid, but it's supposed to cooperate with * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ @@ -1816,9 +1814,6 @@ static inline void check_timer(void) pin2 = ioapic_i8259.pin; apic2 = ioapic_i8259.apic; - if (pin1 == 0) - timer_uses_ioapic_pin_0 = 1; - apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", vector, apic1, pin1, apic2, pin2); diff --git a/trunk/arch/x86_64/kernel/kprobes.c b/trunk/arch/x86_64/kernel/kprobes.c index fa1d19ca700a..1eaa5dae6174 100644 --- a/trunk/arch/x86_64/kernel/kprobes.c +++ b/trunk/arch/x86_64/kernel/kprobes.c @@ -514,13 +514,13 @@ static void __kprobes resume_execution(struct kprobe *p, *tos = orig_rip + (*tos - copy_rip); break; case 0xff: - if ((insn[1] & 0x30) == 0x10) { + if ((*insn & 0x30) == 0x10) { /* call absolute, indirect */ /* Fix return addr; rip is correct. */ next_rip = regs->rip; *tos = orig_rip + (*tos - copy_rip); - } else if (((insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */ - ((insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */ + } else if (((*insn & 0x31) == 0x20) || /* jmp near, absolute indirect */ + ((*insn & 0x31) == 0x21)) { /* jmp far, absolute indirect */ /* rip is correct. */ next_rip = regs->rip; } diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index 083da7e606b1..b17cf3eba359 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -968,17 +968,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) */ int irq = gsi; if (gsi < MAX_GSI_NUM) { - /* - * Retain the VIA chipset work-around (gsi > 15), but - * avoid a problem where the 8254 timer (IRQ0) is setup - * via an override (so it's not on pin 0 of the ioapic), - * and at the same time, the pin 0 interrupt is a PCI - * type. The gsi > 15 test could cause these two pins - * to be shared as IRQ0, and they are not shareable. - * So test for this condition, and if necessary, avoid - * the pin collision. - */ - if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0)) + if (gsi > 15) gsi = pci_irq++; /* * Don't assign IRQ used by ACPI SCI diff --git a/trunk/arch/x86_64/kernel/pci-gart.c b/trunk/arch/x86_64/kernel/pci-gart.c index 2480d3f08a47..9d3d76c85ae7 100644 --- a/trunk/arch/x86_64/kernel/pci-gart.c +++ b/trunk/arch/x86_64/kernel/pci-gart.c @@ -639,14 +639,6 @@ static int __init pci_iommu_init(void) return -1; } - i = 0; - for_all_nb(dev) - i++; - if (i > MAX_NB) { - printk(KERN_ERR "PCI-GART: Too many northbridges (%ld). Disabled\n", i); - return -1; - } - printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); aper_size = info.aper_size * 1024 * 1024; iommu_size = check_iommu_size(info.aper_base, aper_size); diff --git a/trunk/arch/x86_64/kernel/pci-nommu.c b/trunk/arch/x86_64/kernel/pci-nommu.c index 1f6ecc62061d..44adcc2d5e5b 100644 --- a/trunk/arch/x86_64/kernel/pci-nommu.c +++ b/trunk/arch/x86_64/kernel/pci-nommu.c @@ -12,10 +12,9 @@ static int check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) { if (hwdev && bus + size > *hwdev->dma_mask) { - if (*hwdev->dma_mask >= 0xffffffffULL) - printk(KERN_ERR - "nommu_%s: overflow %Lx+%lu of device mask %Lx\n", - name, (long long)bus, size, (long long)*hwdev->dma_mask); + printk(KERN_ERR + "nommu_%s: overflow %Lx+%lu of device mask %Lx\n", + name, (long long)bus, size, (long long)*hwdev->dma_mask); return 0; } return 1; diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index f0870bef24d1..ebc3c33b1c6c 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -571,28 +571,17 @@ static inline void copy_edd(void) #endif #define EBDA_ADDR_POINTER 0x40E - -unsigned __initdata ebda_addr; -unsigned __initdata ebda_size; - -static void discover_ebda(void) +static void __init reserve_ebda_region(void) { - /* + unsigned int addr; + /** * there is a real-mode segmented pointer pointing to the * 4K EBDA area at 0x40E */ - ebda_addr = *(unsigned short *)EBDA_ADDR_POINTER; - ebda_addr <<= 4; - - ebda_size = *(unsigned short *)(unsigned long)ebda_addr; - - /* Round EBDA up to pages */ - if (ebda_size == 0) - ebda_size = 1; - ebda_size <<= 10; - ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE); - if (ebda_size > 64*1024) - ebda_size = 64*1024; + addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER); + addr <<= 4; + if (addr) + reserve_bootmem_generic(addr, PAGE_SIZE); } void __init setup_arch(char **cmdline_p) @@ -638,8 +627,6 @@ void __init setup_arch(char **cmdline_p) check_efer(); - discover_ebda(); - init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); dmi_scan_machine(); @@ -682,8 +669,7 @@ void __init setup_arch(char **cmdline_p) reserve_bootmem_generic(0, PAGE_SIZE); /* reserve ebda region */ - if (ebda_addr) - reserve_bootmem_generic(ebda_addr, ebda_size); + reserve_ebda_region(); #ifdef CONFIG_SMP /* diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index cea335e8746c..2700b1375c1f 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -102,8 +102,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) { if (regs->eflags & X86_EFLAGS_IF) local_irq_disable(); - /* Make sure to not schedule here because we could be running - on an exception stack. */ preempt_enable_no_resched(); } @@ -387,7 +385,6 @@ void out_of_line_bug(void) static DEFINE_SPINLOCK(die_lock); static int die_owner = -1; -static unsigned int die_nest_count; unsigned __kprobes long oops_begin(void) { @@ -402,7 +399,6 @@ unsigned __kprobes long oops_begin(void) else spin_lock(&die_lock); } - die_nest_count++; die_owner = cpu; console_verbose(); bust_spinlocks(1); @@ -413,13 +409,7 @@ void __kprobes oops_end(unsigned long flags) { die_owner = -1; bust_spinlocks(0); - die_nest_count--; - if (die_nest_count) - /* We still own the lock */ - local_irq_restore(flags); - else - /* Nest count reaches zero, release the lock. */ - spin_unlock_irqrestore(&die_lock, flags); + spin_unlock_irqrestore(&die_lock, flags); if (panic_on_oops) panic("Oops"); } @@ -474,8 +464,6 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs) panic("nmi watchdog"); printk("console shuts up ...\n"); oops_end(flags); - nmi_exit(); - local_irq_enable(); do_exit(SIGSEGV); } @@ -485,6 +473,8 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, { struct task_struct *tsk = current; + conditional_sti(regs); + tsk->thread.error_code = error_code; tsk->thread.trap_no = trapnr; @@ -521,7 +511,6 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ == NOTIFY_STOP) \ return; \ - conditional_sti(regs); \ do_trap(trapnr, signr, str, regs, error_code, NULL); \ } @@ -536,7 +525,6 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ == NOTIFY_STOP) \ return; \ - conditional_sti(regs); \ do_trap(trapnr, signr, str, regs, error_code, &info); \ } @@ -550,17 +538,7 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) DO_ERROR(18, SIGSEGV, "reserved", reserved) - -/* Runs on IST stack */ -asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code) -{ - if (notify_die(DIE_TRAP, "stack segment", regs, error_code, - 12, SIGBUS) == NOTIFY_STOP) - return; - preempt_conditional_sti(regs); - do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL); - preempt_conditional_cli(regs); -} +DO_ERROR(12, SIGBUS, "stack segment", stack_segment) asmlinkage void do_double_fault(struct pt_regs * regs, long error_code) { @@ -694,9 +672,8 @@ asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code) if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) { return; } - preempt_conditional_sti(regs); do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); - preempt_conditional_cli(regs); + return; } /* Help handler running on IST stack to switch back to user stack diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index e1513532df29..15ae9fcd65a7 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -34,10 +34,7 @@ static nodemask_t nodes_found __initdata; static struct bootnode nodes[MAX_NUMNODES] __initdata; static struct bootnode nodes_add[MAX_NUMNODES] __initdata; static int found_add_area __initdata; -int hotadd_percent __initdata = 0; -#ifndef RESERVE_HOTADD -#define hotadd_percent 0 /* Ignore all settings */ -#endif +int hotadd_percent __initdata = 10; static u8 pxm2node[256] = { [0 ... 255] = 0xff }; /* Too small nodes confuse the VM badly. Usually they result @@ -106,7 +103,6 @@ static __init void bad_srat(void) int i; printk(KERN_ERR "SRAT: SRAT not used.\n"); acpi_numa = -1; - found_add_area = 0; for (i = 0; i < MAX_LOCAL_APIC; i++) apicid_to_node[i] = NUMA_NO_NODE; for (i = 0; i < MAX_NUMNODES; i++) @@ -158,8 +154,7 @@ 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_table_processor_affinity)) { - bad_srat(); + if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) { bad_srat(); return; } if (pa->flags.enabled == 0) @@ -196,17 +191,15 @@ static int hotadd_enough_memory(struct bootnode *nd) allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE; allowed = (allowed / 100) * hotadd_percent; if (allocated + mem > allowed) { - unsigned long range; /* Give them at least part of their hotadd memory upto hotadd_percent It would be better to spread the limit out over multiple hotplug areas, but that is too complicated right now */ if (allocated >= allowed) return 0; - range = allowed - allocated; - pages = (range / PAGE_SIZE); + pages = (allowed - allocated + mem) / sizeof(struct page); mem = pages * sizeof(struct page); - nd->end = nd->start + range; + nd->end = nd->start + pages*PAGE_SIZE; } /* Not completely fool proof, but a good sanity check */ addr = find_e820_area(last_area_end, end_pfn<queuelist, pos); - /* - * most requeues happen because of a busy condition, don't - * force unplug of the queue for that case. - */ - unplug_it = 0; break; default: @@ -413,7 +407,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) BUG(); } - if (unplug_it && blk_queue_plugged(q)) { + if (blk_queue_plugged(q)) { int nrq = q->rq.count[READ] + q->rq.count[WRITE] - q->in_flight; diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 7eb36c53f4b7..e5041a02e21f 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -1732,21 +1732,8 @@ void blk_run_queue(struct request_queue *q) spin_lock_irqsave(q->queue_lock, flags); blk_remove_plug(q); - - /* - * Only recurse once to avoid overrunning the stack, let the unplug - * handling reinvoke the handler shortly if we already got there. - */ - if (!elv_queue_empty(q)) { - if (!test_and_set_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) { - q->request_fn(q); - clear_bit(QUEUE_FLAG_REENTER, &q->queue_flags); - } else { - blk_plug_device(q); - kblockd_schedule_work(&q->unplug_work); - } - } - + if (!elv_queue_empty(q)) + q->request_fn(q); spin_unlock_irqrestore(q->queue_lock, flags); } EXPORT_SYMBOL(blk_run_queue); @@ -3452,12 +3439,7 @@ void end_that_request_last(struct request *req, int uptodate) if (unlikely(laptop_mode) && blk_fs_request(req)) laptop_io_completion(); - /* - * Account IO completion. bar_rq isn't accounted as a normal - * IO on queueing nor completion. Accounting the containing - * request is enough. - */ - if (disk && blk_fs_request(req) && req != &req->q->bar_rq) { + if (disk && blk_fs_request(req)) { unsigned long duration = jiffies - req->start_time; const int rw = rq_data_dir(req); diff --git a/trunk/drivers/base/class.c b/trunk/drivers/base/class.c index b1ea4df85c7d..0e71dff327cd 100644 --- a/trunk/drivers/base/class.c +++ b/trunk/drivers/base/class.c @@ -456,35 +456,6 @@ static void class_device_remove_attrs(struct class_device * cd) } } -static int class_device_add_groups(struct class_device * cd) -{ - int i; - int error = 0; - - if (cd->groups) { - for (i = 0; cd->groups[i]; i++) { - error = sysfs_create_group(&cd->kobj, cd->groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&cd->kobj, cd->groups[i]); - goto out; - } - } - } -out: - return error; -} - -static void class_device_remove_groups(struct class_device * cd) -{ - int i; - if (cd->groups) { - for (i = 0; cd->groups[i]; i++) { - sysfs_remove_group(&cd->kobj, cd->groups[i]); - } - } -} - static ssize_t show_dev(struct class_device *class_dev, char *buf) { return print_dev_t(buf, class_dev->devt); @@ -588,8 +559,6 @@ int class_device_add(struct class_device *class_dev) class_name); } - class_device_add_groups(class_dev); - kobject_uevent(&class_dev->kobj, KOBJ_ADD); /* notify any interfaces this device is now here */ @@ -703,7 +672,6 @@ void class_device_del(struct class_device *class_dev) if (class_dev->devt_attr) class_device_remove_file(class_dev, class_dev->devt_attr); class_device_remove_attrs(class_dev); - class_device_remove_groups(class_dev); kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); kobject_del(&class_dev->kobj); diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index 0c99ae6a3407..472318205236 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -86,9 +86,18 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count) static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); static void fw_class_dev_release(struct class_device *class_dev); +int firmware_class_uevent(struct class_device *dev, char **envp, + int num_envp, char *buffer, int buffer_size); -static int firmware_class_uevent(struct class_device *class_dev, char **envp, - int num_envp, char *buffer, int buffer_size) +static struct class firmware_class = { + .name = "firmware", + .uevent = firmware_class_uevent, + .release = fw_class_dev_release, +}; + +int +firmware_class_uevent(struct class_device *class_dev, char **envp, + int num_envp, char *buffer, int buffer_size) { struct firmware_priv *fw_priv = class_get_devdata(class_dev); int i = 0, len = 0; @@ -107,12 +116,6 @@ static int firmware_class_uevent(struct class_device *class_dev, char **envp, return 0; } -static struct class firmware_class = { - .name = "firmware", - .uevent = firmware_class_uevent, - .release = fw_class_dev_release, -}; - static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf) { @@ -490,6 +493,25 @@ release_firmware(const struct firmware *fw) } } +/** + * register_firmware: - provide a firmware image for later usage + * @name: name of firmware image file + * @data: buffer pointer for the firmware image + * @size: size of the data buffer area + * + * Make sure that @data will be available by requesting firmware @name. + * + * Note: This will not be possible until some kind of persistence + * is available. + **/ +void +register_firmware(const char *name, const u8 *data, size_t size) +{ + /* This is meaningless without firmware caching, so until we + * decide if firmware caching is reasonable just leave it as a + * noop */ +} + /* Async support */ struct firmware_work { struct work_struct work; @@ -608,3 +630,4 @@ module_exit(firmware_class_exit); EXPORT_SYMBOL(release_firmware); EXPORT_SYMBOL(request_firmware); EXPORT_SYMBOL(request_firmware_nowait); +EXPORT_SYMBOL(register_firmware); diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c index c688c25992e4..f73446f580df 100644 --- a/trunk/drivers/block/ub.c +++ b/trunk/drivers/block/ub.c @@ -536,9 +536,6 @@ static void ub_cleanup(struct ub_dev *sc) kfree(lun); } - usb_set_intfdata(sc->intf, NULL); - usb_put_intf(sc->intf); - usb_put_dev(sc->dev); kfree(sc); } @@ -2224,12 +2221,7 @@ static int ub_probe(struct usb_interface *intf, // sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; usb_set_intfdata(intf, sc); usb_get_dev(sc->dev); - /* - * Since we give the interface struct to the block level through - * disk->driverfs_dev, we have to pin it. Otherwise, block_uevent - * oopses on close after a disconnect (kernels 2.6.16 and up). - */ - usb_get_intf(sc->intf); + // usb_get_intf(sc->intf); /* Do we need this? */ snprintf(sc->name, 12, DRV_NAME "(%d.%d)", sc->dev->bus->busnum, sc->dev->devnum); @@ -2294,7 +2286,7 @@ static int ub_probe(struct usb_interface *intf, err_dev_desc: usb_set_intfdata(intf, NULL); - usb_put_intf(sc->intf); + // usb_put_intf(sc->intf); usb_put_dev(sc->dev); kfree(sc); err_core: @@ -2469,6 +2461,12 @@ static void ub_disconnect(struct usb_interface *intf) * and no URBs left in transit. */ + usb_set_intfdata(intf, NULL); + // usb_put_intf(sc->intf); + sc->intf = NULL; + usb_put_dev(sc->dev); + sc->dev = NULL; + ub_put(sc); } diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 78d928f9d9f1..402296670d3a 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -291,7 +291,7 @@ config SX config RIO tristate "Specialix RIO system support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && !64BIT help This is a driver for the Specialix RIO, a smart serial card which drives an outboard box that can support up to 128 ports. Product diff --git a/trunk/drivers/char/pcmcia/cm4000_cs.c b/trunk/drivers/char/pcmcia/cm4000_cs.c index 128b2632512d..02114a0bd0d9 100644 --- a/trunk/drivers/char/pcmcia/cm4000_cs.c +++ b/trunk/drivers/char/pcmcia/cm4000_cs.c @@ -1981,6 +1981,10 @@ static int __init cmm_init(void) if (!cmm_class) return -1; + rc = pcmcia_register_driver(&cm4000_driver); + if (rc < 0) + return rc; + major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); if (major < 0) { printk(KERN_WARNING MODULE_NAME @@ -1988,12 +1992,6 @@ static int __init cmm_init(void) return -1; } - rc = pcmcia_register_driver(&cm4000_driver); - if (rc < 0) { - unregister_chrdev(major, DEVICE_NAME); - return rc; - } - return 0; } diff --git a/trunk/drivers/char/pcmcia/cm4040_cs.c b/trunk/drivers/char/pcmcia/cm4040_cs.c index 47a8465bf95b..29efa64580a8 100644 --- a/trunk/drivers/char/pcmcia/cm4040_cs.c +++ b/trunk/drivers/char/pcmcia/cm4040_cs.c @@ -724,19 +724,16 @@ static int __init cm4040_init(void) if (!cmx_class) return -1; + rc = pcmcia_register_driver(&reader_driver); + if (rc < 0) + return rc; + major = register_chrdev(0, DEVICE_NAME, &reader_fops); if (major < 0) { printk(KERN_WARNING MODULE_NAME ": could not get major number\n"); return -1; } - - rc = pcmcia_register_driver(&reader_driver); - if (rc < 0) { - unregister_chrdev(major, DEVICE_NAME); - return rc; - } - return 0; } diff --git a/trunk/drivers/char/rio/host.h b/trunk/drivers/char/rio/host.h index 179cdbea712b..3ec73d1a279a 100644 --- a/trunk/drivers/char/rio/host.h +++ b/trunk/drivers/char/rio/host.h @@ -33,6 +33,12 @@ #ifndef __rio_host_h__ #define __rio_host_h__ +#ifdef SCCS_LABELS +#ifndef lint +static char *_host_h_sccs_ = "@(#)host.h 1.2"; +#endif +#endif + /* ** the host structure - one per host card in the system. */ @@ -71,6 +77,9 @@ struct Host { #define RC_STARTUP 1 #define RC_RUNNING 2 #define RC_STUFFED 3 +#define RC_SOMETHING 4 +#define RC_SOMETHING_NEW 5 +#define RC_SOMETHING_ELSE 6 #define RC_READY 7 #define RUN_STATE 7 /* diff --git a/trunk/drivers/char/rio/rioboot.c b/trunk/drivers/char/rio/rioboot.c index 290143addd34..acda9326c2ef 100644 --- a/trunk/drivers/char/rio/rioboot.c +++ b/trunk/drivers/char/rio/rioboot.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/rio/rioctrl.c b/trunk/drivers/char/rio/rioctrl.c index 75b2557c37ec..d31aba62bb7f 100644 --- a/trunk/drivers/char/rio/rioctrl.c +++ b/trunk/drivers/char/rio/rioctrl.c @@ -1394,17 +1394,14 @@ int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd) return RIO_FAIL; } - if ((PortP->InUse == (typeof(PortP->InUse))-1) || - !(CmdBlkP = RIOGetCmdBlk())) { - rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block " - "for command %d on port %d\n", Cmd, PortP->PortNum); + if (((int) ((char) PortP->InUse) == -1) || !(CmdBlkP = RIOGetCmdBlk())) { + rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n", Cmd, PortP->PortNum); return RIO_FAIL; } - rio_dprintk(RIO_DEBUG_CTRL, "Command blk %p - InUse now %d\n", - CmdBlkP, PortP->InUse); + rio_dprintk(RIO_DEBUG_CTRL, "Command blk %p - InUse now %d\n", CmdBlkP, PortP->InUse); - PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0]; + PktCmdP = (struct PktCmd_M *) &CmdBlkP->Packet.data[0]; CmdBlkP->Packet.src_unit = 0; if (PortP->SecondBlock) @@ -1428,46 +1425,38 @@ int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd) switch (Cmd) { case MEMDUMP: - rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p " - "(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr); + rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p (addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr); PktCmdP->SubCommand = MEMDUMP; PktCmdP->SubAddr = SubCmd.Addr; break; case FCLOSE: - rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n", - CmdBlkP); + rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n", CmdBlkP); break; case READ_REGISTER: - rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) " - "command blk %p\n", (int) SubCmd.Addr, CmdBlkP); + rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk %p\n", (int) SubCmd.Addr, CmdBlkP); PktCmdP->SubCommand = READ_REGISTER; PktCmdP->SubAddr = SubCmd.Addr; break; case RESUME: - rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n", - CmdBlkP); + rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n", CmdBlkP); break; case RFLUSH: - rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n", - CmdBlkP); + rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n", CmdBlkP); CmdBlkP->PostFuncP = RIORFlushEnable; break; case SUSPEND: - rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n", - CmdBlkP); + rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n", CmdBlkP); break; case MGET: - rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n", - CmdBlkP); + rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n", CmdBlkP); break; case MSET: case MBIC: case MBIS: CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; - rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command " - "blk %p\n", CmdBlkP); + rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk %p\n", CmdBlkP); break; case WFLUSH: @@ -1476,14 +1465,12 @@ int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd) ** allowed then we should not bother sending any more to the ** RTA. */ - if (PortP->WflushFlag == (typeof(PortP->WflushFlag))-1) { - rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, " - "WflushFlag about to wrap!"); + if ((int) ((char) PortP->WflushFlag) == (int) -1) { + rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!"); RIOFreeCmdBlk(CmdBlkP); return (RIO_FAIL); } else { - rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command " - "blk %p\n", CmdBlkP); + rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command blk %p\n", CmdBlkP); CmdBlkP->PostFuncP = RIOWFlushMark; } break; diff --git a/trunk/drivers/char/rio/rioioctl.h b/trunk/drivers/char/rio/rioioctl.h index e8af5b30519e..14b83fae75c8 100644 --- a/trunk/drivers/char/rio/rioioctl.h +++ b/trunk/drivers/char/rio/rioioctl.h @@ -33,6 +33,10 @@ #ifndef __rioioctl_h__ #define __rioioctl_h__ +#ifdef SCCS_LABELS +static char *_rioioctl_h_sccs_ = "@(#)rioioctl.h 1.2"; +#endif + /* ** RIO device driver - user ioctls and associated structures. */ @@ -40,13 +44,55 @@ struct portStats { int port; int gather; - unsigned long txchars; - unsigned long rxchars; - unsigned long opens; - unsigned long closes; - unsigned long ioctls; + ulong txchars; + ulong rxchars; + ulong opens; + ulong closes; + ulong ioctls; }; + +#define rIOC ('r'<<8) +#define TCRIOSTATE (rIOC | 1) +#define TCRIOXPON (rIOC | 2) +#define TCRIOXPOFF (rIOC | 3) +#define TCRIOXPCPS (rIOC | 4) +#define TCRIOXPRINT (rIOC | 5) +#define TCRIOIXANYON (rIOC | 6) +#define TCRIOIXANYOFF (rIOC | 7) +#define TCRIOIXONON (rIOC | 8) +#define TCRIOIXONOFF (rIOC | 9) +#define TCRIOMBIS (rIOC | 10) +#define TCRIOMBIC (rIOC | 11) +#define TCRIOTRIAD (rIOC | 12) +#define TCRIOTSTATE (rIOC | 13) + +/* +** 15.10.1998 ARG - ESIL 0761 part fix +** Add RIO ioctls for manipulating RTS and CTS flow control, (as LynxOS +** appears to not support hardware flow control). +*/ +#define TCRIOCTSFLOWEN (rIOC | 14) /* enable CTS flow control */ +#define TCRIOCTSFLOWDIS (rIOC | 15) /* disable CTS flow control */ +#define TCRIORTSFLOWEN (rIOC | 16) /* enable RTS flow control */ +#define TCRIORTSFLOWDIS (rIOC | 17) /* disable RTS flow control */ + +/* +** 09.12.1998 ARG - ESIL 0776 part fix +** Definition for 'RIOC' also appears in daemon.h, so we'd better do a +** #ifndef here first. +** 'RIO_QUICK_CHECK' also #define'd here as this ioctl is now +** allowed to be used by customers. +** +** 05.02.1999 ARG - +** This is what I've decied to do with ioctls etc., which are intended to be +** invoked from users applications : +** Anything that needs to be defined here will be removed from daemon.h, that +** way it won't end up having to be defined/maintained in two places. The only +** consequence of this is that this file should now be #include'd by daemon.h +** +** 'stats' ioctls now #define'd here as they are to be used by customers. +*/ #define RIOC ('R'<<8)|('i'<<16)|('o'<<24) #define RIO_QUICK_CHECK (RIOC | 105) diff --git a/trunk/drivers/char/tpm/Kconfig b/trunk/drivers/char/tpm/Kconfig index fe00c7dfb649..1efde3b27619 100644 --- a/trunk/drivers/char/tpm/Kconfig +++ b/trunk/drivers/char/tpm/Kconfig @@ -22,7 +22,7 @@ config TCG_TPM config TCG_TIS tristate "TPM Interface Specification 1.2 Interface" - depends on TCG_TPM && PNPACPI + depends on TCG_TPM ---help--- If you have a TPM security chip that is compliant with the TCG TIS 1.2 TPM specification say Yes and it will be accessible diff --git a/trunk/drivers/char/tpm/tpm.h b/trunk/drivers/char/tpm/tpm.h index 050ced247f68..54a4c804e25f 100644 --- a/trunk/drivers/char/tpm/tpm.h +++ b/trunk/drivers/char/tpm/tpm.h @@ -140,7 +140,7 @@ extern int tpm_pm_resume(struct device *); extern struct dentry ** tpm_bios_log_setup(char *); extern void tpm_bios_log_teardown(struct dentry **); #else -static inline struct dentry ** tpm_bios_log_setup(char *name) +static inline struct dentry* tpm_bios_log_setup(char *name) { return NULL; } diff --git a/trunk/drivers/char/tpm/tpm_tis.c b/trunk/drivers/char/tpm/tpm_tis.c index f621168f38ae..b9cae9a238bb 100644 --- a/trunk/drivers/char/tpm/tpm_tis.c +++ b/trunk/drivers/char/tpm/tpm_tis.c @@ -55,7 +55,7 @@ enum tis_int_flags { }; enum tis_defaults { - TIS_MEM_BASE = 0xFED40000, + TIS_MEM_BASE = 0xFED4000, TIS_MEM_LEN = 0x5000, TIS_SHORT_TIMEOUT = 750, /* ms */ TIS_LONG_TIMEOUT = 2000, /* 2 sec */ diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index a88b94a82b14..f07637a8f88f 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -398,7 +398,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, while (unlikely(size > copied)); return copied; } -EXPORT_SYMBOL(tty_insert_flip_string_flags); +EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); void tty_schedule_flip(struct tty_struct *tty) { diff --git a/trunk/drivers/char/watchdog/i8xx_tco.c b/trunk/drivers/char/watchdog/i8xx_tco.c index fa2ba9ebe42a..a13395e2c372 100644 --- a/trunk/drivers/char/watchdog/i8xx_tco.c +++ b/trunk/drivers/char/watchdog/i8xx_tco.c @@ -33,6 +33,11 @@ * 82801E (C-ICH) : document number 273599-001, 273645-002, * 82801EB (ICH5) : document number 252516-001, 252517-003, * 82801ER (ICH5R) : document number 252516-001, 252517-003, + * 82801FB (ICH6) : document number 301473-002, 301474-007, + * 82801FR (ICH6R) : document number 301473-002, 301474-007, + * 82801FBM (ICH6-M) : document number 301473-002, 301474-007, + * 82801FW (ICH6W) : document number 301473-001, 301474-007, + * 82801FRW (ICH6RW) : document number 301473-001, 301474-007 * * 20000710 Nils Faerber * Initial Version 0.01 @@ -61,10 +66,6 @@ * 20050807 Wim Van Sebroeck * 0.08 Make sure that the watchdog is only "armed" when started. * (Kernel Bug 4251) - * 20060416 Wim Van Sebroeck - * 0.09 Remove support for the ICH6, ICH6R, ICH6-M, ICH6W and ICH6RW and - * ICH7 chipsets. (See Kernel Bug 6031 - other code will support these - * chipsets) */ /* @@ -89,7 +90,7 @@ #include "i8xx_tco.h" /* Module and version information */ -#define TCO_VERSION "0.09" +#define TCO_VERSION "0.08" #define TCO_MODULE_NAME "i8xx TCO timer" #define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION #define PFX TCO_MODULE_NAME ": " @@ -390,6 +391,11 @@ static struct pci_device_id i8xx_tco_pci_tbl[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, /* End of list */ }; diff --git a/trunk/drivers/char/watchdog/s3c2410_wdt.c b/trunk/drivers/char/watchdog/s3c2410_wdt.c index 1ea04e9b2b0b..9dc54736e4eb 100644 --- a/trunk/drivers/char/watchdog/s3c2410_wdt.c +++ b/trunk/drivers/char/watchdog/s3c2410_wdt.c @@ -423,12 +423,6 @@ static int s3c2410wdt_probe(struct platform_device *pdev) if (tmr_atboot && started == 0) { printk(KERN_INFO PFX "Starting Watchdog Timer\n"); s3c2410wdt_start(); - } else if (!tmr_atboot) { - /* if we're not enabling the watchdog, then ensure it is - * disabled if it has been left running from the bootloader - * or other source */ - - s3c2410wdt_stop(); } return 0; diff --git a/trunk/drivers/char/watchdog/sc1200wdt.c b/trunk/drivers/char/watchdog/sc1200wdt.c index 20b88f9b7be2..515ce7572049 100644 --- a/trunk/drivers/char/watchdog/sc1200wdt.c +++ b/trunk/drivers/char/watchdog/sc1200wdt.c @@ -377,7 +377,7 @@ static int __init sc1200wdt_init(void) { int ret; - printk("%s\n", banner); + printk(banner); spin_lock_init(&sc1200wdt_lock); sema_init(&open_sem, 1); diff --git a/trunk/drivers/cpufreq/cpufreq_ondemand.c b/trunk/drivers/cpufreq/cpufreq_ondemand.c index 3e6ffcaa5af4..956d121cb161 100644 --- a/trunk/drivers/cpufreq/cpufreq_ondemand.c +++ b/trunk/drivers/cpufreq/cpufreq_ondemand.c @@ -74,8 +74,6 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ static DEFINE_MUTEX (dbs_mutex); static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); -static struct workqueue_struct *dbs_workq; - struct dbs_tuners { unsigned int sampling_rate; unsigned int sampling_down_factor; @@ -366,29 +364,23 @@ static void do_dbs_timer(void *data) mutex_lock(&dbs_mutex); for_each_online_cpu(i) dbs_check_cpu(i); - queue_delayed_work(dbs_workq, &dbs_work, - usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); + schedule_delayed_work(&dbs_work, + usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); mutex_unlock(&dbs_mutex); } static inline void dbs_timer_init(void) { INIT_WORK(&dbs_work, do_dbs_timer, NULL); - if (!dbs_workq) - dbs_workq = create_singlethread_workqueue("ondemand"); - if (!dbs_workq) { - printk(KERN_ERR "ondemand: Cannot initialize kernel thread\n"); - return; - } - queue_delayed_work(dbs_workq, &dbs_work, - usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); + schedule_delayed_work(&dbs_work, + usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); return; } static inline void dbs_timer_exit(void) { - if (dbs_workq) - cancel_rearming_delayed_workqueue(dbs_workq, &dbs_work); + cancel_delayed_work(&dbs_work); + return; } static int cpufreq_governor_dbs(struct cpufreq_policy *policy, @@ -497,12 +489,8 @@ static int __init cpufreq_gov_dbs_init(void) static void __exit cpufreq_gov_dbs_exit(void) { - /* Make sure that the scheduled work is indeed not running. - Assumes the timer has been cancelled first. */ - if (dbs_workq) { - flush_workqueue(dbs_workq); - destroy_workqueue(dbs_workq); - } + /* Make sure that the scheduled work is indeed not running */ + flush_scheduled_work(); cpufreq_unregister_governor(&cpufreq_gov_dbs); } diff --git a/trunk/drivers/i2c/busses/scx200_acb.c b/trunk/drivers/i2c/busses/scx200_acb.c index a140e4536a4e..8bd305e47f0d 100644 --- a/trunk/drivers/i2c/busses/scx200_acb.c +++ b/trunk/drivers/i2c/busses/scx200_acb.c @@ -133,9 +133,6 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status) outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); outb(ACBST_STASTR | ACBST_NEGACK, ACBST); - - /* Reset the status register */ - outb(0, ACBST); return; } @@ -231,10 +228,6 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface) timeout = jiffies + POLL_TIMEOUT; while (time_before(jiffies, timeout)) { status = inb(ACBST); - - /* Reset the status register to avoid the hang */ - outb(0, ACBST); - if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) { scx200_acb_machine(iface, status); return; @@ -422,6 +415,7 @@ static int __init scx200_acb_create(const char *text, int base, int index) struct scx200_acb_iface *iface; struct i2c_adapter *adapter; int rc; + char description[64]; iface = kzalloc(sizeof(*iface), GFP_KERNEL); if (!iface) { @@ -440,7 +434,10 @@ static int __init scx200_acb_create(const char *text, int base, int index) mutex_init(&iface->mutex); - if (!request_region(base, 8, adapter->name)) { + snprintf(description, sizeof(description), "%s ACCESS.bus [%s]", + text, adapter->name); + + if (request_region(base, 8, description) == 0) { printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", base, base + 8-1); rc = -EBUSY; @@ -527,9 +524,6 @@ static int __init scx200_acb_init(void) } else if (pci_dev_present(divil_pci)) rc = scx200_add_cs553x(); - /* If at least one bus was created, init must succeed */ - if (scx200_acb_list) - return 0; return rc; } diff --git a/trunk/drivers/ide/legacy/ide-cs.c b/trunk/drivers/ide/legacy/ide-cs.c index 602797a44208..4961f1e764a7 100644 --- a/trunk/drivers/ide/legacy/ide-cs.c +++ b/trunk/drivers/ide/legacy/ide-cs.c @@ -392,7 +392,6 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae), PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178), - PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178), PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b), PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c index ffca8b63ee79..78e30f803671 100644 --- a/trunk/drivers/ide/ppc/pmac.c +++ b/trunk/drivers/ide/ppc/pmac.c @@ -553,8 +553,6 @@ pmac_ide_init_hwif_ports(hw_regs_t *hw, if (irq != NULL) *irq = pmac_ide[ix].irq; - - hw->dev = &pmac_ide[ix].mdev->ofdev.dev; } #define PMAC_IDE_REG(x) ((void __iomem *)(IDE_DATA_REG+(x))) diff --git a/trunk/drivers/ieee1394/ohci1394.c b/trunk/drivers/ieee1394/ohci1394.c index 11f13778f139..19222878aae9 100644 --- a/trunk/drivers/ieee1394/ohci1394.c +++ b/trunk/drivers/ieee1394/ohci1394.c @@ -553,7 +553,7 @@ static void ohci_initialize(struct ti_ohci *ohci) * register content. * To actually enable physical responses is the job of our interrupt * handler which programs the physical request filter. */ - reg_write(ohci, OHCI1394_PhyUpperBound, 0x01000000); + reg_write(ohci, OHCI1394_PhyUpperBound, 0xffff0000); DBGMSG("physUpperBoundOffset=%08x", reg_read(ohci, OHCI1394_PhyUpperBound)); diff --git a/trunk/drivers/ieee1394/sbp2.c b/trunk/drivers/ieee1394/sbp2.c index 8a23fb54c693..f4206604db03 100644 --- a/trunk/drivers/ieee1394/sbp2.c +++ b/trunk/drivers/ieee1394/sbp2.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -118,8 +117,7 @@ MODULE_PARM_DESC(serialize_io, "Serialize I/O coming from scsi drivers (default */ static int max_sectors = SBP2_MAX_SECTORS; module_param(max_sectors, int, 0444); -MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported (default = " - __stringify(SBP2_MAX_SECTORS) ")"); +MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported (default = 255)"); /* * Exclusive login to sbp2 device? In most cases, the sbp2 driver should @@ -137,45 +135,18 @@ module_param(exclusive_login, int, 0644); MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device (default = 1)"); /* - * If any of the following workarounds is required for your device to work, - * please submit the kernel messages logged by sbp2 to the linux1394-devel - * mailing list. + * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on + * if your sbp2 device is not properly handling the SCSI inquiry command. + * This hack makes the inquiry look more like a typical MS Windows inquiry + * by enforcing 36 byte inquiry and avoiding access to mode_sense page 8. * - * - 128kB max transfer - * Limit transfer size. Necessary for some old bridges. - * - * - 36 byte inquiry - * When scsi_mod probes the device, let the inquiry command look like that - * from MS Windows. - * - * - skip mode page 8 - * Suppress sending of mode_sense for mode page 8 if the device pretends to - * support the SCSI Primary Block commands instead of Reduced Block Commands. - * - * - fix capacity - * Tell sd_mod to correct the last sector number reported by read_capacity. - * Avoids access beyond actual disk limits on devices with an off-by-one bug. - * Don't use this with devices which don't have this bug. - * - * - override internal blacklist - * Instead of adding to the built-in blacklist, use only the workarounds - * specified in the module load parameter. - * Useful if a blacklist entry interfered with a non-broken device. + * If force_inquiry_hack=1 is required for your device to work, + * please submit the logged sbp2_firmware_revision value of this device to + * the linux1394-devel mailing list. */ -static int sbp2_default_workarounds; -module_param_named(workarounds, sbp2_default_workarounds, int, 0644); -MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" - ", 128kB max transfer = " __stringify(SBP2_WORKAROUND_128K_MAX_TRANS) - ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) - ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) - ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) - ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) - ", or a combination)"); - -/* legacy parameter */ static int force_inquiry_hack; module_param(force_inquiry_hack, int, 0644); -MODULE_PARM_DESC(force_inquiry_hack, "Deprecated, use 'workarounds'"); +MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)"); /* * Export information about protocols/devices supported by this driver. @@ -295,55 +266,14 @@ static struct hpsb_protocol_driver sbp2_driver = { }; /* - * List of devices with known bugs. - * - * The firmware_revision field, masked with 0xffff00, is the best indicator - * for the type of bridge chip of a device. It yields a few false positives - * but this did not break correctly behaving devices so far. + * List of device firmwares that require the inquiry hack. + * Yields a few false positives but did not break other devices so far. */ -static const struct { - u32 firmware_revision; - u32 model_id; - unsigned workarounds; -} sbp2_workarounds_table[] = { - /* TSB42AA9 */ { - .firmware_revision = 0x002800, - .workarounds = SBP2_WORKAROUND_INQUIRY_36 | - SBP2_WORKAROUND_MODE_SENSE_8, - }, - /* Initio bridges, actually only needed for some older ones */ { - .firmware_revision = 0x000200, - .workarounds = SBP2_WORKAROUND_INQUIRY_36, - }, - /* Symbios bridge */ { - .firmware_revision = 0xa0b800, - .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, - }, - /* - * Note about the following Apple iPod blacklist entries: - * - * There are iPods (2nd gen, 3rd gen) with model_id==0. Since our - * matching logic treats 0 as a wildcard, we cannot match this ID - * without rewriting the matching routine. Fortunately these iPods - * do not feature the read_capacity bug according to one report. - * Read_capacity behaviour as well as model_id could change due to - * Apple-supplied firmware updates though. - */ - /* iPod 4th generation */ { - .firmware_revision = 0x0a2700, - .model_id = 0x000021, - .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, - }, - /* iPod mini */ { - .firmware_revision = 0x0a2700, - .model_id = 0x000023, - .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, - }, - /* iPod Photo */ { - .firmware_revision = 0x0a2700, - .model_id = 0x00007e, - .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, - } +static u32 sbp2_broken_inquiry_list[] = { + 0x00002800, /* Stefan Richter */ + /* DViCO Momobay CX-1 */ + 0x00000200 /* Andreas Plesch */ + /* QPS Fire DVDBurner */ }; /************************************** @@ -835,16 +765,11 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud /* Register the status FIFO address range. We could use the same FIFO * for targets at different nodes. However we need different FIFOs per - * target in order to support multi-unit devices. - * The FIFO is located out of the local host controller's physical range - * but, if possible, within the posted write area. Status writes will - * then be performed as unified transactions. This slightly reduces - * bandwidth usage, and some Prolific based devices seem to require it. - */ + * target in order to support multi-unit devices. */ scsi_id->status_fifo_addr = hpsb_allocate_and_register_addrspace( &sbp2_highlevel, ud->ne->host, &sbp2_ops, sizeof(struct sbp2_status_block), sizeof(quadlet_t), - 0x010000000000ULL, CSR1212_ALL_SPACE_END); + ~0ULL, ~0ULL); if (!scsi_id->status_fifo_addr) { SBP2_ERR("failed to allocate status FIFO address range"); goto failed_alloc; @@ -1525,8 +1450,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, struct csr1212_dentry *dentry; u64 management_agent_addr; u32 command_set_spec_id, command_set, unit_characteristics, - firmware_revision; - unsigned workarounds; + firmware_revision, workarounds; int i; SBP2_DEBUG_ENTER(); @@ -1582,8 +1506,12 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, case SBP2_FIRMWARE_REVISION_KEY: /* Firmware revision */ firmware_revision = kv->value.immediate; - SBP2_DEBUG("sbp2_firmware_revision = %x", - (unsigned int)firmware_revision); + if (force_inquiry_hack) + SBP2_INFO("sbp2_firmware_revision = %x", + (unsigned int)firmware_revision); + else + SBP2_DEBUG("sbp2_firmware_revision = %x", + (unsigned int)firmware_revision); break; default: @@ -1591,44 +1519,41 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, } } - workarounds = sbp2_default_workarounds; - if (force_inquiry_hack) { - SBP2_WARN("force_inquiry_hack is deprecated. " - "Use parameter 'workarounds' instead."); - workarounds |= SBP2_WORKAROUND_INQUIRY_36; - } + /* This is the start of our broken device checking. We try to hack + * around oddities and known defects. */ + workarounds = 0x0; - if (!(workarounds & SBP2_WORKAROUND_OVERRIDE)) - for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) { - if (sbp2_workarounds_table[i].firmware_revision && - sbp2_workarounds_table[i].firmware_revision != - (firmware_revision & 0xffff00)) - continue; - if (sbp2_workarounds_table[i].model_id && - sbp2_workarounds_table[i].model_id != ud->model_id) - continue; - workarounds |= sbp2_workarounds_table[i].workarounds; - break; + /* If the vendor id is 0xa0b8 (Symbios vendor id), then we have a + * bridge with 128KB max transfer size limitation. For sanity, we + * only voice this when the current max_sectors setting + * exceeds the 128k limit. By default, that is not the case. + * + * It would be really nice if we could detect this before the scsi + * host gets initialized. That way we can down-force the + * max_sectors to account for it. That is not currently + * possible. */ + if ((firmware_revision & 0xffff00) == + SBP2_128KB_BROKEN_FIRMWARE && + (max_sectors * 512) > (128*1024)) { + SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB max transfer size.", + NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid)); + SBP2_WARN("WARNING: Current max_sectors setting is larger than 128KB (%d sectors)!", + max_sectors); + workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER; + } + + /* Check for a blacklisted set of devices that require us to force + * a 36 byte host inquiry. This can be overriden as a module param + * (to force all hosts). */ + for (i = 0; i < ARRAY_SIZE(sbp2_broken_inquiry_list); i++) { + if ((firmware_revision & 0xffff00) == + sbp2_broken_inquiry_list[i]) { + SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround", + NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid)); + workarounds |= SBP2_BREAKAGE_INQUIRY_HACK; + break; /* No need to continue. */ } - - if (workarounds) - SBP2_INFO("Workarounds for node " NODE_BUS_FMT ": 0x%x " - "(firmware_revision 0x%06x, vendor_id 0x%06x," - " model_id 0x%06x)", - NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid), - workarounds, firmware_revision, - ud->vendor_id ? ud->vendor_id : ud->ne->vendor_id, - ud->model_id); - - /* We would need one SCSI host template for each target to adjust - * max_sectors on the fly, therefore warn only. */ - if (workarounds & SBP2_WORKAROUND_128K_MAX_TRANS && - (max_sectors * 512) > (128 * 1024)) - SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB " - "max transfer size. WARNING: Current max_sectors " - "setting is larger than 128KB (%d sectors)", - NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid), - max_sectors); + } /* If this is a logical unit directory entry, process the parent * to get the values. */ @@ -2522,25 +2447,19 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev) scsi_id->sdev = sdev; - if (scsi_id->workarounds & SBP2_WORKAROUND_INQUIRY_36) + if (force_inquiry_hack || + scsi_id->workarounds & SBP2_BREAKAGE_INQUIRY_HACK) { sdev->inquiry_len = 36; + sdev->skip_ms_page_8 = 1; + } return 0; } static int sbp2scsi_slave_configure(struct scsi_device *sdev) { - struct scsi_id_instance_data *scsi_id = - (struct scsi_id_instance_data *)sdev->host->hostdata[0]; - blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); sdev->use_10_for_rw = 1; sdev->use_10_for_ms = 1; - - if (sdev->type == TYPE_DISK && - scsi_id->workarounds & SBP2_WORKAROUND_MODE_SENSE_8) - sdev->skip_ms_page_8 = 1; - if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) - sdev->fix_capacity = 1; return 0; } @@ -2684,9 +2603,7 @@ static int sbp2_module_init(void) scsi_driver_template.cmd_per_lun = 1; } - if (sbp2_default_workarounds & SBP2_WORKAROUND_128K_MAX_TRANS && - (max_sectors * 512) > (128 * 1024)) - max_sectors = 128 * 1024 / 512; + /* Set max sectors (module load option). Default is 255 sectors. */ scsi_driver_template.max_sectors = max_sectors; /* Register our high level driver with 1394 stack */ diff --git a/trunk/drivers/ieee1394/sbp2.h b/trunk/drivers/ieee1394/sbp2.h index f4ccc9d0fba4..e2d357a9ea3a 100644 --- a/trunk/drivers/ieee1394/sbp2.h +++ b/trunk/drivers/ieee1394/sbp2.h @@ -226,6 +226,11 @@ struct sbp2_status_block { #define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e #define SBP2_SW_VERSION_ENTRY 0x00010483 +/* + * Other misc defines + */ +#define SBP2_128KB_BROKEN_FIRMWARE 0xa0b800 + /* * SCSI specific stuff */ @@ -234,13 +239,6 @@ struct sbp2_status_block { #define SBP2_MAX_SECTORS 255 /* Max sectors supported */ #define SBP2_MAX_CMDS 8 /* This should be safe */ -/* Flags for detected oddities and brokeness */ -#define SBP2_WORKAROUND_128K_MAX_TRANS 0x1 -#define SBP2_WORKAROUND_INQUIRY_36 0x2 -#define SBP2_WORKAROUND_MODE_SENSE_8 0x4 -#define SBP2_WORKAROUND_FIX_CAPACITY 0x8 -#define SBP2_WORKAROUND_OVERRIDE 0x100 - /* This is the two dma types we use for cmd_dma below */ enum cmd_dma_types { CMD_DMA_NONE, @@ -270,6 +268,10 @@ struct sbp2_command_info { }; +/* A list of flags for detected oddities and brokeness. */ +#define SBP2_BREAKAGE_128K_MAX_TRANSFER 0x1 +#define SBP2_BREAKAGE_INQUIRY_HACK 0x2 + struct sbp2scsi_host_info; /* @@ -343,7 +345,7 @@ struct scsi_id_instance_data { struct Scsi_Host *scsi_host; /* Device specific workarounds/brokeness */ - unsigned workarounds; + u32 workarounds; }; /* Sbp2 host data structure (one per IEEE1394 host) */ diff --git a/trunk/drivers/infiniband/core/cm.c b/trunk/drivers/infiniband/core/cm.c index 86fee43502cd..7cfedb8d9bcd 100644 --- a/trunk/drivers/infiniband/core/cm.c +++ b/trunk/drivers/infiniband/core/cm.c @@ -34,8 +34,6 @@ * * $Id: cm.c 2821 2005-07-08 17:07:28Z sean.hefty $ */ - -#include #include #include #include @@ -124,7 +122,7 @@ struct cm_id_private { struct rb_node service_node; struct rb_node sidr_id_node; spinlock_t lock; /* Do not acquire inside cm.lock */ - struct completion comp; + wait_queue_head_t wait; atomic_t refcount; struct ib_mad_send_buf *msg; @@ -161,7 +159,7 @@ static void cm_work_handler(void *data); static inline void cm_deref_id(struct cm_id_private *cm_id_priv) { if (atomic_dec_and_test(&cm_id_priv->refcount)) - complete(&cm_id_priv->comp); + wake_up(&cm_id_priv->wait); } static int cm_alloc_msg(struct cm_id_private *cm_id_priv, @@ -561,7 +559,7 @@ struct ib_cm_id *ib_create_cm_id(struct ib_device *device, goto error; spin_lock_init(&cm_id_priv->lock); - init_completion(&cm_id_priv->comp); + init_waitqueue_head(&cm_id_priv->wait); INIT_LIST_HEAD(&cm_id_priv->work_list); atomic_set(&cm_id_priv->work_count, -1); atomic_set(&cm_id_priv->refcount, 1); @@ -726,8 +724,8 @@ void ib_destroy_cm_id(struct ib_cm_id *cm_id) } cm_free_id(cm_id->local_id); - cm_deref_id(cm_id_priv); - wait_for_completion(&cm_id_priv->comp); + atomic_dec(&cm_id_priv->refcount); + wait_event(cm_id_priv->wait, !atomic_read(&cm_id_priv->refcount)); while ((work = cm_dequeue_work(cm_id_priv)) != NULL) cm_free_work(work); if (cm_id_priv->private_data && cm_id_priv->private_data_len) diff --git a/trunk/drivers/infiniband/core/mad.c b/trunk/drivers/infiniband/core/mad.c index 5ad41a64314c..469b6923a2e2 100644 --- a/trunk/drivers/infiniband/core/mad.c +++ b/trunk/drivers/infiniband/core/mad.c @@ -352,7 +352,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, INIT_WORK(&mad_agent_priv->local_work, local_completions, mad_agent_priv); atomic_set(&mad_agent_priv->refcount, 1); - init_completion(&mad_agent_priv->comp); + init_waitqueue_head(&mad_agent_priv->wait); return &mad_agent_priv->agent; @@ -467,7 +467,7 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device, mad_snoop_priv->agent.qp = port_priv->qp_info[qpn].qp; mad_snoop_priv->agent.port_num = port_num; mad_snoop_priv->mad_snoop_flags = mad_snoop_flags; - init_completion(&mad_snoop_priv->comp); + init_waitqueue_head(&mad_snoop_priv->wait); mad_snoop_priv->snoop_index = register_snoop_agent( &port_priv->qp_info[qpn], mad_snoop_priv); @@ -486,18 +486,6 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device, } EXPORT_SYMBOL(ib_register_mad_snoop); -static inline void deref_mad_agent(struct ib_mad_agent_private *mad_agent_priv) -{ - if (atomic_dec_and_test(&mad_agent_priv->refcount)) - complete(&mad_agent_priv->comp); -} - -static inline void deref_snoop_agent(struct ib_mad_snoop_private *mad_snoop_priv) -{ - if (atomic_dec_and_test(&mad_snoop_priv->refcount)) - complete(&mad_snoop_priv->comp); -} - static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv) { struct ib_mad_port_private *port_priv; @@ -521,8 +509,9 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv) flush_workqueue(port_priv->wq); ib_cancel_rmpp_recvs(mad_agent_priv); - deref_mad_agent(mad_agent_priv); - wait_for_completion(&mad_agent_priv->comp); + atomic_dec(&mad_agent_priv->refcount); + wait_event(mad_agent_priv->wait, + !atomic_read(&mad_agent_priv->refcount)); kfree(mad_agent_priv->reg_req); ib_dereg_mr(mad_agent_priv->agent.mr); @@ -540,8 +529,9 @@ static void unregister_mad_snoop(struct ib_mad_snoop_private *mad_snoop_priv) atomic_dec(&qp_info->snoop_count); spin_unlock_irqrestore(&qp_info->snoop_lock, flags); - deref_snoop_agent(mad_snoop_priv); - wait_for_completion(&mad_snoop_priv->comp); + atomic_dec(&mad_snoop_priv->refcount); + wait_event(mad_snoop_priv->wait, + !atomic_read(&mad_snoop_priv->refcount)); kfree(mad_snoop_priv); } @@ -610,7 +600,8 @@ static void snoop_send(struct ib_mad_qp_info *qp_info, spin_unlock_irqrestore(&qp_info->snoop_lock, flags); mad_snoop_priv->agent.snoop_handler(&mad_snoop_priv->agent, send_buf, mad_send_wc); - deref_snoop_agent(mad_snoop_priv); + if (atomic_dec_and_test(&mad_snoop_priv->refcount)) + wake_up(&mad_snoop_priv->wait); spin_lock_irqsave(&qp_info->snoop_lock, flags); } spin_unlock_irqrestore(&qp_info->snoop_lock, flags); @@ -635,7 +626,8 @@ static void snoop_recv(struct ib_mad_qp_info *qp_info, spin_unlock_irqrestore(&qp_info->snoop_lock, flags); mad_snoop_priv->agent.recv_handler(&mad_snoop_priv->agent, mad_recv_wc); - deref_snoop_agent(mad_snoop_priv); + if (atomic_dec_and_test(&mad_snoop_priv->refcount)) + wake_up(&mad_snoop_priv->wait); spin_lock_irqsave(&qp_info->snoop_lock, flags); } spin_unlock_irqrestore(&qp_info->snoop_lock, flags); @@ -976,7 +968,8 @@ void ib_free_send_mad(struct ib_mad_send_buf *send_buf) free_send_rmpp_list(mad_send_wr); kfree(send_buf->mad); - deref_mad_agent(mad_agent_priv); + if (atomic_dec_and_test(&mad_agent_priv->refcount)) + wake_up(&mad_agent_priv->wait); } EXPORT_SYMBOL(ib_free_send_mad); @@ -1764,7 +1757,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv, mad_recv_wc); if (!mad_recv_wc) { - deref_mad_agent(mad_agent_priv); + if (atomic_dec_and_test(&mad_agent_priv->refcount)) + wake_up(&mad_agent_priv->wait); return; } } @@ -1776,7 +1770,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, if (!mad_send_wr) { spin_unlock_irqrestore(&mad_agent_priv->lock, flags); ib_free_recv_mad(mad_recv_wc); - deref_mad_agent(mad_agent_priv); + if (atomic_dec_and_test(&mad_agent_priv->refcount)) + wake_up(&mad_agent_priv->wait); return; } ib_mark_mad_done(mad_send_wr); @@ -1795,7 +1790,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, } else { mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, mad_recv_wc); - deref_mad_agent(mad_agent_priv); + if (atomic_dec_and_test(&mad_agent_priv->refcount)) + wake_up(&mad_agent_priv->wait); } } @@ -2025,7 +2021,8 @@ void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, mad_send_wc); /* Release reference on agent taken when sending */ - deref_mad_agent(mad_agent_priv); + if (atomic_dec_and_test(&mad_agent_priv->refcount)) + wake_up(&mad_agent_priv->wait); return; done: spin_unlock_irqrestore(&mad_agent_priv->lock, flags); diff --git a/trunk/drivers/infiniband/core/mad_priv.h b/trunk/drivers/infiniband/core/mad_priv.h index b4fa28d3160f..6c9c133d71ef 100644 --- a/trunk/drivers/infiniband/core/mad_priv.h +++ b/trunk/drivers/infiniband/core/mad_priv.h @@ -37,7 +37,6 @@ #ifndef __IB_MAD_PRIV_H__ #define __IB_MAD_PRIV_H__ -#include #include #include #include @@ -109,7 +108,7 @@ struct ib_mad_agent_private { struct list_head rmpp_list; atomic_t refcount; - struct completion comp; + wait_queue_head_t wait; }; struct ib_mad_snoop_private { @@ -118,7 +117,7 @@ struct ib_mad_snoop_private { int snoop_index; int mad_snoop_flags; atomic_t refcount; - struct completion comp; + wait_queue_head_t wait; }; struct ib_mad_send_wr_private { diff --git a/trunk/drivers/infiniband/core/mad_rmpp.c b/trunk/drivers/infiniband/core/mad_rmpp.c index d4704e054e30..dfd4e588ce03 100644 --- a/trunk/drivers/infiniband/core/mad_rmpp.c +++ b/trunk/drivers/infiniband/core/mad_rmpp.c @@ -49,7 +49,7 @@ struct mad_rmpp_recv { struct list_head list; struct work_struct timeout_work; struct work_struct cleanup_work; - struct completion comp; + wait_queue_head_t wait; enum rmpp_state state; spinlock_t lock; atomic_t refcount; @@ -69,16 +69,10 @@ struct mad_rmpp_recv { u8 method; }; -static inline void deref_rmpp_recv(struct mad_rmpp_recv *rmpp_recv) -{ - if (atomic_dec_and_test(&rmpp_recv->refcount)) - complete(&rmpp_recv->comp); -} - static void destroy_rmpp_recv(struct mad_rmpp_recv *rmpp_recv) { - deref_rmpp_recv(rmpp_recv); - wait_for_completion(&rmpp_recv->comp); + atomic_dec(&rmpp_recv->refcount); + wait_event(rmpp_recv->wait, !atomic_read(&rmpp_recv->refcount)); ib_destroy_ah(rmpp_recv->ah); kfree(rmpp_recv); } @@ -259,7 +253,7 @@ create_rmpp_recv(struct ib_mad_agent_private *agent, goto error; rmpp_recv->agent = agent; - init_completion(&rmpp_recv->comp); + init_waitqueue_head(&rmpp_recv->wait); INIT_WORK(&rmpp_recv->timeout_work, recv_timeout_handler, rmpp_recv); INIT_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler, rmpp_recv); spin_lock_init(&rmpp_recv->lock); @@ -285,6 +279,12 @@ error: kfree(rmpp_recv); return NULL; } +static inline void deref_rmpp_recv(struct mad_rmpp_recv *rmpp_recv) +{ + if (atomic_dec_and_test(&rmpp_recv->refcount)) + wake_up(&rmpp_recv->wait); +} + static struct mad_rmpp_recv * find_rmpp_recv(struct ib_mad_agent_private *agent, struct ib_mad_recv_wc *mad_recv_wc) diff --git a/trunk/drivers/infiniband/core/sysfs.c b/trunk/drivers/infiniband/core/sysfs.c index 21f9282c1b25..15121cb5a1f6 100644 --- a/trunk/drivers/infiniband/core/sysfs.c +++ b/trunk/drivers/infiniband/core/sysfs.c @@ -336,7 +336,7 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr, switch (width) { case 4: ret = sprintf(buf, "%u\n", (out_mad->data[40 + offset / 8] >> - (4 - (offset % 8))) & 0xf); + (offset % 4)) & 0xf); break; case 8: ret = sprintf(buf, "%u\n", out_mad->data[40 + offset / 8]); diff --git a/trunk/drivers/infiniband/core/ucm.c b/trunk/drivers/infiniband/core/ucm.c index 9164a09b6ccd..f6a05965a4e8 100644 --- a/trunk/drivers/infiniband/core/ucm.c +++ b/trunk/drivers/infiniband/core/ucm.c @@ -32,8 +32,6 @@ * * $Id: ucm.c 2594 2005-06-13 19:46:02Z libor $ */ - -#include #include #include #include @@ -74,7 +72,7 @@ struct ib_ucm_file { struct ib_ucm_context { int id; - struct completion comp; + wait_queue_head_t wait; atomic_t ref; int events_reported; @@ -140,7 +138,7 @@ static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) static void ib_ucm_ctx_put(struct ib_ucm_context *ctx) { if (atomic_dec_and_test(&ctx->ref)) - complete(&ctx->comp); + wake_up(&ctx->wait); } static inline int ib_ucm_new_cm_id(int event) @@ -180,7 +178,7 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) return NULL; atomic_set(&ctx->ref, 1); - init_completion(&ctx->comp); + init_waitqueue_head(&ctx->wait); ctx->file = file; INIT_LIST_HEAD(&ctx->events); @@ -588,8 +586,8 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx); - ib_ucm_ctx_put(ctx); - wait_for_completion(&ctx->comp); + atomic_dec(&ctx->ref); + wait_event(ctx->wait, !atomic_read(&ctx->ref)); /* No new events will be generated after destroying the cm_id. */ ib_destroy_cm_id(ctx->cm_id); diff --git a/trunk/drivers/infiniband/core/uverbs_mem.c b/trunk/drivers/infiniband/core/uverbs_mem.c index efe147dbeb42..36a32c315668 100644 --- a/trunk/drivers/infiniband/core/uverbs_mem.c +++ b/trunk/drivers/infiniband/core/uverbs_mem.c @@ -211,10 +211,8 @@ void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem) */ work = kmalloc(sizeof *work, GFP_KERNEL); - if (!work) { - mmput(mm); + if (!work) return; - } INIT_WORK(&work->work, ib_umem_account, work); work->mm = mm; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_driver.c b/trunk/drivers/infiniband/hw/ipath/ipath_driver.c index 3697edafd6d2..398add4d4cb1 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_driver.c @@ -116,9 +116,10 @@ static int __devinit ipath_init_one(struct pci_dev *, #define PCI_DEVICE_ID_INFINIPATH_PE800 0x10 static const struct pci_device_id ipath_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) }, - { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) }, - { 0, } + {PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, + PCI_DEVICE_ID_INFINIPATH_HT)}, + {PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, + PCI_DEVICE_ID_INFINIPATH_PE800)}, }; MODULE_DEVICE_TABLE(pci, ipath_pci_tbl); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c index 798e13e14faf..1985b5dfa481 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -182,7 +182,7 @@ struct mthca_cmd_context { u8 status; }; -static int fw_cmd_doorbell = 0; +static int fw_cmd_doorbell = 1; module_param(fw_cmd_doorbell, int, 0644); MODULE_PARM_DESC(fw_cmd_doorbell, "post FW commands through doorbell page if nonzero " "(and supported by FW)"); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c index 205854e9c662..312cf90731ea 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c @@ -238,9 +238,9 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn, spin_lock(&dev->cq_table.lock); cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1)); - if (cq) - ++cq->refcount; + if (cq) + atomic_inc(&cq->refcount); spin_unlock(&dev->cq_table.lock); if (!cq) { @@ -254,10 +254,8 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn, if (cq->ibcq.event_handler) cq->ibcq.event_handler(&event, cq->ibcq.cq_context); - spin_lock(&dev->cq_table.lock); - if (!--cq->refcount) + if (atomic_dec_and_test(&cq->refcount)) wake_up(&cq->wait); - spin_unlock(&dev->cq_table.lock); } static inline int is_recv_cqe(struct mthca_cqe *cqe) @@ -269,13 +267,23 @@ static inline int is_recv_cqe(struct mthca_cqe *cqe) return !(cqe->is_send & 0x80); } -void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn, +void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, struct mthca_srq *srq) { + struct mthca_cq *cq; struct mthca_cqe *cqe; u32 prod_index; int nfreed = 0; + spin_lock_irq(&dev->cq_table.lock); + cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1)); + if (cq) + atomic_inc(&cq->refcount); + spin_unlock_irq(&dev->cq_table.lock); + + if (!cq) + return; + spin_lock_irq(&cq->lock); /* @@ -293,7 +301,7 @@ void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn, if (0) mthca_dbg(dev, "Cleaning QPN %06x from CQN %06x; ci %d, pi %d\n", - qpn, cq->cqn, cq->cons_index, prod_index); + qpn, cqn, cq->cons_index, prod_index); /* * Now sweep backwards through the CQ, removing CQ entries @@ -317,6 +325,8 @@ void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn, } spin_unlock_irq(&cq->lock); + if (atomic_dec_and_test(&cq->refcount)) + wake_up(&cq->wait); } void mthca_cq_resize_copy_cqes(struct mthca_cq *cq) @@ -811,7 +821,7 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, } spin_lock_init(&cq->lock); - cq->refcount = 1; + atomic_set(&cq->refcount, 1); init_waitqueue_head(&cq->wait); memset(cq_context, 0, sizeof *cq_context); @@ -886,17 +896,6 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, return err; } -static inline int get_cq_refcount(struct mthca_dev *dev, struct mthca_cq *cq) -{ - int c; - - spin_lock_irq(&dev->cq_table.lock); - c = cq->refcount; - spin_unlock_irq(&dev->cq_table.lock); - - return c; -} - void mthca_free_cq(struct mthca_dev *dev, struct mthca_cq *cq) { @@ -930,7 +929,6 @@ void mthca_free_cq(struct mthca_dev *dev, spin_lock_irq(&dev->cq_table.lock); mthca_array_clear(&dev->cq_table.cq, cq->cqn & (dev->limits.num_cqs - 1)); - --cq->refcount; spin_unlock_irq(&dev->cq_table.lock); if (dev->mthca_flags & MTHCA_FLAG_MSI_X) @@ -938,7 +936,8 @@ void mthca_free_cq(struct mthca_dev *dev, else synchronize_irq(dev->pdev->irq); - wait_event(cq->wait, !get_cq_refcount(dev, cq)); + atomic_dec(&cq->refcount); + wait_event(cq->wait, !atomic_read(&cq->refcount)); if (cq->is_kernel) { mthca_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h index f8160b8de090..4c1dcb4c1822 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h @@ -496,7 +496,7 @@ void mthca_free_cq(struct mthca_dev *dev, void mthca_cq_completion(struct mthca_dev *dev, u32 cqn); void mthca_cq_event(struct mthca_dev *dev, u32 cqn, enum ib_event_type event_type); -void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn, +void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, struct mthca_srq *srq); void mthca_cq_resize_copy_cqes(struct mthca_cq *cq); int mthca_alloc_cq_buf(struct mthca_dev *dev, struct mthca_cq_buf *buf, int nent); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_mr.c b/trunk/drivers/infiniband/hw/mthca/mthca_mr.c index a486dec1707e..25e1c1db9a40 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_mr.c @@ -761,7 +761,6 @@ void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) int __devinit mthca_init_mr_table(struct mthca_dev *dev) { - unsigned long addr; int err, i; err = mthca_alloc_init(&dev->mr_table.mpt_alloc, @@ -797,12 +796,9 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev) goto err_fmr_mpt; } - addr = pci_resource_start(dev->pdev, 4) + - ((pci_resource_len(dev->pdev, 4) - 1) & - dev->mr_table.mpt_base); - dev->mr_table.tavor_fmr.mpt_base = - ioremap(addr, (1 << i) * sizeof(struct mthca_mpt_entry)); + ioremap(dev->mr_table.mpt_base, + (1 << i) * sizeof (struct mthca_mpt_entry)); if (!dev->mr_table.tavor_fmr.mpt_base) { mthca_warn(dev, "MPT ioremap for FMR failed.\n"); @@ -810,12 +806,9 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev) goto err_fmr_mpt; } - addr = pci_resource_start(dev->pdev, 4) + - ((pci_resource_len(dev->pdev, 4) - 1) & - dev->mr_table.mtt_base); - dev->mr_table.tavor_fmr.mtt_base = - ioremap(addr, (1 << i) * MTHCA_MTT_SEG_SIZE); + ioremap(dev->mr_table.mtt_base, + (1 << i) * MTHCA_MTT_SEG_SIZE); if (!dev->mr_table.tavor_fmr.mtt_base) { mthca_warn(dev, "MTT ioremap for FMR failed.\n"); err = -ENOMEM; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_provider.h b/trunk/drivers/infiniband/hw/mthca/mthca_provider.h index 179a8f610d0f..6676a786d690 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_provider.h +++ b/trunk/drivers/infiniband/hw/mthca/mthca_provider.h @@ -139,12 +139,11 @@ struct mthca_ah { * a qp may be locked, with the send cq locked first. No other * nesting should be done. * - * Each struct mthca_cq/qp also has an ref count, protected by the - * corresponding table lock. The pointer from the cq/qp_table to the - * struct counts as one reference. This reference also is good for - * access through the consumer API, so modifying the CQ/QP etc doesn't - * need to take another reference. Access to a QP because of a - * completion being polled does not need a reference either. + * Each struct mthca_cq/qp also has an atomic_t ref count. The + * pointer from the cq/qp_table to the struct counts as one reference. + * This reference also is good for access through the consumer API, so + * modifying the CQ/QP etc doesn't need to take another reference. + * Access because of a completion being polled does need a reference. * * Finally, each struct mthca_cq/qp has a wait_queue_head_t for the * destroy function to sleep on. @@ -160,9 +159,8 @@ struct mthca_ah { * - decrement ref count; if zero, wake up waiters * * To destroy a CQ/QP, we can do the following: - * - lock cq/qp_table - * - remove pointer and decrement ref count - * - unlock cq/qp_table lock + * - lock cq/qp_table, remove pointer, unlock cq/qp_table lock + * - decrement ref count * - wait_event until ref count is zero * * It is the consumer's responsibilty to make sure that no QP @@ -199,7 +197,7 @@ struct mthca_cq_resize { struct mthca_cq { struct ib_cq ibcq; spinlock_t lock; - int refcount; + atomic_t refcount; int cqn; u32 cons_index; struct mthca_cq_buf buf; @@ -219,7 +217,7 @@ struct mthca_cq { struct mthca_srq { struct ib_srq ibsrq; spinlock_t lock; - int refcount; + atomic_t refcount; int srqn; int max; int max_gs; @@ -256,7 +254,7 @@ struct mthca_wq { struct mthca_qp { struct ib_qp ibqp; - int refcount; + atomic_t refcount; u32 qpn; int is_direct; u8 port; /* for SQP and memfree use only */ diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c index 07c13be07a4a..f37b0e367323 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c @@ -240,7 +240,7 @@ void mthca_qp_event(struct mthca_dev *dev, u32 qpn, spin_lock(&dev->qp_table.lock); qp = mthca_array_get(&dev->qp_table.qp, qpn & (dev->limits.num_qps - 1)); if (qp) - ++qp->refcount; + atomic_inc(&qp->refcount); spin_unlock(&dev->qp_table.lock); if (!qp) { @@ -257,10 +257,8 @@ void mthca_qp_event(struct mthca_dev *dev, u32 qpn, if (qp->ibqp.event_handler) qp->ibqp.event_handler(&event, qp->ibqp.qp_context); - spin_lock(&dev->qp_table.lock); - if (!--qp->refcount) + if (atomic_dec_and_test(&qp->refcount)) wake_up(&qp->wait); - spin_unlock(&dev->qp_table.lock); } static int to_mthca_state(enum ib_qp_state ib_state) @@ -835,10 +833,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) * entries and reinitialize the QP. */ if (new_state == IB_QPS_RESET && !qp->ibqp.uobject) { - mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq), qp->qpn, + mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn, qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); if (qp->ibqp.send_cq != qp->ibqp.recv_cq) - mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn, + mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn, qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); mthca_wq_init(&qp->sq); @@ -1098,7 +1096,7 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, int ret; int i; - qp->refcount = 1; + atomic_set(&qp->refcount, 1); init_waitqueue_head(&qp->wait); qp->state = IB_QPS_RESET; qp->atomic_rd_en = 0; @@ -1320,17 +1318,6 @@ int mthca_alloc_sqp(struct mthca_dev *dev, return err; } -static inline int get_qp_refcount(struct mthca_dev *dev, struct mthca_qp *qp) -{ - int c; - - spin_lock_irq(&dev->qp_table.lock); - c = qp->refcount; - spin_unlock_irq(&dev->qp_table.lock); - - return c; -} - void mthca_free_qp(struct mthca_dev *dev, struct mthca_qp *qp) { @@ -1352,14 +1339,14 @@ void mthca_free_qp(struct mthca_dev *dev, spin_lock(&dev->qp_table.lock); mthca_array_clear(&dev->qp_table.qp, qp->qpn & (dev->limits.num_qps - 1)); - --qp->refcount; spin_unlock(&dev->qp_table.lock); if (send_cq != recv_cq) spin_unlock(&recv_cq->lock); spin_unlock_irq(&send_cq->lock); - wait_event(qp->wait, !get_qp_refcount(dev, qp)); + atomic_dec(&qp->refcount); + wait_event(qp->wait, !atomic_read(&qp->refcount)); if (qp->state != IB_QPS_RESET) mthca_MODIFY_QP(dev, qp->state, IB_QPS_RESET, qp->qpn, 0, @@ -1371,10 +1358,10 @@ void mthca_free_qp(struct mthca_dev *dev, * unref the mem-free tables and free the QPN in our table. */ if (!qp->ibqp.uobject) { - mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq), qp->qpn, + mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn, qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); if (qp->ibqp.send_cq != qp->ibqp.recv_cq) - mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn, + mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn, qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); mthca_free_memfree(dev, qp); @@ -1727,7 +1714,23 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, ind = qp->rq.next_ind; - for (nreq = 0; wr; wr = wr->next) { + for (nreq = 0; wr; ++nreq, wr = wr->next) { + if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) { + nreq = 0; + + doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); + doorbell[1] = cpu_to_be32(qp->qpn << 8); + + wmb(); + + mthca_write64(doorbell, + dev->kar + MTHCA_RECEIVE_DOORBELL, + MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); + + qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB; + size0 = 0; + } + if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { mthca_err(dev, "RQ %06x full (%u head, %u tail," " %d max, %d nreq)\n", qp->qpn, @@ -1781,23 +1784,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, ++ind; if (unlikely(ind >= qp->rq.max)) ind -= qp->rq.max; - - ++nreq; - if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) { - nreq = 0; - - doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); - doorbell[1] = cpu_to_be32(qp->qpn << 8); - - wmb(); - - mthca_write64(doorbell, - dev->kar + MTHCA_RECEIVE_DOORBELL, - MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); - - qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB; - size0 = 0; - } } out: diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c index 1ea433291fa7..adcaf85355ae 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c @@ -241,7 +241,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, goto err_out_mailbox; spin_lock_init(&srq->lock); - srq->refcount = 1; + atomic_set(&srq->refcount, 1); init_waitqueue_head(&srq->wait); if (mthca_is_memfree(dev)) @@ -308,17 +308,6 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, return err; } -static inline int get_srq_refcount(struct mthca_dev *dev, struct mthca_srq *srq) -{ - int c; - - spin_lock_irq(&dev->srq_table.lock); - c = srq->refcount; - spin_unlock_irq(&dev->srq_table.lock); - - return c; -} - void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq) { struct mthca_mailbox *mailbox; @@ -340,10 +329,10 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq) spin_lock_irq(&dev->srq_table.lock); mthca_array_clear(&dev->srq_table.srq, srq->srqn & (dev->limits.num_srqs - 1)); - --srq->refcount; spin_unlock_irq(&dev->srq_table.lock); - wait_event(srq->wait, !get_srq_refcount(dev, srq)); + atomic_dec(&srq->refcount); + wait_event(srq->wait, !atomic_read(&srq->refcount)); if (!srq->ibsrq.uobject) { mthca_free_srq_buf(dev, srq); @@ -425,7 +414,7 @@ void mthca_srq_event(struct mthca_dev *dev, u32 srqn, spin_lock(&dev->srq_table.lock); srq = mthca_array_get(&dev->srq_table.srq, srqn & (dev->limits.num_srqs - 1)); if (srq) - ++srq->refcount; + atomic_inc(&srq->refcount); spin_unlock(&dev->srq_table.lock); if (!srq) { @@ -442,10 +431,8 @@ void mthca_srq_event(struct mthca_dev *dev, u32 srqn, srq->ibsrq.event_handler(&event, srq->ibsrq.srq_context); out: - spin_lock(&dev->srq_table.lock); - if (!--srq->refcount) + if (atomic_dec_and_test(&srq->refcount)) wake_up(&srq->wait); - spin_unlock(&dev->srq_table.lock); } /* diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index f887780e8093..4ca175553f9f 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -158,8 +158,10 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) if (priv->pkey == pkey) { unregister_netdev(priv->dev); ipoib_dev_cleanup(priv->dev); + list_del(&priv->list); - free_netdev(priv->dev); + + kfree(priv); ret = 0; break; diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.c b/trunk/drivers/infiniband/ulp/srp/ib_srp.c index 9cbdffa08dc2..5bb55742ada6 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.c +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.c @@ -340,10 +340,7 @@ static void srp_disconnect_target(struct srp_target_port *target) /* XXX should send SRP_I_LOGOUT request */ init_completion(&target->done); - if (ib_send_cm_dreq(target->cm_id, NULL, 0)) { - printk(KERN_DEBUG PFX "Sending CM DREQ failed\n"); - return; - } + ib_send_cm_dreq(target->cm_id, NULL, 0); wait_for_completion(&target->done); } @@ -354,6 +351,7 @@ static void srp_remove_work(void *target_ptr) spin_lock_irq(target->scsi_host->host_lock); if (target->state != SRP_TARGET_DEAD) { spin_unlock_irq(target->scsi_host->host_lock); + scsi_host_put(target->scsi_host); return; } target->state = SRP_TARGET_REMOVED; @@ -367,6 +365,8 @@ static void srp_remove_work(void *target_ptr) ib_destroy_cm_id(target->cm_id); srp_free_target_ib(target); scsi_host_put(target->scsi_host); + /* And another put to really free the target port... */ + scsi_host_put(target->scsi_host); } static int srp_connect_target(struct srp_target_port *target) @@ -409,34 +409,6 @@ static int srp_connect_target(struct srp_target_port *target) } } -static void srp_unmap_data(struct scsi_cmnd *scmnd, - struct srp_target_port *target, - struct srp_request *req) -{ - struct scatterlist *scat; - int nents; - - if (!scmnd->request_buffer || - (scmnd->sc_data_direction != DMA_TO_DEVICE && - scmnd->sc_data_direction != DMA_FROM_DEVICE)) - return; - - /* - * This handling of non-SG commands can be killed when the - * SCSI midlayer no longer generates non-SG commands. - */ - if (likely(scmnd->use_sg)) { - nents = scmnd->use_sg; - scat = scmnd->request_buffer; - } else { - nents = 1; - scat = &req->fake_sg; - } - - dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents, - scmnd->sc_data_direction); -} - static int srp_reconnect_target(struct srp_target_port *target) { struct ib_cm_id *new_cm_id; @@ -483,16 +455,16 @@ static int srp_reconnect_target(struct srp_target_port *target) list_for_each_entry(req, &target->req_queue, list) { req->scmnd->result = DID_RESET << 16; req->scmnd->scsi_done(req->scmnd); - srp_unmap_data(req->scmnd, target, req); } target->rx_head = 0; target->tx_head = 0; target->tx_tail = 0; - INIT_LIST_HEAD(&target->free_reqs); + target->req_head = 0; + for (i = 0; i < SRP_SQ_SIZE - 1; ++i) + target->req_ring[i].next = i + 1; + target->req_ring[SRP_SQ_SIZE - 1].next = -1; INIT_LIST_HEAD(&target->req_queue); - for (i = 0; i < SRP_SQ_SIZE; ++i) - list_add_tail(&target->req_ring[i].list, &target->free_reqs); ret = srp_connect_target(target); if (ret) @@ -617,10 +589,40 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, return len; } -static void srp_remove_req(struct srp_target_port *target, struct srp_request *req) +static void srp_unmap_data(struct scsi_cmnd *scmnd, + struct srp_target_port *target, + struct srp_request *req) +{ + struct scatterlist *scat; + int nents; + + if (!scmnd->request_buffer || + (scmnd->sc_data_direction != DMA_TO_DEVICE && + scmnd->sc_data_direction != DMA_FROM_DEVICE)) + return; + + /* + * This handling of non-SG commands can be killed when the + * SCSI midlayer no longer generates non-SG commands. + */ + if (likely(scmnd->use_sg)) { + nents = scmnd->use_sg; + scat = scmnd->request_buffer; + } else { + nents = 1; + scat = &req->fake_sg; + } + + dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents, + scmnd->sc_data_direction); +} + +static void srp_remove_req(struct srp_target_port *target, struct srp_request *req, + int index) { - srp_unmap_data(req->scmnd, target, req); - list_move_tail(&req->list, &target->free_reqs); + list_del(&req->list); + req->next = target->req_head; + target->req_head = index; } static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) @@ -645,7 +647,7 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) req->tsk_status = rsp->data[3]; complete(&req->done); } else { - scmnd = req->scmnd; + scmnd = req->scmnd; if (!scmnd) printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n", (unsigned long long) rsp->tag); @@ -663,11 +665,14 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt); + srp_unmap_data(scmnd, target, req); + if (!req->tsk_mgmt) { + req->scmnd = NULL; scmnd->host_scribble = (void *) -1L; scmnd->scsi_done(scmnd); - srp_remove_req(target, req); + srp_remove_req(target, req, rsp->tag & ~SRP_TAG_TSK_MGMT); } else req->cmd_done = 1; } @@ -854,6 +859,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, struct srp_request *req; struct srp_iu *iu; struct srp_cmd *cmd; + long req_index; int len; if (target->state == SRP_TARGET_CONNECTING) @@ -873,20 +879,22 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma, SRP_MAX_IU_LEN, DMA_TO_DEVICE); - req = list_entry(target->free_reqs.next, struct srp_request, list); + req_index = target->req_head; scmnd->scsi_done = done; scmnd->result = 0; - scmnd->host_scribble = (void *) (long) req->index; + scmnd->host_scribble = (void *) req_index; cmd = iu->buf; memset(cmd, 0, sizeof *cmd); cmd->opcode = SRP_CMD; cmd->lun = cpu_to_be64((u64) scmnd->device->lun << 48); - cmd->tag = req->index; + cmd->tag = req_index; memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len); + req = &target->req_ring[req_index]; + req->scmnd = scmnd; req->cmd = iu; req->cmd_done = 0; @@ -911,7 +919,8 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, goto err_unmap; } - list_move_tail(&req->list, &target->req_queue); + target->req_head = req->next; + list_add_tail(&req->list, &target->req_queue); return 0; @@ -1134,20 +1143,30 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) return 0; } -static int srp_send_tsk_mgmt(struct srp_target_port *target, - struct srp_request *req, u8 func) +static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) { + struct srp_target_port *target = host_to_target(scmnd->device->host); + struct srp_request *req; struct srp_iu *iu; struct srp_tsk_mgmt *tsk_mgmt; + int req_index; + int ret = FAILED; spin_lock_irq(target->scsi_host->host_lock); if (target->state == SRP_TARGET_DEAD || target->state == SRP_TARGET_REMOVED) { - req->scmnd->result = DID_BAD_TARGET << 16; + scmnd->result = DID_BAD_TARGET << 16; goto out; } + if (scmnd->host_scribble == (void *) -1L) + goto out; + + req_index = (long) scmnd->host_scribble; + printk(KERN_ERR "Abort for req_index %d\n", req_index); + + req = &target->req_ring[req_index]; init_completion(&req->done); iu = __srp_get_tx_iu(target); @@ -1158,10 +1177,10 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target, memset(tsk_mgmt, 0, sizeof *tsk_mgmt); tsk_mgmt->opcode = SRP_TSK_MGMT; - tsk_mgmt->lun = cpu_to_be64((u64) req->scmnd->device->lun << 48); - tsk_mgmt->tag = req->index | SRP_TAG_TSK_MGMT; + tsk_mgmt->lun = cpu_to_be64((u64) scmnd->device->lun << 48); + tsk_mgmt->tag = req_index | SRP_TAG_TSK_MGMT; tsk_mgmt->tsk_mgmt_func = func; - tsk_mgmt->task_tag = req->index; + tsk_mgmt->task_tag = req_index; if (__srp_post_send(target, iu, sizeof *tsk_mgmt)) goto out; @@ -1169,85 +1188,37 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target, req->tsk_mgmt = iu; spin_unlock_irq(target->scsi_host->host_lock); - if (!wait_for_completion_timeout(&req->done, msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS))) - return -1; - - return 0; - -out: - spin_unlock_irq(target->scsi_host->host_lock); - return -1; -} - -static int srp_find_req(struct srp_target_port *target, - struct scsi_cmnd *scmnd, - struct srp_request **req) -{ - if (scmnd->host_scribble == (void *) -1L) - return -1; - - *req = &target->req_ring[(long) scmnd->host_scribble]; - - return 0; -} - -static int srp_abort(struct scsi_cmnd *scmnd) -{ - struct srp_target_port *target = host_to_target(scmnd->device->host); - struct srp_request *req; - int ret = SUCCESS; - - printk(KERN_ERR "SRP abort called\n"); - - if (srp_find_req(target, scmnd, &req)) - return FAILED; - if (srp_send_tsk_mgmt(target, req, SRP_TSK_ABORT_TASK)) return FAILED; - spin_lock_irq(target->scsi_host->host_lock); if (req->cmd_done) { - srp_remove_req(target, req); + srp_remove_req(target, req, req_index); scmnd->scsi_done(scmnd); } else if (!req->tsk_status) { - srp_remove_req(target, req); + srp_remove_req(target, req, req_index); scmnd->result = DID_ABORT << 16; - } else - ret = FAILED; + ret = SUCCESS; + } +out: spin_unlock_irq(target->scsi_host->host_lock); - return ret; } -static int srp_reset_device(struct scsi_cmnd *scmnd) +static int srp_abort(struct scsi_cmnd *scmnd) { - struct srp_target_port *target = host_to_target(scmnd->device->host); - struct srp_request *req, *tmp; - - printk(KERN_ERR "SRP reset_device called\n"); - - if (srp_find_req(target, scmnd, &req)) - return FAILED; - if (srp_send_tsk_mgmt(target, req, SRP_TSK_LUN_RESET)) - return FAILED; - if (req->tsk_status) - return FAILED; - - spin_lock_irq(target->scsi_host->host_lock); + printk(KERN_ERR "SRP abort called\n"); - list_for_each_entry_safe(req, tmp, &target->req_queue, list) - if (req->scmnd->device == scmnd->device) { - req->scmnd->result = DID_RESET << 16; - req->scmnd->scsi_done(req->scmnd); - srp_remove_req(target, req); - } + return srp_send_tsk_mgmt(scmnd, SRP_TSK_ABORT_TASK); +} - spin_unlock_irq(target->scsi_host->host_lock); +static int srp_reset_device(struct scsi_cmnd *scmnd) +{ + printk(KERN_ERR "SRP reset_device called\n"); - return SUCCESS; + return srp_send_tsk_mgmt(scmnd, SRP_TSK_LUN_RESET); } static int srp_reset_host(struct scsi_cmnd *scmnd) @@ -1547,12 +1518,10 @@ static ssize_t srp_create_target(struct class_device *class_dev, INIT_WORK(&target->work, srp_reconnect_work, target); - INIT_LIST_HEAD(&target->free_reqs); + for (i = 0; i < SRP_SQ_SIZE - 1; ++i) + target->req_ring[i].next = i + 1; + target->req_ring[SRP_SQ_SIZE - 1].next = -1; INIT_LIST_HEAD(&target->req_queue); - for (i = 0; i < SRP_SQ_SIZE; ++i) { - target->req_ring[i].index = i; - list_add_tail(&target->req_ring[i].list, &target->free_reqs); - } ret = srp_parse_options(buf, target); if (ret) diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.h b/trunk/drivers/infiniband/ulp/srp/ib_srp.h index c5cd43aae860..bd7f7c3115de 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.h +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.h @@ -101,7 +101,7 @@ struct srp_request { */ struct scatterlist fake_sg; struct completion done; - short index; + short next; u8 cmd_done; u8 tsk_status; }; @@ -133,7 +133,7 @@ struct srp_target_port { unsigned tx_tail; struct srp_iu *tx_ring[SRP_SQ_SIZE + 1]; - struct list_head free_reqs; + int req_head; struct list_head req_queue; struct srp_request req_ring[SRP_SQ_SIZE]; diff --git a/trunk/drivers/isdn/capi/capi.c b/trunk/drivers/isdn/capi/capi.c index 173c899a1fb4..9b493f0becc4 100644 --- a/trunk/drivers/isdn/capi/capi.c +++ b/trunk/drivers/isdn/capi/capi.c @@ -1499,6 +1499,7 @@ static int __init capi_init(void) printk(KERN_ERR "capi20: unable to get major %d\n", capi_major); return major_ret; } + capi_major = major_ret; capi_class = class_create(THIS_MODULE, "capi"); if (IS_ERR(capi_class)) { unregister_chrdev(capi_major, "capi20"); diff --git a/trunk/drivers/isdn/gigaset/usb-gigaset.c b/trunk/drivers/isdn/gigaset/usb-gigaset.c index d86ab68114b0..bfb73fd5077e 100644 --- a/trunk/drivers/isdn/gigaset/usb-gigaset.c +++ b/trunk/drivers/isdn/gigaset/usb-gigaset.c @@ -710,8 +710,8 @@ static int gigaset_probe(struct usb_interface *interface, retval = -ENODEV; //FIXME /* See if the device offered us matches what we can accept */ - if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) || - (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) + if ((le16_to_cpu(udev->descriptor.idVendor != USB_M105_VENDOR_ID)) || + (le16_to_cpu(udev->descriptor.idProduct != USB_M105_PRODUCT_ID))) return -ENODEV; /* this starts to become ascii art... */ diff --git a/trunk/drivers/isdn/i4l/isdn_tty.c b/trunk/drivers/isdn/i4l/isdn_tty.c index 2ac90242d263..3585fb1f3344 100644 --- a/trunk/drivers/isdn/i4l/isdn_tty.c +++ b/trunk/drivers/isdn/i4l/isdn_tty.c @@ -2880,7 +2880,7 @@ isdn_tty_cmd_ATand(char **p, modem_info * info) p[0]++; i = 0; while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) && - (i < ISDN_LMSNLEN - 1)) + (i < ISDN_LMSNLEN)) m->lmsn[i++] = *p[0]++; m->lmsn[i] = '\0'; break; diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig index 626506234b76..3f5b64794542 100644 --- a/trunk/drivers/leds/Kconfig +++ b/trunk/drivers/leds/Kconfig @@ -4,11 +4,8 @@ menu "LED devices" config NEW_LEDS bool "LED Support" help - Say Y to enable Linux LED support. This allows control of supported - LEDs from both userspace and optionally, by kernel events (triggers). - - This is not related to standard keyboard LEDs which are controlled - via the input system. + Say Y to enable Linux LED support. This is not related to standard + keyboard LEDs which are controlled via the input system. config LEDS_CLASS tristate "LED Class Support" diff --git a/trunk/drivers/leds/led-class.c b/trunk/drivers/leds/led-class.c index c75d0ef1609c..b0b5d05fadd6 100644 --- a/trunk/drivers/leds/led-class.c +++ b/trunk/drivers/leds/led-class.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "leds.h" @@ -44,13 +43,9 @@ static ssize_t led_brightness_store(struct class_device *dev, ssize_t ret = -EINVAL; char *after; unsigned long state = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - if (*after && isspace(*after)) - count++; - - if (count == size) { - ret = count; + if (after - buf > 0) { + ret = after - buf; led_set_brightness(led_cdev, state); } diff --git a/trunk/drivers/leds/ledtrig-timer.c b/trunk/drivers/leds/ledtrig-timer.c index fbf141ef46ec..f484b5d6dbf8 100644 --- a/trunk/drivers/leds/ledtrig-timer.c +++ b/trunk/drivers/leds/ledtrig-timer.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "leds.h" @@ -70,15 +69,11 @@ static ssize_t led_delay_on_store(struct class_device *dev, const char *buf, int ret = -EINVAL; char *after; unsigned long state = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - if (*after && isspace(*after)) - count++; - - if (count == size) { + if (after - buf > 0) { timer_data->delay_on = state; mod_timer(&timer_data->timer, jiffies + 1); - ret = count; + ret = after - buf; } return ret; @@ -102,15 +97,11 @@ static ssize_t led_delay_off_store(struct class_device *dev, const char *buf, int ret = -EINVAL; char *after; unsigned long state = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - - if (*after && isspace(*after)) - count++; - if (count == size) { + if (after - buf > 0) { timer_data->delay_off = state; mod_timer(&timer_data->timer, jiffies + 1); - ret = count; + ret = after - buf; } return ret; diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 3ca3cfb03a7e..d7316b829a62 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -2252,7 +2252,7 @@ action_store(mddev_t *mddev, const char *page, size_t len) } else { if (cmd_match(page, "check")) set_bit(MD_RECOVERY_CHECK, &mddev->recovery); - else if (!cmd_match(page, "repair")) + else if (cmd_match(page, "repair")) return -EINVAL; set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); set_bit(MD_RECOVERY_SYNC, &mddev->recovery); diff --git a/trunk/drivers/md/raid0.c b/trunk/drivers/md/raid0.c index cb8c6317e4e5..678f4dbbea1d 100644 --- a/trunk/drivers/md/raid0.c +++ b/trunk/drivers/md/raid0.c @@ -331,14 +331,13 @@ static int raid0_run (mddev_t *mddev) goto out_free_conf; size = conf->strip_zone[cur].size; - conf->hash_table[0] = conf->strip_zone + cur; - for (i=1; i< nb_zone; i++) { + for (i=0; i< nb_zone; i++) { + conf->hash_table[i] = conf->strip_zone + cur; while (size <= conf->hash_spacing) { cur++; size += conf->strip_zone[cur].size; } size -= conf->hash_spacing; - conf->hash_table[i] = conf->strip_zone + cur; } if (conf->preshift) { conf->hash_spacing >>= conf->preshift; diff --git a/trunk/drivers/media/Kconfig b/trunk/drivers/media/Kconfig index 344d83aae3ec..fffc711c260c 100644 --- a/trunk/drivers/media/Kconfig +++ b/trunk/drivers/media/Kconfig @@ -8,54 +8,22 @@ config VIDEO_DEV tristate "Video For Linux" ---help--- Support for audio/video capture and overlay devices and FM radio - cards. The exact capabilities of each device vary. + cards. The exact capabilities of each device vary. User tools for + this are available from + . This kernel includes support for the new Video for Linux Two API, (V4L2) as well as the original system. Drivers and applications need to be rewritten to use V4L2, but drivers for popular cards and applications for most video capture functions already exist. - Additional info and docs are available on the web at - - - Documentation for V4L2 is also available on the web at - . + Documentation for the original API is included in the file + . Documentation for V4L2 is + available on the web at . To compile this driver as a module, choose M here: the module will be called videodev. -config VIDEO_V4L1 - boolean "Enable Video For Linux API 1 (DEPRECATED)" - depends on VIDEO_DEV - select VIDEO_V4L1_COMPAT - default y - ---help--- - Enables a compatibility API used by most V4L2 devices to allow - its usage with legacy applications that supports only V4L1 api. - - If you are unsure as to whether this is required, answer Y. - -config VIDEO_V4L1_COMPAT - boolean "Enable Video For Linux API 1 compatible Layer" - depends on VIDEO_DEV - default y - ---help--- - This api were developed to be used at Kernel 2.2 and 2.4, but - lacks support for several video standards. There are several - drivers at kernel that still depends on it. - - Documentation for the original API is included in the file - . - - User tools for this are available from - . - - If you are unsure as to whether this is required, answer Y. - -config VIDEO_V4L2 - tristate - default y - source "drivers/media/video/Kconfig" source "drivers/media/radio/Kconfig" @@ -97,3 +65,4 @@ config USB_DABUSB module will be called dabusb. endmenu + diff --git a/trunk/drivers/media/common/Kconfig b/trunk/drivers/media/common/Kconfig index 9c45b983e0de..6a901a0268e1 100644 --- a/trunk/drivers/media/common/Kconfig +++ b/trunk/drivers/media/common/Kconfig @@ -4,7 +4,6 @@ config VIDEO_SAA7146 config VIDEO_SAA7146_VV tristate - select VIDEO_V4L2 select VIDEO_BUF select VIDEO_VIDEOBUF select VIDEO_SAA7146 diff --git a/trunk/drivers/media/dvb/Kconfig b/trunk/drivers/media/dvb/Kconfig index a97c8f5e9a5d..3f0ec6be03ae 100644 --- a/trunk/drivers/media/dvb/Kconfig +++ b/trunk/drivers/media/dvb/Kconfig @@ -22,26 +22,26 @@ config DVB source "drivers/media/dvb/dvb-core/Kconfig" comment "Supported SAA7146 based PCI Adapters" - depends on DVB_CORE && PCI && I2C + depends on DVB_CORE && PCI source "drivers/media/dvb/ttpci/Kconfig" comment "Supported USB Adapters" - depends on DVB_CORE && USB && I2C + depends on DVB_CORE && USB source "drivers/media/dvb/dvb-usb/Kconfig" source "drivers/media/dvb/ttusb-budget/Kconfig" source "drivers/media/dvb/ttusb-dec/Kconfig" source "drivers/media/dvb/cinergyT2/Kconfig" comment "Supported FlexCopII (B2C2) Adapters" - depends on DVB_CORE && (PCI || USB) && I2C + depends on DVB_CORE && (PCI || USB) source "drivers/media/dvb/b2c2/Kconfig" comment "Supported BT878 Adapters" - depends on DVB_CORE && PCI && I2C + depends on DVB_CORE && PCI source "drivers/media/dvb/bt8xx/Kconfig" comment "Supported Pluto2 Adapters" - depends on DVB_CORE && PCI && I2C + depends on DVB_CORE && PCI source "drivers/media/dvb/pluto2/Kconfig" comment "Supported DVB Frontends" diff --git a/trunk/drivers/media/dvb/b2c2/Kconfig b/trunk/drivers/media/dvb/b2c2/Kconfig index d7f1fd5b7b02..2963605c0ecc 100644 --- a/trunk/drivers/media/dvb/b2c2/Kconfig +++ b/trunk/drivers/media/dvb/b2c2/Kconfig @@ -1,6 +1,6 @@ config DVB_B2C2_FLEXCOP tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters" - depends on DVB_CORE && I2C + depends on DVB_CORE select DVB_STV0299 select DVB_MT352 select DVB_MT312 @@ -16,7 +16,7 @@ config DVB_B2C2_FLEXCOP config DVB_B2C2_FLEXCOP_PCI tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI" - depends on DVB_B2C2_FLEXCOP && PCI && I2C + depends on DVB_B2C2_FLEXCOP && PCI help Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2. @@ -24,7 +24,7 @@ config DVB_B2C2_FLEXCOP_PCI config DVB_B2C2_FLEXCOP_USB tristate "Technisat/B2C2 Air/Sky/Cable2PC USB" - depends on DVB_B2C2_FLEXCOP && USB && I2C + depends on DVB_B2C2_FLEXCOP && USB help Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2, diff --git a/trunk/drivers/media/dvb/bt8xx/Kconfig b/trunk/drivers/media/dvb/bt8xx/Kconfig index f394002118f8..376ca48f1d1d 100644 --- a/trunk/drivers/media/dvb/bt8xx/Kconfig +++ b/trunk/drivers/media/dvb/bt8xx/Kconfig @@ -1,13 +1,12 @@ config DVB_BT8XX tristate "BT8xx based PCI cards" - depends on DVB_CORE && PCI && I2C && VIDEO_BT848 + depends on DVB_CORE && PCI && VIDEO_BT848 select DVB_MT352 select DVB_SP887X select DVB_NXT6000 select DVB_CX24110 select DVB_OR51211 select DVB_LGDT330X - select DVB_ZL10353 select FW_LOADER help Support for PCI cards based on the Bt8xx PCI bridge. Examples are diff --git a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c index ccc7b2eb4a2d..baa8227ef87c 100644 --- a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -115,7 +115,7 @@ static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev) return 0; } -static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev) +static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev) { unsigned int card_nr; @@ -709,7 +709,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) } } -static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) +static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) { int result; @@ -794,7 +794,7 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) return 0; } -static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) +static int dvb_bt8xx_probe(struct bttv_sub_device *sub) { struct dvb_bt8xx_card *card; struct pci_dev* bttv_pci_dev; diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c index 9325d039ea65..71b575dc22bd 100644 --- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -902,10 +902,7 @@ static int cinergyt2_probe (struct usb_interface *intf, return -ENOMEM; } - if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE)) < 0) { - kfree(cinergyt2); - return err; - } + dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE); cinergyt2->demux.priv = cinergyt2; cinergyt2->demux.filternum = 256; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index a051790161b0..4f8f257e6795 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -106,8 +106,6 @@ struct dvb_frontend_private { unsigned long tune_mode_flags; unsigned int delay; unsigned int reinitialise; - int tone; - int voltage; /* swzigzag values */ unsigned int state; @@ -539,12 +537,6 @@ static int dvb_frontend_thread(void *data) if (fepriv->reinitialise) { dvb_frontend_init(fe); - if (fepriv->tone != -1) { - fe->ops->set_tone(fe, fepriv->tone); - } - if (fepriv->voltage != -1) { - fe->ops->set_voltage(fe, fepriv->voltage); - } fepriv->reinitialise = 0; } @@ -796,7 +788,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_SET_TONE: if (fe->ops->set_tone) { err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); - fepriv->tone = (fe_sec_tone_mode_t) parg; fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } @@ -805,7 +796,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_SET_VOLTAGE: if (fe->ops->set_voltage) { err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg); - fepriv->voltage = (fe_sec_voltage_t) parg; fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } @@ -1005,8 +995,6 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) /* normal tune mode when opened R/W */ fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; - fepriv->tone = -1; - fepriv->voltage = -1; } return ret; diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.c b/trunk/drivers/media/dvb/dvb-core/dvbdev.c index 3852430d0260..96fe0ecae250 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.c @@ -219,6 +219,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, return -ENOMEM; } + mutex_unlock(&dvbdev_register_lock); + memcpy(dvbdev, template, sizeof(struct dvb_device)); dvbdev->type = type; dvbdev->id = id; @@ -229,8 +231,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, list_add_tail (&dvbdev->list_head, &adap->device_list); - mutex_unlock(&dvbdev_register_lock); - devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), S_IFCHR | S_IRUSR | S_IWUSR, "dvb/adapter%d/%s%d", adap->num, dnames[type], id); diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig index e388fb1567d6..d3df12039b06 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Kconfig +++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig @@ -1,6 +1,6 @@ config DVB_USB tristate "Support for various USB DVB devices" - depends on DVB_CORE && USB && I2C + depends on DVB_CORE && USB select FW_LOADER help By enabling this you will be able to choose the various supported diff --git a/trunk/drivers/media/dvb/dvb-usb/cxusb.c b/trunk/drivers/media/dvb/dvb-usb/cxusb.c index 1f0d3e995c8d..7edd6362b9cc 100644 --- a/trunk/drivers/media/dvb/dvb-usb/cxusb.c +++ b/trunk/drivers/media/dvb/dvb-usb/cxusb.c @@ -150,15 +150,6 @@ static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); } -static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 b = 0; - if (onoff) - return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); - else - return 0; -} - static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) { u8 buf[2] = { 0x03, 0x00 }; @@ -553,7 +544,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { .size_of_priv = sizeof(struct cxusb_state), .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_bluebird_power_ctrl, + .power_ctrl = cxusb_power_ctrl, .frontend_attach = cxusb_lgdt3303_frontend_attach, .tuner_attach = cxusb_lgh064f_tuner_attach, @@ -598,7 +589,7 @@ static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = { .size_of_priv = sizeof(struct cxusb_state), .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_bluebird_power_ctrl, + .power_ctrl = cxusb_power_ctrl, .frontend_attach = cxusb_dee1601_frontend_attach, .tuner_attach = cxusb_dee1601_tuner_attach, @@ -647,7 +638,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgz201_properties = { .size_of_priv = sizeof(struct cxusb_state), .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_bluebird_power_ctrl, + .power_ctrl = cxusb_power_ctrl, .frontend_attach = cxusb_mt352_frontend_attach, .tuner_attach = cxusb_lgz201_tuner_attach, @@ -692,7 +683,7 @@ static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties = { .size_of_priv = sizeof(struct cxusb_state), .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_bluebird_power_ctrl, + .power_ctrl = cxusb_power_ctrl, .frontend_attach = cxusb_mt352_frontend_attach, .tuner_attach = cxusb_dtt7579_tuner_attach, diff --git a/trunk/drivers/media/dvb/frontends/cx24123.c b/trunk/drivers/media/dvb/frontends/cx24123.c index 691dc840dcc0..d661c6f9cbe5 100644 --- a/trunk/drivers/media/dvb/frontends/cx24123.c +++ b/trunk/drivers/media/dvb/frontends/cx24123.c @@ -29,9 +29,6 @@ #include "dvb_frontend.h" #include "cx24123.h" -#define XTAL 10111000 - -static int force_band; static int debug; #define dprintk(args...) \ do { \ @@ -55,7 +52,6 @@ struct cx24123_state u32 VGAarg; u32 bandselectarg; u32 pllarg; - u32 FILTune; /* The Demod/Tuner can't easily provide these, we cache them */ u32 currentfreq; @@ -67,33 +63,43 @@ static struct { u32 symbolrate_low; u32 symbolrate_high; + u32 VCAslope; + u32 VCAoffset; + u32 VGA1offset; + u32 VGA2offset; u32 VCAprogdata; u32 VGAprogdata; - u32 FILTune; } cx24123_AGC_vals[] = { { .symbolrate_low = 1000000, .symbolrate_high = 4999999, - /* the specs recommend other values for VGA offsets, - but tests show they are wrong */ - .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x07, - .FILTune = 0x27f /* 0.41 V */ + .VCAslope = 0x07, + .VCAoffset = 0x0f, + .VGA1offset = 0x1f8, + .VGA2offset = 0x1f8, + .VGAprogdata = (2 << 18) | (0x1f8 << 9) | 0x1f8, + .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x07, }, { .symbolrate_low = 5000000, .symbolrate_high = 14999999, - .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x1f, - .FILTune = 0x317 /* 0.90 V */ + .VCAslope = 0x1f, + .VCAoffset = 0x1f, + .VGA1offset = 0x1e0, + .VGA2offset = 0x180, + .VGAprogdata = (2 << 18) | (0x180 << 9) | 0x1e0, + .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x1f, }, { .symbolrate_low = 15000000, .symbolrate_high = 45000000, - .VGAprogdata = (1 << 19) | (0x100 << 9) | 0x180, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x3f, - .FILTune = 0x145 /* 2.70 V */ + .VCAslope = 0x3f, + .VCAoffset = 0x3f, + .VGA1offset = 0x180, + .VGA2offset = 0x100, + .VGAprogdata = (2 << 18) | (0x100 << 9) | 0x180, + .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x3f, }, }; @@ -106,80 +112,91 @@ static struct { u32 freq_low; u32 freq_high; + u32 bandselect; u32 VCOdivider; + u32 VCOnumber; u32 progdata; } cx24123_bandselect_vals[] = { - /* band 1 */ { .freq_low = 950000, + .freq_high = 1018999, + .bandselect = 0x40, + .VCOdivider = 4, + .VCOnumber = 7, + .progdata = (0 << 18) | (0 << 9) | 0x40, + }, + { + .freq_low = 1019000, .freq_high = 1074999, + .bandselect = 0x80, .VCOdivider = 4, - .progdata = (0 << 19) | (0 << 9) | 0x40, + .VCOnumber = 8, + .progdata = (0 << 18) | (0 << 9) | 0x80, }, - - /* band 2 */ { .freq_low = 1075000, - .freq_high = 1177999, - .VCOdivider = 4, - .progdata = (0 << 19) | (0 << 9) | 0x80, + .freq_high = 1227999, + .bandselect = 0x01, + .VCOdivider = 2, + .VCOnumber = 1, + .progdata = (0 << 18) | (1 << 9) | 0x01, }, - - /* band 3 */ { - .freq_low = 1178000, - .freq_high = 1295999, + .freq_low = 1228000, + .freq_high = 1349999, + .bandselect = 0x02, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x01, + .VCOnumber = 2, + .progdata = (0 << 18) | (1 << 9) | 0x02, }, - - /* band 4 */ { - .freq_low = 1296000, - .freq_high = 1431999, + .freq_low = 1350000, + .freq_high = 1481999, + .bandselect = 0x04, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x02, + .VCOnumber = 3, + .progdata = (0 << 18) | (1 << 9) | 0x04, }, - - /* band 5 */ { - .freq_low = 1432000, - .freq_high = 1575999, + .freq_low = 1482000, + .freq_high = 1595999, + .bandselect = 0x08, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x04, + .VCOnumber = 4, + .progdata = (0 << 18) | (1 << 9) | 0x08, }, - - /* band 6 */ { - .freq_low = 1576000, + .freq_low = 1596000, .freq_high = 1717999, + .bandselect = 0x10, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x08, + .VCOnumber = 5, + .progdata = (0 << 18) | (1 << 9) | 0x10, }, - - /* band 7 */ { .freq_low = 1718000, .freq_high = 1855999, + .bandselect = 0x20, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x10, + .VCOnumber = 6, + .progdata = (0 << 18) | (1 << 9) | 0x20, }, - - /* band 8 */ { .freq_low = 1856000, .freq_high = 2035999, + .bandselect = 0x40, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x20, + .VCOnumber = 7, + .progdata = (0 << 18) | (1 << 9) | 0x40, }, - - /* band 9 */ { .freq_low = 2036000, - .freq_high = 2150000, + .freq_high = 2149999, + .bandselect = 0x80, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x40, + .VCOnumber = 8, + .progdata = (0 << 18) | (1 << 9) | 0x80, }, }; @@ -190,44 +207,49 @@ static struct { { {0x00, 0x03}, /* Reset system */ {0x00, 0x00}, /* Clear reset */ - {0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */ - {0x04, 0x10}, /* MPEG */ - {0x05, 0x04}, /* MPEG */ - {0x06, 0x31}, /* MPEG (default) */ - {0x0b, 0x00}, /* Freq search start point (default) */ - {0x0c, 0x00}, /* Demodulator sample gain (default) */ - {0x0d, 0x02}, /* Frequency search range = Fsymbol / 4 (default) */ - {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */ - {0x0f, 0xfe}, /* FEC search mask (all supported codes) */ - {0x10, 0x01}, /* Default search inversion, no repeat (default) */ - {0x16, 0x00}, /* Enable reading of frequency */ - {0x17, 0x01}, /* Enable EsNO Ready Counter */ - {0x1c, 0x80}, /* Enable error counter */ - {0x20, 0x00}, /* Tuner burst clock rate = 500KHz */ - {0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */ - {0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */ - {0x29, 0x00}, /* DiSEqC LNB_DC off */ - {0x2a, 0xb0}, /* DiSEqC Parameters (default) */ - {0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */ - {0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */ + {0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */ + {0x03, 0x07}, + {0x04, 0x10}, + {0x05, 0x04}, + {0x06, 0x31}, + {0x0d, 0x02}, + {0x0e, 0x03}, + {0x0f, 0xfe}, + {0x10, 0x01}, + {0x14, 0x01}, + {0x15, 0x98}, + {0x16, 0x00}, + {0x17, 0x01}, + {0x1b, 0x05}, + {0x1c, 0x80}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x20, 0x41}, + {0x21, 0x15}, + {0x27, 0x14}, + {0x28, 0x46}, + {0x29, 0x00}, + {0x2a, 0xb0}, + {0x2b, 0x73}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, {0x30, 0x00}, {0x31, 0x00}, - {0x32, 0x8c}, /* DiSEqC Parameters (default) */ - {0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */ + {0x32, 0x8c}, + {0x33, 0x00}, {0x34, 0x00}, - {0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */ - {0x36, 0x02}, /* DiSEqC Parameters (default) */ - {0x37, 0x3a}, /* DiSEqC Parameters (default) */ - {0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */ - {0x44, 0x00}, /* Constellation (default) */ - {0x45, 0x00}, /* Symbol count (default) */ - {0x46, 0x0d}, /* Symbol rate estimator on (default) */ - {0x56, 0x41}, /* Various (default) */ - {0x57, 0xff}, /* Error Counter Window (default) */ - {0x67, 0x83}, /* Non-DCII symbol clock */ + {0x35, 0x03}, + {0x36, 0x02}, + {0x37, 0x3a}, + {0x3a, 0x00}, /* Enable AGC accumulator */ + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x05}, + {0x56, 0x41}, + {0x57, 0xff}, + {0x67, 0x83}, }; static int cx24123_writereg(struct cx24123_state* state, int reg, int data) @@ -236,10 +258,6 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data) struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; int err; - if (debug>1) - printk("cx24123: %s: write reg 0x%02x, value 0x%02x\n", - __FUNCTION__,reg, data); - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { printk("%s: writereg error(err == %i, reg == 0x%02x," " data == 0x%02x)\n", __FUNCTION__, err, reg, data); @@ -256,10 +274,6 @@ static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data) struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 }; int err; - if (debug>1) - printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n", - __FUNCTION__,reg, data); - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { printk("%s: writelnbreg error (err == %i, reg == 0x%02x," " data == 0x%02x)\n", __FUNCTION__, err, reg, data); @@ -289,9 +303,6 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg) return ret; } - if (debug>1) - printk("cx24123: read reg 0x%02x, value 0x%02x\n",reg, ret); - return b1[0]; } @@ -302,23 +313,17 @@ static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) { - u8 nom_reg = cx24123_readreg(state, 0x0e); - u8 auto_reg = cx24123_readreg(state, 0x10); - switch (inversion) { case INVERSION_OFF: - dprintk("%s: inversion off\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg & ~0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); + cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f); + cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); break; case INVERSION_ON: - dprintk("%s: inversion on\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); + cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80); + cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); break; case INVERSION_AUTO: - dprintk("%s: inversion auto\n",__FUNCTION__); - cx24123_writereg(state, 0x10, auto_reg & ~0x80); + cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f); break; default: return -EINVAL; @@ -333,191 +338,92 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers val = cx24123_readreg(state, 0x1b) >> 7; - if (val == 0) { - dprintk("%s: read inversion off\n",__FUNCTION__); + if (val == 0) *inversion = INVERSION_OFF; - } else { - dprintk("%s: read inversion on\n",__FUNCTION__); + else *inversion = INVERSION_ON; - } return 0; } static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) { - u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07; - if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) fec = FEC_AUTO; + /* Hardware has 5/11 and 3/5 but are never unused */ switch (fec) { + case FEC_NONE: + return cx24123_writereg(state, 0x0f, 0x01); case FEC_1_2: - dprintk("%s: set FEC to 1/2\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x01); - cx24123_writereg(state, 0x0f, 0x02); - break; + return cx24123_writereg(state, 0x0f, 0x02); case FEC_2_3: - dprintk("%s: set FEC to 2/3\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x02); - cx24123_writereg(state, 0x0f, 0x04); - break; + return cx24123_writereg(state, 0x0f, 0x04); case FEC_3_4: - dprintk("%s: set FEC to 3/4\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x03); - cx24123_writereg(state, 0x0f, 0x08); - break; - case FEC_4_5: - dprintk("%s: set FEC to 4/5\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x04); - cx24123_writereg(state, 0x0f, 0x10); - break; + return cx24123_writereg(state, 0x0f, 0x08); case FEC_5_6: - dprintk("%s: set FEC to 5/6\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x05); - cx24123_writereg(state, 0x0f, 0x20); - break; - case FEC_6_7: - dprintk("%s: set FEC to 6/7\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x06); - cx24123_writereg(state, 0x0f, 0x40); - break; + return cx24123_writereg(state, 0x0f, 0x20); case FEC_7_8: - dprintk("%s: set FEC to 7/8\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x07); - cx24123_writereg(state, 0x0f, 0x80); - break; + return cx24123_writereg(state, 0x0f, 0x80); case FEC_AUTO: - dprintk("%s: set FEC to auto\n",__FUNCTION__); - cx24123_writereg(state, 0x0f, 0xfe); - break; + return cx24123_writereg(state, 0x0f, 0xae); default: return -EOPNOTSUPP; } - - return 0; } static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec) { int ret; + u8 val; ret = cx24123_readreg (state, 0x1b); if (ret < 0) return ret; - ret = ret & 0x07; - - switch (ret) { + val = ret & 0x07; + switch (val) { case 1: *fec = FEC_1_2; break; - case 2: - *fec = FEC_2_3; - break; case 3: - *fec = FEC_3_4; + *fec = FEC_2_3; break; case 4: - *fec = FEC_4_5; + *fec = FEC_3_4; break; case 5: - *fec = FEC_5_6; + *fec = FEC_4_5; break; case 6: - *fec = FEC_6_7; + *fec = FEC_5_6; break; case 7: *fec = FEC_7_8; break; + case 2: /* *fec = FEC_3_5; break; */ + case 0: /* *fec = FEC_5_11; break; */ + *fec = FEC_AUTO; + break; default: - /* this can happen when there's no lock */ - *fec = FEC_NONE; + *fec = FEC_NONE; // can't happen } return 0; } -/* Approximation of closest integer of log2(a/b). It actually gives the - lowest integer i such that 2^i >= round(a/b) */ -static u32 cx24123_int_log2(u32 a, u32 b) -{ - u32 exp, nearest = 0; - u32 div = a / b; - if(a % b >= b / 2) ++div; - if(div < (1 << 31)) - { - for(exp = 1; div > exp; nearest++) - exp += exp; - } - return nearest; -} - +/* fixme: Symbol rates < 3MSps may not work because of precision loss */ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) { - u32 tmp, sample_rate, ratio, sample_gain; - u8 pll_mult; - - /* check if symbol rate is within limits */ - if ((srate > state->ops.info.symbol_rate_max) || - (srate < state->ops.info.symbol_rate_min)) - return -EOPNOTSUPP;; - - /* choose the sampling rate high enough for the required operation, - while optimizing the power consumed by the demodulator */ - if (srate < (XTAL*2)/2) - pll_mult = 2; - else if (srate < (XTAL*3)/2) - pll_mult = 3; - else if (srate < (XTAL*4)/2) - pll_mult = 4; - else if (srate < (XTAL*5)/2) - pll_mult = 5; - else if (srate < (XTAL*6)/2) - pll_mult = 6; - else if (srate < (XTAL*7)/2) - pll_mult = 7; - else if (srate < (XTAL*8)/2) - pll_mult = 8; - else - pll_mult = 9; - - - sample_rate = pll_mult * XTAL; - - /* - SYSSymbolRate[21:0] = (srate << 23) / sample_rate - - We have to use 32 bit unsigned arithmetic without precision loss. - The maximum srate is 45000000 or 0x02AEA540. This number has - only 6 clear bits on top, hence we can shift it left only 6 bits - at a time. Borrowed from cx24110.c - */ - - tmp = srate << 6; - ratio = tmp / sample_rate; - - tmp = (tmp % sample_rate) << 6; - ratio = (ratio << 6) + (tmp / sample_rate); - - tmp = (tmp % sample_rate) << 6; - ratio = (ratio << 6) + (tmp / sample_rate); - - tmp = (tmp % sample_rate) << 5; - ratio = (ratio << 5) + (tmp / sample_rate); - - - cx24123_writereg(state, 0x01, pll_mult * 6); + u32 val; - cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f ); - cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff ); - cx24123_writereg(state, 0x0a, (ratio ) & 0xff ); + val = (srate / 1185) * 100; - /* also set the demodulator sample gain */ - sample_gain = cx24123_int_log2(sample_rate, srate); - tmp = cx24123_readreg(state, 0x0c) & ~0xe0; - cx24123_writereg(state, 0x0c, tmp | sample_gain << 5); + /* Compensate for scaling up, by removing 17 symbols per 1Msps */ + val = val - (17 * (srate / 1000000)); - dprintk("%s: srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", __FUNCTION__, srate, ratio, sample_rate, sample_gain); + cx24123_writereg(state, 0x08, (val >> 16) & 0xff ); + cx24123_writereg(state, 0x09, (val >> 8) & 0xff ); + cx24123_writereg(state, 0x0a, (val ) & 0xff ); return 0; } @@ -531,9 +437,6 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa struct cx24123_state *state = fe->demodulator_priv; u32 ndiv = 0, adiv = 0, vco_div = 0; int i = 0; - int pump = 2; - int band = 0; - int num_bands = sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); /* Defaults for low freq, low rate */ state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; @@ -541,49 +444,38 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa state->bandselectarg = cx24123_bandselect_vals[0].progdata; vco_div = cx24123_bandselect_vals[0].VCOdivider; - /* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */ + /* For the given symbolerate, determine the VCA and VGA programming bits */ for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) { if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && - (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { + (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; - state->FILTune = cx24123_AGC_vals[i].FILTune; } } - /* determine the band to use */ - if(force_band < 1 || force_band > num_bands) + /* For the given frequency, determine the bandselect programming bits */ + for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++) { - for (i = 0; i < num_bands; i++) - { - if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && - (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) - band = i; + if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && + (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) { + state->bandselectarg = cx24123_bandselect_vals[i].progdata; + vco_div = cx24123_bandselect_vals[i].VCOdivider; } } - else - band = force_band - 1; - - state->bandselectarg = cx24123_bandselect_vals[band].progdata; - vco_div = cx24123_bandselect_vals[band].VCOdivider; - - /* determine the charge pump current */ - if ( p->frequency < (cx24123_bandselect_vals[band].freq_low + cx24123_bandselect_vals[band].freq_high)/2 ) - pump = 0x01; - else - pump = 0x02; /* Determine the N/A dividers for the requested lband freq (in kHz). */ - /* Note: the reference divider R=10, frequency is in KHz, XTAL is in Hz */ - ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff; - adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f; + /* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */ + ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff; + adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f; if (adiv == 0) - ndiv++; + adiv++; - /* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */ - state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv; + /* determine the correct pll frequency values. */ + /* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */ + state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14); + state->pllarg |= (ndiv << 5) | adiv; return 0; } @@ -597,8 +489,6 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par struct cx24123_state *state = fe->demodulator_priv; unsigned long timeout; - dprintk("%s: pll writereg called, data=0x%08x\n",__FUNCTION__,data); - /* align the 21 bytes into to bit23 boundary */ data = data << 3; @@ -648,9 +538,6 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - dprintk("frequency=%i\n", p->frequency); if (cx24123_pll_calculate(fe, p) != 0) { printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__); @@ -665,14 +552,6 @@ static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_paramet cx24123_pll_writereg(fe, p, state->bandselectarg); cx24123_pll_writereg(fe, p, state->pllarg); - /* set the FILTUNE voltage */ - val = cx24123_readreg(state, 0x28) & ~0x3; - cx24123_writereg(state, 0x27, state->FILTune >> 2); - cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3)); - - dprintk("%s: pll tune VCA=%d, band=%d, pll=%d\n",__FUNCTION__,state->VCAarg, - state->bandselectarg,state->pllarg); - return 0; } @@ -681,8 +560,6 @@ static int cx24123_initfe(struct dvb_frontend* fe) struct cx24123_state *state = fe->demodulator_priv; int i; - dprintk("%s: init frontend\n",__FUNCTION__); - /* Configure the demod to a good set of defaults */ for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); @@ -710,13 +587,10 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage switch (voltage) { case SEC_VOLTAGE_13: - dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ case SEC_VOLTAGE_18: - dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ case SEC_VOLTAGE_OFF: - dprintk("%s: isl5421 voltage off\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val & 0x30); default: return -EINVAL; @@ -750,93 +624,13 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage return 0; } -/* wait for diseqc queue to become ready (or timeout) */ -static void cx24123_wait_for_diseqc(struct cx24123_state *state) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(200); - while (!(cx24123_readreg(state, 0x29) & 0x40)) { - if(time_after(jiffies, timeout)) { - printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__); - break; - } - msleep(10); - } -} - -static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) +static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, + struct dvb_diseqc_master_cmd *cmd) { - struct cx24123_state *state = fe->demodulator_priv; - int i, val; - - dprintk("%s:\n",__FUNCTION__); - - /* check if continuous tone has been stopped */ - if (state->config->use_isl6421) - val = cx24123_readlnbreg(state, 0x00) & 0x10; - else - val = cx24123_readreg(state, 0x29) & 0x10; + /* fixme: Implement diseqc */ + printk("%s: No support yet\n",__FUNCTION__); - - if (val) { - printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); - return -ENOTSUPP; - } - - /* wait for diseqc queue ready */ - cx24123_wait_for_diseqc(state); - - /* select tone mode */ - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8); - - for (i = 0; i < cmd->msg_len; i++) - cx24123_writereg(state, 0x2C + i, cmd->msg[i]); - - val = cx24123_readreg(state, 0x29); - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | ((cmd->msg_len-3) & 3)); - - /* wait for diseqc message to finish sending */ - cx24123_wait_for_diseqc(state); - - return 0; -} - -static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - struct cx24123_state *state = fe->demodulator_priv; - int val; - - dprintk("%s:\n", __FUNCTION__); - - /* check if continuous tone has been stoped */ - if (state->config->use_isl6421) - val = cx24123_readlnbreg(state, 0x00) & 0x10; - else - val = cx24123_readreg(state, 0x29) & 0x10; - - - if (val) { - printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); - return -ENOTSUPP; - } - - cx24123_wait_for_diseqc(state); - - /* select tone mode */ - val = cx24123_readreg(state, 0x2a) & 0xf8; - cx24123_writereg(state, 0x2a, val | 0x04); - - val = cx24123_readreg(state, 0x29); - - if (burst == SEC_MINI_A) - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); - else if (burst == SEC_MINI_B) - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08)); - else - return -EINVAL; - - cx24123_wait_for_diseqc(state); - - return 0; + return -ENOTSUPP; } static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) @@ -848,15 +642,13 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) *status = 0; if (lock & 0x01) - *status |= FE_HAS_SIGNAL; - if (sync & 0x02) - *status |= FE_HAS_CARRIER; + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; if (sync & 0x04) *status |= FE_HAS_VITERBI; if (sync & 0x08) - *status |= FE_HAS_SYNC; + *status |= FE_HAS_CARRIER; if (sync & 0x80) - *status |= FE_HAS_LOCK; + *status |= FE_HAS_SYNC | FE_HAS_LOCK; return 0; } @@ -889,8 +681,6 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber) else state->snr = 0; - dprintk("%s: BER = %d, S/N index = %d\n",__FUNCTION__,state->lastber, state->snr); - *ber = state->lastber; return 0; @@ -901,8 +691,6 @@ static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_str struct cx24123_state *state = fe->demodulator_priv; *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ - dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength); - return 0; } @@ -911,8 +699,6 @@ static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) struct cx24123_state *state = fe->demodulator_priv; *snr = state->snr; - dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr); - return 0; } @@ -921,8 +707,6 @@ static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) struct cx24123_state *state = fe->demodulator_priv; *ucblocks = state->lastber; - dprintk("%s: ucblocks (ber) = %d\n",__FUNCTION__,*ucblocks); - return 0; } @@ -930,8 +714,6 @@ static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par { struct cx24123_state *state = fe->demodulator_priv; - dprintk("%s: set_frontend\n",__FUNCTION__); - if (state->config->set_ts_params) state->config->set_ts_params(fe, 0); @@ -955,8 +737,6 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par { struct cx24123_state *state = fe->demodulator_priv; - dprintk("%s: get_frontend\n",__FUNCTION__); - if (cx24123_get_inversion(state, &p->inversion) != 0) { printk("%s: Failed to get inversion status\n",__FUNCTION__); return -EREMOTEIO; @@ -983,10 +763,8 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) switch (tone) { case SEC_TONE_ON: - dprintk("%s: isl6421 sec tone on\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val | 0x10); case SEC_TONE_OFF: - dprintk("%s: isl6421 sec tone off\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val & 0x2f); default: printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); @@ -1077,13 +855,12 @@ static struct dvb_frontend_ops cx24123_ops = { .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 5000, + .frequency_tolerance = 29500, .symbol_rate_min = 1000000, .symbol_rate_max = 45000000, .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_RECOVER }, @@ -1098,16 +875,12 @@ static struct dvb_frontend_ops cx24123_ops = { .read_snr = cx24123_read_snr, .read_ucblocks = cx24123_read_ucblocks, .diseqc_send_master_cmd = cx24123_send_diseqc_msg, - .diseqc_send_burst = cx24123_diseqc_send_burst, .set_tone = cx24123_set_tone, .set_voltage = cx24123_set_voltage, }; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -module_param(force_band, int, 0644); -MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off)."); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware"); MODULE_AUTHOR("Steven Toth"); diff --git a/trunk/drivers/media/dvb/frontends/dvb-pll.c b/trunk/drivers/media/dvb/frontends/dvb-pll.c index 791706ec1da3..b6e2c387a04c 100644 --- a/trunk/drivers/media/dvb/frontends/dvb-pll.c +++ b/trunk/drivers/media/dvb/frontends/dvb-pll.c @@ -235,8 +235,8 @@ struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { .max = 863000000, .count = 3, .entries = { - { 165000000, 44000000, 62500, 0xce, 0x01 }, - { 450000000, 44000000, 62500, 0xce, 0x02 }, + { 160000000, 44000000, 62500, 0xce, 0x01 }, + { 455000000, 44000000, 62500, 0xce, 0x02 }, { 999999999, 44000000, 62500, 0xce, 0x04 }, }, }; diff --git a/trunk/drivers/media/dvb/pluto2/Kconfig b/trunk/drivers/media/dvb/pluto2/Kconfig index 48252e9ce586..84f8f9f52869 100644 --- a/trunk/drivers/media/dvb/pluto2/Kconfig +++ b/trunk/drivers/media/dvb/pluto2/Kconfig @@ -1,6 +1,6 @@ config DVB_PLUTO2 tristate "Pluto2 cards" - depends on DVB_CORE && PCI && I2C + depends on DVB_CORE && PCI select I2C select I2C_ALGOBIT select DVB_TDA1004X diff --git a/trunk/drivers/media/dvb/pluto2/Makefile b/trunk/drivers/media/dvb/pluto2/Makefile index ce6a9aaf937e..86ca84b2be6e 100644 --- a/trunk/drivers/media/dvb/pluto2/Makefile +++ b/trunk/drivers/media/dvb/pluto2/Makefile @@ -1,3 +1,3 @@ -obj-$(CONFIG_DVB_PLUTO2) += pluto2.o +obj-$(CONFIG_DVB_PLUTO2) = pluto2.o EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ diff --git a/trunk/drivers/media/dvb/ttpci/Kconfig b/trunk/drivers/media/dvb/ttpci/Kconfig index b5ac7dfde52f..5b2aadb8385c 100644 --- a/trunk/drivers/media/dvb/ttpci/Kconfig +++ b/trunk/drivers/media/dvb/ttpci/Kconfig @@ -1,7 +1,8 @@ config DVB_AV7110 tristate "AV7110 cards" - depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 + depends on DVB_CORE && PCI select FW_LOADER + select VIDEO_DEV select VIDEO_SAA7146_VV select DVB_VES1820 select DVB_VES1X93 @@ -58,7 +59,7 @@ config DVB_AV7110_OSD config DVB_BUDGET tristate "Budget cards" - depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 + depends on DVB_CORE && PCI select VIDEO_SAA7146 select DVB_STV0299 select DVB_VES1X93 @@ -79,7 +80,7 @@ config DVB_BUDGET config DVB_BUDGET_CI tristate "Budget cards with onboard CI connector" - depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 + depends on DVB_CORE && PCI select VIDEO_SAA7146 select DVB_STV0297 select DVB_STV0299 @@ -99,7 +100,8 @@ config DVB_BUDGET_CI config DVB_BUDGET_AV tristate "Budget cards with analog video inputs" - depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 + depends on DVB_CORE && PCI + select VIDEO_DEV select VIDEO_SAA7146_VV select DVB_STV0299 select DVB_TDA1004X @@ -117,7 +119,7 @@ config DVB_BUDGET_AV config DVB_BUDGET_PATCH tristate "AV7110 cards with Budget Patch" - depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1 + depends on DVB_CORE && DVB_BUDGET select DVB_AV7110 select DVB_STV0299 select DVB_VES1X93 diff --git a/trunk/drivers/media/dvb/ttpci/budget-av.c b/trunk/drivers/media/dvb/ttpci/budget-av.c index 8a7cd7d505cf..8efe3ce5f66c 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-av.c +++ b/trunk/drivers/media/dvb/ttpci/budget-av.c @@ -1190,6 +1190,8 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio SAA7146_HPS_SYNC_PORT_A); saa7113_setinput(budget_av, 0); + } else { + ciintf_init(budget_av); } /* fixme: find some sane values here... */ @@ -1209,10 +1211,6 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio budget_av->budget.dvb_adapter.priv = budget_av; frontend_init(budget_av); - if (!budget_av->has_saa7113) { - ciintf_init(budget_av); - } - return 0; } diff --git a/trunk/drivers/media/dvb/ttpci/budget-ci.c b/trunk/drivers/media/dvb/ttpci/budget-ci.c index e64a609cf4ff..5f91036f5b87 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-ci.c +++ b/trunk/drivers/media/dvb/ttpci/budget-ci.c @@ -71,7 +71,6 @@ struct budget_ci { struct tasklet_struct msp430_irq_tasklet; struct tasklet_struct ciintf_irq_tasklet; int slot_status; - int ci_irq; struct dvb_ca_en50221 ca; char ir_dev_name[50]; u8 tuner_pll_address; /* used for philips_tdm1316l configs */ @@ -277,10 +276,8 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) if (slot != 0) return -EINVAL; - if (budget_ci->ci_irq) { - // trigger on RISING edge during reset so we know when READY is re-asserted - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - } + // trigger on RISING edge during reset so we know when READY is re-asserted + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); budget_ci->slot_status = SLOTSTATUS_RESET; ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); msleep(1); @@ -373,50 +370,11 @@ static void ciintf_interrupt(unsigned long data) } } -static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - unsigned int flags; - - // ensure we don't get spurious IRQs during initialisation - if (!budget_ci->budget.ci_present) - return -EINVAL; - - // read the CAM status - flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - if (flags & CICONTROL_CAMDETECT) { - // mark it as present if it wasn't before - if (budget_ci->slot_status & SLOTSTATUS_NONE) { - budget_ci->slot_status = SLOTSTATUS_PRESENT; - } - - // during a RESET, we check if we can read from IO memory to see when CAM is ready - if (budget_ci->slot_status & SLOTSTATUS_RESET) { - if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) { - budget_ci->slot_status = SLOTSTATUS_READY; - } - } - } else { - budget_ci->slot_status = SLOTSTATUS_NONE; - } - - if (budget_ci->slot_status != SLOTSTATUS_NONE) { - if (budget_ci->slot_status & SLOTSTATUS_READY) { - return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; - } - return DVB_CA_EN50221_POLL_CAM_PRESENT; - } - - return 0; -} - static int ciintf_init(struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; int flags; int result; - int ci_version; - int ca_flags; memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221)); @@ -424,29 +382,16 @@ static int ciintf_init(struct budget_ci *budget_ci) saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800); // test if it is there - ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0); - if ((ci_version & 0xa0) != 0xa0) { + if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) { result = -ENODEV; goto error; } - // determine whether a CAM is present or not flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); budget_ci->slot_status = SLOTSTATUS_NONE; if (flags & CICONTROL_CAMDETECT) budget_ci->slot_status = SLOTSTATUS_PRESENT; - // version 0xa2 of the CI firmware doesn't generate interrupts - if (ci_version == 0xa2) { - ca_flags = 0; - budget_ci->ci_irq = 0; - } else { - ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | - DVB_CA_EN50221_FLAG_IRQ_FR | - DVB_CA_EN50221_FLAG_IRQ_DA; - budget_ci->ci_irq = 1; - } - // register CI interface budget_ci->ca.owner = THIS_MODULE; budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem; @@ -456,27 +401,23 @@ static int ciintf_init(struct budget_ci *budget_ci) budget_ci->ca.slot_reset = ciintf_slot_reset; budget_ci->ca.slot_shutdown = ciintf_slot_shutdown; budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable; - budget_ci->ca.poll_slot_status = ciintf_poll_slot_status; budget_ci->ca.data = budget_ci; if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter, &budget_ci->ca, - ca_flags, 1)) != 0) { + DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | + DVB_CA_EN50221_FLAG_IRQ_FR | + DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) { printk("budget_ci: CI interface detected, but initialisation failed.\n"); goto error; } - // Setup CI slot IRQ - if (budget_ci->ci_irq) { - tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); - if (budget_ci->slot_status != SLOTSTATUS_NONE) { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); - } else { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - } - saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03); + tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); + if (budget_ci->slot_status != SLOTSTATUS_NONE) { + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); + } else { + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); } - - // enable interface + saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03); ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET, 1, 0); @@ -485,12 +426,10 @@ static int ciintf_init(struct budget_ci *budget_ci) budget_ci->budget.ci_present = 1; // forge a fake CI IRQ so the CAM state is setup correctly - if (budget_ci->ci_irq) { - flags = DVB_CA_EN50221_CAMCHANGE_REMOVED; - if (budget_ci->slot_status != SLOTSTATUS_NONE) - flags = DVB_CA_EN50221_CAMCHANGE_INSERTED; - dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags); - } + flags = DVB_CA_EN50221_CAMCHANGE_REMOVED; + if (budget_ci->slot_status != SLOTSTATUS_NONE) + flags = DVB_CA_EN50221_CAMCHANGE_INSERTED; + dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags); return 0; @@ -504,13 +443,9 @@ static void ciintf_deinit(struct budget_ci *budget_ci) struct saa7146_dev *saa = budget_ci->budget.dev; // disable CI interrupts - if (budget_ci->ci_irq) { - saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03); - saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); - tasklet_kill(&budget_ci->ciintf_irq_tasklet); - } - - // reset interface + saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03); + saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); + tasklet_kill(&budget_ci->ciintf_irq_tasklet); ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); msleep(1); ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, @@ -538,7 +473,7 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr) if (*isr & MASK_10) ttpci_budget_irq10_handler(dev, isr); - if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq)) + if ((*isr & MASK_03) && (budget_ci->budget.ci_present)) tasklet_schedule(&budget_ci->ciintf_irq_tasklet); } diff --git a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 6ceae38125c7..248fdc7accfb 100644 --- a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1507,11 +1507,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i mutex_unlock(&ttusb->semi2c); - if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE)) < 0) { - ttusb_free_iso_urbs(ttusb); - kfree(ttusb); - return result; - } + dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE); ttusb->adapter.priv = ttusb; /* i2c */ diff --git a/trunk/drivers/media/radio/Kconfig b/trunk/drivers/media/radio/Kconfig index 3fff75763693..d318be383de6 100644 --- a/trunk/drivers/media/radio/Kconfig +++ b/trunk/drivers/media/radio/Kconfig @@ -7,7 +7,7 @@ menu "Radio Adapters" config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these AM/FM radio cards, and then fill in the port address below. @@ -25,7 +25,7 @@ config RADIO_CADET config RADIO_RTRACK tristate "AIMSlab RadioTrack (aka RadioReveal) support" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. @@ -59,7 +59,7 @@ config RADIO_RTRACK_PORT config RADIO_RTRACK2 tristate "AIMSlab RadioTrack II support" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. @@ -82,7 +82,7 @@ config RADIO_RTRACK2_PORT config RADIO_AZTECH tristate "Aztech/Packard Bell Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. @@ -106,7 +106,7 @@ config RADIO_AZTECH_PORT config RADIO_GEMTEK tristate "GemTek Radio Card support" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. @@ -131,7 +131,7 @@ config RADIO_GEMTEK_PORT config RADIO_GEMTEK_PCI tristate "GemTek PCI Radio Card support" - depends on VIDEO_V4L1 && PCI + depends on VIDEO_DEV && PCI ---help--- Choose Y here if you have this PCI FM radio card. @@ -145,7 +145,7 @@ config RADIO_GEMTEK_PCI config RADIO_MAXIRADIO tristate "Guillemot MAXI Radio FM 2000 radio" - depends on VIDEO_V4L1 && PCI + depends on VIDEO_DEV && PCI ---help--- Choose Y here if you have this radio card. This card may also be found as Gemtek PCI FM. @@ -160,7 +160,7 @@ config RADIO_MAXIRADIO config RADIO_MAESTRO tristate "Maestro on board radio" - depends on VIDEO_V4L1 + depends on VIDEO_DEV ---help--- Say Y here to directly support the on-board radio tuner on the Maestro 2 or 2E sound card. @@ -175,7 +175,7 @@ config RADIO_MAESTRO config RADIO_MIROPCM20 tristate "miroSOUND PCM20 radio" - depends on ISA && VIDEO_V4L1 && SOUND_ACI_MIXER + depends on ISA && VIDEO_DEV && SOUND_ACI_MIXER ---help--- Choose Y here if you have this FM radio card. You also need to say Y to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound") @@ -208,7 +208,7 @@ config RADIO_MIROPCM20_RDS config RADIO_SF16FMI tristate "SF16FMI Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards. If you compile the driver into the kernel and your card is not PnP one, you @@ -225,7 +225,7 @@ config RADIO_SF16FMI config RADIO_SF16FMR2 tristate "SF16FMR2 Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards. @@ -239,7 +239,7 @@ config RADIO_SF16FMR2 config RADIO_TERRATEC tristate "TerraTec ActiveRadio ISA Standalone" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. (TODO) @@ -268,7 +268,7 @@ config RADIO_TERRATEC_PORT config RADIO_TRUST tristate "Trust FM radio card" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV help This is a driver for the Trust FM radio cards. Say Y if you have such a card and want to use it under Linux. @@ -286,7 +286,7 @@ config RADIO_TRUST_PORT config RADIO_TYPHOON tristate "Typhoon Radio (a.k.a. EcoRadio)" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address and the frequency used for muting below. @@ -330,7 +330,7 @@ config RADIO_TYPHOON_MUTEFREQ config RADIO_ZOLTRIX tristate "Zoltrix Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index 6b4197018561..85888a8a93c9 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -2,10 +2,10 @@ # Multimedia Video device configuration # -menu "Video Capture Adapters" +menu "Video For Linux" depends on VIDEO_DEV -comment "Video Capture Adapters" +comment "Video Adapters" config VIDEO_ADV_DEBUG bool "Enable advanced debug functionality" @@ -16,23 +16,11 @@ config VIDEO_ADV_DEBUG V4L devices. In doubt, say N. -config VIDEO_VIVI - tristate "Virtual Video Driver" - depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 - select VIDEO_BUF - default n - ---help--- - Enables a virtual video driver. This device shows a color bar - and a timestamp, as a real device would generate by using V4L2 - api. - Say Y here if you want to test video apps or debug V4L devices. - In doubt, say N. - source "drivers/media/video/bt8xx/Kconfig" config VIDEO_SAA6588 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards" - depends on I2C && VIDEO_BT848 + depends on VIDEO_DEV && I2C && VIDEO_BT848 help Support for Radio Data System (RDS) decoder. This allows seeing @@ -44,7 +32,7 @@ config VIDEO_SAA6588 config VIDEO_PMS tristate "Mediavision Pro Movie Studio Video For Linux" - depends on ISA && VIDEO_V4L1 + depends on VIDEO_DEV && ISA help Say Y if you have such a thing. @@ -53,7 +41,7 @@ config VIDEO_PMS config VIDEO_PLANB tristate "PlanB Video-In on PowerMac" - depends on PPC_PMAC && VIDEO_V4L1 && BROKEN + depends on PPC_PMAC && VIDEO_DEV && BROKEN help PlanB is the V4L driver for the PowerMac 7x00/8x00 series video input hardware. If you want to experiment with this, say Y. @@ -64,7 +52,7 @@ config VIDEO_PLANB config VIDEO_BWQCAM tristate "Quickcam BW Video For Linux" - depends on PARPORT && VIDEO_V4L1 + depends on VIDEO_DEV && PARPORT help Say Y have if you the black and white version of the QuickCam camera. See the next option for the color version. @@ -74,7 +62,7 @@ config VIDEO_BWQCAM config VIDEO_CQCAM tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)" - depends on EXPERIMENTAL && PARPORT && VIDEO_V4L1 + depends on EXPERIMENTAL && VIDEO_DEV && PARPORT help This is the video4linux driver for the colour version of the Connectix QuickCam. If you have one of these cameras, say Y here, @@ -85,7 +73,7 @@ config VIDEO_CQCAM config VIDEO_W9966 tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux" - depends on PARPORT_1284 && PARPORT && VIDEO_V4L1 + depends on PARPORT_1284 && VIDEO_DEV && PARPORT help Video4linux driver for Winbond's w9966 based Webcams. Currently tested with the LifeView FlyCam Supra. @@ -98,7 +86,7 @@ config VIDEO_W9966 config VIDEO_CPIA tristate "CPiA Video For Linux" - depends on VIDEO_V4L1 + depends on VIDEO_DEV ---help--- This is the video4linux driver for cameras based on Vision's CPiA (Colour Processor Interface ASIC), such as the Creative Labs Video @@ -135,7 +123,7 @@ source "drivers/media/video/cpia2/Kconfig" config VIDEO_SAA5246A tristate "SAA5246A, SAA5281 Teletext processor" - depends on I2C && VIDEO_V4L1 + depends on VIDEO_DEV && I2C help Support for I2C bus based teletext using the SAA5246A or SAA5281 chip. Useful only if you live in Europe. @@ -162,7 +150,7 @@ config TUNER_3036 config VIDEO_VINO tristate "SGI Vino Video For Linux (EXPERIMENTAL)" - depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L1 + depends on VIDEO_DEV && I2C && SGI_IP22 && EXPERIMENTAL select I2C_ALGO_SGI help Say Y here to build in support for the Vino video input system found @@ -170,7 +158,7 @@ config VIDEO_VINO config VIDEO_STRADIS tristate "Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)" - depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && !PPC64 + depends on EXPERIMENTAL && VIDEO_DEV && PCI help Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video driver for PCI. There is a product page at @@ -178,7 +166,7 @@ config VIDEO_STRADIS config VIDEO_ZORAN tristate "Zoran ZR36057/36067 Video For Linux" - depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && !PPC64 + depends on VIDEO_DEV && PCI && I2C_ALGOBIT help Say Y for support for MJPEG capture cards based on the Zoran 36057/36067 PCI controller chipset. This includes the Iomega @@ -226,7 +214,7 @@ config VIDEO_ZORAN_LML33R10 config VIDEO_ZR36120 tristate "Zoran ZR36120/36125 Video For Linux" - depends on PCI && I2C && VIDEO_V4L1 && BROKEN + depends on VIDEO_DEV && PCI && I2C && BROKEN help Support for ZR36120/ZR36125 based frame grabber/overlay boards. This includes the Victor II, WaveWatcher, Video Wonder, Maxi-TV, @@ -238,7 +226,7 @@ config VIDEO_ZR36120 config VIDEO_MEYE tristate "Sony Vaio Picturebook Motion Eye Video For Linux" - depends on PCI && SONYPI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI && SONYPI ---help--- This is the video4linux driver for the Motion Eye camera found in the Vaio Picturebook laptops. Please read the material in @@ -254,7 +242,7 @@ source "drivers/media/video/saa7134/Kconfig" config VIDEO_MXB tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" - depends on PCI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI select VIDEO_SAA7146_VV select VIDEO_TUNER ---help--- @@ -266,9 +254,8 @@ config VIDEO_MXB config VIDEO_DPC tristate "Philips-Semiconductors 'dpc7146 demonstration board'" - depends on PCI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI select VIDEO_SAA7146_VV - select VIDEO_V4L2 ---help--- This is a video4linux driver for the 'dpc7146 demonstration board' by Philips-Semiconductors. It's the reference design @@ -281,9 +268,8 @@ config VIDEO_DPC config VIDEO_HEXIUM_ORION tristate "Hexium HV-PCI6 and Orion frame grabber" - depends on PCI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI select VIDEO_SAA7146_VV - select VIDEO_V4L2 ---help--- This is a video4linux driver for the Hexium HV-PCI6 and Orion frame grabber cards by Hexium. @@ -293,9 +279,8 @@ config VIDEO_HEXIUM_ORION config VIDEO_HEXIUM_GEMINI tristate "Hexium Gemini frame grabber" - depends on PCI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI select VIDEO_SAA7146_VV - select VIDEO_V4L2 ---help--- This is a video4linux driver for the Hexium Gemini frame grabber card by Hexium. Please note that the Gemini Dual @@ -308,7 +293,7 @@ source "drivers/media/video/cx88/Kconfig" config VIDEO_OVCAMCHIP tristate "OmniVision Camera Chip support" - depends on I2C && VIDEO_V4L1 + depends on VIDEO_DEV && I2C ---help--- Support for the OmniVision OV6xxx and OV7xxx series of camera chips. This driver is intended to be used with the ov511 and w9968cf USB @@ -319,7 +304,7 @@ config VIDEO_OVCAMCHIP config VIDEO_M32R_AR tristate "AR devices" - depends on M32R && VIDEO_V4L1 + depends on M32R ---help--- This is a video4linux driver for the Renesas AR (Artificial Retina) camera module. @@ -380,17 +365,17 @@ config VIDEO_WM8739 source "drivers/media/video/cx25840/Kconfig" config VIDEO_SAA711X - tristate "Philips SAA7113/4/5 video decoders (OBSOLETED)" - depends on VIDEO_V4L1 && I2C && EXPERIMENTAL + tristate "Philips SAA7113/4/5 video decoders" + depends on VIDEO_DEV && I2C && EXPERIMENTAL ---help--- - Old support for the Philips SAA7113/4 video decoders. + Support for the Philips SAA7113/4/5 video decoders. To compile this driver as a module, choose M here: the module will be called saa7115. config VIDEO_SAA7127 tristate "Philips SAA7127/9 digital video encoders" - depends on VIDEO_V4L2 && I2C && EXPERIMENTAL + depends on VIDEO_DEV && I2C && EXPERIMENTAL ---help--- Support for the Philips SAA7127/9 digital video encoders. @@ -399,7 +384,7 @@ config VIDEO_SAA7127 config VIDEO_UPD64031A tristate "NEC Electronics uPD64031A Ghost Reduction" - depends on VIDEO_V4L2 && I2C && EXPERIMENTAL + depends on VIDEO_DEV && I2C && EXPERIMENTAL ---help--- Support for the NEC Electronics uPD64031A Ghost Reduction video chip. It is most often found in NTSC TV cards made for @@ -411,7 +396,7 @@ config VIDEO_UPD64031A config VIDEO_UPD64083 tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation" - depends on VIDEO_V4L2 && I2C && EXPERIMENTAL + depends on VIDEO_DEV && I2C && EXPERIMENTAL ---help--- Support for the NEC Electronics uPD64083 3-Dimensional Y/C separation video chip. It is used to improve the quality of @@ -433,7 +418,7 @@ source "drivers/media/video/em28xx/Kconfig" config USB_DSBR tristate "D-Link USB FM radio support (EXPERIMENTAL)" - depends on USB && VIDEO_V4L1 && EXPERIMENTAL + depends on USB && VIDEO_DEV && EXPERIMENTAL ---help--- Say Y here if you want to connect this type of radio to your computer's USB port. Note that the audio is not digital, and @@ -449,7 +434,7 @@ source "drivers/media/video/et61x251/Kconfig" config USB_OV511 tristate "USB OV511 Camera support" - depends on USB && VIDEO_V4L1 + depends on USB && VIDEO_DEV ---help--- Say Y here if you want to connect this type of camera to your computer's USB port. See @@ -460,7 +445,7 @@ config USB_OV511 config USB_SE401 tristate "USB SE401 Camera support" - depends on USB && VIDEO_V4L1 + depends on USB && VIDEO_DEV ---help--- Say Y here if you want to connect this type of camera to your computer's USB port. See @@ -473,7 +458,7 @@ source "drivers/media/video/sn9c102/Kconfig" config USB_STV680 tristate "USB STV680 (Pencam) Camera support" - depends on USB && VIDEO_V4L1 + depends on USB && VIDEO_DEV ---help--- Say Y here if you want to connect this type of camera to your computer's USB port. This includes the Pencam line of cameras. @@ -485,7 +470,7 @@ config USB_STV680 config USB_W9968CF tristate "USB W996[87]CF JPEG Dual Mode Camera support" - depends on USB && VIDEO_V4L1 && I2C + depends on USB && VIDEO_DEV && I2C select VIDEO_OVCAMCHIP ---help--- Say Y here if you want support for cameras based on OV681 or diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile index e5bf2687b76d..b3ea2d63db9b 100644 --- a/trunk/drivers/media/video/Makefile +++ b/trunk/drivers/media/video/Makefile @@ -10,11 +10,7 @@ tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ msp3400-objs := msp3400-driver.o msp3400-kthreads.o -obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o - -ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) - obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o -endif +obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o obj-$(CONFIG_VIDEO_BT848) += bt8xx/ obj-$(CONFIG_VIDEO_BT848) += tvaudio.o tda7432.o tda9875.o ir-kbd-i2c.o @@ -88,8 +84,4 @@ obj-$(CONFIG_USB_IBMCAM) += usbvideo/ obj-$(CONFIG_USB_KONICAWC) += usbvideo/ obj-$(CONFIG_USB_VICAM) += usbvideo/ -obj-$(CONFIG_VIDEO_VIVI) += vivi.o - EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT - diff --git a/trunk/drivers/media/video/bt8xx/Kconfig b/trunk/drivers/media/video/bt8xx/Kconfig index 153f6a4a96c9..085477c12612 100644 --- a/trunk/drivers/media/video/bt8xx/Kconfig +++ b/trunk/drivers/media/video/bt8xx/Kconfig @@ -1,6 +1,6 @@ config VIDEO_BT848 tristate "BT848 Video For Linux" - depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 + depends on VIDEO_DEV && PCI && I2C select I2C_ALGOBIT select FW_LOADER select VIDEO_BTCX diff --git a/trunk/drivers/media/video/bt8xx/Makefile b/trunk/drivers/media/video/bt8xx/Makefile index a096a03418aa..db641a36b197 100644 --- a/trunk/drivers/media/video/bt8xx/Makefile +++ b/trunk/drivers/media/video/bt8xx/Makefile @@ -8,5 +8,5 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ obj-$(CONFIG_VIDEO_BT848) += bttv.o -EXTRA_CFLAGS += -Idrivers/media/video +EXTRA_CFLAGS += -I$(src)/.. EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/trunk/drivers/media/video/bt8xx/bttv-cards.c b/trunk/drivers/media/video/bt8xx/bttv-cards.c index 2b64aa835b42..f209a7492051 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-cards.c +++ b/trunk/drivers/media/video/bt8xx/bttv-cards.c @@ -2991,13 +2991,13 @@ void __devinit bttv_idcard(struct bttv *btv) if (UNSET != audiomux[0]) { gpiobits = 0; - for (i = 0; i < 4; i++) { + for (i = 0; i < 5; i++) { bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i]; gpiobits |= audiomux[i]; } } else { gpiobits = audioall; - for (i = 0; i < 4; i++) { + for (i = 0; i < 5; i++) { bttv_tvcards[btv->c.type].gpiomux[i] = audioall; } } diff --git a/trunk/drivers/media/video/bt8xx/bttv-risc.c b/trunk/drivers/media/video/bt8xx/bttv-risc.c index afcfe71e3792..16323a5d68ac 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-risc.c +++ b/trunk/drivers/media/video/bt8xx/bttv-risc.c @@ -233,7 +233,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, const struct bttv_format *fmt, struct bttv_overlay *ov, int skip_even, int skip_odd) { - int dwords,rc,line,maxy,start,end,skip,nskips; + int instructions,rc,line,maxy,start,end,skip,nskips; struct btcx_skiplist *skips; u32 *rp,ri,ra; u32 addr; @@ -242,12 +242,12 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL))) return -ENOMEM; - /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions + /* estimate risc mem: worst case is (clip+1) * lines instructions + sync + jump (all 2 dwords) */ - dwords = (3 * ov->nclips + 2) * - ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height); - dwords += 4; - if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) { + instructions = (ov->nclips + 1) * + ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height); + instructions += 2; + if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) { kfree(skips); return rc; } @@ -276,6 +276,8 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, if (line > maxy) btcx_calc_skips(line, ov->w.width, &maxy, skips, &nskips, ov->clips, ov->nclips); + else + nskips = 0; /* write out risc code */ for (start = 0, skip = 0; start < ov->w.width; start = end) { diff --git a/trunk/drivers/media/video/cx25840/cx25840-firmware.c b/trunk/drivers/media/video/cx25840/cx25840-firmware.c index 1958d4016ea1..f59ced181c55 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-firmware.c +++ b/trunk/drivers/media/video/cx25840/cx25840-firmware.c @@ -39,12 +39,29 @@ #define FWDEV(x) &((x)->adapter->dev) +static int fastfw = 1; static char *firmware = FWFILE; +module_param(fastfw, bool, 0444); module_param(firmware, charp, 0444); +MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]"); MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); +static void set_i2c_delay(struct i2c_client *client, int delay) +{ + struct i2c_algo_bit_data *algod = client->adapter->algo_data; + + /* We aren't guaranteed to be using algo_bit, + * so avoid the null pointer dereference + * and disable the 'fast firmware load' */ + if (algod) { + algod->udelay = delay; + } else { + fastfw = 0; + } +} + static void start_fw_load(struct i2c_client *client) { /* DL_ADDR_LB=0 DL_ADDR_HB=0 */ @@ -54,10 +71,16 @@ static void start_fw_load(struct i2c_client *client) cx25840_write(client, 0x803, 0x0b); /* AUTO_INC_DIS=1 */ cx25840_write(client, 0x000, 0x20); + + if (fastfw) + set_i2c_delay(client, 3); } static void end_fw_load(struct i2c_client *client) { + if (fastfw) + set_i2c_delay(client, 10); + /* AUTO_INC_DIS=0 */ cx25840_write(client, 0x000, 0x00); /* DL_ENABLE=0 */ @@ -84,8 +107,30 @@ static int fw_write(struct i2c_client *client, u8 * data, int size) int sent; if ((sent = i2c_master_send(client, data, size)) < size) { - v4l_err(client, "firmware load i2c failure\n"); - return -ENOSYS; + + if (fastfw) { + v4l_err(client, "333MHz i2c firmware load failed\n"); + fastfw = 0; + set_i2c_delay(client, 10); + + if (sent > 2) { + u16 dl_addr = cx25840_read(client, 0x801) << 8; + dl_addr |= cx25840_read(client, 0x800); + dl_addr -= sent - 2; + cx25840_write(client, 0x801, dl_addr >> 8); + cx25840_write(client, 0x800, dl_addr & 0xff); + } + + if (i2c_master_send(client, data, size) < size) { + v4l_err(client, "100MHz i2c firmware load failed\n"); + return -ENOSYS; + } + + } else { + v4l_err(client, "firmware load i2c failure\n"); + return -ENOSYS; + } + } return 0; diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index f80154b87d22..c7042cf41231 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -564,7 +564,7 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_PCHDTV_HD3000] = { .name = "pcHDTV HD3000 HDTV", - .tuner_type = TUNER_THOMSON_DTT761X, + .tuner_type = TUNER_THOMSON_DTT7610, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, diff --git a/trunk/drivers/media/video/cx88/cx88-core.c b/trunk/drivers/media/video/cx88/cx88-core.c index e1092d5d4628..2c3d9f1999be 100644 --- a/trunk/drivers/media/video/cx88/cx88-core.c +++ b/trunk/drivers/media/video/cx88/cx88-core.c @@ -146,11 +146,9 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, fields++; /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Padding - can cause next bpl to start close to a page border. First DMA - region may be smaller than PAGE_SIZE */ - instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); - instructions += 2; + one write per scan line + syncs + jump (all 2 dwords) */ + instructions = (bpl * lines * fields) / PAGE_SIZE + lines * fields; + instructions += 3 + 4; if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0) return rc; @@ -178,11 +176,9 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, int rc; /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Here - there is no padding and no sync. First DMA region may be smaller - than PAGE_SIZE */ - instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; - instructions += 1; + one write per scan line + syncs + jump (all 2 dwords) */ + instructions = (bpl * lines) / PAGE_SIZE + lines; + instructions += 3 + 4; if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0) return rc; diff --git a/trunk/drivers/media/video/cx88/cx88-dvb.c b/trunk/drivers/media/video/cx88/cx88-dvb.c index 3619a449aefd..f0ea9b5cdbc2 100644 --- a/trunk/drivers/media/video/cx88/cx88-dvb.c +++ b/trunk/drivers/media/video/cx88/cx88-dvb.c @@ -372,7 +372,7 @@ static int or51132_set_ts_param(struct dvb_frontend* fe, static struct or51132_config pchdtv_hd3000 = { .demod_address = 0x15, .pll_address = 0x61, - .pll_desc = &dvb_pll_thomson_dtt761x, + .pll_desc = &dvb_pll_thomson_dtt7610, .set_ts_params = or51132_set_ts_param, }; #endif diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index 694d1d80ff3f..72a417b31745 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -35,10 +35,8 @@ #include "cx88.h" #include -#ifdef CONFIG_VIDEO_V4L1_COMPAT /* Include V4L1 specific functions. Should be removed soon */ #include -#endif MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); diff --git a/trunk/drivers/media/video/em28xx/Kconfig b/trunk/drivers/media/video/em28xx/Kconfig index dfb15bfb83dc..5a793ae7cc23 100644 --- a/trunk/drivers/media/video/em28xx/Kconfig +++ b/trunk/drivers/media/video/em28xx/Kconfig @@ -1,6 +1,6 @@ config VIDEO_EM28XX tristate "Empia EM2800/2820/2840 USB video capture support" - depends on VIDEO_V4L1 && USB && I2C + depends on VIDEO_DEV && USB && I2C select VIDEO_BUF select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c index cf7cdf9ef617..ddc92cbb5276 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-video.c +++ b/trunk/drivers/media/video/em28xx/em28xx-video.c @@ -1576,8 +1576,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, errCode = em28xx_config(dev); if (errCode) { em28xx_errdev("error configuring device\n"); - em28xx_devused&=~(1<devno); kfree(dev); + em28xx_devused&=~(1<devno); return -ENOMEM; } @@ -1603,8 +1603,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->vdev = video_device_alloc(); if (NULL == dev->vdev) { em28xx_errdev("cannot allocate video_device.\n"); - em28xx_devused&=~(1<devno); kfree(dev); + em28xx_devused&=~(1<devno); return -ENOMEM; } @@ -1612,8 +1612,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, if (NULL == dev->vbi_dev) { em28xx_errdev("cannot allocate video_device.\n"); kfree(dev->vdev); - em28xx_devused&=~(1<devno); kfree(dev); + em28xx_devused&=~(1<devno); return -ENOMEM; } @@ -1650,8 +1650,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, mutex_unlock(&dev->lock); list_del(&dev->devlist); video_device_release(dev->vdev); - em28xx_devused&=~(1<devno); kfree(dev); + em28xx_devused&=~(1<devno); return -ENODEV; } @@ -1662,8 +1662,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, list_del(&dev->devlist); video_device_release(dev->vbi_dev); video_device_release(dev->vdev); - em28xx_devused&=~(1<devno); kfree(dev); + em28xx_devused&=~(1<devno); return -ENODEV; } else { printk("registered VBI\n"); diff --git a/trunk/drivers/media/video/et61x251/Kconfig b/trunk/drivers/media/video/et61x251/Kconfig index c6bff705688d..6c43a90c6569 100644 --- a/trunk/drivers/media/video/et61x251/Kconfig +++ b/trunk/drivers/media/video/et61x251/Kconfig @@ -1,6 +1,6 @@ config USB_ET61X251 tristate "USB ET61X[12]51 PC Camera Controller support" - depends on USB && VIDEO_V4L1 + depends on USB && VIDEO_DEV ---help--- Say Y here if you want support for cameras based on Etoms ET61X151 or ET61X251 PC Camera Controllers. diff --git a/trunk/drivers/media/video/pwc/Kconfig b/trunk/drivers/media/video/pwc/Kconfig index 53cbc950f95c..86376556f108 100644 --- a/trunk/drivers/media/video/pwc/Kconfig +++ b/trunk/drivers/media/video/pwc/Kconfig @@ -1,6 +1,6 @@ config USB_PWC tristate "USB Philips Cameras" - depends on USB && VIDEO_V4L1 + depends on USB && VIDEO_DEV ---help--- Say Y or M here if you want to use one of these Philips & OEM webcams: diff --git a/trunk/drivers/media/video/pwc/Makefile b/trunk/drivers/media/video/pwc/Makefile index 33d60126c024..8326684f49f3 100644 --- a/trunk/drivers/media/video/pwc/Makefile +++ b/trunk/drivers/media/video/pwc/Makefile @@ -1,3 +1,20 @@ +ifneq ($(KERNELRELEASE),) + pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o obj-$(CONFIG_USB_PWC) += pwc.o + +else + +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) + +default: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules + +endif + +clean: + rm -f *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c + rm -rf .tmp_versions + diff --git a/trunk/drivers/media/video/saa7127.c b/trunk/drivers/media/video/saa7127.c index c271e2e14105..133f9e5252fe 100644 --- a/trunk/drivers/media/video/saa7127.c +++ b/trunk/drivers/media/video/saa7127.c @@ -142,7 +142,6 @@ struct i2c_reg_value { static const struct i2c_reg_value saa7129_init_config_extra[] = { { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 }, { SAA7127_REG_VTRIG, 0xfa }, - { 0, 0 } }; static const struct i2c_reg_value saa7127_init_config_common[] = { diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c index 86eae3528330..e666a4465ca4 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-cards.c +++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c @@ -3504,7 +3504,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) /* power-up tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); - break; case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: /* this turns the remote control chip off to work around a bug in it */ saa_writeb(SAA7134_GPIO_GPMODE1, 0x80); diff --git a/trunk/drivers/media/video/saa7134/saa7134-core.c b/trunk/drivers/media/video/saa7134/saa7134-core.c index f0c2111f14ad..13de05532e0a 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-core.c +++ b/trunk/drivers/media/video/saa7134/saa7134-core.c @@ -548,8 +548,6 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) if (report & SAA7134_IRQ_REPORT_GPIO16) { switch (dev->has_remote) { case SAA7134_REMOTE_GPIO: - if (!dev->remote) - break; if (dev->remote->mask_keydown & 0x10000) { saa7134_input_irq(dev); } @@ -566,8 +564,6 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) if (report & SAA7134_IRQ_REPORT_GPIO18) { switch (dev->has_remote) { case SAA7134_REMOTE_GPIO: - if (!dev->remote) - break; if ((dev->remote->mask_keydown & 0x40000) || (dev->remote->mask_keyup & 0x40000)) { saa7134_input_irq(dev); @@ -680,7 +676,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev) SAA7134_IRQ2_INTE_PE | SAA7134_IRQ2_INTE_AR; - if (dev->has_remote == SAA7134_REMOTE_GPIO && dev->remote) { + if (dev->has_remote == SAA7134_REMOTE_GPIO) { if (dev->remote->mask_keydown & 0x10000) irq2_mask |= SAA7134_IRQ2_INTE_GPIO16; else if (dev->remote->mask_keydown & 0x40000) diff --git a/trunk/drivers/media/video/saa7134/saa7134-video.c b/trunk/drivers/media/video/saa7134/saa7134-video.c index e4156ec9c6d7..aeef80f88a6b 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-video.c +++ b/trunk/drivers/media/video/saa7134/saa7134-video.c @@ -31,10 +31,8 @@ #include "saa7134.h" #include -#ifdef CONFIG_VIDEO_V4L1_COMPAT /* Include V4L1 specific functions. Should be removed soon */ #include -#endif /* ------------------------------------------------------------------ */ diff --git a/trunk/drivers/media/video/sn9c102/Kconfig b/trunk/drivers/media/video/sn9c102/Kconfig index cf552e6b8ecf..55f2bc11964b 100644 --- a/trunk/drivers/media/video/sn9c102/Kconfig +++ b/trunk/drivers/media/video/sn9c102/Kconfig @@ -1,6 +1,6 @@ config USB_SN9C102 tristate "USB SN9C10x PC Camera Controller support" - depends on USB && VIDEO_V4L1 + depends on USB && VIDEO_DEV ---help--- Say Y here if you want support for cameras based on SONiX SN9C101, SN9C102 or SN9C103 PC Camera Controllers. diff --git a/trunk/drivers/media/video/tuner-types.c b/trunk/drivers/media/video/tuner-types.c index a1ae036b44ec..72e0f01db563 100644 --- a/trunk/drivers/media/video/tuner-types.c +++ b/trunk/drivers/media/video/tuner-types.c @@ -877,8 +877,8 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { /* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */ static struct tuner_range tuner_tua6034_ntsc_ranges[] = { - { 16 * 165.00 /*MHz*/, 0x8e, 0x01 }, - { 16 * 450.00 /*MHz*/, 0x8e, 0x02 }, + { 16 * 160.00 /*MHz*/, 0x8e, 0x01 }, + { 16 * 455.00 /*MHz*/, 0x8e, 0x02 }, { 16 * 999.99 , 0x8e, 0x04 }, }; diff --git a/trunk/drivers/media/video/tveeprom.c b/trunk/drivers/media/video/tveeprom.c index b463e996961a..431c3e2f6c42 100644 --- a/trunk/drivers/media/video/tveeprom.c +++ b/trunk/drivers/media/video/tveeprom.c @@ -218,7 +218,7 @@ hauppauge_tuner[] = /* 110-119 */ { TUNER_ABSENT, "Thompson DTT75105"}, { TUNER_ABSENT, "Conexant_CX24109"}, - { TUNER_TCL_2002N, "TCL M2523_5N_E"}, + { TUNER_ABSENT, "TCL M2523_5N_E"}, { TUNER_ABSENT, "TCL M2523_3DB_E"}, { TUNER_ABSENT, "Philips 8275A"}, { TUNER_ABSENT, "Microtune MT2060"}, diff --git a/trunk/drivers/media/video/usbvideo/Kconfig b/trunk/drivers/media/video/usbvideo/Kconfig index 39269a2c5635..08a5d20bb2c0 100644 --- a/trunk/drivers/media/video/usbvideo/Kconfig +++ b/trunk/drivers/media/video/usbvideo/Kconfig @@ -3,7 +3,7 @@ config VIDEO_USBVIDEO config USB_VICAM tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)" - depends on USB && VIDEO_V4L1 && EXPERIMENTAL + depends on USB && VIDEO_DEV && EXPERIMENTAL select VIDEO_USBVIDEO ---help--- Say Y here if you have 3com homeconnect camera (vicam). @@ -13,7 +13,7 @@ config USB_VICAM config USB_IBMCAM tristate "USB IBM (Xirlink) C-it Camera support" - depends on USB && VIDEO_V4L1 + depends on USB && VIDEO_DEV select VIDEO_USBVIDEO ---help--- Say Y here if you want to connect a IBM "C-It" camera, also known as @@ -28,7 +28,7 @@ config USB_IBMCAM config USB_KONICAWC tristate "USB Konica Webcam support" - depends on USB && VIDEO_V4L1 + depends on USB && VIDEO_DEV select VIDEO_USBVIDEO ---help--- Say Y here if you want support for webcams based on a Konica diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index 779db26771c0..5e813404d068 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -26,11 +26,6 @@ #include #include #include -#include -#ifdef CONFIG_VIDEO_V4L1_COMPAT -/* Include V4L1 specific functions. Should be removed soon */ -#include -#endif #include #include #include diff --git a/trunk/drivers/media/video/zc0301/Kconfig b/trunk/drivers/media/video/zc0301/Kconfig index 115833e4f4dd..c3bf886b80cd 100644 --- a/trunk/drivers/media/video/zc0301/Kconfig +++ b/trunk/drivers/media/video/zc0301/Kconfig @@ -1,6 +1,6 @@ config USB_ZC0301 tristate "USB ZC0301 Image Processor and Control Chip support" - depends on USB && VIDEO_V4L1 + depends on USB && VIDEO_DEV ---help--- Say Y here if you want support for cameras based on the ZC0301 Image Processor and Control Chip. diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index 9080853fe283..266414ca2814 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -1189,6 +1189,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->diagPending = 0; spin_lock_init(&ioc->diagLock); spin_lock_init(&ioc->fc_rescan_work_lock); + spin_lock_init(&ioc->fc_rport_lock); spin_lock_init(&ioc->initializing_hba_lock); /* Initialize the event logging. @@ -5735,13 +5736,11 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) return rc; } -# define EVENT_DESCR_STR_SZ 100 - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static void EventDescriptionStr(u8 event, u32 evData0, char *evStr) { - char *ds = NULL; + char *ds; switch(event) { case MPI_EVENT_NONE: @@ -5778,9 +5777,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP) ds = "Loop State(LIP) Change"; else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE) - ds = "Loop State(LPE) Change"; /* ??? */ + ds = "Loop State(LPE) Change"; /* ??? */ else - ds = "Loop State(LPB) Change"; /* ??? */ + ds = "Loop State(LPB) Change"; /* ??? */ break; case MPI_EVENT_LOGOUT: ds = "Logout"; @@ -5842,32 +5841,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) break; case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: { + char buf[50]; u8 id = (u8)(evData0); u8 ReasonCode = (u8)(evData0 >> 16); switch (ReasonCode) { case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: Added: id=%d", id); + sprintf(buf,"SAS Device Status Change: Added: id=%d", id); break; case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: Deleted: id=%d", id); + sprintf(buf,"SAS Device Status Change: Deleted: id=%d", id); break; case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: SMART Data: id=%d", - id); + sprintf(buf,"SAS Device Status Change: SMART Data: id=%d", id); break; case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: No Persistancy " - "Added: id=%d", id); + sprintf(buf,"SAS Device Status Change: No Persistancy Added: id=%d", id); break; default: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: Unknown: id=%d", id); - break; + sprintf(buf,"SAS Device Status Change: Unknown: id=%d", id); + break; } + ds = buf; break; } case MPI_EVENT_ON_BUS_TIMER_EXPIRED: @@ -5884,46 +5878,41 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) break; case MPI_EVENT_SAS_PHY_LINK_STATUS: { + char buf[50]; u8 LinkRates = (u8)(evData0 >> 8); u8 PhyNumber = (u8)(evData0); LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >> MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT; switch (LinkRates) { case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" + sprintf(buf,"SAS PHY Link Status: Phy=%d:" " Rate Unknown",PhyNumber); break; case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" + sprintf(buf,"SAS PHY Link Status: Phy=%d:" " Phy Disabled",PhyNumber); break; case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" + sprintf(buf,"SAS PHY Link Status: Phy=%d:" " Failed Speed Nego",PhyNumber); break; case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" + sprintf(buf,"SAS PHY Link Status: Phy=%d:" " Sata OOB Completed",PhyNumber); break; case MPI_EVENT_SAS_PLS_LR_RATE_1_5: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" + sprintf(buf,"SAS PHY Link Status: Phy=%d:" " Rate 1.5 Gbps",PhyNumber); break; case MPI_EVENT_SAS_PLS_LR_RATE_3_0: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" + sprintf(buf,"SAS PHY Link Status: Phy=%d:" " Rate 3.0 Gpbs",PhyNumber); break; default: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d", PhyNumber); + sprintf(buf,"SAS PHY Link Status: Phy=%d", PhyNumber); break; } + ds = buf; break; } case MPI_EVENT_SAS_DISCOVERY_ERROR: @@ -5932,8 +5921,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) case MPI_EVENT_IR_RESYNC_UPDATE: { u8 resync_complete = (u8)(evData0 >> 16); - snprintf(evStr, EVENT_DESCR_STR_SZ, - "IR Resync Update: Complete = %d:",resync_complete); + char buf[40]; + sprintf(buf,"IR Resync Update: Complete = %d:",resync_complete); + ds = buf; break; } case MPI_EVENT_IR2: @@ -5986,8 +5976,7 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) ds = "Unknown"; break; } - if (ds) - strncpy(evStr, ds, EVENT_DESCR_STR_SZ); + strcpy(evStr,ds); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -6009,7 +5998,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply int ii; int r = 0; int handlers = 0; - char evStr[EVENT_DESCR_STR_SZ]; + char evStr[100]; u8 event; /* diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h index f673cca507e1..be7e8501b53c 100644 --- a/trunk/drivers/message/fusion/mptbase.h +++ b/trunk/drivers/message/fusion/mptbase.h @@ -76,8 +76,8 @@ #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.03.09" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.09" +#define MPT_LINUX_VERSION_COMMON "3.03.08" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.08" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -489,6 +489,7 @@ typedef struct _RaidCfgData { #define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */ #define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */ +#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV 0x04 /* target mapped in vdev */ /* * data allocated for each fc rport device @@ -500,6 +501,7 @@ struct mptfc_rport_info struct scsi_target *starget; FCDevicePage0_t pg0; u8 flags; + u8 remap_needed; }; /* @@ -626,11 +628,11 @@ typedef struct _MPT_ADAPTER struct work_struct mptscsih_persistTask; struct list_head fc_rports; + spinlock_t fc_rport_lock; /* list and ri flags */ spinlock_t fc_rescan_work_lock; int fc_rescan_work_count; struct work_struct fc_rescan_work; - char fc_rescan_work_q_name[KOBJ_NAME_LEN]; - struct workqueue_struct *fc_rescan_work_q; + } MPT_ADAPTER; /* diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c index 856487741ef4..b343f2a68b1c 100644 --- a/trunk/drivers/message/fusion/mptfc.c +++ b/trunk/drivers/message/fusion/mptfc.c @@ -341,6 +341,9 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid) rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low; rid->port_id = pg0->PortIdentifier; rid->roles = FC_RPORT_ROLE_UNKNOWN; + rid->roles |= FC_RPORT_ROLE_FCP_TARGET; + if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR) + rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR; return 0; } @@ -352,18 +355,15 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) struct fc_rport *rport; struct mptfc_rport_info *ri; int new_ri = 1; - u64 pn, nn; + u64 pn; + unsigned long flags; VirtTarget *vtarget; - u32 roles = FC_RPORT_ROLE_UNKNOWN; if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0) return; - roles |= FC_RPORT_ROLE_FCP_TARGET; - if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR) - roles |= FC_RPORT_ROLE_FCP_INITIATOR; - /* scan list looking for a match */ + spin_lock_irqsave(&ioc->fc_rport_lock, flags); list_for_each_entry(ri, &ioc->fc_rports, list) { pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; if (pn == rport_ids.port_name) { /* match */ @@ -373,9 +373,11 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) } } if (new_ri) { /* allocate one */ + spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL); if (!ri) return; + spin_lock_irqsave(&ioc->fc_rport_lock, flags); list_add_tail(&ri->list, &ioc->fc_rports); } @@ -385,11 +387,14 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */ if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) { ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED; + spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); rport = fc_remote_port_add(ioc->sh, channel, &rport_ids); + spin_lock_irqsave(&ioc->fc_rport_lock, flags); if (rport) { ri->rport = rport; if (new_ri) /* may have been reset by user */ rport->dev_loss_tmo = mptfc_dev_loss_tmo; + *((struct mptfc_rport_info **)rport->dd_data) = ri; /* * if already mapped, remap here. If not mapped, * target_alloc will allocate vtarget and map, @@ -401,21 +406,16 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) vtarget->target_id = pg0->CurrentTargetID; vtarget->bus_id = pg0->CurrentBus; } + ri->remap_needed = 0; } - *((struct mptfc_rport_info **)rport->dd_data) = ri; - /* scan will be scheduled once rport becomes a target */ - fc_remote_port_rolechg(rport,roles); - - pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; - nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low; dfcprintk ((MYIOC_s_INFO_FMT "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " "rport tid %d, tmo %d\n", ioc->name, ioc->sh->host_no, pg0->PortIdentifier, - (unsigned long long)nn, - (unsigned long long)pn, + pg0->WWNN, + pg0->WWPN, pg0->CurrentTargetID, ri->rport->scsi_target_id, ri->rport->dev_loss_tmo)); @@ -425,6 +425,8 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) ri = NULL; } } + spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); + } /* @@ -474,6 +476,7 @@ mptfc_target_alloc(struct scsi_target *starget) vtarget->target_id = ri->pg0.CurrentTargetID; vtarget->bus_id = ri->pg0.CurrentBus; ri->starget = starget; + ri->remap_needed = 0; rc = 0; } } @@ -499,10 +502,10 @@ mptfc_slave_alloc(struct scsi_device *sdev) VirtDevice *vdev; struct scsi_target *starget; struct fc_rport *rport; + unsigned long flags; - starget = scsi_target(sdev); - rport = starget_to_rport(starget); + rport = starget_to_rport(scsi_target(sdev)); if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; @@ -516,8 +519,10 @@ mptfc_slave_alloc(struct scsi_device *sdev) return -ENOMEM; } + spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags); sdev->hostdata = vdev; + starget = scsi_target(sdev); vtarget = starget->hostdata; if (vtarget->num_luns == 0) { @@ -530,16 +535,14 @@ mptfc_slave_alloc(struct scsi_device *sdev) vdev->vtarget = vtarget; vdev->lun = sdev->lun; - vtarget->num_luns++; + spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags); + vtarget->num_luns++; #ifdef DMPT_DEBUG_FC - { - u64 nn, pn; + { struct mptfc_rport_info *ri; ri = *((struct mptfc_rport_info **)rport->dd_data); - pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; - nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low; dfcprintk ((MYIOC_s_INFO_FMT "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " "CurrentTargetID %d, %x %llx %llx\n", @@ -547,9 +550,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) sdev->host->host_no, vtarget->num_luns, sdev->id, ri->pg0.CurrentTargetID, - ri->pg0.PortIdentifier, - (unsigned long long)pn, - (unsigned long long)nn)); + ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN)); } #endif @@ -569,31 +570,11 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) done(SCpnt); return 0; } - - /* dd_data is null until finished adding target */ ri = *((struct mptfc_rport_info **)rport->dd_data); - if (unlikely(!ri)) { - dfcprintk ((MYIOC_s_INFO_FMT - "mptfc_qcmd.%d: %d:%d, dd_data is null.\n", - ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun)); - SCpnt->result = DID_IMM_RETRY << 16; - done(SCpnt); - return 0; - } + if (unlikely(ri->remap_needed)) + return SCSI_MLQUEUE_HOST_BUSY; - err = mptscsih_qcmd(SCpnt,done); -#ifdef DMPT_DEBUG_FC - if (unlikely(err)) { - dfcprintk ((MYIOC_s_INFO_FMT - "mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero.\n", - ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun)); - } -#endif - return err; + return mptscsih_qcmd(SCpnt,done); } static void @@ -634,17 +615,18 @@ mptfc_rescan_devices(void *arg) MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; int ii; int work_to_do; - u64 pn; unsigned long flags; struct mptfc_rport_info *ri; do { /* start by tagging all ports as missing */ + spin_lock_irqsave(&ioc->fc_rport_lock,flags); list_for_each_entry(ri, &ioc->fc_rports, list) { if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING; } } + spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); /* * now rescan devices known to adapter, @@ -657,24 +639,33 @@ mptfc_rescan_devices(void *arg) } /* delete devices still missing */ + spin_lock_irqsave(&ioc->fc_rport_lock, flags); list_for_each_entry(ri, &ioc->fc_rports, list) { /* if newly missing, delete it */ - if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) { + if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED | + MPT_RPORT_INFO_FLAGS_MISSING)) + == (MPT_RPORT_INFO_FLAGS_REGISTERED | + MPT_RPORT_INFO_FLAGS_MISSING)) { ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| MPT_RPORT_INFO_FLAGS_MISSING); - fc_remote_port_delete(ri->rport); /* won't sleep */ + ri->remap_needed = 1; + fc_remote_port_delete(ri->rport); + /* + * remote port not really deleted 'cause + * binding is by WWPN and driver only + * registers FCP_TARGETs but cannot trust + * data structures. + */ ri->rport = NULL; - - pn = (u64)ri->pg0.WWPN.High << 32 | - (u64)ri->pg0.WWPN.Low; dfcprintk ((MYIOC_s_INFO_FMT "mptfc_rescan.%d: %llx deleted\n", ioc->name, ioc->sh->host_no, - (unsigned long long)pn)); + ri->pg0.WWPN)); } } + spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); /* * allow multiple passes as target state @@ -879,23 +870,10 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_mptfc_probe; } - /* initialize workqueue */ - - snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d", - sh->host_no); - ioc->fc_rescan_work_q = - create_singlethread_workqueue(ioc->fc_rescan_work_q_name); - if (!ioc->fc_rescan_work_q) - goto out_mptfc_probe; - - /* - * scan for rports - - * by doing it via the workqueue, some locking is eliminated - */ - - ioc->fc_rescan_work_count = 1; - queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work); - flush_workqueue(ioc->fc_rescan_work_q); + for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { + mptfc_init_host_attr(ioc,ii); + mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); + } return 0; @@ -971,18 +949,8 @@ mptfc_init(void) static void __devexit mptfc_remove(struct pci_dev *pdev) { - MPT_ADAPTER *ioc = pci_get_drvdata(pdev); - struct mptfc_rport_info *p, *n; - struct workqueue_struct *work_q; - unsigned long flags; - - /* destroy workqueue */ - if ((work_q=ioc->fc_rescan_work_q)) { - spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); - ioc->fc_rescan_work_q = NULL; - spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); - destroy_workqueue(work_q); - } + MPT_ADAPTER *ioc = pci_get_drvdata(pdev); + struct mptfc_rport_info *p, *n; fc_remove_host(ioc->sh); diff --git a/trunk/drivers/message/fusion/mptsas.c b/trunk/drivers/message/fusion/mptsas.c index af6ec553ff7c..e9716b10acea 100644 --- a/trunk/drivers/message/fusion/mptsas.c +++ b/trunk/drivers/message/fusion/mptsas.c @@ -91,7 +91,6 @@ enum mptsas_hotplug_action { MPTSAS_DEL_DEVICE, MPTSAS_ADD_RAID, MPTSAS_DEL_RAID, - MPTSAS_IGNORE_EVENT, }; struct mptsas_hotplug_event { @@ -299,26 +298,6 @@ mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle) return rc; } -/* - * Returns true if there is a scsi end device - */ -static inline int -mptsas_is_end_device(struct mptsas_devinfo * attached) -{ - if ((attached->handle) && - (attached->device_info & - MPI_SAS_DEVICE_INFO_END_DEVICE) && - ((attached->device_info & - MPI_SAS_DEVICE_INFO_SSP_TARGET) | - (attached->device_info & - MPI_SAS_DEVICE_INFO_STP_TARGET) | - (attached->device_info & - MPI_SAS_DEVICE_INFO_SATA_DEVICE))) - return 1; - else - return 0; -} - static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, u32 form, u32 form_specific) @@ -893,11 +872,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, SasDevicePage0_t *buffer; dma_addr_t dma_handle; __le64 sas_address; - int error=0; - - if (ioc->sas_discovery_runtime && - mptsas_is_end_device(device_info)) - goto out; + int error; hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION; hdr.ExtPageLength = 0; @@ -1034,11 +1009,7 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, CONFIGPARMS cfg; SasExpanderPage1_t *buffer; dma_addr_t dma_handle; - int error=0; - - if (ioc->sas_discovery_runtime && - mptsas_is_end_device(&phy_info->attached)) - goto out; + int error; hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; hdr.ExtPageLength = 0; @@ -1097,6 +1068,26 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, return error; } +/* + * Returns true if there is a scsi end device + */ +static inline int +mptsas_is_end_device(struct mptsas_devinfo * attached) +{ + if ((attached->handle) && + (attached->device_info & + MPI_SAS_DEVICE_INFO_END_DEVICE) && + ((attached->device_info & + MPI_SAS_DEVICE_INFO_SSP_TARGET) | + (attached->device_info & + MPI_SAS_DEVICE_INFO_STP_TARGET) | + (attached->device_info & + MPI_SAS_DEVICE_INFO_SATA_DEVICE))) + return 1; + else + return 0; +} + static void mptsas_parse_device_info(struct sas_identify *identify, struct mptsas_devinfo *device_info) @@ -1746,9 +1737,6 @@ mptsas_hotplug_work(void *arg) break; case MPTSAS_ADD_DEVICE: - if (ev->phys_disk_num_valid) - mpt_findImVolumes(ioc); - /* * Refresh sas device pg0 data */ @@ -1880,9 +1868,6 @@ mptsas_hotplug_work(void *arg) scsi_device_put(sdev); mpt_findImVolumes(ioc); break; - case MPTSAS_IGNORE_EVENT: - default: - break; } kfree(ev); @@ -1955,8 +1940,7 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, EVENT_DATA_RAID *raid_event_data) { struct mptsas_hotplug_event *ev; - int status = le32_to_cpu(raid_event_data->SettingsStatus); - int state = (status >> 8) & 0xff; + RAID_VOL0_STATUS * volumeStatus; if (ioc->bus_type != SAS) return; @@ -1971,7 +1955,6 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, INIT_WORK(&ev->work, mptsas_hotplug_work, ev); ev->ioc = ioc; ev->id = raid_event_data->VolumeID; - ev->event_type = MPTSAS_IGNORE_EVENT; switch (raid_event_data->ReasonCode) { case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: @@ -1983,25 +1966,6 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, ev->phys_disk_num = raid_event_data->PhysDiskNum; ev->event_type = MPTSAS_DEL_DEVICE; break; - case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: - switch (state) { - case MPI_PD_STATE_ONLINE: - ioc->raid_data.isRaid = 1; - ev->phys_disk_num_valid = 1; - ev->phys_disk_num = raid_event_data->PhysDiskNum; - ev->event_type = MPTSAS_ADD_DEVICE; - break; - case MPI_PD_STATE_MISSING: - case MPI_PD_STATE_NOT_COMPATIBLE: - case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST: - case MPI_PD_STATE_FAILED_AT_HOST_REQUEST: - case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON: - ev->event_type = MPTSAS_DEL_DEVICE; - break; - default: - break; - } - break; case MPI_EVENT_RAID_RC_VOLUME_DELETED: ev->event_type = MPTSAS_DEL_RAID; break; @@ -2009,18 +1973,11 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, ev->event_type = MPTSAS_ADD_RAID; break; case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: - switch (state) { - case MPI_RAIDVOL0_STATUS_STATE_FAILED: - case MPI_RAIDVOL0_STATUS_STATE_MISSING: - ev->event_type = MPTSAS_DEL_RAID; - break; - case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL: - case MPI_RAIDVOL0_STATUS_STATE_DEGRADED: - ev->event_type = MPTSAS_ADD_RAID; - break; - default: - break; - } + volumeStatus = (RAID_VOL0_STATUS *) & + raid_event_data->SettingsStatus; + ev->event_type = (volumeStatus->State == + MPI_RAIDVOL0_STATUS_STATE_FAILED) ? + MPTSAS_DEL_RAID : MPTSAS_ADD_RAID; break; default: break; diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c index 84fa271eb8f4..3729062db317 100644 --- a/trunk/drivers/message/fusion/mptscsih.c +++ b/trunk/drivers/message/fusion/mptscsih.c @@ -632,11 +632,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ /* Spoof to SCSI Selection Timeout! */ - if (ioc->bus_type != FC) - sc->result = DID_NO_CONNECT << 16; - /* else fibre, just stall until rescan event */ - else - sc->result = DID_REQUEUE << 16; + sc->result = DID_NO_CONNECT << 16; if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF) hd->sel_timeout[pScsiReq->TargetID]++; @@ -881,7 +877,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) struct scsi_cmnd *sc; dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", - vdevice->vtarget->target_id, vdevice->lun, max)); + vdevice->target_id, vdevice->lun, max)); for (ii=0; ii < max; ii++) { if ((sc = hd->ScsiLookup[ii]) != NULL) { @@ -1649,6 +1645,7 @@ int mptscsih_abort(struct scsi_cmnd * SCpnt) { MPT_SCSI_HOST *hd; + MPT_ADAPTER *ioc; MPT_FRAME_HDR *mf; u32 ctx2abort; int scpnt_idx; @@ -1666,6 +1663,14 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) return FAILED; } + ioc = hd->ioc; + if (hd->resetPending) { + return FAILED; + } + + if (hd->timeouts < -1) + hd->timeouts++; + /* Find this command */ if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { @@ -1679,13 +1684,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) return SUCCESS; } - if (hd->resetPending) { - return FAILED; - } - - if (hd->timeouts < -1) - hd->timeouts++; - printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n", hd->ioc->name, SCpnt); scsi_print_command(SCpnt); @@ -1705,7 +1703,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) vdev = SCpnt->device->hostdata; retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, - ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); + ctx2abort, mptscsih_get_tm_timeout(ioc)); printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", hd->ioc->name, @@ -2523,15 +2521,15 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) /* 7. FC: Rescan for blocked rports which might have returned. */ - if (ioc->bus_type == FC) { + else if (ioc->bus_type == FC) { + int work_count; + unsigned long flags; + spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); - if (ioc->fc_rescan_work_q) { - if (ioc->fc_rescan_work_count++ == 0) { - queue_work(ioc->fc_rescan_work_q, - &ioc->fc_rescan_work); - } - } + work_count = ++ioc->fc_rescan_work_count; spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); + if (work_count == 1) + schedule_work(&ioc->fc_rescan_work); } dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); @@ -2546,6 +2544,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) { MPT_SCSI_HOST *hd; u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; + int work_count; unsigned long flags; devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", @@ -2570,13 +2569,10 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) case MPI_EVENT_RESCAN: /* 06 */ spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); - if (ioc->fc_rescan_work_q) { - if (ioc->fc_rescan_work_count++ == 0) { - queue_work(ioc->fc_rescan_work_q, - &ioc->fc_rescan_work); - } - } + work_count = ++ioc->fc_rescan_work_count; spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); + if (work_count == 1) + schedule_work(&ioc->fc_rescan_work); break; /* diff --git a/trunk/drivers/message/fusion/mptspi.c b/trunk/drivers/message/fusion/mptspi.c index f2a4d382ea19..09c745b19cc8 100644 --- a/trunk/drivers/message/fusion/mptspi.c +++ b/trunk/drivers/message/fusion/mptspi.c @@ -783,70 +783,6 @@ static struct pci_device_id mptspi_pci_table[] = { }; MODULE_DEVICE_TABLE(pci, mptspi_pci_table); - -/* - * renegotiate for a given target - */ -static void -mptspi_dv_renegotiate_work(void *data) -{ - struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; - struct _MPT_SCSI_HOST *hd = wqw->hd; - struct scsi_device *sdev; - - kfree(wqw); - - shost_for_each_device(sdev, hd->ioc->sh) - mptspi_dv_device(hd, sdev); -} - -static void -mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd) -{ - struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC); - - if (!wqw) - return; - - INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work, wqw); - wqw->hd = hd; - - schedule_work(&wqw->work); -} - -/* - * spi module reset handler - */ -static int -mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) -{ - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; - int rc; - - rc = mptscsih_ioc_reset(ioc, reset_phase); - - if (reset_phase == MPT_IOC_POST_RESET) - mptspi_dv_renegotiate(hd); - - return rc; -} - -/* - * spi module resume handler - */ -static int -mptspi_resume(struct pci_dev *pdev) -{ - MPT_ADAPTER *ioc = pci_get_drvdata(pdev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; - int rc; - - rc = mptscsih_resume(pdev); - mptspi_dv_renegotiate(hd); - - return rc; -} - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -1096,7 +1032,7 @@ static struct pci_driver mptspi_driver = { .shutdown = mptscsih_shutdown, #ifdef CONFIG_PM .suspend = mptscsih_suspend, - .resume = mptspi_resume, + .resume = mptscsih_resume, #endif }; @@ -1125,7 +1061,7 @@ mptspi_init(void) ": Registered for IOC event notifications\n")); } - if (mpt_reset_register(mptspiDoneCtx, mptspi_ioc_reset) == 0) { + if (mpt_reset_register(mptspiDoneCtx, mptscsih_ioc_reset) == 0) { dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n")); } diff --git a/trunk/drivers/mmc/au1xmmc.c b/trunk/drivers/mmc/au1xmmc.c index 5dc4bee7abeb..914d62b24064 100644 --- a/trunk/drivers/mmc/au1xmmc.c +++ b/trunk/drivers/mmc/au1xmmc.c @@ -310,7 +310,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) } else data->bytes_xfered = - (data->blocks * data->blksz) - + (data->blocks * (1 << data->blksz_bits)) - host->pio.len; } @@ -575,7 +575,7 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) { - int datalen = data->blocks * data->blksz; + int datalen = data->blocks * (1 << data->blksz_bits); if (dma != 0) host->flags |= HOST_F_DMA; @@ -596,7 +596,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) if (host->dma.len == 0) return MMC_ERR_TIMEOUT; - au_writel(data->blksz - 1, HOST_BLKSIZE(host)); + au_writel((1 << data->blksz_bits) - 1, HOST_BLKSIZE(host)); if (host->flags & HOST_F_DMA) { int i; diff --git a/trunk/drivers/mmc/imxmmc.c b/trunk/drivers/mmc/imxmmc.c index a4eb1d0e7a71..79358e223f57 100644 --- a/trunk/drivers/mmc/imxmmc.c +++ b/trunk/drivers/mmc/imxmmc.c @@ -218,10 +218,8 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host, if(!loops) return 0; - /* The busy-wait is expected there for clock <8MHz due to SDHC hardware flaws */ - if(!(stat_mask & STATUS_END_CMD_RESP) || (host->mmc->ios.clock>=8000000)) - dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n", - loops, where, *pstat, stat_mask); + dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n", + loops, where, *pstat, stat_mask); return loops; } @@ -335,9 +333,6 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, WARN_ON(host->cmd != NULL); host->cmd = cmd; - /* Ensure, that clock are stopped else command programming and start fails */ - imxmci_stop_clock(host); - if (cmd->flags & MMC_RSP_BUSY) cmdat |= CMD_DAT_CONT_BUSY; @@ -558,7 +553,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) int trans_done = 0; unsigned int stat = *pstat; - if(host->actual_bus_width != MMC_BUS_WIDTH_4) + if(host->actual_bus_width == MMC_BUS_WIDTH_4) burst_len = 16; else burst_len = 64; @@ -596,7 +591,8 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) stat = MMC_STATUS; /* Flush extra bytes from FIFO */ - while(flush_len && !(stat & STATUS_DATA_TRANS_DONE)){ + while(flush_len >= 2){ + flush_len -= 2; i = MMC_BUFFER_ACCESS; stat = MMC_STATUS; stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */ @@ -750,6 +746,10 @@ static void imxmci_tasklet_fnc(unsigned long data) data_dir_mask = STATUS_DATA_TRANS_DONE; } + imxmci_busy_wait_for_status(host, &stat, + data_dir_mask, + 50, "imxmci_tasklet_fnc data"); + if(stat & data_dir_mask) { clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events); imxmci_data_done(host, stat); @@ -865,11 +865,7 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) imxmci_stop_clock(host); MMC_CLK_RATE = (prescaler<<3) | clk; - /* - * Under my understanding, clock should not be started there, because it would - * initiate SDHC sequencer and send last or random command into card - */ - /*imxmci_start_clock(host);*/ + imxmci_start_clock(host); dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE); } else { diff --git a/trunk/drivers/mmc/mmc.c b/trunk/drivers/mmc/mmc.c index 6201f3086a02..1ca2c8b9c9b5 100644 --- a/trunk/drivers/mmc/mmc.c +++ b/trunk/drivers/mmc/mmc.c @@ -951,7 +951,6 @@ static void mmc_read_scrs(struct mmc_host *host) data.timeout_ns = card->csd.tacc_ns * 10; data.timeout_clks = card->csd.tacc_clks * 10; data.blksz_bits = 3; - data.blksz = 1 << 3; data.blocks = 1; data.flags = MMC_DATA_READ; data.sg = &sg; diff --git a/trunk/drivers/mmc/mmc_block.c b/trunk/drivers/mmc/mmc_block.c index e39cc05c64c2..06bd1f4cb9b1 100644 --- a/trunk/drivers/mmc/mmc_block.c +++ b/trunk/drivers/mmc/mmc_block.c @@ -175,7 +175,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.data.timeout_ns = card->csd.tacc_ns * 10; brq.data.timeout_clks = card->csd.tacc_clks * 10; brq.data.blksz_bits = md->block_bits; - brq.data.blksz = 1 << md->block_bits; brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); brq.stop.opcode = MMC_STOP_TRANSMISSION; brq.stop.arg = 0; diff --git a/trunk/drivers/mmc/pxamci.c b/trunk/drivers/mmc/pxamci.c index b49368fd96b8..f97b472085cb 100644 --- a/trunk/drivers/mmc/pxamci.c +++ b/trunk/drivers/mmc/pxamci.c @@ -119,7 +119,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) nob = 0xffff; writel(nob, host->base + MMC_NOB); - writel(data->blksz, host->base + MMC_BLKLEN); + writel(1 << data->blksz_bits, host->base + MMC_BLKLEN); clks = (unsigned long long)data->timeout_ns * CLOCKRATE; do_div(clks, 1000000000UL); @@ -283,7 +283,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) * data blocks as being in error. */ if (data->error == MMC_ERR_NONE) - data->bytes_xfered = data->blocks * data->blksz; + data->bytes_xfered = data->blocks << data->blksz_bits; else data->bytes_xfered = 0; diff --git a/trunk/drivers/mmc/wbsd.c b/trunk/drivers/mmc/wbsd.c index 8167332d4013..39b3d97f891e 100644 --- a/trunk/drivers/mmc/wbsd.c +++ b/trunk/drivers/mmc/wbsd.c @@ -662,14 +662,14 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) unsigned long dmaflags; DBGF("blksz %04x blks %04x flags %08x\n", - data->blksz, data->blocks, data->flags); + 1 << data->blksz_bits, data->blocks, data->flags); DBGF("tsac %d ms nsac %d clk\n", data->timeout_ns / 1000000, data->timeout_clks); /* * Calculate size. */ - host->size = data->blocks * data->blksz; + host->size = data->blocks << data->blksz_bits; /* * Check timeout values for overflow. @@ -696,12 +696,12 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) * Two bytes are needed for each data line. */ if (host->bus_width == MMC_BUS_WIDTH_1) { - blksize = data->blksz + 2; + blksize = (1 << data->blksz_bits) + 2; wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); } else if (host->bus_width == MMC_BUS_WIDTH_4) { - blksize = data->blksz + 2 * 4; + blksize = (1 << data->blksz_bits) + 2 * 4; wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH); diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index f499a3bc629f..bdaaad8f2123 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -865,22 +865,6 @@ config DM9000 . The module will be called dm9000. -config SMC911X - tristate "SMSC LAN911[5678] support" - select CRC32 - select MII - depends on NET_ETHERNET - help - This is a driver for SMSC's LAN911x series of Ethernet chipsets - including the new LAN9115, LAN9116, LAN9117, and LAN9118. - Say Y if you want it compiled into the kernel, - and read the Ethernet-HOWTO, available from - . - - This driver is also available as a module. The module will be - called smc911x. If you want to compile it as a module, say M - here and read - config NET_VENDOR_RACAL bool "Racal-Interlan (Micom) NI cards" depends on NET_ETHERNET && ISA @@ -2327,23 +2311,6 @@ config S2IO_NAPI If in doubt, say N. -config MYRI10GE - tristate "Myricom Myri-10G Ethernet support" - depends on PCI - select FW_LOADER - select CRC32 - ---help--- - This driver supports Myricom Myri-10G Dual Protocol interface in - Ethernet mode. If the eeprom on your board is not recent enough, - you will need a newer firmware image. - You may get this image or more information, at: - - - - To compile this driver as a module, choose M here and read - . The module - will be called myri10ge. - endmenu source "drivers/net/tokenring/Kconfig" diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 1eced3287507..b90468aea077 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -192,9 +192,7 @@ obj-$(CONFIG_R8169) += r8169.o obj-$(CONFIG_AMD8111_ETH) += amd8111e.o obj-$(CONFIG_IBMVETH) += ibmveth.o obj-$(CONFIG_S2IO) += s2io.o -obj-$(CONFIG_MYRI10GE) += myri10ge/ obj-$(CONFIG_SMC91X) += smc91x.o -obj-$(CONFIG_SMC911X) += smc911x.o obj-$(CONFIG_DM9000) += dm9000.o obj-$(CONFIG_FEC_8XX) += fec_8xx/ diff --git a/trunk/drivers/net/au1000_eth.c b/trunk/drivers/net/au1000_eth.c index e1fe960d71b3..1363083b4d83 100644 --- a/trunk/drivers/net/au1000_eth.c +++ b/trunk/drivers/net/au1000_eth.c @@ -2,7 +2,7 @@ * * Alchemy Au1x00 ethernet driver * - * Copyright 2001-2003, 2006 MontaVista Software Inc. + * Copyright 2001,2002,2003 MontaVista Software Inc. * Copyright 2002 TimeSys Corp. * Added ethtool/mii-tool support, * Copyright 2004 Matt Porter @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include @@ -68,7 +67,7 @@ static int au1000_debug = 5; static int au1000_debug = 3; #endif -#define DRV_NAME "au1000_eth" +#define DRV_NAME "au1000eth" #define DRV_VERSION "1.5" #define DRV_AUTHOR "Pete Popov " #define DRV_DESC "Au1xxx on-chip Ethernet driver" @@ -80,7 +79,7 @@ MODULE_LICENSE("GPL"); // prototypes static void hard_stop(struct net_device *); static void enable_rx_tx(struct net_device *dev); -static struct net_device * au1000_probe(int port_num); +static struct net_device * au1000_probe(u32 ioaddr, int irq, int port_num); static int au1000_init(struct net_device *); static int au1000_open(struct net_device *); static int au1000_close(struct net_device *); @@ -1160,27 +1159,12 @@ setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base) } static struct { + int port; u32 base_addr; u32 macen_addr; int irq; struct net_device *dev; -} iflist[2] = { -#ifdef CONFIG_SOC_AU1000 - {AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT}, - {AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT} -#endif -#ifdef CONFIG_SOC_AU1100 - {AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT} -#endif -#ifdef CONFIG_SOC_AU1500 - {AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT}, - {AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT} -#endif -#ifdef CONFIG_SOC_AU1550 - {AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT}, - {AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT} -#endif -}; +} iflist[2]; static int num_ifs; @@ -1191,14 +1175,58 @@ static int num_ifs; */ static int __init au1000_init_module(void) { + struct cpuinfo_mips *c = ¤t_cpu_data; int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4); struct net_device *dev; int i, found_one = 0; - num_ifs = NUM_ETH_INTERFACES - ni; - + switch (c->cputype) { +#ifdef CONFIG_SOC_AU1000 + case CPU_AU1000: + num_ifs = 2 - ni; + iflist[0].base_addr = AU1000_ETH0_BASE; + iflist[1].base_addr = AU1000_ETH1_BASE; + iflist[0].macen_addr = AU1000_MAC0_ENABLE; + iflist[1].macen_addr = AU1000_MAC1_ENABLE; + iflist[0].irq = AU1000_MAC0_DMA_INT; + iflist[1].irq = AU1000_MAC1_DMA_INT; + break; +#endif +#ifdef CONFIG_SOC_AU1100 + case CPU_AU1100: + num_ifs = 1 - ni; + iflist[0].base_addr = AU1100_ETH0_BASE; + iflist[0].macen_addr = AU1100_MAC0_ENABLE; + iflist[0].irq = AU1100_MAC0_DMA_INT; + break; +#endif +#ifdef CONFIG_SOC_AU1500 + case CPU_AU1500: + num_ifs = 2 - ni; + iflist[0].base_addr = AU1500_ETH0_BASE; + iflist[1].base_addr = AU1500_ETH1_BASE; + iflist[0].macen_addr = AU1500_MAC0_ENABLE; + iflist[1].macen_addr = AU1500_MAC1_ENABLE; + iflist[0].irq = AU1500_MAC0_DMA_INT; + iflist[1].irq = AU1500_MAC1_DMA_INT; + break; +#endif +#ifdef CONFIG_SOC_AU1550 + case CPU_AU1550: + num_ifs = 2 - ni; + iflist[0].base_addr = AU1550_ETH0_BASE; + iflist[1].base_addr = AU1550_ETH1_BASE; + iflist[0].macen_addr = AU1550_MAC0_ENABLE; + iflist[1].macen_addr = AU1550_MAC1_ENABLE; + iflist[0].irq = AU1550_MAC0_DMA_INT; + iflist[1].irq = AU1550_MAC1_DMA_INT; + break; +#endif + default: + num_ifs = 0; + } for(i = 0; i < num_ifs; i++) { - dev = au1000_probe(i); + dev = au1000_probe(iflist[i].base_addr, iflist[i].irq, i); iflist[i].dev = dev; if (dev) found_one++; @@ -1407,7 +1435,8 @@ static struct ethtool_ops au1000_ethtool_ops = { .get_link = au1000_get_link }; -static struct net_device * au1000_probe(int port_num) +static struct net_device * +au1000_probe(u32 ioaddr, int irq, int port_num) { static unsigned version_printed = 0; struct au1000_private *aup = NULL; @@ -1415,95 +1444,94 @@ static struct net_device * au1000_probe(int port_num) db_dest_t *pDB, *pDBfree; char *pmac, *argptr; char ethaddr[6]; - int irq, i, err; - u32 base, macen; - - if (port_num >= NUM_ETH_INTERFACES) - return NULL; + int i, err; - base = CPHYSADDR(iflist[port_num].base_addr ); - macen = CPHYSADDR(iflist[port_num].macen_addr); - irq = iflist[port_num].irq; - - if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") || - !request_mem_region(macen, 4, "Au1x00 ENET")) + if (!request_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE, "Au1x00 ENET")) return NULL; - if (version_printed++ == 0) + if (version_printed++ == 0) printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); dev = alloc_etherdev(sizeof(struct au1000_private)); if (!dev) { - printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME); + printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n"); return NULL; } - if ((err = register_netdev(dev)) != 0) { - printk(KERN_ERR "%s: Cannot register net device, error %d\n", - DRV_NAME, err); + if ((err = register_netdev(dev))) { + printk(KERN_ERR "Au1x_eth Cannot register net device err %d\n", + err); free_netdev(dev); return NULL; } - printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n", - dev->name, base, irq); + printk("%s: Au1x Ethernet found at 0x%x, irq %d\n", + dev->name, ioaddr, irq); aup = dev->priv; /* Allocate the data buffers */ /* Snooping works fine with eth on all au1xxx */ - aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE * - (NUM_TX_BUFFS + NUM_RX_BUFFS), - &aup->dma_addr, 0); + aup->vaddr = (u32)dma_alloc_noncoherent(NULL, + MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), + &aup->dma_addr, + 0); if (!aup->vaddr) { free_netdev(dev); - release_mem_region( base, MAC_IOSIZE); - release_mem_region(macen, 4); + release_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE); return NULL; } /* aup->mac is the base address of the MAC's registers */ - aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr; - + aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr); /* Setup some variables for quick register address access */ - aup->enable = (volatile u32 *)iflist[port_num].macen_addr; - aup->mac_id = port_num; - au_macs[port_num] = aup; - - if (port_num == 0) { - /* Check the environment variables first */ - if (get_ethernet_addr(ethaddr) == 0) + if (ioaddr == iflist[0].base_addr) + { + /* check env variables first */ + if (!get_ethernet_addr(ethaddr)) { memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); - else { + } else { /* Check command line */ argptr = prom_getcmdline(); - if ((pmac = strstr(argptr, "ethaddr=")) == NULL) - printk(KERN_INFO "%s: No MAC address found\n", - dev->name); - /* Use the hard coded MAC addresses */ - else { + if ((pmac = strstr(argptr, "ethaddr=")) == NULL) { + printk(KERN_INFO "%s: No mac address found\n", + dev->name); + /* use the hard coded mac addresses */ + } else { str2eaddr(ethaddr, pmac + strlen("ethaddr=")); memcpy(au1000_mac_addr, ethaddr, - sizeof(au1000_mac_addr)); + sizeof(au1000_mac_addr)); } } - + aup->enable = (volatile u32 *) + ((unsigned long)iflist[0].macen_addr); + memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); - } else if (port_num == 1) + aup->mac_id = 0; + au_macs[0] = aup; + } + else + if (ioaddr == iflist[1].base_addr) + { + aup->enable = (volatile u32 *) + ((unsigned long)iflist[1].macen_addr); + memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); + dev->dev_addr[4] += 0x10; setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); + aup->mac_id = 1; + au_macs[1] = aup; + } + else + { + printk(KERN_ERR "%s: bad ioaddr\n", dev->name); + } - /* - * Assign to the Ethernet ports two consecutive MAC addresses - * to match those that are printed on their stickers - */ - memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); - dev->dev_addr[5] += port_num; - - /* Bring the device out of reset, otherwise probing the MII will hang */ + /* bring the device out of reset, otherwise probing the mii + * will hang */ *aup->enable = MAC_EN_CLOCK_ENABLE; au_sync_delay(2); - *aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | - MAC_EN_CLOCK_ENABLE; + *aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | + MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE; au_sync_delay(2); aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL); @@ -1552,7 +1580,7 @@ static struct net_device * au1000_probe(int port_num) } spin_lock_init(&aup->lock); - dev->base_addr = base; + dev->base_addr = ioaddr; dev->irq = irq; dev->open = au1000_open; dev->hard_start_xmit = au1000_tx; @@ -1586,12 +1614,13 @@ static struct net_device * au1000_probe(int port_num) if (aup->tx_db_inuse[i]) ReleaseDB(aup, aup->tx_db_inuse[i]); } - dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), - (void *)aup->vaddr, aup->dma_addr); + dma_free_noncoherent(NULL, + MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), + (void *)aup->vaddr, + aup->dma_addr); unregister_netdev(dev); free_netdev(dev); - release_mem_region( base, MAC_IOSIZE); - release_mem_region(macen, 4); + release_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE); return NULL; } @@ -1776,18 +1805,20 @@ static void __exit au1000_cleanup_module(void) aup = (struct au1000_private *) dev->priv; unregister_netdev(dev); kfree(aup->mii); - for (j = 0; j < NUM_RX_DMA; j++) + for (j = 0; j < NUM_RX_DMA; j++) { if (aup->rx_db_inuse[j]) ReleaseDB(aup, aup->rx_db_inuse[j]); - for (j = 0; j < NUM_TX_DMA; j++) + } + for (j = 0; j < NUM_TX_DMA; j++) { if (aup->tx_db_inuse[j]) ReleaseDB(aup, aup->tx_db_inuse[j]); - dma_free_noncoherent(NULL, MAX_BUF_SIZE * - (NUM_TX_BUFFS + NUM_RX_BUFFS), - (void *)aup->vaddr, aup->dma_addr); - release_mem_region(dev->base_addr, MAC_IOSIZE); - release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4); + } + dma_free_noncoherent(NULL, + MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), + (void *)aup->vaddr, + aup->dma_addr); free_netdev(dev); + release_mem_region(CPHYSADDR(iflist[i].base_addr), MAC_IOSIZE); } } } @@ -2039,6 +2070,23 @@ static void au1000_tx_timeout(struct net_device *dev) netif_wake_queue(dev); } + +static unsigned const ethernet_polynomial = 0x04c11db7U; +static inline u32 ether_crc(int length, unsigned char *data) +{ + int crc = -1; + + while(--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 0; bit < 8; bit++, current_octet >>= 1) + crc = (crc << 1) ^ + ((crc < 0) ^ (current_octet & 1) ? + ethernet_polynomial : 0); + } + return crc; +} + static void set_rx_mode(struct net_device *dev) { struct au1000_private *aup = (struct au1000_private *) dev->priv; diff --git a/trunk/drivers/net/b44.c b/trunk/drivers/net/b44.c index d8233e0b7899..3d306681919e 100644 --- a/trunk/drivers/net/b44.c +++ b/trunk/drivers/net/b44.c @@ -650,11 +650,9 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) /* Hardware bug work-around, the chip is unable to do PCI DMA to/from anything above 1GB :-( */ - if (dma_mapping_error(mapping) || - mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { + if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { /* Sigh... */ - if (!dma_mapping_error(mapping)) - pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); + pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA); if (skb == NULL) @@ -662,10 +660,8 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) mapping = pci_map_single(bp->pdev, skb->data, RX_PKT_BUF_SZ, PCI_DMA_FROMDEVICE); - if (dma_mapping_error(mapping) || - mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { - if (!dma_mapping_error(mapping)) - pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); + if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { + pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); return -ENOMEM; } @@ -971,10 +967,9 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) } mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); - if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) { + if (mapping + len > B44_DMA_MASK) { /* Chip can't handle DMA to/from >1GB, use bounce buffer */ - if (!dma_mapping_error(mapping)) - pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); + pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA); @@ -983,9 +978,8 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) mapping = pci_map_single(bp->pdev, bounce_skb->data, len, PCI_DMA_TODEVICE); - if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) { - if (!dma_mapping_error(mapping)) - pci_unmap_single(bp->pdev, mapping, + if (mapping + len > B44_DMA_MASK) { + pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); dev_kfree_skb_any(bounce_skb); goto err_out; @@ -1209,8 +1203,7 @@ static int b44_alloc_consistent(struct b44 *bp) DMA_TABLE_BYTES, DMA_BIDIRECTIONAL); - if (dma_mapping_error(rx_ring_dma) || - rx_ring_dma + size > B44_DMA_MASK) { + if (rx_ring_dma + size > B44_DMA_MASK) { kfree(rx_ring); goto out_err; } @@ -1236,8 +1229,7 @@ static int b44_alloc_consistent(struct b44 *bp) DMA_TABLE_BYTES, DMA_TO_DEVICE); - if (dma_mapping_error(tx_ring_dma) || - tx_ring_dma + size > B44_DMA_MASK) { + if (tx_ring_dma + size > B44_DMA_MASK) { kfree(tx_ring); goto out_err; } diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 54161aef3cac..5ca99e26660a 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -55,8 +55,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.4.40" -#define DRV_MODULE_RELDATE "May 22, 2006" +#define DRV_MODULE_VERSION "1.4.39" +#define DRV_MODULE_RELDATE "March 22, 2006" #define RUN_AT(x) (jiffies + (x)) @@ -2945,7 +2945,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, int buf_size) { u32 written, offset32, len32; - u8 *buf, start[4], end[4], *flash_buffer = NULL; + u8 *buf, start[4], end[4]; int rc = 0; int align_start, align_end; @@ -2985,19 +2985,12 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, memcpy(buf + align_start, data_buf, buf_size); } - if (bp->flash_info->buffered == 0) { - flash_buffer = kmalloc(264, GFP_KERNEL); - if (flash_buffer == NULL) { - rc = -ENOMEM; - goto nvram_write_end; - } - } - written = 0; while ((written < len32) && (rc == 0)) { u32 page_start, page_end, data_start, data_end; u32 addr, cmd_flags; int i; + u8 flash_buffer[264]; /* Find the page_start addr */ page_start = offset32 + written; @@ -3068,7 +3061,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, } /* Loop to write the new data from data_start to data_end */ - for (addr = data_start; addr < data_end; addr += 4, i += 4) { + for (addr = data_start; addr < data_end; addr += 4, i++) { if ((addr == page_end - 4) || ((bp->flash_info->buffered) && (addr == data_end - 4))) { @@ -3116,9 +3109,6 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, } nvram_write_end: - if (bp->flash_info->buffered == 0) - kfree(flash_buffer); - if (align_start || align_end) kfree(buf); return rc; diff --git a/trunk/drivers/net/cassini.c b/trunk/drivers/net/cassini.c index 39f36aa05aa8..ac48f7543500 100644 --- a/trunk/drivers/net/cassini.c +++ b/trunk/drivers/net/cassini.c @@ -4877,7 +4877,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int cas_version_printed = 0; - unsigned long casreg_len; + unsigned long casreg_base, casreg_len; struct net_device *dev; struct cas *cp; int i, err, pci_using_dac; @@ -4972,6 +4972,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, pci_using_dac = 0; } + casreg_base = pci_resource_start(pdev, 0); casreg_len = pci_resource_len(pdev, 0); cp = netdev_priv(dev); @@ -5023,7 +5024,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, cp->timer_ticks = 0; /* give us access to cassini registers */ - cp->regs = pci_iomap(pdev, 0, casreg_len); + cp->regs = ioremap(casreg_base, casreg_len); if (cp->regs == 0UL) { printk(KERN_ERR PFX "Cannot map device registers, " "aborting.\n"); @@ -5122,7 +5123,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, cas_shutdown(cp); mutex_unlock(&cp->pm_mutex); - pci_iounmap(pdev, cp->regs); + iounmap(cp->regs); err_out_free_res: @@ -5170,7 +5171,7 @@ static void __devexit cas_remove_one(struct pci_dev *pdev) #endif pci_free_consistent(pdev, sizeof(struct cas_init_block), cp->init_block, cp->block_dvma); - pci_iounmap(pdev, cp->regs); + iounmap(cp->regs); free_netdev(dev); pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/trunk/drivers/net/dl2k.c b/trunk/drivers/net/dl2k.c index 038447fb5c5e..1f3627470c95 100644 --- a/trunk/drivers/net/dl2k.c +++ b/trunk/drivers/net/dl2k.c @@ -53,7 +53,6 @@ #define DRV_VERSION "v1.17b" #define DRV_RELDATE "2006/03/10" #include "dl2k.h" -#include static char version[] __devinitdata = KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n"; @@ -766,7 +765,7 @@ rio_free_tx (struct net_device *dev, int irq) break; skb = np->tx_skbuff[entry]; pci_unmap_single (np->pdev, - np->tx_ring[entry].fraginfo & DMA_48BIT_MASK, + np->tx_ring[entry].fraginfo & 0xffffffffffff, skb->len, PCI_DMA_TODEVICE); if (irq) dev_kfree_skb_irq (skb); @@ -894,7 +893,7 @@ receive_packet (struct net_device *dev) /* Small skbuffs for short packets */ if (pkt_len > copy_thresh) { pci_unmap_single (np->pdev, - desc->fraginfo & DMA_48BIT_MASK, + desc->fraginfo & 0xffffffffffff, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb_put (skb = np->rx_skbuff[entry], pkt_len); @@ -902,7 +901,7 @@ receive_packet (struct net_device *dev) } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) { pci_dma_sync_single_for_cpu(np->pdev, desc->fraginfo & - DMA_48BIT_MASK, + 0xffffffffffff, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; @@ -914,7 +913,7 @@ receive_packet (struct net_device *dev) skb_put (skb, pkt_len); pci_dma_sync_single_for_device(np->pdev, desc->fraginfo & - DMA_48BIT_MASK, + 0xffffffffffff, np->rx_buf_sz, PCI_DMA_FROMDEVICE); } @@ -1801,7 +1800,7 @@ rio_close (struct net_device *dev) skb = np->rx_skbuff[i]; if (skb) { pci_unmap_single(np->pdev, - np->rx_ring[i].fraginfo & DMA_48BIT_MASK, + np->rx_ring[i].fraginfo & 0xffffffffffff, skb->len, PCI_DMA_FROMDEVICE); dev_kfree_skb (skb); np->rx_skbuff[i] = NULL; @@ -1811,7 +1810,7 @@ rio_close (struct net_device *dev) skb = np->tx_skbuff[i]; if (skb) { pci_unmap_single(np->pdev, - np->tx_ring[i].fraginfo & DMA_48BIT_MASK, + np->tx_ring[i].fraginfo & 0xffffffffffff, skb->len, PCI_DMA_TODEVICE); dev_kfree_skb (skb); np->tx_skbuff[i] = NULL; diff --git a/trunk/drivers/net/e1000/Makefile b/trunk/drivers/net/e1000/Makefile index 5dea2b7dea4d..ca9f89552da3 100644 --- a/trunk/drivers/net/e1000/Makefile +++ b/trunk/drivers/net/e1000/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # -# Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. +# Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free @@ -22,7 +22,6 @@ # # Contact Information: # Linux NICS -# e1000-devel Mailing List # Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 # ################################################################################ diff --git a/trunk/drivers/net/e1000/e1000.h b/trunk/drivers/net/e1000/e1000.h index 2bc34fbfa69c..281de41d030a 100644 --- a/trunk/drivers/net/e1000/e1000.h +++ b/trunk/drivers/net/e1000/e1000.h @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,7 +22,6 @@ Contact Information: Linux NICS - e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ @@ -115,8 +114,6 @@ struct e1000_adapter; /* Supported Rx Buffer Sizes */ #define E1000_RXBUFFER_128 128 /* Used for packet split */ #define E1000_RXBUFFER_256 256 /* Used for packet split */ -#define E1000_RXBUFFER_512 512 -#define E1000_RXBUFFER_1024 1024 #define E1000_RXBUFFER_2048 2048 #define E1000_RXBUFFER_4096 4096 #define E1000_RXBUFFER_8192 8192 @@ -337,6 +334,7 @@ struct e1000_adapter { boolean_t have_msi; #endif /* to not mess up cache alignment, always add to the bottom */ + boolean_t txb2b; #ifdef NETIF_F_TSO boolean_t tso_force; #endif diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index cfdf0b24ffc1..ecccca35c6f4 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,7 +22,6 @@ Contact Information: Linux NICS - e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ @@ -865,15 +864,15 @@ static int e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) { struct net_device *netdev = adapter->netdev; - uint32_t mask, i=0, shared_int = TRUE; - uint32_t irq = adapter->pdev->irq; + uint32_t mask, i=0, shared_int = TRUE; + uint32_t irq = adapter->pdev->irq; *data = 0; /* Hook up test interrupt handler just for this test */ - if (!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { - shared_int = FALSE; - } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, + if (!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { + shared_int = FALSE; + } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, netdev->name, netdev)){ *data = 1; return -1; @@ -889,22 +888,22 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) /* Interrupt to test */ mask = 1 << i; - if (!shared_int) { - /* Disable the interrupt to be reported in - * the cause register and then force the same - * interrupt and see if one gets posted. If - * an interrupt was posted to the bus, the - * test failed. - */ - adapter->test_icr = 0; - E1000_WRITE_REG(&adapter->hw, IMC, mask); - E1000_WRITE_REG(&adapter->hw, ICS, mask); - msec_delay(10); - - if (adapter->test_icr & mask) { - *data = 3; - break; - } + if (!shared_int) { + /* Disable the interrupt to be reported in + * the cause register and then force the same + * interrupt and see if one gets posted. If + * an interrupt was posted to the bus, the + * test failed. + */ + adapter->test_icr = 0; + E1000_WRITE_REG(&adapter->hw, IMC, mask); + E1000_WRITE_REG(&adapter->hw, ICS, mask); + msec_delay(10); + + if (adapter->test_icr & mask) { + *data = 3; + break; + } } /* Enable the interrupt to be reported in @@ -923,7 +922,7 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) break; } - if (!shared_int) { + if (!shared_int) { /* Disable the other interrupts to be reported in * the cause register and then force the other * interrupts and see if any get posted. If diff --git a/trunk/drivers/net/e1000/e1000_hw.c b/trunk/drivers/net/e1000/e1000_hw.c index 3959039b16ec..523c2c9fc0ac 100644 --- a/trunk/drivers/net/e1000/e1000_hw.c +++ b/trunk/drivers/net/e1000/e1000_hw.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,7 +22,6 @@ Contact Information: Linux NICS - e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ @@ -765,7 +764,7 @@ e1000_init_hw(struct e1000_hw *hw) } if (hw->mac_type == e1000_82573) { - e1000_enable_tx_pkt_filtering(hw); + e1000_enable_tx_pkt_filtering(hw); } switch (hw->mac_type) { @@ -861,7 +860,7 @@ e1000_adjust_serdes_amplitude(struct e1000_hw *hw) if(eeprom_data != EEPROM_RESERVED_WORD) { /* Adjust SERDES output amplitude only. */ - eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK; + eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data); if(ret_val) return ret_val; @@ -1228,7 +1227,7 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw) if (hw->phy_reset_disable) return E1000_SUCCESS; - + ret_val = e1000_phy_reset(hw); if (ret_val) { DEBUGOUT("Error Resetting the PHY\n"); @@ -1370,7 +1369,7 @@ e1000_copper_link_ggp_setup(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_ggp_setup"); if(!hw->phy_reset_disable) { - + /* Enable CRS on TX for half-duplex operation. */ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); @@ -1519,7 +1518,7 @@ e1000_copper_link_mgp_setup(struct e1000_hw *hw) if(hw->phy_reset_disable) return E1000_SUCCESS; - + /* Enable CRS on TX. This must be set for half-duplex operation. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if(ret_val) @@ -1665,7 +1664,7 @@ e1000_copper_link_autoneg(struct e1000_hw *hw) * collision distance in the Transmit Control Register. * 2) Set up flow control on the MAC to that established with * the link partner. -* 3) Config DSP to improve Gigabit link quality for some PHY revisions. +* 3) Config DSP to improve Gigabit link quality for some PHY revisions. * * hw - Struct containing variables accessed by shared code ******************************************************************************/ @@ -1674,7 +1673,7 @@ e1000_copper_link_postconfig(struct e1000_hw *hw) { int32_t ret_val; DEBUGFUNC("e1000_copper_link_postconfig"); - + if(hw->mac_type >= e1000_82544) { e1000_config_collision_dist(hw); } else { @@ -1698,7 +1697,7 @@ e1000_copper_link_postconfig(struct e1000_hw *hw) return ret_val; } } - + return E1000_SUCCESS; } @@ -1754,11 +1753,11 @@ e1000_setup_copper_link(struct e1000_hw *hw) } if(hw->autoneg) { - /* Setup autoneg and flow control advertisement - * and perform autonegotiation */ + /* Setup autoneg and flow control advertisement + * and perform autonegotiation */ ret_val = e1000_copper_link_autoneg(hw); if(ret_val) - return ret_val; + return ret_val; } else { /* PHY will be set to 10H, 10F, 100H,or 100F * depending on value from forced_speed_duplex. */ @@ -1786,7 +1785,7 @@ e1000_setup_copper_link(struct e1000_hw *hw) ret_val = e1000_copper_link_postconfig(hw); if(ret_val) return ret_val; - + DEBUGOUT("Valid link established!!!\n"); return E1000_SUCCESS; } @@ -1984,7 +1983,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw) DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); - ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); + ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); if(ret_val) return ret_val; @@ -2273,7 +2272,7 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) DEBUGFUNC("e1000_config_mac_to_phy"); - /* 82544 or newer MAC, Auto Speed Detection takes care of + /* 82544 or newer MAC, Auto Speed Detection takes care of * MAC speed/duplex configuration.*/ if (hw->mac_type >= e1000_82544) return E1000_SUCCESS; @@ -2292,9 +2291,9 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) if(ret_val) return ret_val; - if(phy_data & M88E1000_PSSR_DPLX) + if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD; - else + else ctrl &= ~E1000_CTRL_FD; e1000_config_collision_dist(hw); @@ -2493,10 +2492,10 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) */ if(hw->original_fc == e1000_fc_full) { hw->fc = e1000_fc_full; - DEBUGOUT("Flow Control = FULL.\n"); + DEBUGOUT("Flow Control = FULL.\r\n"); } else { hw->fc = e1000_fc_rx_pause; - DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); + DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n"); } } /* For receiving PAUSE frames ONLY. @@ -2512,7 +2511,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc = e1000_fc_tx_pause; - DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); + DEBUGOUT("Flow Control = TX PAUSE frames only.\r\n"); } /* For transmitting PAUSE frames ONLY. * @@ -2527,7 +2526,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc = e1000_fc_rx_pause; - DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); + DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n"); } /* Per the IEEE spec, at this point flow control should be * disabled. However, we want to consider that we could @@ -2553,10 +2552,10 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) hw->original_fc == e1000_fc_tx_pause) || hw->fc_strict_ieee) { hw->fc = e1000_fc_none; - DEBUGOUT("Flow Control = NONE.\n"); + DEBUGOUT("Flow Control = NONE.\r\n"); } else { hw->fc = e1000_fc_rx_pause; - DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); + DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n"); } /* Now we need to do one last check... If we auto- @@ -2581,7 +2580,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) return ret_val; } } else { - DEBUGOUT("Copper PHY and Auto Neg has not completed.\n"); + DEBUGOUT("Copper PHY and Auto Neg has not completed.\r\n"); } } return E1000_SUCCESS; @@ -2764,7 +2763,7 @@ e1000_check_for_link(struct e1000_hw *hw) hw->autoneg_failed = 1; return 0; } - DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n"); + DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n"); /* Disable auto-negotiation in the TXCW register */ E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE)); @@ -2789,7 +2788,7 @@ e1000_check_for_link(struct e1000_hw *hw) else if(((hw->media_type == e1000_media_type_fiber) || (hw->media_type == e1000_media_type_internal_serdes)) && (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { - DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n"); + DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\r\n"); E1000_WRITE_REG(hw, TXCW, hw->txcw); E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU)); @@ -2852,13 +2851,13 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw, if(status & E1000_STATUS_FD) { *duplex = FULL_DUPLEX; - DEBUGOUT("Full Duplex\n"); + DEBUGOUT("Full Duplex\r\n"); } else { *duplex = HALF_DUPLEX; - DEBUGOUT(" Half Duplex\n"); + DEBUGOUT(" Half Duplex\r\n"); } } else { - DEBUGOUT("1000 Mbs, Full Duplex\n"); + DEBUGOUT("1000 Mbs, Full Duplex\r\n"); *speed = SPEED_1000; *duplex = FULL_DUPLEX; } @@ -2884,7 +2883,7 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw, } } - if ((hw->mac_type == e1000_80003es2lan) && + if ((hw->mac_type == e1000_80003es2lan) && (hw->media_type == e1000_media_type_copper)) { if (*speed == SPEED_1000) ret_val = e1000_configure_kmrn_for_1000(hw); @@ -3160,7 +3159,7 @@ e1000_read_phy_reg(struct e1000_hw *hw, if (e1000_swfw_sync_acquire(hw, swfw)) return -E1000_ERR_SWFW_SYNC; - if((hw->phy_type == e1000_phy_igp || + if((hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, @@ -3299,7 +3298,7 @@ e1000_write_phy_reg(struct e1000_hw *hw, if (e1000_swfw_sync_acquire(hw, swfw)) return -E1000_ERR_SWFW_SYNC; - if((hw->phy_type == e1000_phy_igp || + if((hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, @@ -3497,22 +3496,22 @@ e1000_phy_hw_reset(struct e1000_hw *hw) } /* Read the device control register and assert the E1000_CTRL_PHY_RST * bit. Then, take it out of reset. - * For pre-e1000_82571 hardware, we delay for 10ms between the assert + * For pre-e1000_82571 hardware, we delay for 10ms between the assert * and deassert. For e1000_82571 hardware and later, we instead delay * for 50us between and 10ms after the deassertion. */ ctrl = E1000_READ_REG(hw, CTRL); E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST); E1000_WRITE_FLUSH(hw); - - if (hw->mac_type < e1000_82571) + + if (hw->mac_type < e1000_82571) msec_delay(10); else udelay(100); - + E1000_WRITE_REG(hw, CTRL, ctrl); E1000_WRITE_FLUSH(hw); - + if (hw->mac_type >= e1000_82571) msec_delay(10); e1000_swfw_sync_release(hw, swfw); @@ -3816,7 +3815,7 @@ e1000_phy_m88_get_info(struct e1000_hw *hw, /* Check polarity status */ ret_val = e1000_check_polarity(hw, &polarity); if(ret_val) - return ret_val; + return ret_val; phy_info->cable_polarity = polarity; ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); @@ -4541,14 +4540,14 @@ e1000_read_eeprom_eerd(struct e1000_hw *hw, E1000_WRITE_REG(hw, EERD, eerd); error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ); - + if(error) { break; } data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA); - + } - + return error; } @@ -4574,24 +4573,24 @@ e1000_write_eeprom_eewr(struct e1000_hw *hw, return -E1000_ERR_SWFW_SYNC; for (i = 0; i < words; i++) { - register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) | - ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) | + register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) | + ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) | E1000_EEPROM_RW_REG_START; error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE); if(error) { break; - } + } E1000_WRITE_REG(hw, EEWR, register_value); - + error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE); - + if(error) { break; - } + } } - + e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM); return error; } @@ -4611,7 +4610,7 @@ e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd) for(i = 0; i < attempts; i++) { if(eerd == E1000_EEPROM_POLL_READ) reg = E1000_READ_REG(hw, EERD); - else + else reg = E1000_READ_REG(hw, EEWR); if(reg & E1000_EEPROM_RW_REG_DONE) { @@ -5136,7 +5135,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, uint32_t i; uint32_t num_rar_entry; uint32_t num_mta_entry; - + DEBUGFUNC("e1000_mc_addr_list_update"); /* Set the new number of MC addresses that we are being requested to use. */ @@ -6241,7 +6240,7 @@ e1000_check_polarity(struct e1000_hw *hw, * 1 - Downshift ocured. * * returns: - E1000_ERR_XXX - * E1000_SUCCESS + * E1000_SUCCESS * * For phy's older then IGP, this function reads the Downshift bit in the Phy * Specific Status register. For IGP phy's, it reads the Downgrade bit in the @@ -6256,7 +6255,7 @@ e1000_check_downshift(struct e1000_hw *hw) DEBUGFUNC("e1000_check_downshift"); - if(hw->phy_type == e1000_phy_igp || + if(hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data); @@ -6685,8 +6684,8 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, } else { - - phy_data |= IGP02E1000_PM_D0_LPLU; + + phy_data |= IGP02E1000_PM_D0_LPLU; ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); if (ret_val) return ret_val; @@ -6778,7 +6777,7 @@ int32_t e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer) { uint8_t i; - uint32_t offset = E1000_MNG_DHCP_COOKIE_OFFSET; + uint32_t offset = E1000_MNG_DHCP_COOKIE_OFFSET; uint8_t length = E1000_MNG_DHCP_COOKIE_LENGTH; length = (length >> 2); @@ -6797,7 +6796,7 @@ e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer) * and also checks whether the previous command is completed. * It busy waits in case of previous command is not completed. * - * returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or + * returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or * timeout * - E1000_SUCCESS for success. ****************************************************************************/ @@ -6821,7 +6820,7 @@ e1000_mng_enable_host_if(struct e1000_hw * hw) msec_delay_irq(1); } - if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { + if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { DEBUGOUT("Previous command timeout failed .\n"); return -E1000_ERR_HOST_INTERFACE_COMMAND; } diff --git a/trunk/drivers/net/e1000/e1000_hw.h b/trunk/drivers/net/e1000/e1000_hw.h index 467c9ed944f8..150e45e30f87 100644 --- a/trunk/drivers/net/e1000/e1000_hw.h +++ b/trunk/drivers/net/e1000/e1000_hw.h @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,7 +22,6 @@ Contact Information: Linux NICS - e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ @@ -375,7 +374,7 @@ struct e1000_host_mng_dhcp_cookie{ }; #endif -int32_t e1000_mng_write_dhcp_info(struct e1000_hw *hw, uint8_t *buffer, +int32_t e1000_mng_write_dhcp_info(struct e1000_hw *hw, uint8_t *buffer, uint16_t length); boolean_t e1000_check_mng_mode(struct e1000_hw *hw); boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw); @@ -1802,7 +1801,7 @@ struct e1000_hw { * value2 = [0..64512], default=4096 * value3 = [0..64512], default=0 */ - + #define E1000_PSRCTL_BSIZE0_MASK 0x0000007F #define E1000_PSRCTL_BSIZE1_MASK 0x00003F00 #define E1000_PSRCTL_BSIZE2_MASK 0x003F0000 diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 258c7d53930e..c99e87838f92 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,13 +22,51 @@ Contact Information: Linux NICS - e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ #include "e1000.h" +/* Change Log + * 7.0.33 3-Feb-2006 + * o Added another fix for the pass false carrier bit + * 7.0.32 24-Jan-2006 + * o Need to rebuild with noew version number for the pass false carrier + * fix in e1000_hw.c + * 7.0.30 18-Jan-2006 + * o fixup for tso workaround to disable it for pci-x + * o fix mem leak on 82542 + * o fixes for 10 Mb/s connections and incorrect stats + * 7.0.28 01/06/2006 + * o hardware workaround to only set "speed mode" bit for 1G link. + * 7.0.26 12/23/2005 + * o wake on lan support modified for device ID 10B5 + * o fix dhcp + vlan issue not making it to the iAMT firmware + * 7.0.24 12/9/2005 + * o New hardware support for the Gigabit NIC embedded in the south bridge + * o Fixes to the recycling logic (skb->tail) from IBM LTC + * 6.3.9 12/16/2005 + * o incorporate fix for recycled skbs from IBM LTC + * 6.3.7 11/18/2005 + * o Honor eeprom setting for enabling/disabling Wake On Lan + * 6.3.5 11/17/2005 + * o Fix memory leak in rx ring handling for PCI Express adapters + * 6.3.4 11/8/05 + * o Patch from Jesper Juhl to remove redundant NULL checks for kfree + * 6.3.2 9/20/05 + * o Render logic that sets/resets DRV_LOAD as inline functions to + * avoid code replication. If f/w is AMT then set DRV_LOAD only when + * network interface is open. + * o Handle DRV_LOAD set/reset in cases where AMT uses VLANs. + * o Adjust PBA partioning for Jumbo frames using MTU size and not + * rx_buffer_len + * 6.3.1 9/19/05 + * o Use adapter->tx_timeout_factor in Tx Hung Detect logic + * (e1000_clean_tx_irq) + * o Support for 8086:10B5 device (Quad Port) + */ + char e1000_driver_name[] = "e1000"; static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #ifndef CONFIG_E1000_NAPI @@ -36,9 +74,9 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "7.0.38-k4"DRIVERNAPI +#define DRV_VERSION "7.0.33-k2"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; -static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; +static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; /* e1000_pci_tbl - PCI Device ID Table * @@ -170,8 +208,8 @@ static void e1000_leave_82542_rst(struct e1000_adapter *adapter); static void e1000_tx_timeout(struct net_device *dev); static void e1000_reset_task(struct net_device *dev); static void e1000_smartspeed(struct e1000_adapter *adapter); -static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, - struct sk_buff *skb); +static inline int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, + struct sk_buff *skb); static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); @@ -182,7 +220,6 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter); static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); static int e1000_resume(struct pci_dev *pdev); #endif -static void e1000_shutdown(struct pci_dev *pdev); #ifdef CONFIG_NET_POLL_CONTROLLER /* for netdump / net console */ @@ -198,9 +235,8 @@ static struct pci_driver e1000_driver = { /* Power Managment Hooks */ #ifdef CONFIG_PM .suspend = e1000_suspend, - .resume = e1000_resume, + .resume = e1000_resume #endif - .shutdown = e1000_shutdown }; MODULE_AUTHOR("Intel Corporation, "); @@ -255,7 +291,7 @@ module_exit(e1000_exit_module); * @adapter: board private structure **/ -static void +static inline void e1000_irq_disable(struct e1000_adapter *adapter) { atomic_inc(&adapter->irq_sem); @@ -269,7 +305,7 @@ e1000_irq_disable(struct e1000_adapter *adapter) * @adapter: board private structure **/ -static void +static inline void e1000_irq_enable(struct e1000_adapter *adapter) { if (likely(atomic_dec_and_test(&adapter->irq_sem))) { @@ -310,10 +346,10 @@ e1000_update_mng_vlan(struct e1000_adapter *adapter) * For ASF and Pass Through versions of f/w this means that the * driver is no longer loaded. For AMT version (only with 82573) i * of the f/w this means that the netowrk i/f is closed. - * + * **/ -static void +static inline void e1000_release_hw_control(struct e1000_adapter *adapter) { uint32_t ctrl_ext; @@ -323,7 +359,6 @@ e1000_release_hw_control(struct e1000_adapter *adapter) switch (adapter->hw.mac_type) { case e1000_82571: case e1000_82572: - case e1000_80003es2lan: ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT); E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD); @@ -342,13 +377,13 @@ e1000_release_hw_control(struct e1000_adapter *adapter) * @adapter: address of board private structure * * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit. - * For ASF and Pass Through versions of f/w this means that - * the driver is loaded. For AMT version (only with 82573) + * For ASF and Pass Through versions of f/w this means that + * the driver is loaded. For AMT version (only with 82573) * of the f/w this means that the netowrk i/f is open. - * + * **/ -static void +static inline void e1000_get_hw_control(struct e1000_adapter *adapter) { uint32_t ctrl_ext; @@ -357,7 +392,6 @@ e1000_get_hw_control(struct e1000_adapter *adapter) switch (adapter->hw.mac_type) { case e1000_82571: case e1000_82572: - case e1000_80003es2lan: ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT); E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); @@ -385,7 +419,7 @@ e1000_up(struct e1000_adapter *adapter) uint16_t mii_reg; e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg); if (mii_reg & MII_CR_POWER_DOWN) - e1000_phy_hw_reset(&adapter->hw); + e1000_phy_reset(&adapter->hw); } e1000_set_multi(netdev); @@ -675,8 +709,8 @@ e1000_probe(struct pci_dev *pdev, DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n"); /* if ksp3, indicate if it's port a being setup */ - if (pdev->device == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 && - e1000_ksp3_port_a == 0) + if (pdev->device == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 && + e1000_ksp3_port_a == 0) adapter->ksp3_port_a = 1; e1000_ksp3_port_a++; /* Reset for multiple KP3 adapters */ @@ -704,9 +738,9 @@ e1000_probe(struct pci_dev *pdev, if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; - /* hard_start_xmit is safe against parallel locking */ - netdev->features |= NETIF_F_LLTX; - + /* hard_start_xmit is safe against parallel locking */ + netdev->features |= NETIF_F_LLTX; + adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw); /* before reading the EEPROM, reset the controller to @@ -936,8 +970,8 @@ e1000_sw_init(struct e1000_adapter *adapter) pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); - adapter->rx_buffer_len = MAXIMUM_ETHERNET_FRAME_SIZE; - adapter->rx_ps_bsize0 = E1000_RXBUFFER_128; + adapter->rx_buffer_len = E1000_RXBUFFER_2048; + adapter->rx_ps_bsize0 = E1000_RXBUFFER_256; hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; @@ -1145,7 +1179,7 @@ e1000_close(struct net_device *netdev) * @start: address of beginning of memory * @len: length of memory **/ -static boolean_t +static inline boolean_t e1000_check_64k_bound(struct e1000_adapter *adapter, void *start, unsigned long len) { @@ -1563,21 +1597,14 @@ e1000_setup_rctl(struct e1000_adapter *adapter) rctl |= E1000_RCTL_LPE; /* Setup buffer sizes */ - rctl &= ~E1000_RCTL_SZ_4096; - rctl |= E1000_RCTL_BSEX; - switch (adapter->rx_buffer_len) { - case E1000_RXBUFFER_256: - rctl |= E1000_RCTL_SZ_256; - rctl &= ~E1000_RCTL_BSEX; - break; - case E1000_RXBUFFER_512: - rctl |= E1000_RCTL_SZ_512; - rctl &= ~E1000_RCTL_BSEX; - break; - case E1000_RXBUFFER_1024: - rctl |= E1000_RCTL_SZ_1024; - rctl &= ~E1000_RCTL_BSEX; - break; + if (adapter->hw.mac_type >= e1000_82571) { + /* We can now specify buffers in 1K increments. + * BSIZE and BSEX are ignored in this case. */ + rctl |= adapter->rx_buffer_len << 0x11; + } else { + rctl &= ~E1000_RCTL_SZ_4096; + rctl |= E1000_RCTL_BSEX; + switch (adapter->rx_buffer_len) { case E1000_RXBUFFER_2048: default: rctl |= E1000_RCTL_SZ_2048; @@ -1592,6 +1619,7 @@ e1000_setup_rctl(struct e1000_adapter *adapter) case E1000_RXBUFFER_16384: rctl |= E1000_RCTL_SZ_16384; break; + } } #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT @@ -1685,7 +1713,7 @@ e1000_configure_rx(struct e1000_adapter *adapter) if (hw->mac_type >= e1000_82571) { ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); /* Reset delay timers after every interrupt */ - ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR; + ctrl_ext |= E1000_CTRL_EXT_CANC; #ifdef CONFIG_E1000_NAPI /* Auto-Mask interrupts upon ICR read. */ ctrl_ext |= E1000_CTRL_EXT_IAME; @@ -1777,7 +1805,7 @@ e1000_free_all_tx_resources(struct e1000_adapter *adapter) e1000_free_tx_resources(adapter, &adapter->tx_ring[i]); } -static void +static inline void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info) { @@ -2217,7 +2245,6 @@ e1000_watchdog_task(struct e1000_adapter *adapter) if (link) { if (!netif_carrier_ok(netdev)) { - boolean_t txb2b = 1; e1000_get_speed_and_duplex(&adapter->hw, &adapter->link_speed, &adapter->link_duplex); @@ -2231,22 +2258,23 @@ e1000_watchdog_task(struct e1000_adapter *adapter) * and adjust the timeout factor */ netdev->tx_queue_len = adapter->tx_queue_len; adapter->tx_timeout_factor = 1; + adapter->txb2b = 1; switch (adapter->link_speed) { case SPEED_10: - txb2b = 0; + adapter->txb2b = 0; netdev->tx_queue_len = 10; adapter->tx_timeout_factor = 8; break; case SPEED_100: - txb2b = 0; + adapter->txb2b = 0; netdev->tx_queue_len = 100; /* maybe add some timeout factor ? */ break; } - if ((adapter->hw.mac_type == e1000_82571 || + if ((adapter->hw.mac_type == e1000_82571 || adapter->hw.mac_type == e1000_82572) && - txb2b == 0) { + adapter->txb2b == 0) { #define SPEED_MODE_BIT (1 << 21) uint32_t tarc0; tarc0 = E1000_READ_REG(&adapter->hw, TARC0); @@ -2370,7 +2398,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter) #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 #define E1000_TX_FLAGS_VLAN_SHIFT 16 -static int +static inline int e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, struct sk_buff *skb) { @@ -2450,7 +2478,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, return FALSE; } -static boolean_t +static inline boolean_t e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, struct sk_buff *skb) { @@ -2486,7 +2514,7 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, #define E1000_MAX_TXD_PWR 12 #define E1000_MAX_DATA_PER_TXD (1<tx_fifo_size - adapter->tx_fifo_head; @@ -2686,7 +2714,7 @@ e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb) } #define MINIMUM_DHCP_PACKET_SIZE 282 -static int +static inline int e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb) { struct e1000_hw *hw = &adapter->hw; @@ -2734,7 +2762,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) unsigned int nr_frags = 0; unsigned int mss = 0; int count = 0; - int tso; + int tso; unsigned int f; len -= skb->data_len; @@ -2747,7 +2775,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) #ifdef NETIF_F_TSO mss = skb_shinfo(skb)->tso_size; - /* The controller does a simple calculation to + /* The controller does a simple calculation to * make sure there is enough room in the FIFO before * initiating the DMA for each buffer. The calc is: * 4 = ceil(buffer len/mss). To make sure we don't @@ -2770,7 +2798,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) case e1000_82573: pull_size = min((unsigned int)4, skb->data_len); if (!__pskb_pull_tail(skb, pull_size)) { - printk(KERN_ERR + printk(KERN_ERR "__pskb_pull_tail failed.\n"); dev_kfree_skb_any(skb); return NETDEV_TX_OK; @@ -2952,7 +2980,8 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) /* Adapter-specific max frame size limits. */ switch (adapter->hw.mac_type) { - case e1000_undefined ... e1000_82542_rev2_1: + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) { DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n"); return -EINVAL; @@ -2986,32 +3015,27 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) break; } - /* NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN - * means we reserve 2 more, this pushes us to allocate from the next - * larger slab size - * i.e. RXBUFFER_2048 --> size-4096 slab */ - - if (max_frame <= E1000_RXBUFFER_256) - adapter->rx_buffer_len = E1000_RXBUFFER_256; - else if (max_frame <= E1000_RXBUFFER_512) - adapter->rx_buffer_len = E1000_RXBUFFER_512; - else if (max_frame <= E1000_RXBUFFER_1024) - adapter->rx_buffer_len = E1000_RXBUFFER_1024; - else if (max_frame <= E1000_RXBUFFER_2048) - adapter->rx_buffer_len = E1000_RXBUFFER_2048; - else if (max_frame <= E1000_RXBUFFER_4096) - adapter->rx_buffer_len = E1000_RXBUFFER_4096; - else if (max_frame <= E1000_RXBUFFER_8192) - adapter->rx_buffer_len = E1000_RXBUFFER_8192; - else if (max_frame <= E1000_RXBUFFER_16384) - adapter->rx_buffer_len = E1000_RXBUFFER_16384; - - /* adjust allocation if LPE protects us, and we aren't using SBP */ -#define MAXIMUM_ETHERNET_VLAN_SIZE 1522 - if (!adapter->hw.tbi_compatibility_on && - ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) || - (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))) - adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; + + if (adapter->hw.mac_type > e1000_82547_rev_2) { + adapter->rx_buffer_len = max_frame; + E1000_ROUNDUP(adapter->rx_buffer_len, 1024); + } else { + if(unlikely((adapter->hw.mac_type < e1000_82543) && + (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) { + DPRINTK(PROBE, ERR, "Jumbo Frames not supported " + "on 82542\n"); + return -EINVAL; + } else { + if(max_frame <= E1000_RXBUFFER_2048) + adapter->rx_buffer_len = E1000_RXBUFFER_2048; + else if(max_frame <= E1000_RXBUFFER_4096) + adapter->rx_buffer_len = E1000_RXBUFFER_4096; + else if(max_frame <= E1000_RXBUFFER_8192) + adapter->rx_buffer_len = E1000_RXBUFFER_8192; + else if(max_frame <= E1000_RXBUFFER_16384) + adapter->rx_buffer_len = E1000_RXBUFFER_16384; + } + } netdev->mtu = new_mtu; @@ -3139,6 +3163,7 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->stats.crcerrs + adapter->stats.algnerrc + adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr; + adapter->net_stats.rx_dropped = 0; adapter->net_stats.rx_length_errors = adapter->stats.ruc + adapter->stats.roc; adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs; @@ -3364,15 +3389,13 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, tx_ring->next_to_clean = i; -#define TX_WAKE_THRESHOLD 32 + spin_lock(&tx_ring->tx_lock); + if (unlikely(cleaned && netif_queue_stopped(netdev) && - netif_carrier_ok(netdev))) { - spin_lock(&tx_ring->tx_lock); - if (netif_queue_stopped(netdev) && - (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) - netif_wake_queue(netdev); - spin_unlock(&tx_ring->tx_lock); - } + netif_carrier_ok(netdev))) + netif_wake_queue(netdev); + + spin_unlock(&tx_ring->tx_lock); if (adapter->detect_tx_hung) { /* Detect a transmit hang in hardware, this serializes the @@ -3420,7 +3443,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, * @sk_buff: socket buffer with received data **/ -static void +static inline void e1000_rx_checksum(struct e1000_adapter *adapter, uint32_t status_err, uint32_t csum, struct sk_buff *skb) @@ -3544,8 +3567,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, flags); length--; } else { - /* recycle */ - buffer_info->skb = skb; + dev_kfree_skb_irq(skb); goto next_desc; } } @@ -3653,7 +3675,6 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC_PS(*rx_ring, i); staterr = le32_to_cpu(rx_desc->wb.middle.status_error); - buffer_info = &rx_ring->buffer_info[i]; while (staterr & E1000_RXD_STAT_DD) { buffer_info = &rx_ring->buffer_info[i]; @@ -3714,9 +3735,9 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, /* page alloc/put takes too long and effects small packet * throughput, so unsplit small packets and save the alloc/put*/ - if (l1 && ((length + l1) <= adapter->rx_ps_bsize0)) { + if (l1 && ((length + l1) < E1000_CB_LENGTH)) { u8 *vaddr; - /* there is no documentation about how to call + /* there is no documentation about how to call * kmap_atomic, so we can't hold the mapping * very long */ pci_dma_sync_single_for_cpu(pdev, @@ -4136,7 +4157,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) spin_unlock_irqrestore(&adapter->stats_lock, flags); return -EIO; } - if (adapter->hw.media_type == e1000_media_type_copper) { + if (adapter->hw.phy_type == e1000_media_type_copper) { switch (data->reg_num) { case PHY_CTRL: if (mii_reg & MII_CR_POWER_DOWN) @@ -4495,13 +4516,21 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN); E1000_WRITE_REG(&adapter->hw, WUFC, wufc); - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); + retval = pci_enable_wake(pdev, PCI_D3hot, 1); + if (retval) + DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); + retval = pci_enable_wake(pdev, PCI_D3cold, 1); + if (retval) + DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); } else { E1000_WRITE_REG(&adapter->hw, WUC, 0); E1000_WRITE_REG(&adapter->hw, WUFC, 0); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); + retval = pci_enable_wake(pdev, PCI_D3hot, 0); + if (retval) + DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); + retval = pci_enable_wake(pdev, PCI_D3cold, 0); + if (retval) + DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); } if (adapter->hw.mac_type >= e1000_82540 && @@ -4510,8 +4539,13 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) if (manc & E1000_MANC_SMBUS_EN) { manc |= E1000_MANC_ARP_EN; E1000_WRITE_REG(&adapter->hw, MANC, manc); - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); + retval = pci_enable_wake(pdev, PCI_D3hot, 1); + if (retval) + DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); + retval = pci_enable_wake(pdev, PCI_D3cold, 1); + if (retval) + DPRINTK(PROBE, ERR, + "Error enabling D3 cold wake\n"); } } @@ -4521,7 +4555,9 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); + retval = pci_set_power_state(pdev, pci_choose_state(pdev, state)); + if (retval) + DPRINTK(PROBE, ERR, "Error in setting power state\n"); return 0; } @@ -4532,15 +4568,22 @@ e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); + int retval; uint32_t manc, ret_val; - pci_set_power_state(pdev, PCI_D0); + retval = pci_set_power_state(pdev, PCI_D0); + if (retval) + DPRINTK(PROBE, ERR, "Error in setting power state\n"); e1000_pci_restore_state(adapter); ret_val = pci_enable_device(pdev); pci_set_master(pdev); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); + retval = pci_enable_wake(pdev, PCI_D3hot, 0); + if (retval) + DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); + retval = pci_enable_wake(pdev, PCI_D3cold, 0); + if (retval) + DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); @@ -4568,12 +4611,6 @@ e1000_resume(struct pci_dev *pdev) return 0; } #endif - -static void e1000_shutdown(struct pci_dev *pdev) -{ - e1000_suspend(pdev, PMSG_SUSPEND); -} - #ifdef CONFIG_NET_POLL_CONTROLLER /* * Polling 'interrupt' - used by things like netconsole to send skbs diff --git a/trunk/drivers/net/e1000/e1000_osdep.h b/trunk/drivers/net/e1000/e1000_osdep.h index 048d052be29d..9790db974dc1 100644 --- a/trunk/drivers/net/e1000/e1000_osdep.h +++ b/trunk/drivers/net/e1000/e1000_osdep.h @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,7 +22,6 @@ Contact Information: Linux NICS - e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ diff --git a/trunk/drivers/net/e1000/e1000_param.c b/trunk/drivers/net/e1000/e1000_param.c index e55f8969a0fb..e0a4d37d1b85 100644 --- a/trunk/drivers/net/e1000/e1000_param.c +++ b/trunk/drivers/net/e1000/e1000_param.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,7 +22,6 @@ Contact Information: Linux NICS - e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 705e1229d89d..f7235c9bc421 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -2891,6 +2891,78 @@ static int nv_open(struct net_device *dev) goto out_drain; } + if (np->msi_flags & NV_MSI_X_CAPABLE) { + for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { + np->msi_x_entry[i].entry = i; + } + if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) { + np->msi_flags |= NV_MSI_X_ENABLED; + if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) { + /* Request irq for rx handling */ + if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) { + printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret); + pci_disable_msix(np->pci_dev); + np->msi_flags &= ~NV_MSI_X_ENABLED; + goto out_drain; + } + /* Request irq for tx handling */ + if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) { + printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret); + pci_disable_msix(np->pci_dev); + np->msi_flags &= ~NV_MSI_X_ENABLED; + goto out_drain; + } + /* Request irq for link and timer handling */ + if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, SA_SHIRQ, dev->name, dev) != 0) { + printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret); + pci_disable_msix(np->pci_dev); + np->msi_flags &= ~NV_MSI_X_ENABLED; + goto out_drain; + } + + /* map interrupts to their respective vector */ + writel(0, base + NvRegMSIXMap0); + writel(0, base + NvRegMSIXMap1); + set_msix_vector_map(dev, NV_MSI_X_VECTOR_RX, NVREG_IRQ_RX_ALL); + set_msix_vector_map(dev, NV_MSI_X_VECTOR_TX, NVREG_IRQ_TX_ALL); + 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, &nv_nic_irq, SA_SHIRQ, 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; + goto out_drain; + } + + /* map interrupts to vector 0 */ + writel(0, base + NvRegMSIXMap0); + writel(0, base + NvRegMSIXMap1); + } + } + } + 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, &nv_nic_irq, SA_SHIRQ, 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; + goto out_drain; + } + + /* map interrupts to vector 0 */ + writel(0, base + NvRegMSIMap0); + writel(0, base + NvRegMSIMap1); + /* enable msi vector 0 */ + writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); + } + } + if (ret != 0) { + if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) + goto out_drain; + } + /* ask for interrupts */ nv_enable_hw_interrupts(dev, np->irqmask); diff --git a/trunk/drivers/net/irda/Makefile b/trunk/drivers/net/irda/Makefile index c1ce2398efea..27ab75f20799 100644 --- a/trunk/drivers/net/irda/Makefile +++ b/trunk/drivers/net/irda/Makefile @@ -46,4 +46,4 @@ obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o # The SIR helper module -sir-dev-objs := sir_dev.o sir_dongle.o +sir-dev-objs := sir_dev.o sir_dongle.o sir_kthread.o diff --git a/trunk/drivers/net/irda/irda-usb.c b/trunk/drivers/net/irda/irda-usb.c index cd87593e4e8a..96bdb73c2283 100644 --- a/trunk/drivers/net/irda/irda-usb.c +++ b/trunk/drivers/net/irda/irda-usb.c @@ -1778,7 +1778,7 @@ static int irda_usb_probe(struct usb_interface *intf, if (self->needspatch) { ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0), - 0x02, 0x40, 0, 0, NULL, 0, 500); + 0x02, 0x40, 0, 0, 0, 0, msecs_to_jiffies(500)); if (ret < 0) { IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret); goto err_out_3; diff --git a/trunk/drivers/net/irda/sir-dev.h b/trunk/drivers/net/irda/sir-dev.h index 9fa294a546d6..f69fb4cec76f 100644 --- a/trunk/drivers/net/irda/sir-dev.h +++ b/trunk/drivers/net/irda/sir-dev.h @@ -15,14 +15,23 @@ #define IRDA_SIR_H #include -#include #include #include // iobuff_t +/* FIXME: unify irda_request with sir_fsm! */ + +struct irda_request { + struct list_head lh_request; + unsigned long pending; + void (*func)(void *); + void *data; + struct timer_list timer; +}; + struct sir_fsm { struct semaphore sem; - struct work_struct work; + struct irda_request rq; unsigned state, substate; int param; int result; diff --git a/trunk/drivers/net/irda/sir_dev.c b/trunk/drivers/net/irda/sir_dev.c index 3b5854d10c17..ea7c9464d46a 100644 --- a/trunk/drivers/net/irda/sir_dev.c +++ b/trunk/drivers/net/irda/sir_dev.c @@ -23,298 +23,6 @@ #include "sir-dev.h" - -static struct workqueue_struct *irda_sir_wq; - -/* STATE MACHINE */ - -/* substate handler of the config-fsm to handle the cases where we want - * to wait for transmit completion before changing the port configuration - */ - -static int sirdev_tx_complete_fsm(struct sir_dev *dev) -{ - struct sir_fsm *fsm = &dev->fsm; - unsigned next_state, delay; - unsigned bytes_left; - - do { - next_state = fsm->substate; /* default: stay in current substate */ - delay = 0; - - switch(fsm->substate) { - - case SIRDEV_STATE_WAIT_XMIT: - if (dev->drv->chars_in_buffer) - bytes_left = dev->drv->chars_in_buffer(dev); - else - bytes_left = 0; - if (!bytes_left) { - next_state = SIRDEV_STATE_WAIT_UNTIL_SENT; - break; - } - - if (dev->speed > 115200) - delay = (bytes_left*8*10000) / (dev->speed/100); - else if (dev->speed > 0) - delay = (bytes_left*10*10000) / (dev->speed/100); - else - delay = 0; - /* expected delay (usec) until remaining bytes are sent */ - if (delay < 100) { - udelay(delay); - delay = 0; - break; - } - /* sleep some longer delay (msec) */ - delay = (delay+999) / 1000; - break; - - case SIRDEV_STATE_WAIT_UNTIL_SENT: - /* block until underlaying hardware buffer are empty */ - if (dev->drv->wait_until_sent) - dev->drv->wait_until_sent(dev); - next_state = SIRDEV_STATE_TX_DONE; - break; - - case SIRDEV_STATE_TX_DONE: - return 0; - - default: - IRDA_ERROR("%s - undefined state\n", __FUNCTION__); - return -EINVAL; - } - fsm->substate = next_state; - } while (delay == 0); - return delay; -} - -/* - * Function sirdev_config_fsm - * - * State machine to handle the configuration of the device (and attached dongle, if any). - * This handler is scheduled for execution in kIrDAd context, so we can sleep. - * however, kIrDAd is shared by all sir_dev devices so we better don't sleep there too - * long. Instead, for longer delays we start a timer to reschedule us later. - * On entry, fsm->sem is always locked and the netdev xmit queue stopped. - * Both must be unlocked/restarted on completion - but only on final exit. - */ - -static void sirdev_config_fsm(void *data) -{ - struct sir_dev *dev = data; - struct sir_fsm *fsm = &dev->fsm; - int next_state; - int ret = -1; - unsigned delay; - - IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies); - - do { - IRDA_DEBUG(3, "%s - state=0x%04x / substate=0x%04x\n", - __FUNCTION__, fsm->state, fsm->substate); - - next_state = fsm->state; - delay = 0; - - switch(fsm->state) { - - case SIRDEV_STATE_DONGLE_OPEN: - if (dev->dongle_drv != NULL) { - ret = sirdev_put_dongle(dev); - if (ret) { - fsm->result = -EINVAL; - next_state = SIRDEV_STATE_ERROR; - break; - } - } - - /* Initialize dongle */ - ret = sirdev_get_dongle(dev, fsm->param); - if (ret) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - - /* Dongles are powered through the modem control lines which - * were just set during open. Before resetting, let's wait for - * the power to stabilize. This is what some dongle drivers did - * in open before, while others didn't - should be safe anyway. - */ - - delay = 50; - fsm->substate = SIRDEV_STATE_DONGLE_RESET; - next_state = SIRDEV_STATE_DONGLE_RESET; - - fsm->param = 9600; - - break; - - case SIRDEV_STATE_DONGLE_CLOSE: - /* shouldn't we just treat this as success=? */ - if (dev->dongle_drv == NULL) { - fsm->result = -EINVAL; - next_state = SIRDEV_STATE_ERROR; - break; - } - - ret = sirdev_put_dongle(dev); - if (ret) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - next_state = SIRDEV_STATE_DONE; - break; - - case SIRDEV_STATE_SET_DTR_RTS: - ret = sirdev_set_dtr_rts(dev, - (fsm->param&0x02) ? TRUE : FALSE, - (fsm->param&0x01) ? TRUE : FALSE); - next_state = SIRDEV_STATE_DONE; - break; - - case SIRDEV_STATE_SET_SPEED: - fsm->substate = SIRDEV_STATE_WAIT_XMIT; - next_state = SIRDEV_STATE_DONGLE_CHECK; - break; - - case SIRDEV_STATE_DONGLE_CHECK: - ret = sirdev_tx_complete_fsm(dev); - if (ret < 0) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - if ((delay=ret) != 0) - break; - - if (dev->dongle_drv) { - fsm->substate = SIRDEV_STATE_DONGLE_RESET; - next_state = SIRDEV_STATE_DONGLE_RESET; - } - else { - dev->speed = fsm->param; - next_state = SIRDEV_STATE_PORT_SPEED; - } - break; - - case SIRDEV_STATE_DONGLE_RESET: - if (dev->dongle_drv->reset) { - ret = dev->dongle_drv->reset(dev); - if (ret < 0) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - } - else - ret = 0; - if ((delay=ret) == 0) { - /* set serial port according to dongle default speed */ - if (dev->drv->set_speed) - dev->drv->set_speed(dev, dev->speed); - fsm->substate = SIRDEV_STATE_DONGLE_SPEED; - next_state = SIRDEV_STATE_DONGLE_SPEED; - } - break; - - case SIRDEV_STATE_DONGLE_SPEED: - if (dev->dongle_drv->reset) { - ret = dev->dongle_drv->set_speed(dev, fsm->param); - if (ret < 0) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - } - else - ret = 0; - if ((delay=ret) == 0) - next_state = SIRDEV_STATE_PORT_SPEED; - break; - - case SIRDEV_STATE_PORT_SPEED: - /* Finally we are ready to change the serial port speed */ - if (dev->drv->set_speed) - dev->drv->set_speed(dev, dev->speed); - dev->new_speed = 0; - next_state = SIRDEV_STATE_DONE; - break; - - case SIRDEV_STATE_DONE: - /* Signal network layer so it can send more frames */ - netif_wake_queue(dev->netdev); - next_state = SIRDEV_STATE_COMPLETE; - break; - - default: - IRDA_ERROR("%s - undefined state\n", __FUNCTION__); - fsm->result = -EINVAL; - /* fall thru */ - - case SIRDEV_STATE_ERROR: - IRDA_ERROR("%s - error: %d\n", __FUNCTION__, fsm->result); - -#if 0 /* don't enable this before we have netdev->tx_timeout to recover */ - netif_stop_queue(dev->netdev); -#else - netif_wake_queue(dev->netdev); -#endif - /* fall thru */ - - case SIRDEV_STATE_COMPLETE: - /* config change finished, so we are not busy any longer */ - sirdev_enable_rx(dev); - up(&fsm->sem); - return; - } - fsm->state = next_state; - } while(!delay); - - queue_delayed_work(irda_sir_wq, &fsm->work, msecs_to_jiffies(delay)); -} - -/* schedule some device configuration task for execution by kIrDAd - * on behalf of the above state machine. - * can be called from process or interrupt/tasklet context. - */ - -int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned param) -{ - struct sir_fsm *fsm = &dev->fsm; - - IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __FUNCTION__, initial_state, param); - - if (down_trylock(&fsm->sem)) { - if (in_interrupt() || in_atomic() || irqs_disabled()) { - IRDA_DEBUG(1, "%s(), state machine busy!\n", __FUNCTION__); - return -EWOULDBLOCK; - } else - down(&fsm->sem); - } - - if (fsm->state == SIRDEV_STATE_DEAD) { - /* race with sirdev_close should never happen */ - IRDA_ERROR("%s(), instance staled!\n", __FUNCTION__); - up(&fsm->sem); - return -ESTALE; /* or better EPIPE? */ - } - - netif_stop_queue(dev->netdev); - atomic_set(&dev->enable_rx, 0); - - fsm->state = initial_state; - fsm->param = param; - fsm->result = 0; - - INIT_WORK(&fsm->work, sirdev_config_fsm, dev); - queue_work(irda_sir_wq, &fsm->work); - return 0; -} - - /***************************************************************************/ void sirdev_enable_rx(struct sir_dev *dev) @@ -911,6 +619,10 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n spin_lock_init(&dev->tx_lock); init_MUTEX(&dev->fsm.sem); + INIT_LIST_HEAD(&dev->fsm.rq.lh_request); + dev->fsm.rq.pending = 0; + init_timer(&dev->fsm.rq.timer); + dev->drv = drv; dev->netdev = ndev; @@ -970,22 +682,3 @@ int sirdev_put_instance(struct sir_dev *dev) } EXPORT_SYMBOL(sirdev_put_instance); -static int __init sir_wq_init(void) -{ - irda_sir_wq = create_singlethread_workqueue("irda_sir_wq"); - if (!irda_sir_wq) - return -ENOMEM; - return 0; -} - -static void __exit sir_wq_exit(void) -{ - destroy_workqueue(irda_sir_wq); -} - -module_init(sir_wq_init); -module_exit(sir_wq_exit); - -MODULE_AUTHOR("Martin Diehl "); -MODULE_DESCRIPTION("IrDA SIR core"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/irda/sir_kthread.c b/trunk/drivers/net/irda/sir_kthread.c new file mode 100644 index 000000000000..e3904d6bfecd --- /dev/null +++ b/trunk/drivers/net/irda/sir_kthread.c @@ -0,0 +1,508 @@ +/********************************************************************* + * + * sir_kthread.c: dedicated thread to process scheduled + * sir device setup requests + * + * Copyright (c) 2002 Martin Diehl + * + * 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. + * + ********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "sir-dev.h" + +/************************************************************************** + * + * kIrDAd kernel thread and config state machine + * + */ + +struct irda_request_queue { + struct list_head request_list; + spinlock_t lock; + task_t *thread; + struct completion exit; + wait_queue_head_t kick, done; + atomic_t num_pending; +}; + +static struct irda_request_queue irda_rq_queue; + +static int irda_queue_request(struct irda_request *rq) +{ + int ret = 0; + unsigned long flags; + + if (!test_and_set_bit(0, &rq->pending)) { + spin_lock_irqsave(&irda_rq_queue.lock, flags); + list_add_tail(&rq->lh_request, &irda_rq_queue.request_list); + wake_up(&irda_rq_queue.kick); + atomic_inc(&irda_rq_queue.num_pending); + spin_unlock_irqrestore(&irda_rq_queue.lock, flags); + ret = 1; + } + return ret; +} + +static void irda_request_timer(unsigned long data) +{ + struct irda_request *rq = (struct irda_request *)data; + unsigned long flags; + + spin_lock_irqsave(&irda_rq_queue.lock, flags); + list_add_tail(&rq->lh_request, &irda_rq_queue.request_list); + wake_up(&irda_rq_queue.kick); + spin_unlock_irqrestore(&irda_rq_queue.lock, flags); +} + +static int irda_queue_delayed_request(struct irda_request *rq, unsigned long delay) +{ + int ret = 0; + struct timer_list *timer = &rq->timer; + + if (!test_and_set_bit(0, &rq->pending)) { + timer->expires = jiffies + delay; + timer->function = irda_request_timer; + timer->data = (unsigned long)rq; + atomic_inc(&irda_rq_queue.num_pending); + add_timer(timer); + ret = 1; + } + return ret; +} + +static void run_irda_queue(void) +{ + unsigned long flags; + struct list_head *entry, *tmp; + struct irda_request *rq; + + spin_lock_irqsave(&irda_rq_queue.lock, flags); + list_for_each_safe(entry, tmp, &irda_rq_queue.request_list) { + rq = list_entry(entry, struct irda_request, lh_request); + list_del_init(entry); + spin_unlock_irqrestore(&irda_rq_queue.lock, flags); + + clear_bit(0, &rq->pending); + rq->func(rq->data); + + if (atomic_dec_and_test(&irda_rq_queue.num_pending)) + wake_up(&irda_rq_queue.done); + + spin_lock_irqsave(&irda_rq_queue.lock, flags); + } + spin_unlock_irqrestore(&irda_rq_queue.lock, flags); +} + +static int irda_thread(void *startup) +{ + DECLARE_WAITQUEUE(wait, current); + + daemonize("kIrDAd"); + + irda_rq_queue.thread = current; + + complete((struct completion *)startup); + + while (irda_rq_queue.thread != NULL) { + + /* We use TASK_INTERRUPTIBLE, rather than + * TASK_UNINTERRUPTIBLE. Andrew Morton made this + * change ; he told me that it is safe, because "signal + * blocking is now handled in daemonize()", he added + * that the problem is that "uninterruptible sleep + * contributes to load average", making user worry. + * Jean II */ + set_task_state(current, TASK_INTERRUPTIBLE); + add_wait_queue(&irda_rq_queue.kick, &wait); + if (list_empty(&irda_rq_queue.request_list)) + schedule(); + else + __set_task_state(current, TASK_RUNNING); + remove_wait_queue(&irda_rq_queue.kick, &wait); + + /* make swsusp happy with our thread */ + try_to_freeze(); + + run_irda_queue(); + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,35) + reparent_to_init(); +#endif + complete_and_exit(&irda_rq_queue.exit, 0); + /* never reached */ + return 0; +} + + +static void flush_irda_queue(void) +{ + if (atomic_read(&irda_rq_queue.num_pending)) { + + DECLARE_WAITQUEUE(wait, current); + + if (!list_empty(&irda_rq_queue.request_list)) + run_irda_queue(); + + set_task_state(current, TASK_UNINTERRUPTIBLE); + add_wait_queue(&irda_rq_queue.done, &wait); + if (atomic_read(&irda_rq_queue.num_pending)) + schedule(); + else + __set_task_state(current, TASK_RUNNING); + remove_wait_queue(&irda_rq_queue.done, &wait); + } +} + +/* substate handler of the config-fsm to handle the cases where we want + * to wait for transmit completion before changing the port configuration + */ + +static int irda_tx_complete_fsm(struct sir_dev *dev) +{ + struct sir_fsm *fsm = &dev->fsm; + unsigned next_state, delay; + unsigned bytes_left; + + do { + next_state = fsm->substate; /* default: stay in current substate */ + delay = 0; + + switch(fsm->substate) { + + case SIRDEV_STATE_WAIT_XMIT: + if (dev->drv->chars_in_buffer) + bytes_left = dev->drv->chars_in_buffer(dev); + else + bytes_left = 0; + if (!bytes_left) { + next_state = SIRDEV_STATE_WAIT_UNTIL_SENT; + break; + } + + if (dev->speed > 115200) + delay = (bytes_left*8*10000) / (dev->speed/100); + else if (dev->speed > 0) + delay = (bytes_left*10*10000) / (dev->speed/100); + else + delay = 0; + /* expected delay (usec) until remaining bytes are sent */ + if (delay < 100) { + udelay(delay); + delay = 0; + break; + } + /* sleep some longer delay (msec) */ + delay = (delay+999) / 1000; + break; + + case SIRDEV_STATE_WAIT_UNTIL_SENT: + /* block until underlaying hardware buffer are empty */ + if (dev->drv->wait_until_sent) + dev->drv->wait_until_sent(dev); + next_state = SIRDEV_STATE_TX_DONE; + break; + + case SIRDEV_STATE_TX_DONE: + return 0; + + default: + IRDA_ERROR("%s - undefined state\n", __FUNCTION__); + return -EINVAL; + } + fsm->substate = next_state; + } while (delay == 0); + return delay; +} + +/* + * Function irda_config_fsm + * + * State machine to handle the configuration of the device (and attached dongle, if any). + * This handler is scheduled for execution in kIrDAd context, so we can sleep. + * however, kIrDAd is shared by all sir_dev devices so we better don't sleep there too + * long. Instead, for longer delays we start a timer to reschedule us later. + * On entry, fsm->sem is always locked and the netdev xmit queue stopped. + * Both must be unlocked/restarted on completion - but only on final exit. + */ + +static void irda_config_fsm(void *data) +{ + struct sir_dev *dev = data; + struct sir_fsm *fsm = &dev->fsm; + int next_state; + int ret = -1; + unsigned delay; + + IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies); + + do { + IRDA_DEBUG(3, "%s - state=0x%04x / substate=0x%04x\n", + __FUNCTION__, fsm->state, fsm->substate); + + next_state = fsm->state; + delay = 0; + + switch(fsm->state) { + + case SIRDEV_STATE_DONGLE_OPEN: + if (dev->dongle_drv != NULL) { + ret = sirdev_put_dongle(dev); + if (ret) { + fsm->result = -EINVAL; + next_state = SIRDEV_STATE_ERROR; + break; + } + } + + /* Initialize dongle */ + ret = sirdev_get_dongle(dev, fsm->param); + if (ret) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + + /* Dongles are powered through the modem control lines which + * were just set during open. Before resetting, let's wait for + * the power to stabilize. This is what some dongle drivers did + * in open before, while others didn't - should be safe anyway. + */ + + delay = 50; + fsm->substate = SIRDEV_STATE_DONGLE_RESET; + next_state = SIRDEV_STATE_DONGLE_RESET; + + fsm->param = 9600; + + break; + + case SIRDEV_STATE_DONGLE_CLOSE: + /* shouldn't we just treat this as success=? */ + if (dev->dongle_drv == NULL) { + fsm->result = -EINVAL; + next_state = SIRDEV_STATE_ERROR; + break; + } + + ret = sirdev_put_dongle(dev); + if (ret) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + next_state = SIRDEV_STATE_DONE; + break; + + case SIRDEV_STATE_SET_DTR_RTS: + ret = sirdev_set_dtr_rts(dev, + (fsm->param&0x02) ? TRUE : FALSE, + (fsm->param&0x01) ? TRUE : FALSE); + next_state = SIRDEV_STATE_DONE; + break; + + case SIRDEV_STATE_SET_SPEED: + fsm->substate = SIRDEV_STATE_WAIT_XMIT; + next_state = SIRDEV_STATE_DONGLE_CHECK; + break; + + case SIRDEV_STATE_DONGLE_CHECK: + ret = irda_tx_complete_fsm(dev); + if (ret < 0) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + if ((delay=ret) != 0) + break; + + if (dev->dongle_drv) { + fsm->substate = SIRDEV_STATE_DONGLE_RESET; + next_state = SIRDEV_STATE_DONGLE_RESET; + } + else { + dev->speed = fsm->param; + next_state = SIRDEV_STATE_PORT_SPEED; + } + break; + + case SIRDEV_STATE_DONGLE_RESET: + if (dev->dongle_drv->reset) { + ret = dev->dongle_drv->reset(dev); + if (ret < 0) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + } + else + ret = 0; + if ((delay=ret) == 0) { + /* set serial port according to dongle default speed */ + if (dev->drv->set_speed) + dev->drv->set_speed(dev, dev->speed); + fsm->substate = SIRDEV_STATE_DONGLE_SPEED; + next_state = SIRDEV_STATE_DONGLE_SPEED; + } + break; + + case SIRDEV_STATE_DONGLE_SPEED: + if (dev->dongle_drv->reset) { + ret = dev->dongle_drv->set_speed(dev, fsm->param); + if (ret < 0) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + } + else + ret = 0; + if ((delay=ret) == 0) + next_state = SIRDEV_STATE_PORT_SPEED; + break; + + case SIRDEV_STATE_PORT_SPEED: + /* Finally we are ready to change the serial port speed */ + if (dev->drv->set_speed) + dev->drv->set_speed(dev, dev->speed); + dev->new_speed = 0; + next_state = SIRDEV_STATE_DONE; + break; + + case SIRDEV_STATE_DONE: + /* Signal network layer so it can send more frames */ + netif_wake_queue(dev->netdev); + next_state = SIRDEV_STATE_COMPLETE; + break; + + default: + IRDA_ERROR("%s - undefined state\n", __FUNCTION__); + fsm->result = -EINVAL; + /* fall thru */ + + case SIRDEV_STATE_ERROR: + IRDA_ERROR("%s - error: %d\n", __FUNCTION__, fsm->result); + +#if 0 /* don't enable this before we have netdev->tx_timeout to recover */ + netif_stop_queue(dev->netdev); +#else + netif_wake_queue(dev->netdev); +#endif + /* fall thru */ + + case SIRDEV_STATE_COMPLETE: + /* config change finished, so we are not busy any longer */ + sirdev_enable_rx(dev); + up(&fsm->sem); + return; + } + fsm->state = next_state; + } while(!delay); + + irda_queue_delayed_request(&fsm->rq, msecs_to_jiffies(delay)); +} + +/* schedule some device configuration task for execution by kIrDAd + * on behalf of the above state machine. + * can be called from process or interrupt/tasklet context. + */ + +int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned param) +{ + struct sir_fsm *fsm = &dev->fsm; + int xmit_was_down; + + IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __FUNCTION__, initial_state, param); + + if (down_trylock(&fsm->sem)) { + if (in_interrupt() || in_atomic() || irqs_disabled()) { + IRDA_DEBUG(1, "%s(), state machine busy!\n", __FUNCTION__); + return -EWOULDBLOCK; + } else + down(&fsm->sem); + } + + if (fsm->state == SIRDEV_STATE_DEAD) { + /* race with sirdev_close should never happen */ + IRDA_ERROR("%s(), instance staled!\n", __FUNCTION__); + up(&fsm->sem); + return -ESTALE; /* or better EPIPE? */ + } + + xmit_was_down = netif_queue_stopped(dev->netdev); + netif_stop_queue(dev->netdev); + atomic_set(&dev->enable_rx, 0); + + fsm->state = initial_state; + fsm->param = param; + fsm->result = 0; + + INIT_LIST_HEAD(&fsm->rq.lh_request); + fsm->rq.pending = 0; + fsm->rq.func = irda_config_fsm; + fsm->rq.data = dev; + + if (!irda_queue_request(&fsm->rq)) { /* returns 0 on error! */ + atomic_set(&dev->enable_rx, 1); + if (!xmit_was_down) + netif_wake_queue(dev->netdev); + up(&fsm->sem); + return -EAGAIN; + } + return 0; +} + +static int __init irda_thread_create(void) +{ + struct completion startup; + int pid; + + spin_lock_init(&irda_rq_queue.lock); + irda_rq_queue.thread = NULL; + INIT_LIST_HEAD(&irda_rq_queue.request_list); + init_waitqueue_head(&irda_rq_queue.kick); + init_waitqueue_head(&irda_rq_queue.done); + atomic_set(&irda_rq_queue.num_pending, 0); + + init_completion(&startup); + pid = kernel_thread(irda_thread, &startup, CLONE_FS|CLONE_FILES); + if (pid <= 0) + return -EAGAIN; + else + wait_for_completion(&startup); + + return 0; +} + +static void __exit irda_thread_join(void) +{ + if (irda_rq_queue.thread) { + flush_irda_queue(); + init_completion(&irda_rq_queue.exit); + irda_rq_queue.thread = NULL; + wake_up(&irda_rq_queue.kick); + wait_for_completion(&irda_rq_queue.exit); + } +} + +module_init(irda_thread_create); +module_exit(irda_thread_join); + +MODULE_AUTHOR("Martin Diehl "); +MODULE_DESCRIPTION("IrDA SIR core"); +MODULE_LICENSE("GPL"); + diff --git a/trunk/drivers/net/irda/smsc-ircc2.c b/trunk/drivers/net/irda/smsc-ircc2.c index a4674044bd6f..58f76cefbc83 100644 --- a/trunk/drivers/net/irda/smsc-ircc2.c +++ b/trunk/drivers/net/irda/smsc-ircc2.c @@ -54,7 +54,6 @@ #include #include #include -#include #include #include @@ -359,16 +358,6 @@ static inline void register_bank(int iobase, int bank) iobase + IRCC_MASTER); } -#ifdef CONFIG_PNP -/* PNP hotplug support */ -static const struct pnp_device_id smsc_ircc_pnp_table[] = { - { .id = "SMCf010", .driver_data = 0 }, - /* and presumably others */ - { } -}; -MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); -#endif - /******************************************************************************* * @@ -2083,8 +2072,7 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self) /* PROBING * - * REVISIT we can be told about the device by PNP, and should use that info - * instead of probing hardware and creating a platform_device ... + * */ static int __init smsc_ircc_look_for_chips(void) diff --git a/trunk/drivers/net/ixgb/ixgb.h b/trunk/drivers/net/ixgb/ixgb.h index b9c37fdc8418..c83271b38621 100644 --- a/trunk/drivers/net/ixgb/ixgb.h +++ b/trunk/drivers/net/ixgb/ixgb.h @@ -84,12 +84,7 @@ struct ixgb_adapter; #define IXGB_DBG(args...) #endif -#define PFX "ixgb: " -#define DPRINTK(nlevel, klevel, fmt, args...) \ - (void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \ - printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \ - __FUNCTION__ , ## args)) - +#define IXGB_ERR(args...) printk(KERN_ERR "ixgb: " args) /* TX/RX descriptor defines */ #define DEFAULT_TXD 256 @@ -180,7 +175,6 @@ struct ixgb_adapter { uint64_t hw_csum_tx_good; uint64_t hw_csum_tx_error; uint32_t tx_int_delay; - uint32_t tx_timeout_count; boolean_t tx_int_delay_enable; boolean_t detect_tx_hung; @@ -198,7 +192,6 @@ struct ixgb_adapter { /* structs defined in ixgb_hw.h */ struct ixgb_hw hw; - u16 msg_enable; struct ixgb_hw_stats stats; #ifdef CONFIG_PCI_MSI boolean_t have_msi; diff --git a/trunk/drivers/net/ixgb/ixgb_ethtool.c b/trunk/drivers/net/ixgb/ixgb_ethtool.c index 6d8192f4314c..d38ade5f2f4e 100644 --- a/trunk/drivers/net/ixgb/ixgb_ethtool.c +++ b/trunk/drivers/net/ixgb/ixgb_ethtool.c @@ -44,8 +44,6 @@ extern void ixgb_free_rx_resources(struct ixgb_adapter *adapter); extern void ixgb_free_tx_resources(struct ixgb_adapter *adapter); extern void ixgb_update_stats(struct ixgb_adapter *adapter); -#define IXGB_ALL_RAR_ENTRIES 16 - struct ixgb_stats { char stat_string[ETH_GSTRING_LEN]; int sizeof_stat; @@ -78,7 +76,6 @@ static struct ixgb_stats ixgb_gstrings_stats[] = { {"tx_heartbeat_errors", IXGB_STAT(net_stats.tx_heartbeat_errors)}, {"tx_window_errors", IXGB_STAT(net_stats.tx_window_errors)}, {"tx_deferred_ok", IXGB_STAT(stats.dc)}, - {"tx_timeout_count", IXGB_STAT(tx_timeout_count) }, {"rx_long_length_errors", IXGB_STAT(stats.roc)}, {"rx_short_length_errors", IXGB_STAT(stats.ruc)}, #ifdef NETIF_F_TSO @@ -120,16 +117,6 @@ ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) return 0; } -static void ixgb_set_speed_duplex(struct net_device *netdev) -{ - struct ixgb_adapter *adapter = netdev_priv(netdev); - /* be optimistic about our link, since we were up before */ - adapter->link_speed = 10000; - adapter->link_duplex = FULL_DUPLEX; - netif_carrier_on(netdev); - netif_wake_queue(netdev); -} - static int ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { @@ -143,7 +130,12 @@ ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ixgb_down(adapter, TRUE); ixgb_reset(adapter); ixgb_up(adapter); - ixgb_set_speed_duplex(netdev); + /* be optimistic about our link, since we were up before */ + adapter->link_speed = 10000; + adapter->link_duplex = FULL_DUPLEX; + netif_carrier_on(netdev); + netif_wake_queue(netdev); + } else ixgb_reset(adapter); @@ -191,7 +183,11 @@ ixgb_set_pauseparam(struct net_device *netdev, if(netif_running(adapter->netdev)) { ixgb_down(adapter, TRUE); ixgb_up(adapter); - ixgb_set_speed_duplex(netdev); + /* be optimistic about our link, since we were up before */ + adapter->link_speed = 10000; + adapter->link_duplex = FULL_DUPLEX; + netif_carrier_on(netdev); + netif_wake_queue(netdev); } else ixgb_reset(adapter); @@ -216,7 +212,11 @@ ixgb_set_rx_csum(struct net_device *netdev, uint32_t data) if(netif_running(netdev)) { ixgb_down(adapter,TRUE); ixgb_up(adapter); - ixgb_set_speed_duplex(netdev); + /* be optimistic about our link, since we were up before */ + adapter->link_speed = 10000; + adapter->link_duplex = FULL_DUPLEX; + netif_carrier_on(netdev); + netif_wake_queue(netdev); } else ixgb_reset(adapter); return 0; @@ -251,19 +251,6 @@ ixgb_set_tso(struct net_device *netdev, uint32_t data) } #endif /* NETIF_F_TSO */ -static uint32_t -ixgb_get_msglevel(struct net_device *netdev) -{ - struct ixgb_adapter *adapter = netdev->priv; - return adapter->msg_enable; -} - -static void -ixgb_set_msglevel(struct net_device *netdev, uint32_t data) -{ - struct ixgb_adapter *adapter = netdev->priv; - adapter->msg_enable = data; -} #define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_ static int @@ -316,7 +303,7 @@ ixgb_get_regs(struct net_device *netdev, *reg++ = IXGB_READ_REG(hw, RXCSUM); /* 20 */ /* there are 16 RAR entries in hardware, we only use 3 */ - for(i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) { + for(i = 0; i < 16; i++) { *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */ *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */ } @@ -606,7 +593,11 @@ ixgb_set_ringparam(struct net_device *netdev, adapter->tx_ring = tx_new; if((err = ixgb_up(adapter))) return err; - ixgb_set_speed_duplex(netdev); + /* be optimistic about our link, since we were up before */ + adapter->link_speed = 10000; + adapter->link_duplex = FULL_DUPLEX; + netif_carrier_on(netdev); + netif_wake_queue(netdev); } return 0; @@ -723,8 +714,6 @@ static struct ethtool_ops ixgb_ethtool_ops = { .set_tx_csum = ixgb_set_tx_csum, .get_sg = ethtool_op_get_sg, .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, diff --git a/trunk/drivers/net/ixgb/ixgb_hw.h b/trunk/drivers/net/ixgb/ixgb_hw.h index 19513c6c2f15..382c6300ccc2 100644 --- a/trunk/drivers/net/ixgb/ixgb_hw.h +++ b/trunk/drivers/net/ixgb/ixgb_hw.h @@ -57,7 +57,6 @@ typedef enum { typedef enum { ixgb_media_type_unknown = 0, ixgb_media_type_fiber = 1, - ixgb_media_type_copper = 2, ixgb_num_media_types } ixgb_media_type; diff --git a/trunk/drivers/net/ixgb/ixgb_ids.h b/trunk/drivers/net/ixgb/ixgb_ids.h index e119c05a6f2d..aee207eaa287 100644 --- a/trunk/drivers/net/ixgb/ixgb_ids.h +++ b/trunk/drivers/net/ixgb/ixgb_ids.h @@ -43,8 +43,6 @@ #define IXGB_SUBDEVICE_ID_A11F 0xA11F #define IXGB_SUBDEVICE_ID_A01F 0xA01F -#define IXGB_DEVICE_ID_82597EX_CX4 0x109E -#define IXGB_SUBDEVICE_ID_A00C 0xA00C - #endif /* #ifndef _IXGB_IDS_H_ */ + /* End of File */ diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index 0905a8240939..cfd67d812f0d 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -52,7 +52,7 @@ static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "1.0.104-k2"DRIVERNAPI +#define DRV_VERSION "1.0.100-k2"DRIVERNAPI char ixgb_driver_version[] = DRV_VERSION; static char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; @@ -67,8 +67,6 @@ static char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; static struct pci_device_id ixgb_pci_tbl[] = { {INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_CX4, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_SR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_LR, @@ -150,11 +148,6 @@ MODULE_DESCRIPTION("Intel(R) PRO/10GbE Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -#define DEFAULT_DEBUG_LEVEL_SHIFT 3 -static int debug = DEFAULT_DEBUG_LEVEL_SHIFT; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - /* some defines for controlling descriptor fetches in h/w */ #define RXDCTL_WTHRESH_DEFAULT 16 /* chip writes back at this many or RXT0 */ #define RXDCTL_PTHRESH_DEFAULT 0 /* chip considers prefech below @@ -256,7 +249,7 @@ ixgb_up(struct ixgb_adapter *adapter) if (!pcix) adapter->have_msi = FALSE; else if((err = pci_enable_msi(adapter->pdev))) { - DPRINTK(PROBE, ERR, + printk (KERN_ERR "Unable to allocate MSI interrupt Error: %d\n", err); adapter->have_msi = FALSE; /* proceed to try to request regular interrupt */ @@ -266,11 +259,8 @@ ixgb_up(struct ixgb_adapter *adapter) #endif if((err = request_irq(adapter->pdev->irq, &ixgb_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, - netdev->name, netdev))) { - DPRINTK(PROBE, ERR, - "Unable to allocate interrupt Error: %d\n", err); + netdev->name, netdev))) return err; - } /* disable interrupts and get the hardware into a known state */ IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff); @@ -336,7 +326,7 @@ ixgb_reset(struct ixgb_adapter *adapter) ixgb_adapter_stop(&adapter->hw); if(!ixgb_init_hw(&adapter->hw)) - DPRINTK(PROBE, ERR, "ixgb_init_hw failed.\n"); + IXGB_DBG("ixgb_init_hw failed.\n"); } /** @@ -373,8 +363,7 @@ ixgb_probe(struct pci_dev *pdev, } else { if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) || (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) { - printk(KERN_ERR - "ixgb: No usable DMA configuration, aborting\n"); + IXGB_ERR("No usable DMA configuration, aborting\n"); goto err_dma_mask; } pci_using_dac = 0; @@ -399,7 +388,6 @@ ixgb_probe(struct pci_dev *pdev, adapter->netdev = netdev; adapter->pdev = pdev; adapter->hw.back = adapter; - adapter->msg_enable = netif_msg_init(debug, DEFAULT_DEBUG_LEVEL_SHIFT); mmio_start = pci_resource_start(pdev, BAR_0); mmio_len = pci_resource_len(pdev, BAR_0); @@ -428,7 +416,7 @@ ixgb_probe(struct pci_dev *pdev, netdev->change_mtu = &ixgb_change_mtu; ixgb_set_ethtool_ops(netdev); netdev->tx_timeout = &ixgb_tx_timeout; - netdev->watchdog_timeo = 5 * HZ; + netdev->watchdog_timeo = HZ; #ifdef CONFIG_IXGB_NAPI netdev->poll = &ixgb_clean; netdev->weight = 64; @@ -440,7 +428,6 @@ ixgb_probe(struct pci_dev *pdev, netdev->poll_controller = ixgb_netpoll; #endif - strcpy(netdev->name, pci_name(pdev)); netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len; netdev->base_addr = adapter->hw.io_base; @@ -462,9 +449,6 @@ ixgb_probe(struct pci_dev *pdev, #ifdef NETIF_F_TSO netdev->features |= NETIF_F_TSO; #endif -#ifdef NETIF_F_LLTX - netdev->features |= NETIF_F_LLTX; -#endif if(pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -472,7 +456,7 @@ ixgb_probe(struct pci_dev *pdev, /* make sure the EEPROM is good */ if(!ixgb_validate_eeprom_checksum(&adapter->hw)) { - DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n"); + printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n"); err = -EIO; goto err_eeprom; } @@ -481,7 +465,6 @@ ixgb_probe(struct pci_dev *pdev, memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); if(!is_valid_ether_addr(netdev->perm_addr)) { - DPRINTK(PROBE, ERR, "Invalid MAC Address\n"); err = -EIO; goto err_eeprom; } @@ -495,7 +478,6 @@ ixgb_probe(struct pci_dev *pdev, INIT_WORK(&adapter->tx_timeout_task, (void (*)(void *))ixgb_tx_timeout_task, netdev); - strcpy(netdev->name, "eth%d"); if((err = register_netdev(netdev))) goto err_register; @@ -504,7 +486,8 @@ ixgb_probe(struct pci_dev *pdev, netif_carrier_off(netdev); netif_stop_queue(netdev); - DPRINTK(PROBE, INFO, "Intel(R) PRO/10GbE Network Connection\n"); + printk(KERN_INFO "%s: Intel(R) PRO/10GbE Network Connection\n", + netdev->name); ixgb_check_options(adapter); /* reset the hardware with the new settings */ @@ -579,13 +562,12 @@ ixgb_sw_init(struct ixgb_adapter *adapter) hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; if((hw->device_id == IXGB_DEVICE_ID_82597EX) - || (hw->device_id == IXGB_DEVICE_ID_82597EX_CX4) - || (hw->device_id == IXGB_DEVICE_ID_82597EX_LR) - || (hw->device_id == IXGB_DEVICE_ID_82597EX_SR)) + ||(hw->device_id == IXGB_DEVICE_ID_82597EX_LR) + ||(hw->device_id == IXGB_DEVICE_ID_82597EX_SR)) hw->mac_type = ixgb_82597; else { /* should never have loaded on this device */ - DPRINTK(PROBE, ERR, "unsupported device id\n"); + printk(KERN_ERR "ixgb: unsupported device id\n"); } /* enable flow control to be programmed */ @@ -683,8 +665,6 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter) size = sizeof(struct ixgb_buffer) * txdr->count; txdr->buffer_info = vmalloc(size); if(!txdr->buffer_info) { - DPRINTK(PROBE, ERR, - "Unable to allocate transmit descriptor ring memory\n"); return -ENOMEM; } memset(txdr->buffer_info, 0, size); @@ -697,8 +677,6 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter) txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); if(!txdr->desc) { vfree(txdr->buffer_info); - DPRINTK(PROBE, ERR, - "Unable to allocate transmit descriptor memory\n"); return -ENOMEM; } memset(txdr->desc, 0, txdr->size); @@ -772,8 +750,6 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter) size = sizeof(struct ixgb_buffer) * rxdr->count; rxdr->buffer_info = vmalloc(size); if(!rxdr->buffer_info) { - DPRINTK(PROBE, ERR, - "Unable to allocate receive descriptor ring\n"); return -ENOMEM; } memset(rxdr->buffer_info, 0, size); @@ -787,8 +763,6 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter) if(!rxdr->desc) { vfree(rxdr->buffer_info); - DPRINTK(PROBE, ERR, - "Unable to allocate receive descriptors\n"); return -ENOMEM; } memset(rxdr->desc, 0, rxdr->size); @@ -1138,8 +1112,8 @@ ixgb_watchdog(unsigned long data) if(adapter->hw.link_up) { if(!netif_carrier_ok(netdev)) { - DPRINTK(LINK, INFO, - "NIC Link is Up 10000 Mbps Full Duplex\n"); + printk(KERN_INFO "ixgb: %s NIC Link is Up %d Mbps %s\n", + netdev->name, 10000, "Full Duplex"); adapter->link_speed = 10000; adapter->link_duplex = FULL_DUPLEX; netif_carrier_on(netdev); @@ -1149,7 +1123,9 @@ ixgb_watchdog(unsigned long data) if(netif_carrier_ok(netdev)) { adapter->link_speed = 0; adapter->link_duplex = 0; - DPRINTK(LINK, INFO, "NIC Link is Down\n"); + printk(KERN_INFO + "ixgb: %s NIC Link is Down\n", + netdev->name); netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -1290,7 +1266,6 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, struct ixgb_buffer *buffer_info; int len = skb->len; unsigned int offset = 0, size, count = 0, i; - unsigned int mss = skb_shinfo(skb)->tso_size; unsigned int nr_frags = skb_shinfo(skb)->nr_frags; unsigned int f; @@ -1302,11 +1277,6 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, while(len) { buffer_info = &tx_ring->buffer_info[i]; size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE); - /* Workaround for premature desc write-backs - * in TSO mode. Append 4-byte sentinel desc */ - if(unlikely(mss && !nr_frags && size == len && size > 8)) - size -= 4; - buffer_info->length = size; buffer_info->dma = pci_map_single(adapter->pdev, @@ -1331,12 +1301,6 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, while(len) { buffer_info = &tx_ring->buffer_info[i]; size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE); - /* 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; - buffer_info->length = size; buffer_info->dma = pci_map_page(adapter->pdev, @@ -1414,8 +1378,7 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags) #define TXD_USE_COUNT(S) (((S) >> IXGB_MAX_TXD_PWR) + \ (((S) & (IXGB_MAX_DATA_PER_TXD - 1)) ? 1 : 0)) #define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) + \ - MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1 \ - /* one more for TSO workaround */ + 1 + MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1 static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) @@ -1432,26 +1395,13 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return 0; } -#ifdef NETIF_F_LLTX - local_irq_save(flags); - if (!spin_trylock(&adapter->tx_lock)) { - /* Collision - tell upper layer to requeue */ - local_irq_restore(flags); - return NETDEV_TX_LOCKED; - } -#else spin_lock_irqsave(&adapter->tx_lock, flags); -#endif - if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) { netif_stop_queue(netdev); spin_unlock_irqrestore(&adapter->tx_lock, flags); - return NETDEV_TX_BUSY; + return 1; } - -#ifndef NETIF_F_LLTX spin_unlock_irqrestore(&adapter->tx_lock, flags); -#endif if(adapter->vlgrp && vlan_tx_tag_present(skb)) { tx_flags |= IXGB_TX_FLAGS_VLAN; @@ -1463,13 +1413,10 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) tso = ixgb_tso(adapter, skb); if (tso < 0) { dev_kfree_skb_any(skb); -#ifdef NETIF_F_LLTX - spin_unlock_irqrestore(&adapter->tx_lock, flags); -#endif return NETDEV_TX_OK; } - if (likely(tso)) + if (tso) tx_flags |= IXGB_TX_FLAGS_TSO; else if(ixgb_tx_csum(adapter, skb)) tx_flags |= IXGB_TX_FLAGS_CSUM; @@ -1479,15 +1426,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) netdev->trans_start = jiffies; -#ifdef NETIF_F_LLTX - /* Make sure there is space in the ring for the next send. */ - if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) - netif_stop_queue(netdev); - - spin_unlock_irqrestore(&adapter->tx_lock, flags); - -#endif - return NETDEV_TX_OK; + return 0; } /** @@ -1509,7 +1448,6 @@ ixgb_tx_timeout_task(struct net_device *netdev) { struct ixgb_adapter *adapter = netdev_priv(netdev); - adapter->tx_timeout_count++; ixgb_down(adapter, TRUE); ixgb_up(adapter); } @@ -1548,7 +1486,7 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu) if((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) { - DPRINTK(PROBE, ERR, "Invalid MTU setting %d\n", new_mtu); + IXGB_ERR("Invalid MTU setting\n"); return -EINVAL; } @@ -1839,31 +1777,11 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter) /* detect a transmit hang in hardware, this serializes the * check with the clearing of time_stamp and movement of i */ adapter->detect_tx_hung = FALSE; - if (tx_ring->buffer_info[eop].dma && - time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + HZ) + if(tx_ring->buffer_info[i].dma && + time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) && !(IXGB_READ_REG(&adapter->hw, STATUS) & - IXGB_STATUS_TXOFF)) { - /* detected Tx unit hang */ - DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n" - " TDH <%x>\n" - " TDT <%x>\n" - " next_to_use <%x>\n" - " next_to_clean <%x>\n" - "buffer_info[next_to_clean]\n" - " time_stamp <%lx>\n" - " next_to_watch <%x>\n" - " jiffies <%lx>\n" - " next_to_watch.status <%x>\n", - IXGB_READ_REG(&adapter->hw, TDH), - IXGB_READ_REG(&adapter->hw, TDT), - tx_ring->next_to_use, - tx_ring->next_to_clean, - tx_ring->buffer_info[eop].time_stamp, - eop, - jiffies, - eop_desc->status); + IXGB_STATUS_TXOFF)) netif_stop_queue(netdev); - } } return cleaned; diff --git a/trunk/drivers/net/ixgb/ixgb_param.c b/trunk/drivers/net/ixgb/ixgb_param.c index 388462cca39d..8a83dfdf746d 100644 --- a/trunk/drivers/net/ixgb/ixgb_param.c +++ b/trunk/drivers/net/ixgb/ixgb_param.c @@ -76,7 +76,7 @@ IXGB_PARAM(RxDescriptors, "Number of receive descriptors"); * - 2 - Tx only, generate PAUSE frames but ignore them on receive * - 3 - Full Flow Control Support * - * Default Value: 2 - Tx only (silicon bug avoidance) + * Default Value: Read flow control settings from the EEPROM */ IXGB_PARAM(FlowControl, "Flow Control setting"); @@ -137,7 +137,7 @@ IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold"); * * Valid Range: 1 - 65535 * - * Default Value: 65535 (0xffff) (we'll send an xon if we recover) + * Default Value: 256 (0x100) */ IXGB_PARAM(FCReqTimeout, "Flow Control Request Timeout"); @@ -165,6 +165,8 @@ IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable"); #define XSUMRX_DEFAULT OPTION_ENABLED +#define FLOW_CONTROL_FULL ixgb_fc_full +#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL #define DEFAULT_FCRTL 0x28000 #define DEFAULT_FCRTH 0x30000 #define MIN_FCRTL 0 @@ -172,9 +174,9 @@ IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable"); #define MIN_FCRTH 8 #define MAX_FCRTH 0x3FFF0 +#define DEFAULT_FCPAUSE 0x100 /* this may be too long */ #define MIN_FCPAUSE 1 #define MAX_FCPAUSE 0xffff -#define DEFAULT_FCPAUSE 0xFFFF /* this may be too long */ struct ixgb_option { enum { enable_option, range_option, list_option } type; @@ -334,7 +336,7 @@ ixgb_check_options(struct ixgb_adapter *adapter) .type = list_option, .name = "Flow Control", .err = "reading default settings from EEPROM", - .def = ixgb_fc_tx_pause, + .def = ixgb_fc_full, .arg = { .l = { .nr = LIST_LEN(fc_list), .p = fc_list }} }; @@ -363,8 +365,8 @@ ixgb_check_options(struct ixgb_adapter *adapter) } else { adapter->hw.fc.high_water = opt.def; } - if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) - printk (KERN_INFO + if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) ) + printk (KERN_INFO "Ignoring RxFCHighThresh when no RxFC\n"); } { /* Receive Flow Control Low Threshold */ @@ -383,8 +385,8 @@ ixgb_check_options(struct ixgb_adapter *adapter) } else { adapter->hw.fc.low_water = opt.def; } - if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) - printk (KERN_INFO + if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) ) + printk (KERN_INFO "Ignoring RxFCLowThresh when no RxFC\n"); } { /* Flow Control Pause Time Request*/ @@ -404,12 +406,12 @@ ixgb_check_options(struct ixgb_adapter *adapter) } else { adapter->hw.fc.pause_time = opt.def; } - if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) - printk (KERN_INFO + if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) ) + printk (KERN_INFO "Ignoring FCReqTimeout when no RxFC\n"); } /* high low and spacing check for rx flow control thresholds */ - if (adapter->hw.fc.type & ixgb_fc_tx_pause) { + if (adapter->hw.fc.type & ixgb_fc_rx_pause) { /* high must be greater than low */ if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) { /* set defaults */ diff --git a/trunk/drivers/net/ixp2000/enp2611.c b/trunk/drivers/net/ixp2000/enp2611.c index b67f586d7392..6f7dce8eba51 100644 --- a/trunk/drivers/net/ixp2000/enp2611.c +++ b/trunk/drivers/net/ixp2000/enp2611.c @@ -149,8 +149,6 @@ static void enp2611_check_link_status(unsigned long __dummy) int status; dev = nds[i]; - if (dev == NULL) - continue; status = pm3386_is_link_up(i); if (status && !netif_carrier_ok(dev)) { @@ -193,7 +191,6 @@ static void enp2611_set_port_admin_status(int port, int up) static int __init enp2611_init_module(void) { - int ports; int i; if (!machine_is_enp2611()) @@ -202,8 +199,7 @@ static int __init enp2611_init_module(void) caleb_reset(); pm3386_reset(); - ports = pm3386_port_count(); - for (i = 0; i < ports; i++) { + for (i = 0; i < 3; i++) { nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv)); if (nds[i] == NULL) { while (--i >= 0) @@ -219,10 +215,9 @@ static int __init enp2611_init_module(void) ixp2400_msf_init(&enp2611_msf_parameters); - if (ixpdev_init(ports, nds, enp2611_set_port_admin_status)) { - for (i = 0; i < ports; i++) - if (nds[i]) - free_netdev(nds[i]); + if (ixpdev_init(3, nds, enp2611_set_port_admin_status)) { + for (i = 0; i < 3; i++) + free_netdev(nds[i]); return -EINVAL; } diff --git a/trunk/drivers/net/ixp2000/pm3386.c b/trunk/drivers/net/ixp2000/pm3386.c index 5224651c9aac..5c7ab7564053 100644 --- a/trunk/drivers/net/ixp2000/pm3386.c +++ b/trunk/drivers/net/ixp2000/pm3386.c @@ -86,53 +86,40 @@ static void pm3386_port_reg_write(int port, int _reg, int spacing, u16 value) pm3386_reg_write(port >> 1, reg, value); } -int pm3386_secondary_present(void) -{ - return pm3386_reg_read(1, 0) == 0x3386; -} void pm3386_reset(void) { u8 mac[3][6]; - int secondary; - - secondary = pm3386_secondary_present(); /* Save programmed MAC addresses. */ pm3386_get_mac(0, mac[0]); pm3386_get_mac(1, mac[1]); - if (secondary) - pm3386_get_mac(2, mac[2]); + pm3386_get_mac(2, mac[2]); /* Assert analog and digital reset. */ pm3386_reg_write(0, 0x002, 0x0060); - if (secondary) - pm3386_reg_write(1, 0x002, 0x0060); + pm3386_reg_write(1, 0x002, 0x0060); mdelay(1); /* Deassert analog reset. */ pm3386_reg_write(0, 0x002, 0x0062); - if (secondary) - pm3386_reg_write(1, 0x002, 0x0062); + pm3386_reg_write(1, 0x002, 0x0062); mdelay(10); /* Deassert digital reset. */ pm3386_reg_write(0, 0x002, 0x0063); - if (secondary) - pm3386_reg_write(1, 0x002, 0x0063); + pm3386_reg_write(1, 0x002, 0x0063); mdelay(10); /* Restore programmed MAC addresses. */ pm3386_set_mac(0, mac[0]); pm3386_set_mac(1, mac[1]); - if (secondary) - pm3386_set_mac(2, mac[2]); + pm3386_set_mac(2, mac[2]); /* Disable carrier on all ports. */ pm3386_set_carrier(0, 0); pm3386_set_carrier(1, 0); - if (secondary) - pm3386_set_carrier(2, 0); + pm3386_set_carrier(2, 0); } static u16 swaph(u16 x) @@ -140,11 +127,6 @@ static u16 swaph(u16 x) return ((x << 8) | (x >> 8)) & 0xffff; } -int pm3386_port_count(void) -{ - return 2 + pm3386_secondary_present(); -} - void pm3386_init_port(int port) { int pm = port >> 1; diff --git a/trunk/drivers/net/ixp2000/pm3386.h b/trunk/drivers/net/ixp2000/pm3386.h index cc4183dca911..fe92bb056ac4 100644 --- a/trunk/drivers/net/ixp2000/pm3386.h +++ b/trunk/drivers/net/ixp2000/pm3386.h @@ -13,7 +13,6 @@ #define __PM3386_H void pm3386_reset(void); -int pm3386_port_count(void); void pm3386_init_port(int port); void pm3386_get_mac(int port, u8 *mac); void pm3386_set_mac(int port, u8 *mac); diff --git a/trunk/drivers/net/myri10ge/Makefile b/trunk/drivers/net/myri10ge/Makefile deleted file mode 100644 index 5df891647aee..000000000000 --- a/trunk/drivers/net/myri10ge/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the Myricom Myri-10G ethernet driver -# - -obj-$(CONFIG_MYRI10GE) += myri10ge.o diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c deleted file mode 100644 index 87933cba7e22..000000000000 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ /dev/null @@ -1,2851 +0,0 @@ -/************************************************************************* - * myri10ge.c: Myricom Myri-10G Ethernet driver. - * - * Copyright (C) 2005, 2006 Myricom, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of Myricom, Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - * If the eeprom on your board is not recent enough, you will need to get a - * newer firmware image at: - * http://www.myri.com/scs/download-Myri10GE.html - * - * Contact Information: - * - * Myricom, Inc., 325N Santa Anita Avenue, Arcadia, CA 91006 - *************************************************************************/ - -#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 -#ifdef CONFIG_MTRR -#include -#endif - -#include "myri10ge_mcp.h" -#include "myri10ge_mcp_gen_header.h" - -#define MYRI10GE_VERSION_STR "0.9.0" - -MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); -MODULE_AUTHOR("Maintainer: help@myri.com"); -MODULE_VERSION(MYRI10GE_VERSION_STR); -MODULE_LICENSE("Dual BSD/GPL"); - -#define MYRI10GE_MAX_ETHER_MTU 9014 - -#define MYRI10GE_ETH_STOPPED 0 -#define MYRI10GE_ETH_STOPPING 1 -#define MYRI10GE_ETH_STARTING 2 -#define MYRI10GE_ETH_RUNNING 3 -#define MYRI10GE_ETH_OPEN_FAILED 4 - -#define MYRI10GE_EEPROM_STRINGS_SIZE 256 -#define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2) - -#define MYRI10GE_NO_CONFIRM_DATA 0xffffffff -#define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff - -struct myri10ge_rx_buffer_state { - struct sk_buff *skb; - DECLARE_PCI_UNMAP_ADDR(bus) - DECLARE_PCI_UNMAP_LEN(len) -}; - -struct myri10ge_tx_buffer_state { - struct sk_buff *skb; - int last; - DECLARE_PCI_UNMAP_ADDR(bus) - DECLARE_PCI_UNMAP_LEN(len) -}; - -struct myri10ge_cmd { - u32 data0; - u32 data1; - u32 data2; -}; - -struct myri10ge_rx_buf { - struct mcp_kreq_ether_recv __iomem *lanai; /* lanai ptr for recv ring */ - u8 __iomem *wc_fifo; /* w/c rx dma addr fifo address */ - struct mcp_kreq_ether_recv *shadow; /* host shadow of recv ring */ - struct myri10ge_rx_buffer_state *info; - int cnt; - int alloc_fail; - int mask; /* number of rx slots -1 */ -}; - -struct myri10ge_tx_buf { - struct mcp_kreq_ether_send __iomem *lanai; /* lanai ptr for sendq */ - u8 __iomem *wc_fifo; /* w/c send fifo address */ - struct mcp_kreq_ether_send *req_list; /* host shadow of sendq */ - char *req_bytes; - struct myri10ge_tx_buffer_state *info; - int mask; /* number of transmit slots -1 */ - int boundary; /* boundary transmits cannot cross */ - int req ____cacheline_aligned; /* transmit slots submitted */ - int pkt_start; /* packets started */ - int done ____cacheline_aligned; /* transmit slots completed */ - int pkt_done; /* packets completed */ -}; - -struct myri10ge_rx_done { - struct mcp_slot *entry; - dma_addr_t bus; - int cnt; - int idx; -}; - -struct myri10ge_priv { - int running; /* running? */ - int csum_flag; /* rx_csums? */ - struct myri10ge_tx_buf tx; /* transmit ring */ - struct myri10ge_rx_buf rx_small; - struct myri10ge_rx_buf rx_big; - struct myri10ge_rx_done rx_done; - int small_bytes; - struct net_device *dev; - struct net_device_stats stats; - u8 __iomem *sram; - int sram_size; - unsigned long board_span; - unsigned long iomem_base; - u32 __iomem *irq_claim; - u32 __iomem *irq_deassert; - char *mac_addr_string; - struct mcp_cmd_response *cmd; - dma_addr_t cmd_bus; - struct mcp_irq_data *fw_stats; - dma_addr_t fw_stats_bus; - struct pci_dev *pdev; - int msi_enabled; - unsigned int link_state; - unsigned int rdma_tags_available; - int intr_coal_delay; - u32 __iomem *intr_coal_delay_ptr; - int mtrr; - int wake_queue; - int stop_queue; - int down_cnt; - wait_queue_head_t down_wq; - struct work_struct watchdog_work; - struct timer_list watchdog_timer; - int watchdog_tx_done; - int watchdog_resets; - int tx_linearized; - int pause; - char *fw_name; - char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE]; - char fw_version[128]; - u8 mac_addr[6]; /* eeprom mac address */ - unsigned long serial_number; - int vendor_specific_offset; - u32 devctl; - u16 msi_flags; - u32 pm_state[16]; - u32 read_dma; - u32 write_dma; - u32 read_write_dma; -}; - -static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat"; -static char *myri10ge_fw_aligned = "myri10ge_eth_z8e.dat"; - -static char *myri10ge_fw_name = NULL; -module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name\n"); - -static int myri10ge_ecrc_enable = 1; -module_param(myri10ge_ecrc_enable, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E\n"); - -static int myri10ge_max_intr_slots = 1024; -module_param(myri10ge_max_intr_slots, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_max_intr_slots, "Interrupt queue slots\n"); - -static int myri10ge_small_bytes = -1; /* -1 == auto */ -module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n"); - -static int myri10ge_msi = 1; /* enable msi by default */ -module_param(myri10ge_msi, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n"); - -static int myri10ge_intr_coal_delay = 25; -module_param(myri10ge_intr_coal_delay, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n"); - -static int myri10ge_flow_control = 1; -module_param(myri10ge_flow_control, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter\n"); - -static int myri10ge_deassert_wait = 1; -module_param(myri10ge_deassert_wait, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(myri10ge_deassert_wait, - "Wait when deasserting legacy interrupts\n"); - -static int myri10ge_force_firmware = 0; -module_param(myri10ge_force_firmware, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_force_firmware, - "Force firmware to assume aligned completions\n"); - -static int myri10ge_skb_cross_4k = 0; -module_param(myri10ge_skb_cross_4k, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(myri10ge_skb_cross_4k, - "Can a small skb cross a 4KB boundary?\n"); - -static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; -module_param(myri10ge_initial_mtu, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n"); - -static int myri10ge_napi_weight = 64; -module_param(myri10ge_napi_weight, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight\n"); - -static int myri10ge_watchdog_timeout = 1; -module_param(myri10ge_watchdog_timeout, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout\n"); - -static int myri10ge_max_irq_loops = 1048576; -module_param(myri10ge_max_irq_loops, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_max_irq_loops, - "Set stuck legacy IRQ detection threshold\n"); - -#define MYRI10GE_FW_OFFSET 1024*1024 -#define MYRI10GE_HIGHPART_TO_U32(X) \ -(sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0) -#define MYRI10GE_LOWPART_TO_U32(X) ((u32)(X)) - -#define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8) - -static int -myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, - struct myri10ge_cmd *data, int atomic) -{ - struct mcp_cmd *buf; - char buf_bytes[sizeof(*buf) + 8]; - struct mcp_cmd_response *response = mgp->cmd; - char __iomem *cmd_addr = mgp->sram + MXGEFW_CMD_OFFSET; - u32 dma_low, dma_high, result, value; - int sleep_total = 0; - - /* ensure buf is aligned to 8 bytes */ - buf = (struct mcp_cmd *)ALIGN((unsigned long)buf_bytes, 8); - - buf->data0 = htonl(data->data0); - buf->data1 = htonl(data->data1); - buf->data2 = htonl(data->data2); - buf->cmd = htonl(cmd); - dma_low = MYRI10GE_LOWPART_TO_U32(mgp->cmd_bus); - dma_high = MYRI10GE_HIGHPART_TO_U32(mgp->cmd_bus); - - buf->response_addr.low = htonl(dma_low); - buf->response_addr.high = htonl(dma_high); - response->result = MYRI10GE_NO_RESPONSE_RESULT; - mb(); - myri10ge_pio_copy(cmd_addr, buf, sizeof(*buf)); - - /* wait up to 15ms. Longest command is the DMA benchmark, - * which is capped at 5ms, but runs from a timeout handler - * that runs every 7.8ms. So a 15ms timeout leaves us with - * a 2.2ms margin - */ - if (atomic) { - /* if atomic is set, do not sleep, - * and try to get the completion quickly - * (1ms will be enough for those commands) */ - for (sleep_total = 0; - sleep_total < 1000 - && response->result == MYRI10GE_NO_RESPONSE_RESULT; - sleep_total += 10) - udelay(10); - } else { - /* use msleep for most command */ - for (sleep_total = 0; - sleep_total < 15 - && response->result == MYRI10GE_NO_RESPONSE_RESULT; - sleep_total++) - msleep(1); - } - - result = ntohl(response->result); - value = ntohl(response->data); - if (result != MYRI10GE_NO_RESPONSE_RESULT) { - if (result == 0) { - data->data0 = value; - return 0; - } else { - dev_err(&mgp->pdev->dev, - "command %d failed, result = %d\n", - cmd, result); - return -ENXIO; - } - } - - dev_err(&mgp->pdev->dev, "command %d timed out, result = %d\n", - cmd, result); - return -EAGAIN; -} - -/* - * The eeprom strings on the lanaiX have the format - * SN=x\0 - * MAC=x:x:x:x:x:x\0 - * PT:ddd mmm xx xx:xx:xx xx\0 - * PV:ddd mmm xx xx:xx:xx xx\0 - */ -static int myri10ge_read_mac_addr(struct myri10ge_priv *mgp) -{ - char *ptr, *limit; - int i; - - ptr = mgp->eeprom_strings; - limit = mgp->eeprom_strings + MYRI10GE_EEPROM_STRINGS_SIZE; - - while (*ptr != '\0' && ptr < limit) { - if (memcmp(ptr, "MAC=", 4) == 0) { - ptr += 4; - mgp->mac_addr_string = ptr; - for (i = 0; i < 6; i++) { - if ((ptr + 2) > limit) - goto abort; - mgp->mac_addr[i] = - simple_strtoul(ptr, &ptr, 16); - ptr += 1; - } - } - if (memcmp((const void *)ptr, "SN=", 3) == 0) { - ptr += 3; - mgp->serial_number = simple_strtoul(ptr, &ptr, 10); - } - while (ptr < limit && *ptr++) ; - } - - return 0; - -abort: - dev_err(&mgp->pdev->dev, "failed to parse eeprom_strings\n"); - return -ENXIO; -} - -/* - * Enable or disable periodic RDMAs from the host to make certain - * chipsets resend dropped PCIe messages - */ - -static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable) -{ - char __iomem *submit; - u32 buf[16]; - u32 dma_low, dma_high; - int i; - - /* clear confirmation addr */ - mgp->cmd->data = 0; - mb(); - - /* send a rdma command to the PCIe engine, and wait for the - * response in the confirmation address. The firmware should - * write a -1 there to indicate it is alive and well - */ - dma_low = MYRI10GE_LOWPART_TO_U32(mgp->cmd_bus); - dma_high = MYRI10GE_HIGHPART_TO_U32(mgp->cmd_bus); - - buf[0] = htonl(dma_high); /* confirm addr MSW */ - buf[1] = htonl(dma_low); /* confirm addr LSW */ - buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA); /* confirm data */ - buf[3] = htonl(dma_high); /* dummy addr MSW */ - buf[4] = htonl(dma_low); /* dummy addr LSW */ - buf[5] = htonl(enable); /* enable? */ - - submit = mgp->sram + 0xfc01c0; - - myri10ge_pio_copy(submit, &buf, sizeof(buf)); - for (i = 0; mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20; i++) - msleep(1); - if (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA) - dev_err(&mgp->pdev->dev, "dummy rdma %s failed\n", - (enable ? "enable" : "disable")); -} - -static int -myri10ge_validate_firmware(struct myri10ge_priv *mgp, - struct mcp_gen_header *hdr) -{ - struct device *dev = &mgp->pdev->dev; - int major, minor; - - /* check firmware type */ - if (ntohl(hdr->mcp_type) != MCP_TYPE_ETH) { - dev_err(dev, "Bad firmware type: 0x%x\n", ntohl(hdr->mcp_type)); - return -EINVAL; - } - - /* save firmware version for ethtool */ - strncpy(mgp->fw_version, hdr->version, sizeof(mgp->fw_version)); - - sscanf(mgp->fw_version, "%d.%d", &major, &minor); - - if (!(major == MXGEFW_VERSION_MAJOR && minor == MXGEFW_VERSION_MINOR)) { - dev_err(dev, "Found firmware version %s\n", mgp->fw_version); - dev_err(dev, "Driver needs %d.%d\n", MXGEFW_VERSION_MAJOR, - MXGEFW_VERSION_MINOR); - return -EINVAL; - } - return 0; -} - -static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size) -{ - unsigned crc, reread_crc; - const struct firmware *fw; - struct device *dev = &mgp->pdev->dev; - struct mcp_gen_header *hdr; - size_t hdr_offset; - int status; - - if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) { - dev_err(dev, "Unable to load %s firmware image via hotplug\n", - mgp->fw_name); - status = -EINVAL; - goto abort_with_nothing; - } - - /* check size */ - - if (fw->size >= mgp->sram_size - MYRI10GE_FW_OFFSET || - fw->size < MCP_HEADER_PTR_OFFSET + 4) { - dev_err(dev, "Firmware size invalid:%d\n", (int)fw->size); - status = -EINVAL; - goto abort_with_fw; - } - - /* check id */ - hdr_offset = ntohl(*(u32 *) (fw->data + MCP_HEADER_PTR_OFFSET)); - if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > fw->size) { - dev_err(dev, "Bad firmware file\n"); - status = -EINVAL; - goto abort_with_fw; - } - hdr = (void *)(fw->data + hdr_offset); - - status = myri10ge_validate_firmware(mgp, hdr); - if (status != 0) - goto abort_with_fw; - - crc = crc32(~0, fw->data, fw->size); - memcpy_toio(mgp->sram + MYRI10GE_FW_OFFSET, fw->data, fw->size); - /* corruption checking is good for parity recovery and buggy chipset */ - memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size); - reread_crc = crc32(~0, fw->data, fw->size); - if (crc != reread_crc) { - dev_err(dev, "CRC failed(fw-len=%u), got 0x%x (expect 0x%x)\n", - (unsigned)fw->size, reread_crc, crc); - status = -EIO; - goto abort_with_fw; - } - *size = (u32) fw->size; - -abort_with_fw: - release_firmware(fw); - -abort_with_nothing: - return status; -} - -static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp) -{ - struct mcp_gen_header *hdr; - struct device *dev = &mgp->pdev->dev; - const size_t bytes = sizeof(struct mcp_gen_header); - size_t hdr_offset; - int status; - - /* find running firmware header */ - hdr_offset = ntohl(__raw_readl(mgp->sram + MCP_HEADER_PTR_OFFSET)); - - if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > mgp->sram_size) { - dev_err(dev, "Running firmware has bad header offset (%d)\n", - (int)hdr_offset); - return -EIO; - } - - /* copy header of running firmware from SRAM to host memory to - * validate firmware */ - hdr = kmalloc(bytes, GFP_KERNEL); - if (hdr == NULL) { - dev_err(dev, "could not malloc firmware hdr\n"); - return -ENOMEM; - } - memcpy_fromio(hdr, mgp->sram + hdr_offset, bytes); - status = myri10ge_validate_firmware(mgp, hdr); - kfree(hdr); - return status; -} - -static int myri10ge_load_firmware(struct myri10ge_priv *mgp) -{ - char __iomem *submit; - u32 buf[16]; - u32 dma_low, dma_high, size; - int status, i; - - status = myri10ge_load_hotplug_firmware(mgp, &size); - if (status) { - dev_warn(&mgp->pdev->dev, "hotplug firmware loading failed\n"); - - /* Do not attempt to adopt firmware if there - * was a bad crc */ - if (status == -EIO) - return status; - - status = myri10ge_adopt_running_firmware(mgp); - if (status != 0) { - dev_err(&mgp->pdev->dev, - "failed to adopt running firmware\n"); - return status; - } - dev_info(&mgp->pdev->dev, - "Successfully adopted running firmware\n"); - if (mgp->tx.boundary == 4096) { - dev_warn(&mgp->pdev->dev, - "Using firmware currently running on NIC" - ". For optimal\n"); - dev_warn(&mgp->pdev->dev, - "performance consider loading optimized " - "firmware\n"); - dev_warn(&mgp->pdev->dev, "via hotplug\n"); - } - - mgp->fw_name = "adopted"; - mgp->tx.boundary = 2048; - return status; - } - - /* clear confirmation addr */ - mgp->cmd->data = 0; - mb(); - - /* send a reload command to the bootstrap MCP, and wait for the - * response in the confirmation address. The firmware should - * write a -1 there to indicate it is alive and well - */ - dma_low = MYRI10GE_LOWPART_TO_U32(mgp->cmd_bus); - dma_high = MYRI10GE_HIGHPART_TO_U32(mgp->cmd_bus); - - buf[0] = htonl(dma_high); /* confirm addr MSW */ - buf[1] = htonl(dma_low); /* confirm addr LSW */ - buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA); /* confirm data */ - - /* FIX: All newest firmware should un-protect the bottom of - * the sram before handoff. However, the very first interfaces - * do not. Therefore the handoff copy must skip the first 8 bytes - */ - buf[3] = htonl(MYRI10GE_FW_OFFSET + 8); /* where the code starts */ - buf[4] = htonl(size - 8); /* length of code */ - buf[5] = htonl(8); /* where to copy to */ - buf[6] = htonl(0); /* where to jump to */ - - submit = mgp->sram + 0xfc0000; - - myri10ge_pio_copy(submit, &buf, sizeof(buf)); - mb(); - msleep(1); - mb(); - i = 0; - while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20) { - msleep(1); - i++; - } - if (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA) { - dev_err(&mgp->pdev->dev, "handoff failed\n"); - return -ENXIO; - } - dev_info(&mgp->pdev->dev, "handoff confirmed\n"); - myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096); - - return 0; -} - -static int myri10ge_update_mac_address(struct myri10ge_priv *mgp, u8 * addr) -{ - struct myri10ge_cmd cmd; - int status; - - cmd.data0 = ((addr[0] << 24) | (addr[1] << 16) - | (addr[2] << 8) | addr[3]); - - cmd.data1 = ((addr[4] << 8) | (addr[5])); - - status = myri10ge_send_cmd(mgp, MXGEFW_SET_MAC_ADDRESS, &cmd, 0); - return status; -} - -static int myri10ge_change_pause(struct myri10ge_priv *mgp, int pause) -{ - struct myri10ge_cmd cmd; - int status, ctl; - - ctl = pause ? MXGEFW_ENABLE_FLOW_CONTROL : MXGEFW_DISABLE_FLOW_CONTROL; - status = myri10ge_send_cmd(mgp, ctl, &cmd, 0); - - if (status) { - printk(KERN_ERR - "myri10ge: %s: Failed to set flow control mode\n", - mgp->dev->name); - return status; - } - mgp->pause = pause; - return 0; -} - -static void -myri10ge_change_promisc(struct myri10ge_priv *mgp, int promisc, int atomic) -{ - struct myri10ge_cmd cmd; - int status, ctl; - - ctl = promisc ? MXGEFW_ENABLE_PROMISC : MXGEFW_DISABLE_PROMISC; - status = myri10ge_send_cmd(mgp, ctl, &cmd, atomic); - if (status) - printk(KERN_ERR "myri10ge: %s: Failed to set promisc mode\n", - mgp->dev->name); -} - -static int myri10ge_reset(struct myri10ge_priv *mgp) -{ - struct myri10ge_cmd cmd; - int status; - size_t bytes; - u32 len; - - /* try to send a reset command to the card to see if it - * is alive */ - memset(&cmd, 0, sizeof(cmd)); - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_RESET, &cmd, 0); - if (status != 0) { - dev_err(&mgp->pdev->dev, "failed reset\n"); - return -ENXIO; - } - - /* Now exchange information about interrupts */ - - bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); - memset(mgp->rx_done.entry, 0, bytes); - cmd.data0 = (u32) bytes; - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0); - cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus); - status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA, &cmd, 0); - - status |= - myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); - mgp->irq_claim = (__iomem u32 *) (mgp->sram + cmd.data0); - if (!mgp->msi_enabled) { - status |= myri10ge_send_cmd - (mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0); - mgp->irq_deassert = (__iomem u32 *) (mgp->sram + cmd.data0); - - } - status |= myri10ge_send_cmd - (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0); - mgp->intr_coal_delay_ptr = (__iomem u32 *) (mgp->sram + cmd.data0); - if (status != 0) { - dev_err(&mgp->pdev->dev, "failed set interrupt parameters\n"); - return status; - } - __raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); - - /* Run a small DMA test. - * The magic multipliers to the length tell the firmware - * to do DMA read, write, or read+write tests. The - * results are returned in cmd.data0. The upper 16 - * bits or the return is the number of transfers completed. - * The lower 16 bits is the time in 0.5us ticks that the - * transfers took to complete. - */ - - len = mgp->tx.boundary; - - cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus); - cmd.data2 = len * 0x10000; - status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); - if (status == 0) - mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / - (cmd.data0 & 0xffff); - else - dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n", - status); - cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus); - cmd.data2 = len * 0x1; - status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); - if (status == 0) - mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / - (cmd.data0 & 0xffff); - else - dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n", - status); - - cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus); - cmd.data2 = len * 0x10001; - status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); - if (status == 0) - mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) / - (cmd.data0 & 0xffff); - else - dev_warn(&mgp->pdev->dev, - "DMA read/write benchmark failed: %d\n", status); - - memset(mgp->rx_done.entry, 0, bytes); - - /* reset mcp/driver shared state back to 0 */ - mgp->tx.req = 0; - mgp->tx.done = 0; - mgp->tx.pkt_start = 0; - mgp->tx.pkt_done = 0; - mgp->rx_big.cnt = 0; - mgp->rx_small.cnt = 0; - mgp->rx_done.idx = 0; - mgp->rx_done.cnt = 0; - status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr); - myri10ge_change_promisc(mgp, 0, 0); - myri10ge_change_pause(mgp, mgp->pause); - return status; -} - -static inline void -myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst, - struct mcp_kreq_ether_recv *src) -{ - u32 low; - - low = src->addr_low; - src->addr_low = DMA_32BIT_MASK; - myri10ge_pio_copy(dst, src, 8 * sizeof(*src)); - mb(); - src->addr_low = low; - __raw_writel(low, &dst->addr_low); - mb(); -} - -/* - * Set of routunes to get a new receive buffer. Any buffer which - * crosses a 4KB boundary must start on a 4KB boundary due to PCIe - * wdma restrictions. We also try to align any smaller allocation to - * at least a 16 byte boundary for efficiency. We assume the linux - * memory allocator works by powers of 2, and will not return memory - * smaller than 2KB which crosses a 4KB boundary. If it does, we fall - * back to allocating 2x as much space as required. - * - * We intend to replace large (>4KB) skb allocations by using - * pages directly and building a fraglist in the near future. - */ - -static inline struct sk_buff *myri10ge_alloc_big(int bytes) -{ - struct sk_buff *skb; - unsigned long data, roundup; - - skb = dev_alloc_skb(bytes + 4096 + MXGEFW_PAD); - if (skb == NULL) - return NULL; - - /* Correct skb->truesize so that socket buffer - * accounting is not confused the rounding we must - * do to satisfy alignment constraints. - */ - skb->truesize -= 4096; - - data = (unsigned long)(skb->data); - roundup = (-data) & (4095); - skb_reserve(skb, roundup); - return skb; -} - -/* Allocate 2x as much space as required and use whichever portion - * does not cross a 4KB boundary */ -static inline struct sk_buff *myri10ge_alloc_small_safe(unsigned int bytes) -{ - struct sk_buff *skb; - unsigned long data, boundary; - - skb = dev_alloc_skb(2 * (bytes + MXGEFW_PAD) - 1); - if (unlikely(skb == NULL)) - return NULL; - - /* Correct skb->truesize so that socket buffer - * accounting is not confused the rounding we must - * do to satisfy alignment constraints. - */ - skb->truesize -= bytes + MXGEFW_PAD; - - data = (unsigned long)(skb->data); - boundary = (data + 4095UL) & ~4095UL; - if ((boundary - data) >= (bytes + MXGEFW_PAD)) - return skb; - - skb_reserve(skb, boundary - data); - return skb; -} - -/* Allocate just enough space, and verify that the allocated - * space does not cross a 4KB boundary */ -static inline struct sk_buff *myri10ge_alloc_small(int bytes) -{ - struct sk_buff *skb; - unsigned long roundup, data, end; - - skb = dev_alloc_skb(bytes + 16 + MXGEFW_PAD); - if (unlikely(skb == NULL)) - return NULL; - - /* Round allocated buffer to 16 byte boundary */ - data = (unsigned long)(skb->data); - roundup = (-data) & 15UL; - skb_reserve(skb, roundup); - /* Verify that the data buffer does not cross a page boundary */ - data = (unsigned long)(skb->data); - end = data + bytes + MXGEFW_PAD - 1; - if (unlikely(((end >> 12) != (data >> 12)) && (data & 4095UL))) { - printk(KERN_NOTICE - "myri10ge_alloc_small: small skb crossed 4KB boundary\n"); - myri10ge_skb_cross_4k = 1; - dev_kfree_skb_any(skb); - skb = myri10ge_alloc_small_safe(bytes); - } - return skb; -} - -static inline int -myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct pci_dev *pdev, int bytes, - int idx) -{ - struct sk_buff *skb; - dma_addr_t bus; - int len, retval = 0; - - bytes += VLAN_HLEN; /* account for 802.1q vlan tag */ - - if ((bytes + MXGEFW_PAD) > (4096 - 16) /* linux overhead */ ) - skb = myri10ge_alloc_big(bytes); - else if (myri10ge_skb_cross_4k) - skb = myri10ge_alloc_small_safe(bytes); - else - skb = myri10ge_alloc_small(bytes); - - if (unlikely(skb == NULL)) { - rx->alloc_fail++; - retval = -ENOBUFS; - goto done; - } - - /* set len so that it only covers the area we - * need mapped for DMA */ - len = bytes + MXGEFW_PAD; - - bus = pci_map_single(pdev, skb->data, len, PCI_DMA_FROMDEVICE); - rx->info[idx].skb = skb; - pci_unmap_addr_set(&rx->info[idx], bus, bus); - pci_unmap_len_set(&rx->info[idx], len, len); - rx->shadow[idx].addr_low = htonl(MYRI10GE_LOWPART_TO_U32(bus)); - rx->shadow[idx].addr_high = htonl(MYRI10GE_HIGHPART_TO_U32(bus)); - -done: - /* copy 8 descriptors (64-bytes) to the mcp at a time */ - if ((idx & 7) == 7) { - if (rx->wc_fifo == NULL) - myri10ge_submit_8rx(&rx->lanai[idx - 7], - &rx->shadow[idx - 7]); - else { - mb(); - myri10ge_pio_copy(rx->wc_fifo, - &rx->shadow[idx - 7], 64); - } - } - return retval; -} - -static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, u16 hw_csum) -{ - struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data); - - if ((skb->protocol == ntohs(ETH_P_8021Q)) && - (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) || - vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) { - skb->csum = hw_csum; - skb->ip_summed = CHECKSUM_HW; - } -} - -static inline unsigned long -myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, - int bytes, int len, int csum) -{ - dma_addr_t bus; - struct sk_buff *skb; - int idx, unmap_len; - - idx = rx->cnt & rx->mask; - rx->cnt++; - - /* save a pointer to the received skb */ - skb = rx->info[idx].skb; - bus = pci_unmap_addr(&rx->info[idx], bus); - unmap_len = pci_unmap_len(&rx->info[idx], len); - - /* try to replace the received skb */ - if (myri10ge_getbuf(rx, mgp->pdev, bytes, idx)) { - /* drop the frame -- the old skbuf is re-cycled */ - mgp->stats.rx_dropped += 1; - return 0; - } - - /* unmap the recvd skb */ - pci_unmap_single(mgp->pdev, bus, unmap_len, PCI_DMA_FROMDEVICE); - - /* mcp implicitly skips 1st bytes so that packet is properly - * aligned */ - skb_reserve(skb, MXGEFW_PAD); - - /* set the length of the frame */ - skb_put(skb, len); - - skb->protocol = eth_type_trans(skb, mgp->dev); - skb->dev = mgp->dev; - if (mgp->csum_flag) { - if ((skb->protocol == ntohs(ETH_P_IP)) || - (skb->protocol == ntohs(ETH_P_IPV6))) { - skb->csum = ntohs((u16) csum); - skb->ip_summed = CHECKSUM_HW; - } else - myri10ge_vlan_ip_csum(skb, ntohs((u16) csum)); - } - - netif_receive_skb(skb); - mgp->dev->last_rx = jiffies; - return 1; -} - -static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index) -{ - struct pci_dev *pdev = mgp->pdev; - struct myri10ge_tx_buf *tx = &mgp->tx; - struct sk_buff *skb; - int idx, len; - int limit = 0; - - while (tx->pkt_done != mcp_index) { - idx = tx->done & tx->mask; - skb = tx->info[idx].skb; - - /* Mark as free */ - tx->info[idx].skb = NULL; - if (tx->info[idx].last) { - tx->pkt_done++; - tx->info[idx].last = 0; - } - tx->done++; - len = pci_unmap_len(&tx->info[idx], len); - pci_unmap_len_set(&tx->info[idx], len, 0); - if (skb) { - mgp->stats.tx_bytes += skb->len; - mgp->stats.tx_packets++; - dev_kfree_skb_irq(skb); - if (len) - pci_unmap_single(pdev, - pci_unmap_addr(&tx->info[idx], - bus), len, - PCI_DMA_TODEVICE); - } else { - if (len) - pci_unmap_page(pdev, - pci_unmap_addr(&tx->info[idx], - bus), len, - PCI_DMA_TODEVICE); - } - - /* limit potential for livelock by only handling - * 2 full tx rings per call */ - if (unlikely(++limit > 2 * tx->mask)) - break; - } - /* start the queue if we've stopped it */ - if (netif_queue_stopped(mgp->dev) - && tx->req - tx->done < (tx->mask >> 1)) { - mgp->wake_queue++; - netif_wake_queue(mgp->dev); - } -} - -static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit) -{ - struct myri10ge_rx_done *rx_done = &mgp->rx_done; - unsigned long rx_bytes = 0; - unsigned long rx_packets = 0; - unsigned long rx_ok; - - int idx = rx_done->idx; - int cnt = rx_done->cnt; - u16 length; - u16 checksum; - - while (rx_done->entry[idx].length != 0 && *limit != 0) { - length = ntohs(rx_done->entry[idx].length); - rx_done->entry[idx].length = 0; - checksum = ntohs(rx_done->entry[idx].checksum); - if (length <= mgp->small_bytes) - rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small, - mgp->small_bytes, - length, checksum); - else - rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big, - mgp->dev->mtu + ETH_HLEN, - length, checksum); - rx_packets += rx_ok; - rx_bytes += rx_ok * (unsigned long)length; - cnt++; - idx = cnt & (myri10ge_max_intr_slots - 1); - - /* limit potential for livelock by only handling a - * limited number of frames. */ - (*limit)--; - } - rx_done->idx = idx; - rx_done->cnt = cnt; - mgp->stats.rx_packets += rx_packets; - mgp->stats.rx_bytes += rx_bytes; -} - -static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) -{ - struct mcp_irq_data *stats = mgp->fw_stats; - - if (unlikely(stats->stats_updated)) { - if (mgp->link_state != stats->link_up) { - mgp->link_state = stats->link_up; - if (mgp->link_state) { - printk(KERN_INFO "myri10ge: %s: link up\n", - mgp->dev->name); - netif_carrier_on(mgp->dev); - } else { - printk(KERN_INFO "myri10ge: %s: link down\n", - mgp->dev->name); - netif_carrier_off(mgp->dev); - } - } - if (mgp->rdma_tags_available != - ntohl(mgp->fw_stats->rdma_tags_available)) { - mgp->rdma_tags_available = - ntohl(mgp->fw_stats->rdma_tags_available); - printk(KERN_WARNING "myri10ge: %s: RDMA timed out! " - "%d tags left\n", mgp->dev->name, - mgp->rdma_tags_available); - } - mgp->down_cnt += stats->link_down; - if (stats->link_down) - wake_up(&mgp->down_wq); - } -} - -static int myri10ge_poll(struct net_device *netdev, int *budget) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - struct myri10ge_rx_done *rx_done = &mgp->rx_done; - int limit, orig_limit, work_done; - - /* process as many rx events as NAPI will allow */ - limit = min(*budget, netdev->quota); - orig_limit = limit; - myri10ge_clean_rx_done(mgp, &limit); - work_done = orig_limit - limit; - *budget -= work_done; - netdev->quota -= work_done; - - if (rx_done->entry[rx_done->idx].length == 0 || !netif_running(netdev)) { - netif_rx_complete(netdev); - __raw_writel(htonl(3), mgp->irq_claim); - return 0; - } - return 1; -} - -static irqreturn_t myri10ge_intr(int irq, void *arg, struct pt_regs *regs) -{ - struct myri10ge_priv *mgp = arg; - struct mcp_irq_data *stats = mgp->fw_stats; - struct myri10ge_tx_buf *tx = &mgp->tx; - u32 send_done_count; - int i; - - /* make sure it is our IRQ, and that the DMA has finished */ - if (unlikely(!stats->valid)) - return (IRQ_NONE); - - /* low bit indicates receives are present, so schedule - * napi poll handler */ - if (stats->valid & 1) - netif_rx_schedule(mgp->dev); - - if (!mgp->msi_enabled) { - __raw_writel(0, mgp->irq_deassert); - if (!myri10ge_deassert_wait) - stats->valid = 0; - mb(); - } else - stats->valid = 0; - - /* Wait for IRQ line to go low, if using INTx */ - i = 0; - while (1) { - i++; - /* check for transmit completes and receives */ - send_done_count = ntohl(stats->send_done_count); - if (send_done_count != tx->pkt_done) - myri10ge_tx_done(mgp, (int)send_done_count); - if (unlikely(i > myri10ge_max_irq_loops)) { - printk(KERN_WARNING "myri10ge: %s: irq stuck?\n", - mgp->dev->name); - stats->valid = 0; - schedule_work(&mgp->watchdog_work); - } - if (likely(stats->valid == 0)) - break; - cpu_relax(); - barrier(); - } - - myri10ge_check_statblock(mgp); - - __raw_writel(htonl(3), mgp->irq_claim + 1); - return (IRQ_HANDLED); -} - -static int -myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) -{ - cmd->autoneg = AUTONEG_DISABLE; - cmd->speed = SPEED_10000; - cmd->duplex = DUPLEX_FULL; - return 0; -} - -static void -myri10ge_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - - strlcpy(info->driver, "myri10ge", sizeof(info->driver)); - strlcpy(info->version, MYRI10GE_VERSION_STR, sizeof(info->version)); - strlcpy(info->fw_version, mgp->fw_version, sizeof(info->fw_version)); - strlcpy(info->bus_info, pci_name(mgp->pdev), sizeof(info->bus_info)); -} - -static int -myri10ge_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - coal->rx_coalesce_usecs = mgp->intr_coal_delay; - return 0; -} - -static int -myri10ge_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - - mgp->intr_coal_delay = coal->rx_coalesce_usecs; - __raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); - return 0; -} - -static void -myri10ge_get_pauseparam(struct net_device *netdev, - struct ethtool_pauseparam *pause) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - - pause->autoneg = 0; - pause->rx_pause = mgp->pause; - pause->tx_pause = mgp->pause; -} - -static int -myri10ge_set_pauseparam(struct net_device *netdev, - struct ethtool_pauseparam *pause) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - - if (pause->tx_pause != mgp->pause) - return myri10ge_change_pause(mgp, pause->tx_pause); - if (pause->rx_pause != mgp->pause) - return myri10ge_change_pause(mgp, pause->tx_pause); - if (pause->autoneg != 0) - return -EINVAL; - return 0; -} - -static void -myri10ge_get_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ring) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - - ring->rx_mini_max_pending = mgp->rx_small.mask + 1; - ring->rx_max_pending = mgp->rx_big.mask + 1; - ring->rx_jumbo_max_pending = 0; - ring->tx_max_pending = mgp->rx_small.mask + 1; - ring->rx_mini_pending = ring->rx_mini_max_pending; - ring->rx_pending = ring->rx_max_pending; - ring->rx_jumbo_pending = ring->rx_jumbo_max_pending; - ring->tx_pending = ring->tx_max_pending; -} - -static u32 myri10ge_get_rx_csum(struct net_device *netdev) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - if (mgp->csum_flag) - return 1; - else - return 0; -} - -static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - if (csum_enabled) - mgp->csum_flag = MXGEFW_FLAGS_CKSUM; - else - mgp->csum_flag = 0; - return 0; -} - -static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { - "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", - "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions", - "rx_length_errors", "rx_over_errors", "rx_crc_errors", - "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors", - "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors", - "tx_heartbeat_errors", "tx_window_errors", - /* device-specific stats */ - "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs", - "serial_number", "tx_pkt_start", "tx_pkt_done", - "tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt", - "wake_queue", "stop_queue", "watchdog_resets", "tx_linearized", - "link_up", "dropped_link_overflow", "dropped_link_error_or_filtered", - "dropped_runt", "dropped_overrun", "dropped_no_small_buffer", - "dropped_no_big_buffer" -}; - -#define MYRI10GE_NET_STATS_LEN 21 -#define MYRI10GE_STATS_LEN sizeof(myri10ge_gstrings_stats) / ETH_GSTRING_LEN - -static void -myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data) -{ - switch (stringset) { - case ETH_SS_STATS: - memcpy(data, *myri10ge_gstrings_stats, - sizeof(myri10ge_gstrings_stats)); - break; - } -} - -static int myri10ge_get_stats_count(struct net_device *netdev) -{ - return MYRI10GE_STATS_LEN; -} - -static void -myri10ge_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, u64 * data) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - int i; - - for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++) - data[i] = ((unsigned long *)&mgp->stats)[i]; - - data[i++] = (unsigned int)mgp->read_dma; - data[i++] = (unsigned int)mgp->write_dma; - data[i++] = (unsigned int)mgp->read_write_dma; - data[i++] = (unsigned int)mgp->serial_number; - data[i++] = (unsigned int)mgp->tx.pkt_start; - data[i++] = (unsigned int)mgp->tx.pkt_done; - data[i++] = (unsigned int)mgp->tx.req; - data[i++] = (unsigned int)mgp->tx.done; - data[i++] = (unsigned int)mgp->rx_small.cnt; - data[i++] = (unsigned int)mgp->rx_big.cnt; - data[i++] = (unsigned int)mgp->wake_queue; - data[i++] = (unsigned int)mgp->stop_queue; - data[i++] = (unsigned int)mgp->watchdog_resets; - data[i++] = (unsigned int)mgp->tx_linearized; - data[i++] = (unsigned int)ntohl(mgp->fw_stats->link_up); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow); - data[i++] = - (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer); -} - -static struct ethtool_ops myri10ge_ethtool_ops = { - .get_settings = myri10ge_get_settings, - .get_drvinfo = myri10ge_get_drvinfo, - .get_coalesce = myri10ge_get_coalesce, - .set_coalesce = myri10ge_set_coalesce, - .get_pauseparam = myri10ge_get_pauseparam, - .set_pauseparam = myri10ge_set_pauseparam, - .get_ringparam = myri10ge_get_ringparam, - .get_rx_csum = myri10ge_get_rx_csum, - .set_rx_csum = myri10ge_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, -#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 -}; - -static int myri10ge_allocate_rings(struct net_device *dev) -{ - struct myri10ge_priv *mgp; - struct myri10ge_cmd cmd; - int tx_ring_size, rx_ring_size; - int tx_ring_entries, rx_ring_entries; - int i, status; - size_t bytes; - - mgp = netdev_priv(dev); - - /* get ring sizes */ - - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0); - tx_ring_size = cmd.data0; - status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0); - rx_ring_size = cmd.data0; - - tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send); - rx_ring_entries = rx_ring_size / sizeof(struct mcp_dma_addr); - mgp->tx.mask = tx_ring_entries - 1; - mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1; - - /* allocate the host shadow rings */ - - bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4) - * sizeof(*mgp->tx.req_list); - mgp->tx.req_bytes = kzalloc(bytes, GFP_KERNEL); - if (mgp->tx.req_bytes == NULL) - goto abort_with_nothing; - - /* ensure req_list entries are aligned to 8 bytes */ - mgp->tx.req_list = (struct mcp_kreq_ether_send *) - ALIGN((unsigned long)mgp->tx.req_bytes, 8); - - bytes = rx_ring_entries * sizeof(*mgp->rx_small.shadow); - mgp->rx_small.shadow = kzalloc(bytes, GFP_KERNEL); - if (mgp->rx_small.shadow == NULL) - goto abort_with_tx_req_bytes; - - bytes = rx_ring_entries * sizeof(*mgp->rx_big.shadow); - mgp->rx_big.shadow = kzalloc(bytes, GFP_KERNEL); - if (mgp->rx_big.shadow == NULL) - goto abort_with_rx_small_shadow; - - /* allocate the host info rings */ - - bytes = tx_ring_entries * sizeof(*mgp->tx.info); - mgp->tx.info = kzalloc(bytes, GFP_KERNEL); - if (mgp->tx.info == NULL) - goto abort_with_rx_big_shadow; - - bytes = rx_ring_entries * sizeof(*mgp->rx_small.info); - mgp->rx_small.info = kzalloc(bytes, GFP_KERNEL); - if (mgp->rx_small.info == NULL) - goto abort_with_tx_info; - - bytes = rx_ring_entries * sizeof(*mgp->rx_big.info); - mgp->rx_big.info = kzalloc(bytes, GFP_KERNEL); - if (mgp->rx_big.info == NULL) - goto abort_with_rx_small_info; - - /* Fill the receive rings */ - - for (i = 0; i <= mgp->rx_small.mask; i++) { - status = myri10ge_getbuf(&mgp->rx_small, mgp->pdev, - mgp->small_bytes, i); - if (status) { - printk(KERN_ERR - "myri10ge: %s: alloced only %d small bufs\n", - dev->name, i); - goto abort_with_rx_small_ring; - } - } - - for (i = 0; i <= mgp->rx_big.mask; i++) { - status = - myri10ge_getbuf(&mgp->rx_big, mgp->pdev, - dev->mtu + ETH_HLEN, i); - if (status) { - printk(KERN_ERR - "myri10ge: %s: alloced only %d big bufs\n", - dev->name, i); - goto abort_with_rx_big_ring; - } - } - - return 0; - -abort_with_rx_big_ring: - for (i = 0; i <= mgp->rx_big.mask; i++) { - if (mgp->rx_big.info[i].skb != NULL) - dev_kfree_skb_any(mgp->rx_big.info[i].skb); - if (pci_unmap_len(&mgp->rx_big.info[i], len)) - pci_unmap_single(mgp->pdev, - pci_unmap_addr(&mgp->rx_big.info[i], - bus), - pci_unmap_len(&mgp->rx_big.info[i], - len), - PCI_DMA_FROMDEVICE); - } - -abort_with_rx_small_ring: - for (i = 0; i <= mgp->rx_small.mask; i++) { - if (mgp->rx_small.info[i].skb != NULL) - dev_kfree_skb_any(mgp->rx_small.info[i].skb); - if (pci_unmap_len(&mgp->rx_small.info[i], len)) - pci_unmap_single(mgp->pdev, - pci_unmap_addr(&mgp->rx_small.info[i], - bus), - pci_unmap_len(&mgp->rx_small.info[i], - len), - PCI_DMA_FROMDEVICE); - } - kfree(mgp->rx_big.info); - -abort_with_rx_small_info: - kfree(mgp->rx_small.info); - -abort_with_tx_info: - kfree(mgp->tx.info); - -abort_with_rx_big_shadow: - kfree(mgp->rx_big.shadow); - -abort_with_rx_small_shadow: - kfree(mgp->rx_small.shadow); - -abort_with_tx_req_bytes: - kfree(mgp->tx.req_bytes); - mgp->tx.req_bytes = NULL; - mgp->tx.req_list = NULL; - -abort_with_nothing: - return status; -} - -static void myri10ge_free_rings(struct net_device *dev) -{ - struct myri10ge_priv *mgp; - struct sk_buff *skb; - struct myri10ge_tx_buf *tx; - int i, len, idx; - - mgp = netdev_priv(dev); - - for (i = 0; i <= mgp->rx_big.mask; i++) { - if (mgp->rx_big.info[i].skb != NULL) - dev_kfree_skb_any(mgp->rx_big.info[i].skb); - if (pci_unmap_len(&mgp->rx_big.info[i], len)) - pci_unmap_single(mgp->pdev, - pci_unmap_addr(&mgp->rx_big.info[i], - bus), - pci_unmap_len(&mgp->rx_big.info[i], - len), - PCI_DMA_FROMDEVICE); - } - - for (i = 0; i <= mgp->rx_small.mask; i++) { - if (mgp->rx_small.info[i].skb != NULL) - dev_kfree_skb_any(mgp->rx_small.info[i].skb); - if (pci_unmap_len(&mgp->rx_small.info[i], len)) - pci_unmap_single(mgp->pdev, - pci_unmap_addr(&mgp->rx_small.info[i], - bus), - pci_unmap_len(&mgp->rx_small.info[i], - len), - PCI_DMA_FROMDEVICE); - } - - tx = &mgp->tx; - while (tx->done != tx->req) { - idx = tx->done & tx->mask; - skb = tx->info[idx].skb; - - /* Mark as free */ - tx->info[idx].skb = NULL; - tx->done++; - len = pci_unmap_len(&tx->info[idx], len); - pci_unmap_len_set(&tx->info[idx], len, 0); - if (skb) { - mgp->stats.tx_dropped++; - dev_kfree_skb_any(skb); - if (len) - pci_unmap_single(mgp->pdev, - pci_unmap_addr(&tx->info[idx], - bus), len, - PCI_DMA_TODEVICE); - } else { - if (len) - pci_unmap_page(mgp->pdev, - pci_unmap_addr(&tx->info[idx], - bus), len, - PCI_DMA_TODEVICE); - } - } - kfree(mgp->rx_big.info); - - kfree(mgp->rx_small.info); - - kfree(mgp->tx.info); - - kfree(mgp->rx_big.shadow); - - kfree(mgp->rx_small.shadow); - - kfree(mgp->tx.req_bytes); - mgp->tx.req_bytes = NULL; - mgp->tx.req_list = NULL; -} - -static int myri10ge_open(struct net_device *dev) -{ - struct myri10ge_priv *mgp; - struct myri10ge_cmd cmd; - int status, big_pow2; - - mgp = netdev_priv(dev); - - if (mgp->running != MYRI10GE_ETH_STOPPED) - return -EBUSY; - - mgp->running = MYRI10GE_ETH_STARTING; - status = myri10ge_reset(mgp); - if (status != 0) { - printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name); - mgp->running = MYRI10GE_ETH_STOPPED; - return -ENXIO; - } - - /* decide what small buffer size to use. For good TCP rx - * performance, it is important to not receive 1514 byte - * frames into jumbo buffers, as it confuses the socket buffer - * accounting code, leading to drops and erratic performance. - */ - - if (dev->mtu <= ETH_DATA_LEN) - mgp->small_bytes = 128; /* enough for a TCP header */ - else - mgp->small_bytes = ETH_FRAME_LEN; /* enough for an ETH_DATA_LEN frame */ - - /* Override the small buffer size? */ - if (myri10ge_small_bytes > 0) - mgp->small_bytes = myri10ge_small_bytes; - - /* If the user sets an obscenely small MTU, adjust the small - * bytes down to nearly nothing */ - if (mgp->small_bytes >= (dev->mtu + ETH_HLEN)) - mgp->small_bytes = 64; - - /* get the lanai pointers to the send and receive rings */ - - status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0); - mgp->tx.lanai = - (struct mcp_kreq_ether_send __iomem *)(mgp->sram + cmd.data0); - - status |= - myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd, 0); - mgp->rx_small.lanai = - (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0); - - status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0); - mgp->rx_big.lanai = - (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0); - - if (status != 0) { - printk(KERN_ERR - "myri10ge: %s: failed to get ring sizes or locations\n", - dev->name); - mgp->running = MYRI10GE_ETH_STOPPED; - return -ENXIO; - } - - if (mgp->mtrr >= 0) { - mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + 0x200000; - mgp->rx_small.wc_fifo = (u8 __iomem *) mgp->sram + 0x300000; - mgp->rx_big.wc_fifo = (u8 __iomem *) mgp->sram + 0x340000; - } else { - mgp->tx.wc_fifo = NULL; - mgp->rx_small.wc_fifo = NULL; - mgp->rx_big.wc_fifo = NULL; - } - - status = myri10ge_allocate_rings(dev); - if (status != 0) - goto abort_with_nothing; - - /* Firmware needs the big buff size as a power of 2. Lie and - * tell him the buffer is larger, because we only use 1 - * buffer/pkt, and the mtu will prevent overruns. - */ - big_pow2 = dev->mtu + ETH_HLEN + MXGEFW_PAD; - while ((big_pow2 & (big_pow2 - 1)) != 0) - big_pow2++; - - /* now give firmware buffers sizes, and MTU */ - cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN; - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_MTU, &cmd, 0); - cmd.data0 = mgp->small_bytes; - status |= - myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_SMALL_BUFFER_SIZE, &cmd, 0); - cmd.data0 = big_pow2; - status |= - myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_BIG_BUFFER_SIZE, &cmd, 0); - if (status) { - printk(KERN_ERR "myri10ge: %s: Couldn't set buffer sizes\n", - dev->name); - goto abort_with_rings; - } - - cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->fw_stats_bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->fw_stats_bus); - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA, &cmd, 0); - if (status) { - printk(KERN_ERR "myri10ge: %s: Couldn't set stats DMA\n", - dev->name); - goto abort_with_rings; - } - - mgp->link_state = -1; - mgp->rdma_tags_available = 15; - - netif_poll_enable(mgp->dev); /* must happen prior to any irq */ - - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0); - if (status) { - printk(KERN_ERR "myri10ge: %s: Couldn't bring up link\n", - dev->name); - goto abort_with_rings; - } - - mgp->wake_queue = 0; - mgp->stop_queue = 0; - mgp->running = MYRI10GE_ETH_RUNNING; - mgp->watchdog_timer.expires = jiffies + myri10ge_watchdog_timeout * HZ; - add_timer(&mgp->watchdog_timer); - netif_wake_queue(dev); - return 0; - -abort_with_rings: - myri10ge_free_rings(dev); - -abort_with_nothing: - mgp->running = MYRI10GE_ETH_STOPPED; - return -ENOMEM; -} - -static int myri10ge_close(struct net_device *dev) -{ - struct myri10ge_priv *mgp; - struct myri10ge_cmd cmd; - int status, old_down_cnt; - - mgp = netdev_priv(dev); - - if (mgp->running != MYRI10GE_ETH_RUNNING) - return 0; - - if (mgp->tx.req_bytes == NULL) - return 0; - - del_timer_sync(&mgp->watchdog_timer); - mgp->running = MYRI10GE_ETH_STOPPING; - netif_poll_disable(mgp->dev); - netif_carrier_off(dev); - netif_stop_queue(dev); - old_down_cnt = mgp->down_cnt; - mb(); - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_DOWN, &cmd, 0); - if (status) - printk(KERN_ERR "myri10ge: %s: Couldn't bring down link\n", - dev->name); - - wait_event_timeout(mgp->down_wq, old_down_cnt != mgp->down_cnt, HZ); - if (old_down_cnt == mgp->down_cnt) - printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name); - - netif_tx_disable(dev); - - myri10ge_free_rings(dev); - - mgp->running = MYRI10GE_ETH_STOPPED; - return 0; -} - -/* copy an array of struct mcp_kreq_ether_send's to the mcp. Copy - * backwards one at a time and handle ring wraps */ - -static inline void -myri10ge_submit_req_backwards(struct myri10ge_tx_buf *tx, - struct mcp_kreq_ether_send *src, int cnt) -{ - int idx, starting_slot; - starting_slot = tx->req; - while (cnt > 1) { - cnt--; - idx = (starting_slot + cnt) & tx->mask; - myri10ge_pio_copy(&tx->lanai[idx], &src[cnt], sizeof(*src)); - mb(); - } -} - -/* - * copy an array of struct mcp_kreq_ether_send's to the mcp. Copy - * at most 32 bytes at a time, so as to avoid involving the software - * pio handler in the nic. We re-write the first segment's flags - * to mark them valid only after writing the entire chain. - */ - -static inline void -myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src, - int cnt) -{ - int idx, i; - struct mcp_kreq_ether_send __iomem *dstp, *dst; - struct mcp_kreq_ether_send *srcp; - u8 last_flags; - - idx = tx->req & tx->mask; - - last_flags = src->flags; - src->flags = 0; - mb(); - dst = dstp = &tx->lanai[idx]; - srcp = src; - - if ((idx + cnt) < tx->mask) { - for (i = 0; i < (cnt - 1); i += 2) { - myri10ge_pio_copy(dstp, srcp, 2 * sizeof(*src)); - mb(); /* force write every 32 bytes */ - srcp += 2; - dstp += 2; - } - } else { - /* submit all but the first request, and ensure - * that it is submitted below */ - myri10ge_submit_req_backwards(tx, src, cnt); - i = 0; - } - if (i < cnt) { - /* submit the first request */ - myri10ge_pio_copy(dstp, srcp, sizeof(*src)); - mb(); /* barrier before setting valid flag */ - } - - /* re-write the last 32-bits with the valid flags */ - src->flags = last_flags; - __raw_writel(*((u32 *) src + 3), (u32 __iomem *) dst + 3); - tx->req += cnt; - mb(); -} - -static inline void -myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx, - struct mcp_kreq_ether_send *src, int cnt) -{ - tx->req += cnt; - mb(); - while (cnt >= 4) { - myri10ge_pio_copy(tx->wc_fifo, src, 64); - mb(); - src += 4; - cnt -= 4; - } - if (cnt > 0) { - /* pad it to 64 bytes. The src is 64 bytes bigger than it - * needs to be so that we don't overrun it */ - myri10ge_pio_copy(tx->wc_fifo + (cnt << 18), src, 64); - mb(); - } -} - -/* - * Transmit a packet. We need to split the packet so that a single - * segment does not cross myri10ge->tx.boundary, so this makes segment - * counting tricky. So rather than try to count segments up front, we - * just give up if there are too few segments to hold a reasonably - * fragmented packet currently available. If we run - * out of segments while preparing a packet for DMA, we just linearize - * it and try again. - */ - -static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct myri10ge_priv *mgp = netdev_priv(dev); - struct mcp_kreq_ether_send *req; - struct myri10ge_tx_buf *tx = &mgp->tx; - struct skb_frag_struct *frag; - dma_addr_t bus; - u32 low, high_swapped; - unsigned int len; - int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments; - u16 pseudo_hdr_offset, cksum_offset; - int cum_len, seglen, boundary, rdma_count; - u8 flags, odd_flag; - -again: - req = tx->req_list; - avail = tx->mask - 1 - (tx->req - tx->done); - - mss = 0; - max_segments = MXGEFW_MAX_SEND_DESC; - -#ifdef NETIF_F_TSO - if (skb->len > (dev->mtu + ETH_HLEN)) { - mss = skb_shinfo(skb)->tso_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 */ - mgp->stop_queue++; - netif_stop_queue(dev); - return 1; - } - - /* Setup checksum offloading, if needed */ - cksum_offset = 0; - pseudo_hdr_offset = 0; - odd_flag = 0; - flags = (MXGEFW_FLAGS_NO_TSO | MXGEFW_FLAGS_FIRST); - if (likely(skb->ip_summed == CHECKSUM_HW)) { - cksum_offset = (skb->h.raw - skb->data); - pseudo_hdr_offset = (skb->h.raw + skb->csum) - skb->data; - /* If the headers are excessively large, then we must - * fall back to a software checksum */ - if (unlikely(cksum_offset > 255 || pseudo_hdr_offset > 127)) { - if (skb_checksum_help(skb, 0)) - goto drop; - cksum_offset = 0; - pseudo_hdr_offset = 0; - } else { - pseudo_hdr_offset = htons(pseudo_hdr_offset); - odd_flag = MXGEFW_FLAGS_ALIGN_ODD; - flags |= MXGEFW_FLAGS_CKSUM; - } - } - - 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); - - /* negative cum_len signifies to the - * send loop that we are still in the - * header portion of the TSO packet. - * TSO header must be at most 134 bytes long */ - cum_len = -((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - - /* for TSO, pseudo_hdr_offset holds mss. - * The firmware figures out where to put - * the checksum by parsing the header. */ - pseudo_hdr_offset = htons(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; - - /* pad frames to at least ETH_ZLEN bytes */ - if (unlikely(skb->len < ETH_ZLEN)) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) { - /* The packet is gone, so we must - * return 0 */ - mgp->stats.tx_dropped += 1; - return 0; - } - /* adjust the len to account for the zero pad - * so that the nic can know how long it is */ - skb->len = ETH_ZLEN; - } - } - - /* map the skb for DMA */ - len = skb->len - skb->data_len; - idx = tx->req & tx->mask; - tx->info[idx].skb = skb; - bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE); - pci_unmap_addr_set(&tx->info[idx], bus, bus); - pci_unmap_len_set(&tx->info[idx], len, len); - - frag_cnt = skb_shinfo(skb)->nr_frags; - frag_idx = 0; - count = 0; - rdma_count = 0; - - /* "rdma_count" is the number of RDMAs belonging to the - * current packet BEFORE the current send request. For - * non-TSO packets, this is equal to "count". - * For TSO packets, rdma_count needs to be reset - * to 0 after a segment cut. - * - * The rdma_count field of the send request is - * the number of RDMAs of the packet starting at - * that request. For TSO send requests with one ore more cuts - * in the middle, this is the number of RDMAs starting - * after the last cut in the request. All previous - * segments before the last cut implicitly have 1 RDMA. - * - * Since the number of RDMAs is not known beforehand, - * it must be filled-in retroactively - after each - * segmentation cut or at the end of the entire packet. - */ - - while (1) { - /* Break the SKB or Fragment up into pieces which - * do not cross mgp->tx.boundary */ - low = MYRI10GE_LOWPART_TO_U32(bus); - high_swapped = htonl(MYRI10GE_HIGHPART_TO_U32(bus)); - while (len) { - u8 flags_next; - int cum_len_next; - - if (unlikely(count == max_segments)) - goto abort_linearize; - - boundary = (low + tx->boundary) & ~(tx->boundary - 1); - seglen = boundary - low; - if (seglen > len) - 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; - - if (likely(cum_len >= 0)) { /* payload */ - int next_is_first, chop; - - chop = (cum_len_next > mss); - cum_len_next = cum_len_next % mss; - next_is_first = (cum_len_next == 0); - flags |= chop * MXGEFW_FLAGS_TSO_CHOP; - flags_next |= next_is_first * - MXGEFW_FLAGS_FIRST; - rdma_count |= -(chop | next_is_first); - rdma_count += chop & !next_is_first; - } else if (likely(cum_len_next >= 0)) { /* header ends */ - int small; - - rdma_count = -1; - cum_len_next = 0; - seglen = -cum_len; - small = (mss <= MXGEFW_SEND_SMALL_SIZE); - flags_next = MXGEFW_FLAGS_TSO_PLD | - MXGEFW_FLAGS_FIRST | - (small * MXGEFW_FLAGS_SMALL); - } - } -#endif /* NETIF_F_TSO */ - req->addr_high = high_swapped; - req->addr_low = htonl(low); - req->pseudo_hdr_offset = pseudo_hdr_offset; - req->pad = 0; /* complete solid 16-byte block; does this matter? */ - req->rdma_count = 1; - req->length = htons(seglen); - req->cksum_offset = cksum_offset; - req->flags = flags | ((cum_len & 1) * odd_flag); - - low += seglen; - len -= seglen; - cum_len = cum_len_next; - flags = flags_next; - req++; - count++; - rdma_count++; - if (unlikely(cksum_offset > seglen)) - cksum_offset -= seglen; - else - cksum_offset = 0; - } - if (frag_idx == frag_cnt) - break; - - /* map next fragment for DMA */ - idx = (count + tx->req) & tx->mask; - frag = &skb_shinfo(skb)->frags[frag_idx]; - frag_idx++; - len = frag->size; - bus = pci_map_page(mgp->pdev, frag->page, frag->page_offset, - len, PCI_DMA_TODEVICE); - pci_unmap_addr_set(&tx->info[idx], bus, bus); - pci_unmap_len_set(&tx->info[idx], len, len); - } - - (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) - myri10ge_submit_req(tx, tx->req_list, count); - else - myri10ge_submit_req_wc(tx, tx->req_list, count); - tx->pkt_start++; - if ((avail - count) < MXGEFW_MAX_SEND_DESC) { - mgp->stop_queue++; - netif_stop_queue(dev); - } - dev->trans_start = jiffies; - return 0; - -abort_linearize: - /* Free any DMA resources we've alloced and clear out the skb - * slot so as to not trip up assertions, and to avoid a - * double-free if linearizing fails */ - - last_idx = (idx + 1) & tx->mask; - idx = tx->req & tx->mask; - tx->info[idx].skb = NULL; - do { - len = pci_unmap_len(&tx->info[idx], len); - if (len) { - if (tx->info[idx].skb != NULL) - pci_unmap_single(mgp->pdev, - pci_unmap_addr(&tx->info[idx], - bus), len, - PCI_DMA_TODEVICE); - else - pci_unmap_page(mgp->pdev, - pci_unmap_addr(&tx->info[idx], - bus), len, - PCI_DMA_TODEVICE); - pci_unmap_len_set(&tx->info[idx], len, 0); - tx->info[idx].skb = NULL; - } - idx = (idx + 1) & tx->mask; - } while (idx != last_idx); - if (skb_shinfo(skb)->tso_size) { - printk(KERN_ERR - "myri10ge: %s: TSO but wanted to linearize?!?!?\n", - mgp->dev->name); - goto drop; - } - - if (skb_linearize(skb, GFP_ATOMIC)) - goto drop; - - mgp->tx_linearized++; - goto again; - -drop: - dev_kfree_skb_any(skb); - mgp->stats.tx_dropped += 1; - return 0; - -} - -static struct net_device_stats *myri10ge_get_stats(struct net_device *dev) -{ - struct myri10ge_priv *mgp = netdev_priv(dev); - return &mgp->stats; -} - -static void myri10ge_set_multicast_list(struct net_device *dev) -{ - /* can be called from atomic contexts, - * pass 1 to force atomicity in myri10ge_send_cmd() */ - myri10ge_change_promisc(netdev_priv(dev), dev->flags & IFF_PROMISC, 1); -} - -static int myri10ge_set_mac_address(struct net_device *dev, void *addr) -{ - struct sockaddr *sa = addr; - struct myri10ge_priv *mgp = netdev_priv(dev); - int status; - - if (!is_valid_ether_addr(sa->sa_data)) - return -EADDRNOTAVAIL; - - status = myri10ge_update_mac_address(mgp, sa->sa_data); - if (status != 0) { - printk(KERN_ERR - "myri10ge: %s: changing mac address failed with %d\n", - dev->name, status); - return status; - } - - /* change the dev structure */ - memcpy(dev->dev_addr, sa->sa_data, 6); - return 0; -} - -static int myri10ge_change_mtu(struct net_device *dev, int new_mtu) -{ - struct myri10ge_priv *mgp = netdev_priv(dev); - int error = 0; - - if ((new_mtu < 68) || (ETH_HLEN + new_mtu > MYRI10GE_MAX_ETHER_MTU)) { - printk(KERN_ERR "myri10ge: %s: new mtu (%d) is not valid\n", - dev->name, new_mtu); - return -EINVAL; - } - printk(KERN_INFO "%s: changing mtu from %d to %d\n", - dev->name, dev->mtu, new_mtu); - if (mgp->running) { - /* if we change the mtu on an active device, we must - * reset the device so the firmware sees the change */ - myri10ge_close(dev); - dev->mtu = new_mtu; - myri10ge_open(dev); - } else - dev->mtu = new_mtu; - - return error; -} - -/* - * Enable ECRC to align PCI-E Completion packets on an 8-byte boundary. - * Only do it if the bridge is a root port since we don't want to disturb - * any other device, except if forced with myri10ge_ecrc_enable > 1. - */ - -#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_PCIE 0x005d - -static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) -{ - struct pci_dev *bridge = mgp->pdev->bus->self; - struct device *dev = &mgp->pdev->dev; - unsigned cap; - unsigned err_cap; - u16 val; - u8 ext_type; - int ret; - - if (!myri10ge_ecrc_enable || !bridge) - return; - - /* check that the bridge is a root port */ - cap = pci_find_capability(bridge, PCI_CAP_ID_EXP); - pci_read_config_word(bridge, cap + PCI_CAP_FLAGS, &val); - ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4; - if (ext_type != PCI_EXP_TYPE_ROOT_PORT) { - if (myri10ge_ecrc_enable > 1) { - struct pci_dev *old_bridge = bridge; - - /* Walk the hierarchy up to the root port - * where ECRC has to be enabled */ - do { - bridge = bridge->bus->self; - if (!bridge) { - dev_err(dev, - "Failed to find root port" - " to force ECRC\n"); - return; - } - cap = - pci_find_capability(bridge, PCI_CAP_ID_EXP); - pci_read_config_word(bridge, - cap + PCI_CAP_FLAGS, &val); - ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4; - } while (ext_type != PCI_EXP_TYPE_ROOT_PORT); - - dev_info(dev, - "Forcing ECRC on non-root port %s" - " (enabling on root port %s)\n", - pci_name(old_bridge), pci_name(bridge)); - } else { - dev_err(dev, - "Not enabling ECRC on non-root port %s\n", - pci_name(bridge)); - return; - } - } - - cap = pci_find_ext_capability(bridge, PCI_EXT_CAP_ID_ERR); - /* nvidia ext cap is not always linked in ext cap chain */ - if (!cap - && bridge->vendor == PCI_VENDOR_ID_NVIDIA - && bridge->device == PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_PCIE) - cap = 0x160; - - if (!cap) - return; - - ret = pci_read_config_dword(bridge, cap + PCI_ERR_CAP, &err_cap); - if (ret) { - dev_err(dev, "failed reading ext-conf-space of %s\n", - pci_name(bridge)); - dev_err(dev, "\t pci=nommconf in use? " - "or buggy/incomplete/absent ACPI MCFG attr?\n"); - return; - } - if (!(err_cap & PCI_ERR_CAP_ECRC_GENC)) - return; - - err_cap |= PCI_ERR_CAP_ECRC_GENE; - pci_write_config_dword(bridge, cap + PCI_ERR_CAP, err_cap); - dev_info(dev, "Enabled ECRC on upstream bridge %s\n", pci_name(bridge)); - mgp->tx.boundary = 4096; - mgp->fw_name = myri10ge_fw_aligned; -} - -/* - * The Lanai Z8E PCI-E interface achieves higher Read-DMA throughput - * when the PCI-E Completion packets are aligned on an 8-byte - * boundary. Some PCI-E chip sets always align Completion packets; on - * the ones that do not, the alignment can be enforced by enabling - * ECRC generation (if supported). - * - * When PCI-E Completion packets are not aligned, it is actually more - * efficient to limit Read-DMA transactions to 2KB, rather than 4KB. - * - * If the driver can neither enable ECRC nor verify that it has - * already been enabled, then it must use a firmware image which works - * around unaligned completion packets (myri10ge_ethp_z8e.dat), and it - * should also ensure that it never gives the device a Read-DMA which is - * larger than 2KB by setting the tx.boundary to 2KB. If ECRC is - * enabled, then the driver should use the aligned (myri10ge_eth_z8e.dat) - * firmware image, and set tx.boundary to 4KB. - */ - -#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 - -static void myri10ge_select_firmware(struct myri10ge_priv *mgp) -{ - struct pci_dev *bridge = mgp->pdev->bus->self; - - mgp->tx.boundary = 2048; - mgp->fw_name = myri10ge_fw_unaligned; - - if (myri10ge_force_firmware == 0) { - myri10ge_enable_ecrc(mgp); - - /* Check to see if the upstream bridge is known to - * provide aligned completions */ - if (bridge - /* ServerWorks HT2000/HT1000 */ - && bridge->vendor == PCI_VENDOR_ID_SERVERWORKS - && bridge->device == - PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) { - dev_info(&mgp->pdev->dev, - "Assuming aligned completions (0x%x:0x%x)\n", - bridge->vendor, bridge->device); - mgp->tx.boundary = 4096; - mgp->fw_name = myri10ge_fw_aligned; - } - } else { - if (myri10ge_force_firmware == 1) { - dev_info(&mgp->pdev->dev, - "Assuming aligned completions (forced)\n"); - mgp->tx.boundary = 4096; - mgp->fw_name = myri10ge_fw_aligned; - } else { - dev_info(&mgp->pdev->dev, - "Assuming unaligned completions (forced)\n"); - mgp->tx.boundary = 2048; - mgp->fw_name = myri10ge_fw_unaligned; - } - } - if (myri10ge_fw_name != NULL) { - dev_info(&mgp->pdev->dev, "overriding firmware to %s\n", - myri10ge_fw_name); - mgp->fw_name = myri10ge_fw_name; - } -} - -static void myri10ge_save_state(struct myri10ge_priv *mgp) -{ - struct pci_dev *pdev = mgp->pdev; - int cap; - - pci_save_state(pdev); - /* now save PCIe and MSI state that Linux will not - * save for us */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, &mgp->devctl); - cap = pci_find_capability(pdev, PCI_CAP_ID_MSI); - pci_read_config_word(pdev, cap + PCI_MSI_FLAGS, &mgp->msi_flags); -} - -static void myri10ge_restore_state(struct myri10ge_priv *mgp) -{ - struct pci_dev *pdev = mgp->pdev; - int cap; - - /* restore PCIe and MSI state that linux will not */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - pci_write_config_dword(pdev, cap + PCI_CAP_ID_EXP, mgp->devctl); - cap = pci_find_capability(pdev, PCI_CAP_ID_MSI); - pci_write_config_word(pdev, cap + PCI_MSI_FLAGS, mgp->msi_flags); - - pci_restore_state(pdev); -} - -#ifdef CONFIG_PM - -static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct myri10ge_priv *mgp; - struct net_device *netdev; - - mgp = pci_get_drvdata(pdev); - if (mgp == NULL) - return -EINVAL; - netdev = mgp->dev; - - netif_device_detach(netdev); - if (netif_running(netdev)) { - printk(KERN_INFO "myri10ge: closing %s\n", netdev->name); - rtnl_lock(); - myri10ge_close(netdev); - rtnl_unlock(); - } - myri10ge_dummy_rdma(mgp, 0); - free_irq(pdev->irq, mgp); - myri10ge_save_state(mgp); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; -} - -static int myri10ge_resume(struct pci_dev *pdev) -{ - struct myri10ge_priv *mgp; - struct net_device *netdev; - int status; - u16 vendor; - - mgp = pci_get_drvdata(pdev); - if (mgp == NULL) - return -EINVAL; - netdev = mgp->dev; - pci_set_power_state(pdev, 0); /* zeros conf space as a side effect */ - msleep(5); /* give card time to respond */ - pci_read_config_word(mgp->pdev, PCI_VENDOR_ID, &vendor); - if (vendor == 0xffff) { - printk(KERN_ERR "myri10ge: %s: device disappeared!\n", - mgp->dev->name); - return -EIO; - } - myri10ge_restore_state(mgp); - pci_enable_device(pdev); - pci_set_master(pdev); - - status = request_irq(pdev->irq, myri10ge_intr, SA_SHIRQ, - netdev->name, mgp); - if (status != 0) { - dev_err(&pdev->dev, "failed to allocate IRQ\n"); - goto abort_with_msi; - } - - myri10ge_reset(mgp); - myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096); - - /* Save configuration space to be restored if the - * nic resets due to a parity error */ - myri10ge_save_state(mgp); - - if (netif_running(netdev)) { - rtnl_lock(); - myri10ge_open(netdev); - rtnl_unlock(); - } - netif_device_attach(netdev); - - return 0; - -abort_with_msi: - return -EIO; - -} - -#endif /* CONFIG_PM */ - -static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp) -{ - struct pci_dev *pdev = mgp->pdev; - int vs = mgp->vendor_specific_offset; - u32 reboot; - - /*enter read32 mode */ - pci_write_config_byte(pdev, vs + 0x10, 0x3); - - /*read REBOOT_STATUS (0xfffffff0) */ - pci_write_config_dword(pdev, vs + 0x18, 0xfffffff0); - pci_read_config_dword(pdev, vs + 0x14, &reboot); - return reboot; -} - -/* - * This watchdog is used to check whether the board has suffered - * from a parity error and needs to be recovered. - */ -static void myri10ge_watchdog(void *arg) -{ - struct myri10ge_priv *mgp = arg; - u32 reboot; - int status; - u16 cmd, vendor; - - mgp->watchdog_resets++; - pci_read_config_word(mgp->pdev, PCI_COMMAND, &cmd); - if ((cmd & PCI_COMMAND_MASTER) == 0) { - /* Bus master DMA disabled? Check to see - * if the card rebooted due to a parity error - * For now, just report it */ - reboot = myri10ge_read_reboot(mgp); - printk(KERN_ERR - "myri10ge: %s: NIC rebooted (0x%x), resetting\n", - mgp->dev->name, reboot); - /* - * A rebooted nic will come back with config space as - * it was after power was applied to PCIe bus. - * Attempt to restore config space which was saved - * when the driver was loaded, or the last time the - * nic was resumed from power saving mode. - */ - myri10ge_restore_state(mgp); - } else { - /* if we get back -1's from our slot, perhaps somebody - * powered off our card. Don't try to reset it in - * this case */ - if (cmd == 0xffff) { - pci_read_config_word(mgp->pdev, PCI_VENDOR_ID, &vendor); - if (vendor == 0xffff) { - printk(KERN_ERR - "myri10ge: %s: device disappeared!\n", - mgp->dev->name); - return; - } - } - /* Perhaps it is a software error. Try to reset */ - - printk(KERN_ERR "myri10ge: %s: device timeout, resetting\n", - mgp->dev->name); - printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n", - mgp->dev->name, mgp->tx.req, mgp->tx.done, - mgp->tx.pkt_start, mgp->tx.pkt_done, - (int)ntohl(mgp->fw_stats->send_done_count)); - msleep(2000); - printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n", - mgp->dev->name, mgp->tx.req, mgp->tx.done, - mgp->tx.pkt_start, mgp->tx.pkt_done, - (int)ntohl(mgp->fw_stats->send_done_count)); - } - rtnl_lock(); - myri10ge_close(mgp->dev); - status = myri10ge_load_firmware(mgp); - if (status != 0) - printk(KERN_ERR "myri10ge: %s: failed to load firmware\n", - mgp->dev->name); - else - myri10ge_open(mgp->dev); - rtnl_unlock(); -} - -/* - * We use our own timer routine rather than relying upon - * netdev->tx_timeout because we have a very large hardware transmit - * queue. Due to the large queue, the netdev->tx_timeout function - * cannot detect a NIC with a parity error in a timely fashion if the - * NIC is lightly loaded. - */ -static void myri10ge_watchdog_timer(unsigned long arg) -{ - struct myri10ge_priv *mgp; - - mgp = (struct myri10ge_priv *)arg; - if (mgp->tx.req != mgp->tx.done && - mgp->tx.done == mgp->watchdog_tx_done) - /* nic seems like it might be stuck.. */ - schedule_work(&mgp->watchdog_work); - else - /* rearm timer */ - mod_timer(&mgp->watchdog_timer, - jiffies + myri10ge_watchdog_timeout * HZ); - - mgp->watchdog_tx_done = mgp->tx.done; -} - -static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct net_device *netdev; - struct myri10ge_priv *mgp; - struct device *dev = &pdev->dev; - size_t bytes; - int i; - int status = -ENXIO; - int cap; - int dac_enabled; - u16 val; - - netdev = alloc_etherdev(sizeof(*mgp)); - if (netdev == NULL) { - dev_err(dev, "Could not allocate ethernet device\n"); - return -ENOMEM; - } - - mgp = netdev_priv(netdev); - memset(mgp, 0, sizeof(*mgp)); - mgp->dev = netdev; - mgp->pdev = pdev; - mgp->csum_flag = MXGEFW_FLAGS_CKSUM; - mgp->pause = myri10ge_flow_control; - mgp->intr_coal_delay = myri10ge_intr_coal_delay; - init_waitqueue_head(&mgp->down_wq); - - if (pci_enable_device(pdev)) { - dev_err(&pdev->dev, "pci_enable_device call failed\n"); - status = -ENODEV; - goto abort_with_netdev; - } - myri10ge_select_firmware(mgp); - - /* Find the vendor-specific cap so we can check - * the reboot register later on */ - mgp->vendor_specific_offset - = pci_find_capability(pdev, PCI_CAP_ID_VNDR); - - /* Set our max read request to 4KB */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (cap < 64) { - dev_err(&pdev->dev, "Bad PCI_CAP_ID_EXP location %d\n", cap); - goto abort_with_netdev; - } - status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val); - if (status != 0) { - dev_err(&pdev->dev, "Error %d reading PCI_EXP_DEVCTL\n", - status); - goto abort_with_netdev; - } - val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12); - status = pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, val); - if (status != 0) { - dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n", - status); - goto abort_with_netdev; - } - - pci_set_master(pdev); - dac_enabled = 1; - status = pci_set_dma_mask(pdev, DMA_64BIT_MASK); - if (status != 0) { - dac_enabled = 0; - dev_err(&pdev->dev, - "64-bit pci address mask was refused, trying 32-bit"); - status = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - } - if (status != 0) { - dev_err(&pdev->dev, "Error %d setting DMA mask\n", status); - goto abort_with_netdev; - } - mgp->cmd = pci_alloc_consistent(pdev, sizeof(*mgp->cmd), &mgp->cmd_bus); - if (mgp->cmd == NULL) - goto abort_with_netdev; - - mgp->fw_stats = pci_alloc_consistent(pdev, sizeof(*mgp->fw_stats), - &mgp->fw_stats_bus); - if (mgp->fw_stats == NULL) - goto abort_with_cmd; - - mgp->board_span = pci_resource_len(pdev, 0); - mgp->iomem_base = pci_resource_start(pdev, 0); - mgp->mtrr = -1; -#ifdef CONFIG_MTRR - mgp->mtrr = mtrr_add(mgp->iomem_base, mgp->board_span, - MTRR_TYPE_WRCOMB, 1); -#endif - /* Hack. need to get rid of these magic numbers */ - mgp->sram_size = - 2 * 1024 * 1024 - (2 * (48 * 1024) + (32 * 1024)) - 0x100; - if (mgp->sram_size > mgp->board_span) { - dev_err(&pdev->dev, "board span %ld bytes too small\n", - mgp->board_span); - goto abort_with_wc; - } - mgp->sram = ioremap(mgp->iomem_base, mgp->board_span); - if (mgp->sram == NULL) { - dev_err(&pdev->dev, "ioremap failed for %ld bytes at 0x%lx\n", - mgp->board_span, mgp->iomem_base); - status = -ENXIO; - goto abort_with_wc; - } - memcpy_fromio(mgp->eeprom_strings, - mgp->sram + mgp->sram_size - MYRI10GE_EEPROM_STRINGS_SIZE, - MYRI10GE_EEPROM_STRINGS_SIZE); - memset(mgp->eeprom_strings + MYRI10GE_EEPROM_STRINGS_SIZE - 2, 0, 2); - status = myri10ge_read_mac_addr(mgp); - if (status) - goto abort_with_ioremap; - - for (i = 0; i < ETH_ALEN; i++) - netdev->dev_addr[i] = mgp->mac_addr[i]; - - /* allocate rx done ring */ - bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); - mgp->rx_done.entry = - pci_alloc_consistent(pdev, bytes, &mgp->rx_done.bus); - if (mgp->rx_done.entry == NULL) - goto abort_with_ioremap; - memset(mgp->rx_done.entry, 0, bytes); - - status = myri10ge_load_firmware(mgp); - if (status != 0) { - dev_err(&pdev->dev, "failed to load firmware\n"); - goto abort_with_rx_done; - } - - status = myri10ge_reset(mgp); - if (status != 0) { - dev_err(&pdev->dev, "failed reset\n"); - goto abort_with_firmware; - } - - if (myri10ge_msi) { - status = pci_enable_msi(pdev); - if (status != 0) - dev_err(&pdev->dev, - "Error %d setting up MSI; falling back to xPIC\n", - status); - else - mgp->msi_enabled = 1; - } - - status = request_irq(pdev->irq, myri10ge_intr, SA_SHIRQ, - netdev->name, mgp); - if (status != 0) { - dev_err(&pdev->dev, "failed to allocate IRQ\n"); - goto abort_with_firmware; - } - - pci_set_drvdata(pdev, mgp); - if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU) - myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; - if ((myri10ge_initial_mtu + ETH_HLEN) < 68) - myri10ge_initial_mtu = 68; - netdev->mtu = myri10ge_initial_mtu; - netdev->open = myri10ge_open; - netdev->stop = myri10ge_close; - netdev->hard_start_xmit = myri10ge_xmit; - netdev->get_stats = myri10ge_get_stats; - netdev->base_addr = mgp->iomem_base; - netdev->irq = pdev->irq; - netdev->change_mtu = myri10ge_change_mtu; - netdev->set_multicast_list = myri10ge_set_multicast_list; - netdev->set_mac_address = myri10ge_set_mac_address; - netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO; - if (dac_enabled) - netdev->features |= NETIF_F_HIGHDMA; - netdev->poll = myri10ge_poll; - netdev->weight = myri10ge_napi_weight; - - /* Save configuration space to be restored if the - * nic resets due to a parity error */ - myri10ge_save_state(mgp); - /* Restore state immediately since pci_save_msi_state disables MSI */ - myri10ge_restore_state(mgp); - - /* Setup the watchdog timer */ - setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, - (unsigned long)mgp); - - SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops); - INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog, mgp); - status = register_netdev(netdev); - if (status != 0) { - dev_err(&pdev->dev, "register_netdev failed: %d\n", status); - goto abort_with_irq; - } - - printk(KERN_INFO "myri10ge: %s: %s IRQ %d, tx bndry %d, fw %s, WC %s\n", - netdev->name, (mgp->msi_enabled ? "MSI" : "xPIC"), - pdev->irq, mgp->tx.boundary, mgp->fw_name, - (mgp->mtrr >= 0 ? "Enabled" : "Disabled")); - - return 0; - -abort_with_irq: - free_irq(pdev->irq, mgp); - if (mgp->msi_enabled) - pci_disable_msi(pdev); - -abort_with_firmware: - myri10ge_dummy_rdma(mgp, 0); - -abort_with_rx_done: - bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); - pci_free_consistent(pdev, bytes, mgp->rx_done.entry, mgp->rx_done.bus); - -abort_with_ioremap: - iounmap(mgp->sram); - -abort_with_wc: -#ifdef CONFIG_MTRR - if (mgp->mtrr >= 0) - mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span); -#endif - pci_free_consistent(pdev, sizeof(*mgp->fw_stats), - mgp->fw_stats, mgp->fw_stats_bus); - -abort_with_cmd: - pci_free_consistent(pdev, sizeof(*mgp->cmd), mgp->cmd, mgp->cmd_bus); - -abort_with_netdev: - - free_netdev(netdev); - return status; -} - -/* - * myri10ge_remove - * - * Does what is necessary to shutdown one Myrinet device. Called - * once for each Myrinet card by the kernel when a module is - * unloaded. - */ -static void myri10ge_remove(struct pci_dev *pdev) -{ - struct myri10ge_priv *mgp; - struct net_device *netdev; - size_t bytes; - - mgp = pci_get_drvdata(pdev); - if (mgp == NULL) - return; - - flush_scheduled_work(); - netdev = mgp->dev; - unregister_netdev(netdev); - free_irq(pdev->irq, mgp); - if (mgp->msi_enabled) - pci_disable_msi(pdev); - - myri10ge_dummy_rdma(mgp, 0); - - bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); - pci_free_consistent(pdev, bytes, mgp->rx_done.entry, mgp->rx_done.bus); - - iounmap(mgp->sram); - -#ifdef CONFIG_MTRR - if (mgp->mtrr >= 0) - mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span); -#endif - pci_free_consistent(pdev, sizeof(*mgp->fw_stats), - mgp->fw_stats, mgp->fw_stats_bus); - - pci_free_consistent(pdev, sizeof(*mgp->cmd), mgp->cmd, mgp->cmd_bus); - - free_netdev(netdev); - pci_set_drvdata(pdev, NULL); -} - -#define PCI_DEVICE_ID_MYIRCOM_MYRI10GE_Z8E 0x0008 - -static struct pci_device_id myri10ge_pci_tbl[] = { - {PCI_DEVICE(PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYIRCOM_MYRI10GE_Z8E)}, - {0}, -}; - -static struct pci_driver myri10ge_driver = { - .name = "myri10ge", - .probe = myri10ge_probe, - .remove = myri10ge_remove, - .id_table = myri10ge_pci_tbl, -#ifdef CONFIG_PM - .suspend = myri10ge_suspend, - .resume = myri10ge_resume, -#endif -}; - -static __init int myri10ge_init_module(void) -{ - printk(KERN_INFO "%s: Version %s\n", myri10ge_driver.name, - MYRI10GE_VERSION_STR); - return pci_register_driver(&myri10ge_driver); -} - -module_init(myri10ge_init_module); - -static __exit void myri10ge_cleanup_module(void) -{ - pci_unregister_driver(&myri10ge_driver); -} - -module_exit(myri10ge_cleanup_module); diff --git a/trunk/drivers/net/myri10ge/myri10ge_mcp.h b/trunk/drivers/net/myri10ge/myri10ge_mcp.h deleted file mode 100644 index 0a6cae6cb186..000000000000 --- a/trunk/drivers/net/myri10ge/myri10ge_mcp.h +++ /dev/null @@ -1,205 +0,0 @@ -#ifndef __MYRI10GE_MCP_H__ -#define __MYRI10GE_MCP_H__ - -#define MXGEFW_VERSION_MAJOR 1 -#define MXGEFW_VERSION_MINOR 4 - -/* 8 Bytes */ -struct mcp_dma_addr { - u32 high; - u32 low; -}; - -/* 4 Bytes */ -struct mcp_slot { - u16 checksum; - u16 length; -}; - -/* 64 Bytes */ -struct mcp_cmd { - u32 cmd; - u32 data0; /* will be low portion if data > 32 bits */ - /* 8 */ - u32 data1; /* will be high portion if data > 32 bits */ - u32 data2; /* currently unused.. */ - /* 16 */ - struct mcp_dma_addr response_addr; - /* 24 */ - u8 pad[40]; -}; - -/* 8 Bytes */ -struct mcp_cmd_response { - u32 data; - u32 result; -}; - -/* - * flags used in mcp_kreq_ether_send_t: - * - * The SMALL flag is only needed in the first segment. It is raised - * for packets that are total less or equal 512 bytes. - * - * The CKSUM flag must be set in all segments. - * - * The PADDED flags is set if the packet needs to be padded, and it - * must be set for all segments. - * - * The MXGEFW_FLAGS_ALIGN_ODD must be set if the cumulative - * length of all previous segments was odd. - */ - -#define MXGEFW_FLAGS_SMALL 0x1 -#define MXGEFW_FLAGS_TSO_HDR 0x1 -#define MXGEFW_FLAGS_FIRST 0x2 -#define MXGEFW_FLAGS_ALIGN_ODD 0x4 -#define MXGEFW_FLAGS_CKSUM 0x8 -#define MXGEFW_FLAGS_TSO_LAST 0x8 -#define MXGEFW_FLAGS_NO_TSO 0x10 -#define MXGEFW_FLAGS_TSO_CHOP 0x10 -#define MXGEFW_FLAGS_TSO_PLD 0x20 - -#define MXGEFW_SEND_SMALL_SIZE 1520 -#define MXGEFW_MAX_MTU 9400 - -union mcp_pso_or_cumlen { - u16 pseudo_hdr_offset; - u16 cum_len; -}; - -#define MXGEFW_MAX_SEND_DESC 12 -#define MXGEFW_PAD 2 - -/* 16 Bytes */ -struct mcp_kreq_ether_send { - u32 addr_high; - u32 addr_low; - u16 pseudo_hdr_offset; - u16 length; - u8 pad; - u8 rdma_count; - u8 cksum_offset; /* where to start computing cksum */ - u8 flags; /* as defined above */ -}; - -/* 8 Bytes */ -struct mcp_kreq_ether_recv { - u32 addr_high; - u32 addr_low; -}; - -/* Commands */ - -#define MXGEFW_CMD_OFFSET 0xf80000 - -enum myri10ge_mcp_cmd_type { - MXGEFW_CMD_NONE = 0, - /* Reset the mcp, it is left in a safe state, waiting - * for the driver to set all its parameters */ - MXGEFW_CMD_RESET, - - /* get the version number of the current firmware.. - * (may be available in the eeprom strings..? */ - MXGEFW_GET_MCP_VERSION, - - /* Parameters which must be set by the driver before it can - * issue MXGEFW_CMD_ETHERNET_UP. They persist until the next - * MXGEFW_CMD_RESET is issued */ - - MXGEFW_CMD_SET_INTRQ_DMA, - MXGEFW_CMD_SET_BIG_BUFFER_SIZE, /* in bytes, power of 2 */ - MXGEFW_CMD_SET_SMALL_BUFFER_SIZE, /* in bytes */ - - /* Parameters which refer to lanai SRAM addresses where the - * driver must issue PIO writes for various things */ - - MXGEFW_CMD_GET_SEND_OFFSET, - MXGEFW_CMD_GET_SMALL_RX_OFFSET, - MXGEFW_CMD_GET_BIG_RX_OFFSET, - MXGEFW_CMD_GET_IRQ_ACK_OFFSET, - MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, - - /* Parameters which refer to rings stored on the MCP, - * and whose size is controlled by the mcp */ - - MXGEFW_CMD_GET_SEND_RING_SIZE, /* in bytes */ - MXGEFW_CMD_GET_RX_RING_SIZE, /* in bytes */ - - /* Parameters which refer to rings stored in the host, - * and whose size is controlled by the host. Note that - * all must be physically contiguous and must contain - * a power of 2 number of entries. */ - - MXGEFW_CMD_SET_INTRQ_SIZE, /* in bytes */ - - /* command to bring ethernet interface up. Above parameters - * (plus mtu & mac address) must have been exchanged prior - * to issuing this command */ - MXGEFW_CMD_ETHERNET_UP, - - /* command to bring ethernet interface down. No further sends - * or receives may be processed until an MXGEFW_CMD_ETHERNET_UP - * is issued, and all interrupt queues must be flushed prior - * to ack'ing this command */ - - MXGEFW_CMD_ETHERNET_DOWN, - - /* commands the driver may issue live, without resetting - * the nic. Note that increasing the mtu "live" should - * only be done if the driver has already supplied buffers - * sufficiently large to handle the new mtu. Decreasing - * the mtu live is safe */ - - MXGEFW_CMD_SET_MTU, - MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, /* in microseconds */ - MXGEFW_CMD_SET_STATS_INTERVAL, /* in microseconds */ - MXGEFW_CMD_SET_STATS_DMA, - - MXGEFW_ENABLE_PROMISC, - MXGEFW_DISABLE_PROMISC, - MXGEFW_SET_MAC_ADDRESS, - - MXGEFW_ENABLE_FLOW_CONTROL, - MXGEFW_DISABLE_FLOW_CONTROL, - - /* do a DMA test - * data0,data1 = DMA address - * data2 = RDMA length (MSH), WDMA length (LSH) - * command return data = repetitions (MSH), 0.5-ms ticks (LSH) - */ - MXGEFW_DMA_TEST -}; - -enum myri10ge_mcp_cmd_status { - MXGEFW_CMD_OK = 0, - MXGEFW_CMD_UNKNOWN, - MXGEFW_CMD_ERROR_RANGE, - MXGEFW_CMD_ERROR_BUSY, - MXGEFW_CMD_ERROR_EMPTY, - MXGEFW_CMD_ERROR_CLOSED, - MXGEFW_CMD_ERROR_HASH_ERROR, - MXGEFW_CMD_ERROR_BAD_PORT, - MXGEFW_CMD_ERROR_RESOURCES -}; - -/* 40 Bytes */ -struct mcp_irq_data { - u32 send_done_count; - - u32 link_up; - u32 dropped_link_overflow; - u32 dropped_link_error_or_filtered; - u32 dropped_runt; - u32 dropped_overrun; - u32 dropped_no_small_buffer; - u32 dropped_no_big_buffer; - u32 rdma_tags_available; - - u8 tx_stopped; - u8 link_down; - u8 stats_updated; - u8 valid; -}; - -#endif /* __MYRI10GE_MCP_H__ */ diff --git a/trunk/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/trunk/drivers/net/myri10ge/myri10ge_mcp_gen_header.h deleted file mode 100644 index 487f7792fd46..000000000000 --- a/trunk/drivers/net/myri10ge/myri10ge_mcp_gen_header.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __MYRI10GE_MCP_GEN_HEADER_H__ -#define __MYRI10GE_MCP_GEN_HEADER_H__ - -/* this file define a standard header used as a first entry point to - * exchange information between firmware/driver and driver. The - * header structure can be anywhere in the mcp. It will usually be in - * the .data section, because some fields needs to be initialized at - * compile time. - * The 32bit word at offset MX_HEADER_PTR_OFFSET in the mcp must - * contains the location of the header. - * - * Typically a MCP will start with the following: - * .text - * .space 52 ! to help catch MEMORY_INT errors - * bt start ! jump to real code - * nop - * .long _gen_mcp_header - * - * The source will have a definition like: - * - * mcp_gen_header_t gen_mcp_header = { - * .header_length = sizeof(mcp_gen_header_t), - * .mcp_type = MCP_TYPE_XXX, - * .version = "something $Id: mcp_gen_header.h,v 1.2 2006/05/13 10:04:35 bgoglin Exp $", - * .mcp_globals = (unsigned)&Globals - * }; - */ - -#define MCP_HEADER_PTR_OFFSET 0x3c - -#define MCP_TYPE_MX 0x4d582020 /* "MX " */ -#define MCP_TYPE_PCIE 0x70636965 /* "PCIE" pcie-only MCP */ -#define MCP_TYPE_ETH 0x45544820 /* "ETH " */ -#define MCP_TYPE_MCP0 0x4d435030 /* "MCP0" */ - -struct mcp_gen_header { - /* the first 4 fields are filled at compile time */ - unsigned header_length; - unsigned mcp_type; - char version[128]; - unsigned mcp_globals; /* pointer to mcp-type specific structure */ - - /* filled by the MCP at run-time */ - unsigned sram_size; - unsigned string_specs; /* either the original STRING_SPECS or a superset */ - unsigned string_specs_len; - - /* Fields above this comment are guaranteed to be present. - * - * Fields below this comment are extensions added in later versions - * of this struct, drivers should compare the header_length against - * offsetof(field) to check wether a given MCP implements them. - * - * Never remove any field. Keep everything naturally align. - */ -}; - -#endif /* __MYRI10GE_MCP_GEN_HEADER_H__ */ diff --git a/trunk/drivers/net/ne.c b/trunk/drivers/net/ne.c index b32765215f75..93c494bcd18d 100644 --- a/trunk/drivers/net/ne.c +++ b/trunk/drivers/net/ne.c @@ -139,9 +139,8 @@ bad_clone_list[] __initdata = { #if defined(CONFIG_PLAT_MAPPI) # define DCR_VAL 0x4b -#elif defined(CONFIG_PLAT_OAKS32R) || \ - defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) -# define DCR_VAL 0x48 /* 8-bit mode */ +#elif defined(CONFIG_PLAT_OAKS32R) +# define DCR_VAL 0x48 #else # define DCR_VAL 0x49 #endif @@ -397,22 +396,10 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) /* We must set the 8390 for word mode. */ outb_p(DCR_VAL, ioaddr + EN0_DCFG); start_page = NESM_START_PG; - - /* - * Realtek RTL8019AS datasheet says that the PSTOP register - * shouldn't exceed 0x60 in 8-bit mode. - * This chip can be identified by reading the signature from - * the remote byte count registers (otherwise write-only)... - */ - if ((DCR_VAL & 0x01) == 0 && /* 8-bit mode */ - inb(ioaddr + EN0_RCNTLO) == 0x50 && - inb(ioaddr + EN0_RCNTHI) == 0x70) - stop_page = 0x60; - else - stop_page = NESM_STOP_PG; + stop_page = NESM_STOP_PG; } else { start_page = NE1SM_START_PG; - stop_page = NE1SM_STOP_PG; + stop_page = NE1SM_STOP_PG; } #if defined(CONFIG_PLAT_MAPPI) || defined(CONFIG_PLAT_OAKS32R) @@ -522,9 +509,15 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) ei_status.name = name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; +#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) + wordlength = 1; +#endif - /* Use 16-bit mode only if this wasn't overridden by DCR_VAL */ - ei_status.word16 = (wordlength == 2 && (DCR_VAL & 0x01)); +#ifdef CONFIG_PLAT_OAKS32R + ei_status.word16 = 0; +#else + ei_status.word16 = (wordlength == 2); +#endif ei_status.rx_start_page = start_page + TX_PAGES; #ifdef PACKETBUF_MEMSIZE diff --git a/trunk/drivers/net/pcmcia/axnet_cs.c b/trunk/drivers/net/pcmcia/axnet_cs.c index 2ea66aca648b..448a09488529 100644 --- a/trunk/drivers/net/pcmcia/axnet_cs.c +++ b/trunk/drivers/net/pcmcia/axnet_cs.c @@ -1691,6 +1691,17 @@ static void do_set_multicast_list(struct net_device *dev) memset(ei_local->mcfilter, 0xFF, 8); } + /* + * DP8390 manuals don't specify any magic sequence for altering + * the multicast regs on an already running card. To be safe, we + * ensure multicast mode is off prior to loading up the new hash + * table. If this proves to be not enough, we can always resort + * to stopping the NIC, loading the table and then restarting. + */ + + if (netif_running(dev)) + outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); + outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); for(i = 0; i < 8; i++) { @@ -1704,8 +1715,6 @@ static void do_set_multicast_list(struct net_device *dev) outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR); else outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR); - - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD); } /* diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index 661bfe54ff5d..d090df413049 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -12,7 +12,7 @@ Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net pcnet_cs.c 1.153 2003/11/09 18:53:09 - + The network driver code is based on Donald Becker's NE2000 code: Written 1992,1993 by Donald Becker. @@ -146,7 +146,7 @@ typedef struct hw_info_t { #define MII_PHYID_REG2 0x03 static hw_info_t hw_info[] = { - { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, + { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 }, { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 }, { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94, @@ -193,7 +193,7 @@ static hw_info_t hw_info[] = { { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 }, { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65, HAS_MISC_REG | HAS_IBM_MISC }, - { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, + { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, HAS_MISC_REG | HAS_IBM_MISC }, { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 }, { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 }, @@ -330,7 +330,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) for (j = 0; j < 6; j++) dev->dev_addr[j] = readb(base + (j<<1)); } - + iounmap(virt); j = pcmcia_release_window(link->win); if (j != CS_SUCCESS) @@ -490,7 +490,7 @@ static int try_io_port(struct pcmcia_device *link) if (link->io.NumPorts2 > 0) { /* for master/slave multifunction cards */ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->irq.Attributes = + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; } } else { @@ -543,19 +543,19 @@ static int pcnet_config(struct pcmcia_device *link) manfid = le16_to_cpu(buf[0]); prodid = le16_to_cpu(buf[1]); } - + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (last_ret == CS_SUCCESS) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); - + if (pcmcia_get_tuple_data(link, &tuple) != 0 || pcmcia_parse_tuple(link, &tuple, &parse) != 0 || cfg->index == 0 || cfg->io.nwin == 0) goto next_entry; - + link->conf.ConfigIndex = cfg->index; /* For multifunction cards, by convention, we configure the network function with window 0, and serial with window 1 */ @@ -584,7 +584,7 @@ static int pcnet_config(struct pcmcia_device *link) } CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - + if (link->io.NumPorts2 == 8) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; @@ -592,7 +592,7 @@ static int pcnet_config(struct pcmcia_device *link) if ((manfid == MANFID_IBM) && (prodid == PRODID_IBM_HOME_AND_AWAY)) link->conf.ConfigIndex |= 0x10; - + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -614,7 +614,7 @@ static int pcnet_config(struct pcmcia_device *link) hw_info = get_ax88190(link); if (hw_info == NULL) hw_info = get_hwired(link); - + if (hw_info == NULL) { printk(KERN_NOTICE "pcnet_cs: unable to read hardware net" " address for io base %#3lx\n", dev->base_addr); @@ -631,7 +631,7 @@ static int pcnet_config(struct pcmcia_device *link) info->flags &= ~USE_BIG_BUF; if (!use_big_buf) info->flags &= ~USE_BIG_BUF; - + if (info->flags & USE_BIG_BUF) { start_pg = SOCKET_START_PG; stop_pg = SOCKET_STOP_PG; @@ -929,7 +929,7 @@ static void set_misc_reg(struct net_device *dev) kio_addr_t nic_base = dev->base_addr; pcnet_dev_t *info = PRIV(dev); u_char tmp; - + if (info->flags & HAS_MISC_REG) { tmp = inb_p(nic_base + PCNET_MISC) & ~3; if (dev->if_port == 2) @@ -1022,7 +1022,7 @@ static int pcnet_close(struct net_device *dev) ei_close(dev); free_irq(dev->irq, dev); - + link->open--; netif_stop_queue(dev); del_timer_sync(&info->watchdog); @@ -1054,12 +1054,12 @@ static void pcnet_reset_8390(struct net_device *dev) udelay(100); } outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ - + if (i == 100) printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n", dev->name); set_misc_reg(dev); - + } /* pcnet_reset_8390 */ /*====================================================================*/ @@ -1233,7 +1233,7 @@ static void dma_get_8390_hdr(struct net_device *dev, dev->name, ei_status.dmaing, ei_status.irqlock); return; } - + ei_status.dmaing |= 0x01; outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD); outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); @@ -1458,7 +1458,7 @@ static void shmem_get_8390_hdr(struct net_device *dev, void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8) + (ring_page << 8) - (ei_status.rx_start_page << 8); - + copyin(hdr, xfer_start, sizeof(struct e8390_pkt_hdr)); /* Fix for big endian systems */ hdr->count = le16_to_cpu(hdr->count); @@ -1473,7 +1473,7 @@ static void shmem_block_input(struct net_device *dev, int count, unsigned long offset = (TX_PAGES<<8) + ring_offset - (ei_status.rx_start_page << 8); char *buf = skb->data; - + if (offset + count > ei_status.priv) { /* We must wrap the input move. */ int semi_count = ei_status.priv - offset; @@ -1541,7 +1541,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, info->base = NULL; link->win = NULL; goto failed; } - + ei_status.mem = info->base + offset; ei_status.priv = req.Size; dev->mem_start = (u_long)ei_status.mem; @@ -1768,8 +1768,6 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "tamarack.cis"), - PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0", - 0xb4be14e3, 0x43ac239b, 0x0877b627), PCMCIA_DEVICE_NULL }; MODULE_DEVICE_TABLE(pcmcia, pcnet_ids); diff --git a/trunk/drivers/net/phy/mdio_bus.c b/trunk/drivers/net/phy/mdio_bus.c index 1b236bdf6b92..459443b572ce 100644 --- a/trunk/drivers/net/phy/mdio_bus.c +++ b/trunk/drivers/net/phy/mdio_bus.c @@ -60,10 +60,8 @@ int mdiobus_register(struct mii_bus *bus) for (i = 0; i < PHY_MAX_ADDR; i++) { struct phy_device *phydev; - if (bus->phy_mask & (1 << i)) { - bus->phy_map[i] = NULL; + if (bus->phy_mask & (1 << i)) continue; - } phydev = get_phy_device(bus, i); diff --git a/trunk/drivers/net/s2io-regs.h b/trunk/drivers/net/s2io-regs.h index 0ef525899566..00179bc3437f 100644 --- a/trunk/drivers/net/s2io-regs.h +++ b/trunk/drivers/net/s2io-regs.h @@ -167,7 +167,6 @@ typedef struct _XENA_dev_config { u8 unused4[0x08]; u64 gpio_int_reg; -#define GPIO_INT_REG_DP_ERR_INT BIT(0) #define GPIO_INT_REG_LINK_DOWN BIT(1) #define GPIO_INT_REG_LINK_UP BIT(2) u64 gpio_int_mask; @@ -188,7 +187,7 @@ typedef struct _XENA_dev_config { /* PIC Control registers */ u64 pic_control; #define PIC_CNTL_RX_ALARM_MAP_1 BIT(0) -#define PIC_CNTL_SHARED_SPLITS(n) vBIT(n,11,5) +#define PIC_CNTL_SHARED_SPLITS(n) vBIT(n,11,4) u64 swapper_ctrl; #define SWAPPER_CTRL_PIF_R_FE BIT(0) @@ -268,21 +267,6 @@ typedef struct _XENA_dev_config { /* General Configuration */ u64 mdio_control; -#define MDIO_MMD_INDX_ADDR(val) vBIT(val, 0, 16) -#define MDIO_MMD_DEV_ADDR(val) vBIT(val, 19, 5) -#define MDIO_MMD_PMA_DEV_ADDR 0x1 -#define MDIO_MMD_PMD_DEV_ADDR 0x1 -#define MDIO_MMD_WIS_DEV_ADDR 0x2 -#define MDIO_MMD_PCS_DEV_ADDR 0x3 -#define MDIO_MMD_PHYXS_DEV_ADDR 0x4 -#define MDIO_MMS_PRT_ADDR(val) vBIT(val, 27, 5) -#define MDIO_CTRL_START_TRANS(val) vBIT(val, 56, 4) -#define MDIO_OP(val) vBIT(val, 60, 2) -#define MDIO_OP_ADDR_TRANS 0x0 -#define MDIO_OP_WRITE_TRANS 0x1 -#define MDIO_OP_READ_POST_INC_TRANS 0x2 -#define MDIO_OP_READ_TRANS 0x3 -#define MDIO_MDIO_DATA(val) vBIT(val, 32, 16) u64 dtx_control; @@ -300,13 +284,9 @@ typedef struct _XENA_dev_config { u64 gpio_control; #define GPIO_CTRL_GPIO_0 BIT(8) u64 misc_control; -#define EXT_REQ_EN BIT(1) #define MISC_LINK_STABILITY_PRD(val) vBIT(val,29,3) - u8 unused7_1[0x230 - 0x208]; - - u64 pic_control2; - u64 ini_dperr_ctrl; + u8 unused7_1[0x240 - 0x208]; u64 wreq_split_mask; #define WREQ_SPLIT_MASK_SET_MASK(val) vBIT(val, 52, 12) @@ -513,7 +493,6 @@ typedef struct _XENA_dev_config { #define PRC_CTRL_NO_SNOOP_DESC BIT(22) #define PRC_CTRL_NO_SNOOP_BUFF BIT(23) #define PRC_CTRL_BIMODAL_INTERRUPT BIT(37) -#define PRC_CTRL_GROUP_READS BIT(38) #define PRC_CTRL_RXD_BACKOFF_INTERVAL(val) vBIT(val,40,24) u64 prc_alarm_action; @@ -562,12 +541,7 @@ typedef struct _XENA_dev_config { #define RX_PA_CFG_IGNORE_LLC_CTRL BIT(3) #define RX_PA_CFG_IGNORE_L2_ERR BIT(6) - u64 unused_11_1; - - u64 ring_bump_counter1; - u64 ring_bump_counter2; - - u8 unused12[0x700 - 0x1F0]; + u8 unused12[0x700 - 0x1D8]; u64 rxdma_debug_ctrl; diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 4e9998181403..79208f434ac1 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -26,22 +26,15 @@ * * The module loadable parameters that are supported by the driver and a brief * explaination of all the variables. - * * rx_ring_num : This can be used to program the number of receive rings used * in the driver. - * rx_ring_sz: This defines the number of receive blocks each ring can have. - * This is also an array of size 8. + * rx_ring_sz: This defines the number of descriptors each ring can have. This + * is also an array of size 8. * rx_ring_mode: This defines the operation mode of all 8 rings. The valid * values are 1, 2 and 3. * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. * tx_fifo_len: This too is an array of 8. Each element defines the number of * Tx descriptors that can be associated with each corresponding FIFO. - * intr_type: This defines the type of interrupt. The values can be 0(INTA), - * 1(MSI), 2(MSI_X). Default value is '0(INTA)' - * lro: Specifies whether to enable Large Receive Offload (LRO) or not. - * Possible values '1' for enable '0' for disable. Default is '0' - * lro_max_pkts: This parameter defines maximum number of packets can be - * aggregated as a single large packet ************************************************************************/ #include @@ -77,7 +70,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.14.2" +#define DRV_VERSION "2.0.11.2" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; @@ -113,14 +106,18 @@ static inline int RXD_IS_UP2DT(RxD_t *rxdp) #define LOW 2 static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) { + int level = 0; mac_info_t *mac_control; mac_control = &sp->mac_control; - if (rxb_size <= rxd_count[sp->rxd_mode]) - return PANIC; - else if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) - return LOW; - return 0; + if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) { + level = LOW; + if (rxb_size <= rxd_count[sp->rxd_mode]) { + level = PANIC; + } + } + + return level; } /* Ethtool related variables and Macros. */ @@ -139,11 +136,7 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { {"tmac_mcst_frms"}, {"tmac_bcst_frms"}, {"tmac_pause_ctrl_frms"}, - {"tmac_ttl_octets"}, - {"tmac_ucst_frms"}, - {"tmac_nucst_frms"}, {"tmac_any_err_frms"}, - {"tmac_ttl_less_fb_octets"}, {"tmac_vld_ip_octets"}, {"tmac_vld_ip"}, {"tmac_drop_ip"}, @@ -158,27 +151,13 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { {"rmac_vld_mcst_frms"}, {"rmac_vld_bcst_frms"}, {"rmac_in_rng_len_err_frms"}, - {"rmac_out_rng_len_err_frms"}, {"rmac_long_frms"}, {"rmac_pause_ctrl_frms"}, - {"rmac_unsup_ctrl_frms"}, - {"rmac_ttl_octets"}, - {"rmac_accepted_ucst_frms"}, - {"rmac_accepted_nucst_frms"}, {"rmac_discarded_frms"}, - {"rmac_drop_events"}, - {"rmac_ttl_less_fb_octets"}, - {"rmac_ttl_frms"}, {"rmac_usized_frms"}, {"rmac_osized_frms"}, {"rmac_frag_frms"}, {"rmac_jabber_frms"}, - {"rmac_ttl_64_frms"}, - {"rmac_ttl_65_127_frms"}, - {"rmac_ttl_128_255_frms"}, - {"rmac_ttl_256_511_frms"}, - {"rmac_ttl_512_1023_frms"}, - {"rmac_ttl_1024_1518_frms"}, {"rmac_ip"}, {"rmac_ip_octets"}, {"rmac_hdr_err_ip"}, @@ -187,82 +166,12 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { {"rmac_tcp"}, {"rmac_udp"}, {"rmac_err_drp_udp"}, - {"rmac_xgmii_err_sym"}, - {"rmac_frms_q0"}, - {"rmac_frms_q1"}, - {"rmac_frms_q2"}, - {"rmac_frms_q3"}, - {"rmac_frms_q4"}, - {"rmac_frms_q5"}, - {"rmac_frms_q6"}, - {"rmac_frms_q7"}, - {"rmac_full_q0"}, - {"rmac_full_q1"}, - {"rmac_full_q2"}, - {"rmac_full_q3"}, - {"rmac_full_q4"}, - {"rmac_full_q5"}, - {"rmac_full_q6"}, - {"rmac_full_q7"}, {"rmac_pause_cnt"}, - {"rmac_xgmii_data_err_cnt"}, - {"rmac_xgmii_ctrl_err_cnt"}, {"rmac_accepted_ip"}, {"rmac_err_tcp"}, - {"rd_req_cnt"}, - {"new_rd_req_cnt"}, - {"new_rd_req_rtry_cnt"}, - {"rd_rtry_cnt"}, - {"wr_rtry_rd_ack_cnt"}, - {"wr_req_cnt"}, - {"new_wr_req_cnt"}, - {"new_wr_req_rtry_cnt"}, - {"wr_rtry_cnt"}, - {"wr_disc_cnt"}, - {"rd_rtry_wr_ack_cnt"}, - {"txp_wr_cnt"}, - {"txd_rd_cnt"}, - {"txd_wr_cnt"}, - {"rxd_rd_cnt"}, - {"rxd_wr_cnt"}, - {"txf_rd_cnt"}, - {"rxf_wr_cnt"}, - {"rmac_ttl_1519_4095_frms"}, - {"rmac_ttl_4096_8191_frms"}, - {"rmac_ttl_8192_max_frms"}, - {"rmac_ttl_gt_max_frms"}, - {"rmac_osized_alt_frms"}, - {"rmac_jabber_alt_frms"}, - {"rmac_gt_max_alt_frms"}, - {"rmac_vlan_frms"}, - {"rmac_len_discard"}, - {"rmac_fcs_discard"}, - {"rmac_pf_discard"}, - {"rmac_da_discard"}, - {"rmac_red_discard"}, - {"rmac_rts_discard"}, - {"rmac_ingm_full_discard"}, - {"link_fault_cnt"}, {"\n DRIVER STATISTICS"}, {"single_bit_ecc_errs"}, {"double_bit_ecc_errs"}, - {"parity_err_cnt"}, - {"serious_err_cnt"}, - {"soft_reset_cnt"}, - {"fifo_full_cnt"}, - {"ring_full_cnt"}, - ("alarm_transceiver_temp_high"), - ("alarm_transceiver_temp_low"), - ("alarm_laser_bias_current_high"), - ("alarm_laser_bias_current_low"), - ("alarm_laser_output_power_high"), - ("alarm_laser_output_power_low"), - ("warn_transceiver_temp_high"), - ("warn_transceiver_temp_low"), - ("warn_laser_bias_current_high"), - ("warn_laser_bias_current_low"), - ("warn_laser_output_power_high"), - ("warn_laser_output_power_low"), ("lro_aggregated_pkts"), ("lro_flush_both_count"), ("lro_out_of_sequence_pkts"), @@ -311,7 +220,9 @@ static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) * the XAUI. */ +#define SWITCH_SIGN 0xA5A5A5A5A5A5A5A5ULL #define END_SIGN 0x0 + static const u64 herc_act_dtx_cfg[] = { /* Set address */ 0x8000051536750000ULL, 0x80000515367500E0ULL, @@ -333,19 +244,37 @@ static const u64 herc_act_dtx_cfg[] = { END_SIGN }; +static const u64 xena_mdio_cfg[] = { + /* Reset PMA PLL */ + 0xC001010000000000ULL, 0xC0010100000000E0ULL, + 0xC0010100008000E4ULL, + /* Remove Reset from PMA PLL */ + 0xC001010000000000ULL, 0xC0010100000000E0ULL, + 0xC0010100000000E4ULL, + END_SIGN +}; + static const u64 xena_dtx_cfg[] = { - /* Set address */ 0x8000051500000000ULL, 0x80000515000000E0ULL, - /* Write data */ - 0x80000515D9350004ULL, 0x80000515D93500E4ULL, - /* Set address */ - 0x8001051500000000ULL, 0x80010515000000E0ULL, - /* Write data */ - 0x80010515001E0004ULL, 0x80010515001E00E4ULL, - /* Set address */ + 0x80000515D93500E4ULL, 0x8001051500000000ULL, + 0x80010515000000E0ULL, 0x80010515001E00E4ULL, 0x8002051500000000ULL, 0x80020515000000E0ULL, - /* Write data */ - 0x80020515F2100004ULL, 0x80020515F21000E4ULL, + 0x80020515F21000E4ULL, + /* Set PADLOOPBACKN */ + 0x8002051500000000ULL, 0x80020515000000E0ULL, + 0x80020515B20000E4ULL, 0x8003051500000000ULL, + 0x80030515000000E0ULL, 0x80030515B20000E4ULL, + 0x8004051500000000ULL, 0x80040515000000E0ULL, + 0x80040515B20000E4ULL, 0x8005051500000000ULL, + 0x80050515000000E0ULL, 0x80050515B20000E4ULL, + SWITCH_SIGN, + /* Remove PADLOOPBACKN */ + 0x8002051500000000ULL, 0x80020515000000E0ULL, + 0x80020515F20000E4ULL, 0x8003051500000000ULL, + 0x80030515000000E0ULL, 0x80030515F20000E4ULL, + 0x8004051500000000ULL, 0x80040515000000E0ULL, + 0x80040515F20000E4ULL, 0x8005051500000000ULL, + 0x80050515000000E0ULL, 0x80050515F20000E4ULL, END_SIGN }; @@ -374,15 +303,15 @@ static const u64 fix_mac[] = { /* Module Loadable parameters. */ static unsigned int tx_fifo_num = 1; static unsigned int tx_fifo_len[MAX_TX_FIFOS] = - {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; + {[0 ...(MAX_TX_FIFOS - 1)] = 0 }; static unsigned int rx_ring_num = 1; static unsigned int rx_ring_sz[MAX_RX_RINGS] = - {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT}; + {[0 ...(MAX_RX_RINGS - 1)] = 0 }; static unsigned int rts_frm_len[MAX_RX_RINGS] = {[0 ...(MAX_RX_RINGS - 1)] = 0 }; static unsigned int rx_ring_mode = 1; static unsigned int use_continuous_tx_intrs = 1; -static unsigned int rmac_pause_time = 0x100; +static unsigned int rmac_pause_time = 65535; static unsigned int mc_pause_threshold_q0q3 = 187; static unsigned int mc_pause_threshold_q4q7 = 187; static unsigned int shared_splits; @@ -620,6 +549,11 @@ static int init_shared_mem(struct s2io_nic *nic) rx_blocks->block_dma_addr + (rxd_size[nic->rxd_mode] * l); } + + mac_control->rings[i].rx_blocks[j].block_virt_addr = + tmp_v_addr; + mac_control->rings[i].rx_blocks[j].block_dma_addr = + tmp_p_addr; } /* Interlinking all Rx Blocks */ for (j = 0; j < blk_cnt; j++) { @@ -838,21 +772,7 @@ static int s2io_verify_pci_mode(nic_t *nic) return mode; } -#define NEC_VENID 0x1033 -#define NEC_DEVID 0x0125 -static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) -{ - struct pci_dev *tdev = NULL; - while ((tdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { - if ((tdev->vendor == NEC_VENID) && (tdev->device == NEC_DEVID)){ - if (tdev->bus == s2io_pdev->bus->parent) - return 1; - } - } - return 0; -} -int bus_speed[8] = {33, 133, 133, 200, 266, 133, 200, 266}; /** * s2io_print_pci_mode - */ @@ -869,14 +789,6 @@ static int s2io_print_pci_mode(nic_t *nic) if ( val64 & PCI_MODE_UNKNOWN_MODE) return -1; /* Unknown PCI mode */ - config->bus_speed = bus_speed[mode]; - - if (s2io_on_nec_bridge(nic->pdev)) { - DBG_PRINT(ERR_DBG, "%s: Device is on PCI-E bus\n", - nic->dev->name); - return mode; - } - if (val64 & PCI_MODE_32_BITS) { DBG_PRINT(ERR_DBG, "%s: Device is on 32 bit ", nic->dev->name); } else { @@ -886,27 +798,35 @@ static int s2io_print_pci_mode(nic_t *nic) switch(mode) { case PCI_MODE_PCI_33: DBG_PRINT(ERR_DBG, "33MHz PCI bus\n"); + config->bus_speed = 33; break; case PCI_MODE_PCI_66: DBG_PRINT(ERR_DBG, "66MHz PCI bus\n"); + config->bus_speed = 133; break; case PCI_MODE_PCIX_M1_66: DBG_PRINT(ERR_DBG, "66MHz PCIX(M1) bus\n"); + config->bus_speed = 133; /* Herc doubles the clock rate */ break; case PCI_MODE_PCIX_M1_100: DBG_PRINT(ERR_DBG, "100MHz PCIX(M1) bus\n"); + config->bus_speed = 200; break; case PCI_MODE_PCIX_M1_133: DBG_PRINT(ERR_DBG, "133MHz PCIX(M1) bus\n"); + config->bus_speed = 266; break; case PCI_MODE_PCIX_M2_66: DBG_PRINT(ERR_DBG, "133MHz PCIX(M2) bus\n"); + config->bus_speed = 133; break; case PCI_MODE_PCIX_M2_100: DBG_PRINT(ERR_DBG, "200MHz PCIX(M2) bus\n"); + config->bus_speed = 200; break; case PCI_MODE_PCIX_M2_133: DBG_PRINT(ERR_DBG, "266MHz PCIX(M2) bus\n"); + config->bus_speed = 266; break; default: return -1; /* Unsupported bus speed */ @@ -934,7 +854,7 @@ static int init_nic(struct s2io_nic *nic) int i, j; mac_info_t *mac_control; struct config_param *config; - int dtx_cnt = 0; + int mdio_cnt = 0, dtx_cnt = 0; unsigned long long mem_share; int mem_size; @@ -981,6 +901,20 @@ static int init_nic(struct s2io_nic *nic) val64 = dev->mtu; writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); + /* + * Configuring the XAUI Interface of Xena. + * *************************************** + * To Configure the Xena's XAUI, one has to write a series + * of 64 bit values into two registers in a particular + * sequence. Hence a macro 'SWITCH_SIGN' has been defined + * which will be defined in the array of configuration values + * (xena_dtx_cfg & xena_mdio_cfg) at appropriate places + * to switch writing from one regsiter to another. We continue + * writing these values until we encounter the 'END_SIGN' macro. + * For example, After making a series of 21 writes into + * dtx_control register the 'SWITCH_SIGN' appears and hence we + * start writing into mdio_control until we encounter END_SIGN. + */ if (nic->device_type & XFRAME_II_DEVICE) { while (herc_act_dtx_cfg[dtx_cnt] != END_SIGN) { SPECIAL_REG_WRITE(herc_act_dtx_cfg[dtx_cnt], @@ -990,11 +924,35 @@ static int init_nic(struct s2io_nic *nic) dtx_cnt++; } } else { - while (xena_dtx_cfg[dtx_cnt] != END_SIGN) { - SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt], - &bar0->dtx_control, UF); - val64 = readq(&bar0->dtx_control); - dtx_cnt++; + while (1) { + dtx_cfg: + while (xena_dtx_cfg[dtx_cnt] != END_SIGN) { + if (xena_dtx_cfg[dtx_cnt] == SWITCH_SIGN) { + dtx_cnt++; + goto mdio_cfg; + } + SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt], + &bar0->dtx_control, UF); + val64 = readq(&bar0->dtx_control); + dtx_cnt++; + } + mdio_cfg: + while (xena_mdio_cfg[mdio_cnt] != END_SIGN) { + if (xena_mdio_cfg[mdio_cnt] == SWITCH_SIGN) { + mdio_cnt++; + goto dtx_cfg; + } + SPECIAL_REG_WRITE(xena_mdio_cfg[mdio_cnt], + &bar0->mdio_control, UF); + val64 = readq(&bar0->mdio_control); + mdio_cnt++; + } + if ((xena_dtx_cfg[dtx_cnt] == END_SIGN) && + (xena_mdio_cfg[mdio_cnt] == END_SIGN)) { + break; + } else { + goto dtx_cfg; + } } } @@ -1036,6 +994,11 @@ static int init_nic(struct s2io_nic *nic) } } + /* Enable Tx FIFO partition 0. */ + val64 = readq(&bar0->tx_fifo_partition_0); + val64 |= BIT(0); /* To enable the FIFO partition. */ + writeq(val64, &bar0->tx_fifo_partition_0); + /* * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug * SXE-008 TRANSMIT DMA ARBITRATION ISSUE. @@ -1214,11 +1177,6 @@ static int init_nic(struct s2io_nic *nic) break; } - /* Enable Tx FIFO partition 0. */ - val64 = readq(&bar0->tx_fifo_partition_0); - val64 |= (TX_FIFO_PARTITION_EN); - writeq(val64, &bar0->tx_fifo_partition_0); - /* Filling the Rx round robin registers as per the * number of Rings and steering based on QoS. */ @@ -1587,26 +1545,19 @@ static int init_nic(struct s2io_nic *nic) val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits); writeq(val64, &bar0->pic_control); - if (nic->config.bus_speed == 266) { - writeq(TXREQTO_VAL(0x7f) | TXREQTO_EN, &bar0->txreqtimeout); - writeq(0x0, &bar0->read_retry_delay); - writeq(0x0, &bar0->write_retry_delay); - } - /* * Programming the Herc to split every write transaction * that does not start on an ADB to reduce disconnects. */ if (nic->device_type == XFRAME_II_DEVICE) { - 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)); - writeq(val64, &bar0->pic_control2); + val64 = WREQ_SPLIT_MASK_SET_MASK(255); + writeq(val64, &bar0->wreq_split_mask); } - if (strstr(nic->product_name, "CX4")) { - val64 = TMAC_AVG_IPG(0x17); - writeq(val64, &bar0->tmac_avg_ipg); + + /* Setting Link stability period to 64 ms */ + if (nic->device_type == XFRAME_II_DEVICE) { + val64 = MISC_LINK_STABILITY_PRD(3); + writeq(val64, &bar0->misc_control); } return SUCCESS; @@ -1997,10 +1948,6 @@ static int start_nic(struct s2io_nic *nic) val64 |= PRC_CTRL_RC_ENABLED; else val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3; - if (nic->device_type == XFRAME_II_DEVICE) - val64 |= PRC_CTRL_GROUP_READS; - val64 &= ~PRC_CTRL_RXD_BACKOFF_INTERVAL(0xFFFFFF); - val64 |= PRC_CTRL_RXD_BACKOFF_INTERVAL(0x1000); writeq(val64, &bar0->prc_ctrl_n[i]); } @@ -2071,13 +2018,6 @@ static int start_nic(struct s2io_nic *nic) val64 |= ADAPTER_EOI_TX_ON; writeq(val64, &bar0->adapter_control); - if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { - /* - * Dont see link state interrupts initally on some switches, - * so directly scheduling the link state task here. - */ - schedule_work(&nic->set_link_task); - } /* SXE-002: Initialize link and activity LED */ subid = nic->pdev->subsystem_device; if (((subid & 0xFF) >= 0x07) && @@ -2089,6 +2029,12 @@ static int start_nic(struct s2io_nic *nic) writeq(val64, (void __iomem *)bar0 + 0x2700); } + /* + * Don't see link state interrupts on certain switches, so + * directly scheduling a link state task from here. + */ + schedule_work(&nic->set_link_task); + return SUCCESS; } /** @@ -2188,7 +2134,7 @@ static void stop_nic(struct s2io_nic *nic) { XENA_dev_config_t __iomem *bar0 = nic->bar0; register u64 val64 = 0; - u16 interruptible; + u16 interruptible, i; mac_info_t *mac_control; struct config_param *config; @@ -2201,10 +2147,12 @@ static void stop_nic(struct s2io_nic *nic) interruptible |= TX_MAC_INTR | RX_MAC_INTR; en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); - /* Clearing Adapter_En bit of ADAPTER_CONTROL Register */ - val64 = readq(&bar0->adapter_control); - val64 &= ~(ADAPTER_CNTL_EN); - writeq(val64, &bar0->adapter_control); + /* Disable PRCs */ + for (i = 0; i < config->rx_ring_num; i++) { + val64 = readq(&bar0->prc_ctrl_n[i]); + val64 &= ~((u64) PRC_CTRL_RC_ENABLED); + writeq(val64, &bar0->prc_ctrl_n[i]); + } } static int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) @@ -2283,12 +2231,13 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) alloc_cnt = mac_control->rings[ring_no].pkt_cnt - atomic_read(&nic->rx_bufs_left[ring_no]); - block_no1 = mac_control->rings[ring_no].rx_curr_get_info.block_index; - off1 = mac_control->rings[ring_no].rx_curr_get_info.offset; while (alloc_tab < alloc_cnt) { block_no = mac_control->rings[ring_no].rx_curr_put_info. block_index; + block_no1 = mac_control->rings[ring_no].rx_curr_get_info. + block_index; off = mac_control->rings[ring_no].rx_curr_put_info.offset; + off1 = mac_control->rings[ring_no].rx_curr_get_info.offset; rxdp = mac_control->rings[ring_no]. rx_blocks[block_no].rxds[off].virt_addr; @@ -2358,9 +2307,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) memset(rxdp, 0, sizeof(RxD1_t)); skb_reserve(skb, NET_IP_ALIGN); ((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); + (nic->pdev, skb->data, size, PCI_DMA_FROMDEVICE); + rxdp->Control_2 &= (~MASK_BUFFER0_SIZE_1); + rxdp->Control_2 |= SET_BUFFER0_SIZE_1(size); } else if (nic->rxd_mode >= RXD_MODE_3A) { /* @@ -2567,7 +2516,7 @@ static int s2io_poll(struct net_device *dev, int *budget) mac_info_t *mac_control; struct config_param *config; XENA_dev_config_t __iomem *bar0 = nic->bar0; - u64 val64 = 0xFFFFFFFFFFFFFFFFULL; + u64 val64; int i; atomic_inc(&nic->isr_cnt); @@ -2579,8 +2528,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; + val64 = readq(&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]); @@ -2605,8 +2554,7 @@ static int s2io_poll(struct net_device *dev, int *budget) } } /* Re enable the Rx interrupts. */ - writeq(0x0, &bar0->rx_traffic_mask); - val64 = readl(&bar0->rx_traffic_mask); + en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); atomic_dec(&nic->isr_cnt); return 0; @@ -2718,7 +2666,6 @@ static void rx_intr_handler(ring_info_t *ring_data) ((RxD3_t*)rxdp)->Buffer2_ptr, dev->mtu, PCI_DMA_FROMDEVICE); } - prefetch(skb->data); rx_osm_handler(ring_data, rxdp); get_info.offset++; ring_data->rx_curr_get_info.offset = get_info.offset; @@ -2790,10 +2737,6 @@ static void tx_intr_handler(fifo_info_t *fifo_data) if (txdlp->Control_1 & TXD_T_CODE) { unsigned long long err; err = txdlp->Control_1 & TXD_T_CODE; - if (err & 0x1) { - nic->mac_control.stats_info->sw_stat. - parity_err_cnt++; - } if ((err >> 48) == 0xA) { DBG_PRINT(TX_DBG, "TxD returned due \ to loss of link\n"); @@ -2817,8 +2760,7 @@ to loss of link\n"); dev_kfree_skb_irq(skb); get_info.offset++; - if (get_info.offset == get_info.fifo_len + 1) - get_info.offset = 0; + get_info.offset %= get_info.fifo_len + 1; txdlp = (TxD_t *) fifo_data->list_info [get_info.offset].list_virt_addr; fifo_data->tx_curr_get_info.offset = @@ -2831,256 +2773,6 @@ to loss of link\n"); spin_unlock(&nic->tx_lock); } -/** - * s2io_mdio_write - Function to write in to MDIO registers - * @mmd_type : MMD type value (PMA/PMD/WIS/PCS/PHYXS) - * @addr : address value - * @value : data value - * @dev : pointer to net_device structure - * Description: - * This function is used to write values to the MDIO registers - * NONE - */ -static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device *dev) -{ - u64 val64 = 0x0; - nic_t *sp = dev->priv; - XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; - - //address transaction - val64 = val64 | MDIO_MMD_INDX_ADDR(addr) - | MDIO_MMD_DEV_ADDR(mmd_type) - | MDIO_MMS_PRT_ADDR(0x0); - writeq(val64, &bar0->mdio_control); - val64 = val64 | MDIO_CTRL_START_TRANS(0xE); - writeq(val64, &bar0->mdio_control); - udelay(100); - - //Data transaction - val64 = 0x0; - val64 = val64 | MDIO_MMD_INDX_ADDR(addr) - | MDIO_MMD_DEV_ADDR(mmd_type) - | MDIO_MMS_PRT_ADDR(0x0) - | MDIO_MDIO_DATA(value) - | MDIO_OP(MDIO_OP_WRITE_TRANS); - writeq(val64, &bar0->mdio_control); - val64 = val64 | MDIO_CTRL_START_TRANS(0xE); - writeq(val64, &bar0->mdio_control); - udelay(100); - - val64 = 0x0; - val64 = val64 | MDIO_MMD_INDX_ADDR(addr) - | MDIO_MMD_DEV_ADDR(mmd_type) - | MDIO_MMS_PRT_ADDR(0x0) - | MDIO_OP(MDIO_OP_READ_TRANS); - writeq(val64, &bar0->mdio_control); - val64 = val64 | MDIO_CTRL_START_TRANS(0xE); - writeq(val64, &bar0->mdio_control); - udelay(100); - -} - -/** - * s2io_mdio_read - Function to write in to MDIO registers - * @mmd_type : MMD type value (PMA/PMD/WIS/PCS/PHYXS) - * @addr : address value - * @dev : pointer to net_device structure - * Description: - * This function is used to read values to the MDIO registers - * NONE - */ -static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev) -{ - u64 val64 = 0x0; - u64 rval64 = 0x0; - nic_t *sp = dev->priv; - XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; - - /* address transaction */ - val64 = val64 | MDIO_MMD_INDX_ADDR(addr) - | MDIO_MMD_DEV_ADDR(mmd_type) - | MDIO_MMS_PRT_ADDR(0x0); - writeq(val64, &bar0->mdio_control); - val64 = val64 | MDIO_CTRL_START_TRANS(0xE); - writeq(val64, &bar0->mdio_control); - udelay(100); - - /* Data transaction */ - val64 = 0x0; - val64 = val64 | MDIO_MMD_INDX_ADDR(addr) - | MDIO_MMD_DEV_ADDR(mmd_type) - | MDIO_MMS_PRT_ADDR(0x0) - | MDIO_OP(MDIO_OP_READ_TRANS); - writeq(val64, &bar0->mdio_control); - val64 = val64 | MDIO_CTRL_START_TRANS(0xE); - writeq(val64, &bar0->mdio_control); - udelay(100); - - /* Read the value from regs */ - rval64 = readq(&bar0->mdio_control); - rval64 = rval64 & 0xFFFF0000; - rval64 = rval64 >> 16; - return rval64; -} -/** - * s2io_chk_xpak_counter - Function to check the status of the xpak counters - * @counter : couter value to be updated - * @flag : flag to indicate the status - * @type : counter type - * Description: - * This function is to check the status of the xpak counters value - * NONE - */ - -static void s2io_chk_xpak_counter(u64 *counter, u64 * regs_stat, u32 index, u16 flag, u16 type) -{ - u64 mask = 0x3; - u64 val64; - int i; - for(i = 0; i 0) - { - *counter = *counter + 1; - val64 = *regs_stat & mask; - val64 = val64 >> (index * 0x2); - val64 = val64 + 1; - if(val64 == 3) - { - switch(type) - { - case 1: - DBG_PRINT(ERR_DBG, "Take Xframe NIC out of " - "service. Excessive temperatures may " - "result in premature transceiver " - "failure \n"); - break; - case 2: - DBG_PRINT(ERR_DBG, "Take Xframe NIC out of " - "service Excessive bias currents may " - "indicate imminent laser diode " - "failure \n"); - break; - case 3: - DBG_PRINT(ERR_DBG, "Take Xframe NIC out of " - "service Excessive laser output " - "power may saturate far-end " - "receiver\n"); - break; - default: - DBG_PRINT(ERR_DBG, "Incorrect XPAK Alarm " - "type \n"); - } - val64 = 0x0; - } - val64 = val64 << (index * 0x2); - *regs_stat = (*regs_stat & (~mask)) | (val64); - - } else { - *regs_stat = *regs_stat & (~mask); - } -} - -/** - * s2io_updt_xpak_counter - Function to update the xpak counters - * @dev : pointer to net_device struct - * Description: - * This function is to upate the status of the xpak counters value - * NONE - */ -static void s2io_updt_xpak_counter(struct net_device *dev) -{ - u16 flag = 0x0; - u16 type = 0x0; - u16 val16 = 0x0; - u64 val64 = 0x0; - u64 addr = 0x0; - - nic_t *sp = dev->priv; - StatInfo_t *stat_info = sp->mac_control.stats_info; - - /* Check the communication with the MDIO slave */ - addr = 0x0000; - val64 = 0x0; - val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); - if((val64 == 0xFFFF) || (val64 == 0x0000)) - { - DBG_PRINT(ERR_DBG, "ERR: MDIO slave access failed - " - "Returned %llx\n", (unsigned long long)val64); - return; - } - - /* Check for the expecte value of 2040 at PMA address 0x0000 */ - if(val64 != 0x2040) - { - DBG_PRINT(ERR_DBG, "Incorrect value at PMA address 0x0000 - "); - DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x2040\n", - (unsigned long long)val64); - return; - } - - /* Loading the DOM register to MDIO register */ - addr = 0xA100; - s2io_mdio_write(MDIO_MMD_PMA_DEV_ADDR, addr, val16, dev); - val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); - - /* Reading the Alarm flags */ - addr = 0xA070; - val64 = 0x0; - val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); - - flag = CHECKBIT(val64, 0x7); - type = 1; - s2io_chk_xpak_counter(&stat_info->xpak_stat.alarm_transceiver_temp_high, - &stat_info->xpak_stat.xpak_regs_stat, - 0x0, flag, type); - - if(CHECKBIT(val64, 0x6)) - stat_info->xpak_stat.alarm_transceiver_temp_low++; - - flag = CHECKBIT(val64, 0x3); - type = 2; - s2io_chk_xpak_counter(&stat_info->xpak_stat.alarm_laser_bias_current_high, - &stat_info->xpak_stat.xpak_regs_stat, - 0x2, flag, type); - - if(CHECKBIT(val64, 0x2)) - stat_info->xpak_stat.alarm_laser_bias_current_low++; - - flag = CHECKBIT(val64, 0x1); - type = 3; - s2io_chk_xpak_counter(&stat_info->xpak_stat.alarm_laser_output_power_high, - &stat_info->xpak_stat.xpak_regs_stat, - 0x4, flag, type); - - if(CHECKBIT(val64, 0x0)) - stat_info->xpak_stat.alarm_laser_output_power_low++; - - /* Reading the Warning flags */ - addr = 0xA074; - val64 = 0x0; - val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); - - if(CHECKBIT(val64, 0x7)) - stat_info->xpak_stat.warn_transceiver_temp_high++; - - if(CHECKBIT(val64, 0x6)) - stat_info->xpak_stat.warn_transceiver_temp_low++; - - if(CHECKBIT(val64, 0x3)) - stat_info->xpak_stat.warn_laser_bias_current_high++; - - if(CHECKBIT(val64, 0x2)) - stat_info->xpak_stat.warn_laser_bias_current_low++; - - if(CHECKBIT(val64, 0x1)) - stat_info->xpak_stat.warn_laser_output_power_high++; - - if(CHECKBIT(val64, 0x0)) - stat_info->xpak_stat.warn_laser_output_power_low++; -} - /** * alarm_intr_handler - Alarm Interrrupt handler * @nic: device private variable @@ -3098,18 +2790,6 @@ static void alarm_intr_handler(struct s2io_nic *nic) struct net_device *dev = (struct net_device *) nic->dev; XENA_dev_config_t __iomem *bar0 = nic->bar0; register u64 val64 = 0, err_reg = 0; - u64 cnt; - int i; - 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) { - /* waiting for an hour */ - nic->mac_control.stats_info->xpak_stat.xpak_timer_count++; - } else { - s2io_updt_xpak_counter(dev); - /* reset the count to zero */ - nic->mac_control.stats_info->xpak_stat.xpak_timer_count = 0; - } /* Handling link status change error Intr */ if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { @@ -3136,8 +2816,6 @@ static void alarm_intr_handler(struct s2io_nic *nic) MC_ERR_REG_MIRI_ECC_DB_ERR_1)) { netif_stop_queue(dev); schedule_work(&nic->rst_timer_task); - nic->mac_control.stats_info->sw_stat. - soft_reset_cnt++; } } } else { @@ -3149,13 +2827,11 @@ static void alarm_intr_handler(struct s2io_nic *nic) /* In case of a serious error, the device will be Reset. */ val64 = readq(&bar0->serr_source); if (val64 & SERR_SOURCE_ANY) { - nic->mac_control.stats_info->sw_stat.serious_err_cnt++; DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); DBG_PRINT(ERR_DBG, "serious error %llx!!\n", (unsigned long long)val64); netif_stop_queue(dev); schedule_work(&nic->rst_timer_task); - nic->mac_control.stats_info->sw_stat.soft_reset_cnt++; } /* @@ -3173,35 +2849,6 @@ static void alarm_intr_handler(struct s2io_nic *nic) ac = readq(&bar0->adapter_control); schedule_work(&nic->set_link_task); } - /* Check for data parity error */ - val64 = readq(&bar0->pic_int_status); - if (val64 & PIC_INT_GPIO) { - val64 = readq(&bar0->gpio_int_reg); - if (val64 & GPIO_INT_REG_DP_ERR_INT) { - nic->mac_control.stats_info->sw_stat.parity_err_cnt++; - schedule_work(&nic->rst_timer_task); - nic->mac_control.stats_info->sw_stat.soft_reset_cnt++; - } - } - - /* Check for ring full counter */ - if (nic->device_type & XFRAME_II_DEVICE) { - val64 = readq(&bar0->ring_bump_counter1); - for (i=0; i<4; i++) { - cnt = ( val64 & vBIT(0xFFFF,(i*16),16)); - cnt >>= 64 - ((i+1)*16); - nic->mac_control.stats_info->sw_stat.ring_full_cnt - += cnt; - } - - val64 = readq(&bar0->ring_bump_counter2); - for (i=0; i<4; i++) { - cnt = ( val64 & vBIT(0xFFFF,(i*16),16)); - cnt >>= 64 - ((i+1)*16); - nic->mac_control.stats_info->sw_stat.ring_full_cnt - += cnt; - } - } /* Other type of interrupts are not being handled now, TODO */ } @@ -3217,26 +2864,23 @@ static void alarm_intr_handler(struct s2io_nic *nic) * SUCCESS on success and FAILURE on failure. */ -static int wait_for_cmd_complete(void *addr, u64 busy_bit) +static int wait_for_cmd_complete(nic_t * sp) { + XENA_dev_config_t __iomem *bar0 = sp->bar0; int ret = FAILURE, cnt = 0; u64 val64; while (TRUE) { - val64 = readq(addr); - if (!(val64 & busy_bit)) { + val64 = readq(&bar0->rmac_addr_cmd_mem); + if (!(val64 & RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { ret = SUCCESS; break; } - - if(in_interrupt()) - mdelay(50); - else - msleep(50); - + msleep(50); if (cnt++ > 10) break; } + return ret; } @@ -3275,9 +2919,6 @@ static void s2io_reset(nic_t * sp) * PCI write to sw_reset register is done by this time. */ msleep(250); - if (strstr(sp->product_name, "CX4")) { - msleep(750); - } /* Restore the PCI state saved during initialization. */ pci_restore_state(sp->pdev); @@ -3496,7 +3137,7 @@ static void restore_xmsi_data(nic_t *nic) u64 val64; int i; - for (i=0; i< nic->avail_msix_vectors; i++) { + for (i=0; i< MAX_REQUESTED_MSI_X; i++) { writeq(nic->msix_info[i].addr, &bar0->xmsi_address); writeq(nic->msix_info[i].data, &bar0->xmsi_data); val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); @@ -3515,7 +3156,7 @@ static void store_xmsi_data(nic_t *nic) int i; /* Store and display */ - for (i=0; i< nic->avail_msix_vectors; i++) { + for (i=0; i< MAX_REQUESTED_MSI_X; i++) { val64 = (BIT(15) | vBIT(i, 26, 6)); writeq(val64, &bar0->xmsi_access); if (wait_for_msix_trans(nic, i)) { @@ -3643,24 +3284,15 @@ static int s2io_enable_msi_x(nic_t *nic) writeq(tx_mat, &bar0->tx_mat0_n[7]); } - nic->avail_msix_vectors = 0; ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X); - /* We fail init if error or we get less vectors than min required */ - if (ret >= (nic->config.tx_fifo_num + nic->config.rx_ring_num + 1)) { - nic->avail_msix_vectors = ret; - ret = pci_enable_msix(nic->pdev, nic->entries, ret); - } if (ret) { DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); kfree(nic->entries); kfree(nic->s2io_entries); nic->entries = NULL; nic->s2io_entries = NULL; - nic->avail_msix_vectors = 0; return -ENOMEM; } - if (!nic->avail_msix_vectors) - nic->avail_msix_vectors = MAX_REQUESTED_MSI_X; /* * To enable MSI-X, MSI also needs to be enabled, due to a bug @@ -3693,6 +3325,8 @@ static int s2io_open(struct net_device *dev) { nic_t *sp = dev->priv; int err = 0; + int i; + u16 msi_control; /* Temp variable */ /* * Make sure you have link off by default every time @@ -3702,14 +3336,11 @@ static int s2io_open(struct net_device *dev) sp->last_link_state = 0; /* Initialize H/W and enable interrupts */ - err = s2io_card_up(sp); - if (err) { + if (s2io_card_up(sp)) { DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", dev->name); - if (err == -ENODEV) - goto hw_init_failed; - else - goto hw_enable_failed; + err = -ENODEV; + goto hw_init_failed; } /* Store the values of the MSIX table in the nic_t structure */ @@ -3726,8 +3357,6 @@ failed\n", dev->name); } } if (sp->intr_type == MSI_X) { - int i; - for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { sprintf(sp->desc1, "%s:MSI-X-%d-TX", @@ -3780,26 +3409,24 @@ failed\n", dev->name, i); isr_registration_failed: del_timer_sync(&sp->alarm_timer); if (sp->intr_type == MSI_X) { - int i; - u16 msi_control; /* Temp variable */ - - for (i=1; (sp->s2io_entries[i].in_use == + if (sp->device_type == XFRAME_II_DEVICE) { + for (i=1; (sp->s2io_entries[i].in_use == MSIX_REGISTERED_SUCCESS); i++) { - int vector = sp->entries[i].vector; - void *arg = sp->s2io_entries[i].arg; + int vector = sp->entries[i].vector; + void *arg = sp->s2io_entries[i].arg; - free_irq(vector, arg); - } - pci_disable_msix(sp->pdev); + free_irq(vector, arg); + } + pci_disable_msix(sp->pdev); - /* Temp */ - pci_read_config_word(sp->pdev, 0x42, &msi_control); - msi_control &= 0xFFFE; /* Disable MSI */ - pci_write_config_word(sp->pdev, 0x42, msi_control); + /* Temp */ + pci_read_config_word(sp->pdev, 0x42, &msi_control); + msi_control &= 0xFFFE; /* Disable MSI */ + pci_write_config_word(sp->pdev, 0x42, msi_control); + } } else if (sp->intr_type == MSI) pci_disable_msi(sp->pdev); -hw_enable_failed: s2io_reset(sp); hw_init_failed: if (sp->intr_type == MSI_X) { @@ -3827,12 +3454,35 @@ failed\n", dev->name, i); static int s2io_close(struct net_device *dev) { nic_t *sp = dev->priv; + int i; + u16 msi_control; flush_scheduled_work(); netif_stop_queue(dev); /* Reset card, kill tasklet and free Tx and Rx buffers. */ - s2io_card_down(sp, 1); + s2io_card_down(sp); + + if (sp->intr_type == MSI_X) { + if (sp->device_type == XFRAME_II_DEVICE) { + for (i=1; (sp->s2io_entries[i].in_use == + MSIX_REGISTERED_SUCCESS); i++) { + int vector = sp->entries[i].vector; + void *arg = sp->s2io_entries[i].arg; + free_irq(vector, arg); + } + pci_read_config_word(sp->pdev, 0x42, &msi_control); + msi_control &= 0xFFFE; /* Disable MSI */ + pci_write_config_word(sp->pdev, 0x42, msi_control); + + pci_disable_msix(sp->pdev); + } + } + else { + free_irq(sp->pdev->irq, dev); + if (sp->intr_type == MSI) + pci_disable_msi(sp->pdev); + } sp->device_close_flag = TRUE; /* Device is shut down. */ return 0; } @@ -3895,8 +3545,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; /* Avoid "put" pointer going beyond "get" pointer */ - if (txdp->Host_Control || - ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { + if (txdp->Host_Control || (((put_off + 1) % queue_len) == get_off)) { DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n"); netif_stop_queue(dev); dev_kfree_skb(skb); @@ -4006,13 +3655,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) mmiowb(); put_off++; - if (put_off == mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1) - put_off = 0; + put_off %= mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; mac_control->fifos[queue].tx_curr_put_info.offset = put_off; /* Avoid "put" pointer going beyond "get" pointer */ - if (((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { - sp->mac_control.stats_info->sw_stat.fifo_full_cnt++; + if (((put_off + 1) % queue_len) == get_off) { DBG_PRINT(TX_DBG, "No free TxDs for xmit, Put: 0x%x Get:0x%x\n", put_off, get_off); @@ -4148,6 +3795,7 @@ s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs) atomic_dec(&sp->isr_cnt); return IRQ_HANDLED; } + static void s2io_txpic_intr_handle(nic_t *sp) { XENA_dev_config_t __iomem *bar0 = sp->bar0; @@ -4158,56 +3806,41 @@ static void s2io_txpic_intr_handle(nic_t *sp) val64 = readq(&bar0->gpio_int_reg); if ((val64 & GPIO_INT_REG_LINK_DOWN) && (val64 & GPIO_INT_REG_LINK_UP)) { - /* - * This is unstable state so clear both up/down - * interrupt and adapter to re-evaluate the link state. - */ val64 |= GPIO_INT_REG_LINK_DOWN; val64 |= GPIO_INT_REG_LINK_UP; writeq(val64, &bar0->gpio_int_reg); + goto masking; + } + + if (((sp->last_link_state == LINK_UP) && + (val64 & GPIO_INT_REG_LINK_DOWN)) || + ((sp->last_link_state == LINK_DOWN) && + (val64 & GPIO_INT_REG_LINK_UP))) { val64 = readq(&bar0->gpio_int_mask); - val64 &= ~(GPIO_INT_MASK_LINK_UP | - GPIO_INT_MASK_LINK_DOWN); + val64 |= GPIO_INT_MASK_LINK_DOWN; + val64 |= GPIO_INT_MASK_LINK_UP; writeq(val64, &bar0->gpio_int_mask); + s2io_set_link((unsigned long)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; - - 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); - 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); - } +masking: + if (sp->last_link_state == LINK_UP) { + /*enable down interrupt */ + val64 = readq(&bar0->gpio_int_mask); + /* unmasks link down intr */ + val64 &= ~GPIO_INT_MASK_LINK_DOWN; + /* masks link up intr */ + val64 |= GPIO_INT_MASK_LINK_UP; + writeq(val64, &bar0->gpio_int_mask); + } else { + /*enable UP Interrupt */ + val64 = readq(&bar0->gpio_int_mask); + /* unmasks link up interrupt */ + val64 &= ~GPIO_INT_MASK_LINK_UP; + /* masks link down interrupt */ + val64 |= GPIO_INT_MASK_LINK_DOWN; + writeq(val64, &bar0->gpio_int_mask); } } - val64 = readq(&bar0->gpio_int_mask); } /** @@ -4230,7 +3863,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) nic_t *sp = dev->priv; XENA_dev_config_t __iomem *bar0 = sp->bar0; int i; - u64 reason = 0, val64, org_mask; + u64 reason = 0, val64; mac_info_t *mac_control; struct config_param *config; @@ -4254,41 +3887,43 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) return IRQ_NONE; } - val64 = 0xFFFFFFFFFFFFFFFFULL; - /* Store current mask before masking all interrupts */ - org_mask = readq(&bar0->general_int_mask); - writeq(val64, &bar0->general_int_mask); - #ifdef CONFIG_S2IO_NAPI if (reason & GEN_INTR_RXTRAFFIC) { if (netif_rx_schedule_prep(dev)) { - writeq(val64, &bar0->rx_traffic_mask); + en_dis_able_nic_intrs(sp, RX_TRAFFIC_INTR, + DISABLE_INTRS); __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]); + /* If Intr is because of Rx Traffic */ + if (reason & GEN_INTR_RXTRAFFIC) { + /* + * 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. + */ + val64 = 0xFFFFFFFFFFFFFFFFULL; + 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. - */ - writeq(val64, &bar0->tx_traffic_int); + /* If Intr is because of Tx Traffic */ + if (reason & GEN_INTR_TXTRAFFIC) { + /* + * 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. + */ + val64 = 0xFFFFFFFFFFFFFFFFULL; + writeq(val64, &bar0->tx_traffic_int); - for (i = 0; i < config->tx_fifo_num; i++) - tx_intr_handler(&mac_control->fifos[i]); + for (i = 0; i < config->tx_fifo_num; i++) + tx_intr_handler(&mac_control->fifos[i]); + } if (reason & GEN_INTR_TXPIC) s2io_txpic_intr_handle(sp); @@ -4314,7 +3949,6 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) DBG_PRINT(ERR_DBG, " in ISR!!\n"); clear_bit(0, (&sp->tasklet_status)); atomic_dec(&sp->isr_cnt); - writeq(org_mask, &bar0->general_int_mask); return IRQ_HANDLED; } clear_bit(0, (&sp->tasklet_status)); @@ -4330,7 +3964,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) } } #endif - writeq(org_mask, &bar0->general_int_mask); + atomic_dec(&sp->isr_cnt); return IRQ_HANDLED; } @@ -4433,8 +4067,7 @@ static void s2io_set_multicast(struct net_device *dev) RMAC_ADDR_CMD_MEM_OFFSET(MAC_MC_ALL_MC_ADDR_OFFSET); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ - wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING); + wait_for_cmd_complete(sp); sp->m_cast_flg = 1; sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET; @@ -4449,8 +4082,7 @@ static void s2io_set_multicast(struct net_device *dev) RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ - wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING); + wait_for_cmd_complete(sp); sp->m_cast_flg = 0; sp->all_multi_pos = 0; @@ -4515,8 +4147,7 @@ static void s2io_set_multicast(struct net_device *dev) writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait for command completes */ - if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { + if (wait_for_cmd_complete(sp)) { DBG_PRINT(ERR_DBG, "%s: Adding ", dev->name); DBG_PRINT(ERR_DBG, "Multicasts failed\n"); @@ -4546,8 +4177,7 @@ static void s2io_set_multicast(struct net_device *dev) writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait for command completes */ - if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { + if (wait_for_cmd_complete(sp)) { DBG_PRINT(ERR_DBG, "%s: Adding ", dev->name); DBG_PRINT(ERR_DBG, "Multicasts failed\n"); @@ -4592,8 +4222,7 @@ static int s2io_set_mac_addr(struct net_device *dev, u8 * addr) RMAC_ADDR_CMD_MEM_OFFSET(0); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ - if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { + if (wait_for_cmd_complete(sp)) { DBG_PRINT(ERR_DBG, "%s: set_mac_addr failed\n", dev->name); return FAILURE; } @@ -4990,44 +4619,6 @@ static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) } return ret; } -static void s2io_vpd_read(nic_t *nic) -{ - u8 vpd_data[256],data; - int i=0, cnt, fail = 0; - int vpd_addr = 0x80; - - if (nic->device_type == XFRAME_II_DEVICE) { - strcpy(nic->product_name, "Xframe II 10GbE network adapter"); - vpd_addr = 0x80; - } - else { - strcpy(nic->product_name, "Xframe I 10GbE network adapter"); - vpd_addr = 0x50; - } - - for (i = 0; i < 256; i +=4 ) { - pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); - pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data); - pci_write_config_byte(nic->pdev, (vpd_addr + 3), 0); - for (cnt = 0; cnt <5; cnt++) { - msleep(2); - pci_read_config_byte(nic->pdev, (vpd_addr + 3), &data); - if (data == 0x80) - break; - } - if (cnt >= 5) { - DBG_PRINT(ERR_DBG, "Read of VPD data failed\n"); - fail = 1; - break; - } - pci_read_config_dword(nic->pdev, (vpd_addr + 4), - (u32 *)&vpd_data[i]); - } - 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]); - } -} /** * s2io_ethtool_geeprom - reads the value stored in the Eeprom. @@ -5340,10 +4931,8 @@ static int s2io_link_test(nic_t * sp, uint64_t * data) u64 val64; val64 = readq(&bar0->adapter_status); - if(!(LINK_IS_UP(val64))) + if (val64 & ADAPTER_STATUS_RMAC_LOCAL_FAULT) *data = 1; - else - *data = 0; return 0; } @@ -5523,6 +5112,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev, int i = 0; nic_t *sp = dev->priv; StatInfo_t *stat_info = sp->mac_control.stats_info; + u64 tmp; s2io_updt_stats(sp); tmp_stats[i++] = @@ -5539,19 +5129,9 @@ static void s2io_get_ethtool_stats(struct net_device *dev, (u64)le32_to_cpu(stat_info->tmac_bcst_frms_oflow) << 32 | le32_to_cpu(stat_info->tmac_bcst_frms); tmp_stats[i++] = le64_to_cpu(stat_info->tmac_pause_ctrl_frms); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->tmac_ttl_octets_oflow) << 32 | - le32_to_cpu(stat_info->tmac_ttl_octets); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->tmac_ucst_frms_oflow) << 32 | - le32_to_cpu(stat_info->tmac_ucst_frms); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->tmac_nucst_frms_oflow) << 32 | - le32_to_cpu(stat_info->tmac_nucst_frms); tmp_stats[i++] = (u64)le32_to_cpu(stat_info->tmac_any_err_frms_oflow) << 32 | le32_to_cpu(stat_info->tmac_any_err_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->tmac_ttl_less_fb_octets); tmp_stats[i++] = le64_to_cpu(stat_info->tmac_vld_ip_octets); tmp_stats[i++] = (u64)le32_to_cpu(stat_info->tmac_vld_ip_oflow) << 32 | @@ -5583,27 +5163,11 @@ static void s2io_get_ethtool_stats(struct net_device *dev, (u64)le32_to_cpu(stat_info->rmac_vld_bcst_frms_oflow) << 32 | le32_to_cpu(stat_info->rmac_vld_bcst_frms); tmp_stats[i++] = le32_to_cpu(stat_info->rmac_in_rng_len_err_frms); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_out_rng_len_err_frms); tmp_stats[i++] = le64_to_cpu(stat_info->rmac_long_frms); tmp_stats[i++] = le64_to_cpu(stat_info->rmac_pause_ctrl_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_unsup_ctrl_frms); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->rmac_ttl_octets_oflow) << 32 | - le32_to_cpu(stat_info->rmac_ttl_octets); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->rmac_accepted_ucst_frms_oflow) - << 32 | le32_to_cpu(stat_info->rmac_accepted_ucst_frms); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->rmac_accepted_nucst_frms_oflow) - << 32 | le32_to_cpu(stat_info->rmac_accepted_nucst_frms); tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_discarded_frms_oflow) << 32 | le32_to_cpu(stat_info->rmac_discarded_frms); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->rmac_drop_events_oflow) - << 32 | le32_to_cpu(stat_info->rmac_drop_events); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_less_fb_octets); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_frms); tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_usized_frms_oflow) << 32 | le32_to_cpu(stat_info->rmac_usized_frms); @@ -5616,129 +5180,40 @@ static void s2io_get_ethtool_stats(struct net_device *dev, tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_jabber_frms_oflow) << 32 | le32_to_cpu(stat_info->rmac_jabber_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_64_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_65_127_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_128_255_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_256_511_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_512_1023_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_1024_1518_frms); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->rmac_ip_oflow) << 32 | + tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_ip_oflow) << 32 | le32_to_cpu(stat_info->rmac_ip); tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ip_octets); tmp_stats[i++] = le32_to_cpu(stat_info->rmac_hdr_err_ip); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->rmac_drop_ip_oflow) << 32 | + tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_drop_ip_oflow) << 32 | le32_to_cpu(stat_info->rmac_drop_ip); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->rmac_icmp_oflow) << 32 | + tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_icmp_oflow) << 32 | le32_to_cpu(stat_info->rmac_icmp); tmp_stats[i++] = le64_to_cpu(stat_info->rmac_tcp); - tmp_stats[i++] = - (u64)le32_to_cpu(stat_info->rmac_udp_oflow) << 32 | + tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_udp_oflow) << 32 | le32_to_cpu(stat_info->rmac_udp); tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_err_drp_udp_oflow) << 32 | le32_to_cpu(stat_info->rmac_err_drp_udp); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_xgmii_err_sym); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q0); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q1); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q2); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q3); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q4); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q5); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q6); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q7); - tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q0); - tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q1); - tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q2); - tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q3); - tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q4); - tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q5); - tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q6); - tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q7); tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_pause_cnt_oflow) << 32 | le32_to_cpu(stat_info->rmac_pause_cnt); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_xgmii_data_err_cnt); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_xgmii_ctrl_err_cnt); tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_accepted_ip_oflow) << 32 | le32_to_cpu(stat_info->rmac_accepted_ip); tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp); - tmp_stats[i++] = le32_to_cpu(stat_info->rd_req_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->new_rd_req_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->new_rd_req_rtry_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->rd_rtry_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->wr_rtry_rd_ack_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->wr_req_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->new_wr_req_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->new_wr_req_rtry_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->wr_rtry_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->wr_disc_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->rd_rtry_wr_ack_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->txp_wr_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->txd_rd_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->txd_wr_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->rxd_rd_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->rxd_wr_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->txf_rd_cnt); - tmp_stats[i++] = le32_to_cpu(stat_info->rxf_wr_cnt); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_1519_4095_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_4096_8191_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_8192_max_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_gt_max_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_osized_alt_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_jabber_alt_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_gt_max_alt_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_vlan_frms); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_len_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_fcs_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pf_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_da_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_red_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_rts_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ingm_full_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->link_fault_cnt); tmp_stats[i++] = 0; tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs; tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; - tmp_stats[i++] = stat_info->sw_stat.parity_err_cnt; - tmp_stats[i++] = stat_info->sw_stat.serious_err_cnt; - tmp_stats[i++] = stat_info->sw_stat.soft_reset_cnt; - tmp_stats[i++] = stat_info->sw_stat.fifo_full_cnt; - tmp_stats[i++] = stat_info->sw_stat.ring_full_cnt; - tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_high; - tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_low; - tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_high; - tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_low; - tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_output_power_high; - tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_output_power_low; - tmp_stats[i++] = stat_info->xpak_stat.warn_transceiver_temp_high; - tmp_stats[i++] = stat_info->xpak_stat.warn_transceiver_temp_low; - tmp_stats[i++] = stat_info->xpak_stat.warn_laser_bias_current_high; - tmp_stats[i++] = stat_info->xpak_stat.warn_laser_bias_current_low; - tmp_stats[i++] = stat_info->xpak_stat.warn_laser_output_power_high; - tmp_stats[i++] = stat_info->xpak_stat.warn_laser_output_power_low; tmp_stats[i++] = stat_info->sw_stat.clubbed_frms_cnt; tmp_stats[i++] = stat_info->sw_stat.sending_both; tmp_stats[i++] = stat_info->sw_stat.outof_sequence_pkts; tmp_stats[i++] = stat_info->sw_stat.flush_max_pkts; + tmp = 0; if (stat_info->sw_stat.num_aggregations) { - u64 tmp = stat_info->sw_stat.sum_avg_pkts_aggregated; - int count = 0; - /* - * Since 64-bit divide does not work on all platforms, - * do repeated subtraction. - */ - while (tmp >= stat_info->sw_stat.num_aggregations) { - tmp -= stat_info->sw_stat.num_aggregations; - count++; - } - tmp_stats[i++] = count; + tmp = stat_info->sw_stat.sum_avg_pkts_aggregated; + do_div(tmp, stat_info->sw_stat.num_aggregations); } - else - tmp_stats[i++] = 0; + tmp_stats[i++] = tmp; } static int s2io_ethtool_get_regs_len(struct net_device *dev) @@ -5876,7 +5351,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) dev->mtu = new_mtu; if (netif_running(dev)) { - s2io_card_down(sp, 0); + s2io_card_down(sp); netif_stop_queue(dev); if (s2io_card_up(sp)) { DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", @@ -6014,172 +5489,12 @@ static void s2io_set_link(unsigned long data) clear_bit(0, &(nic->link_state)); } -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; - - if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) { - /* allocate skb */ - if (*skb) { - DBG_PRINT(INFO_DBG, "SKB is not NULL\n"); - /* - * As Rx frame are not going to be processed, - * using same mapped address for the Rxd - * buffer pointer - */ - ((RxD1_t*)rxdp)->Buffer0_ptr = *temp0; - } else { - *skb = dev_alloc_skb(size); - if (!(*skb)) { - DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); - DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); - return -ENOMEM ; - } - /* storing the mapped addr in a temp variable - * such it will be used for next rxd whose - * Host Control is NULL - */ - ((RxD1_t*)rxdp)->Buffer0_ptr = *temp0 = - pci_map_single( sp->pdev, (*skb)->data, - size - NET_IP_ALIGN, - PCI_DMA_FROMDEVICE); - rxdp->Host_Control = (unsigned long) (*skb); - } - } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { - /* Two buffer Mode */ - if (*skb) { - ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; - ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0; - ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; - } else { - *skb = dev_alloc_skb(size); - ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = - pci_map_single(sp->pdev, (*skb)->data, - dev->mtu + 4, - PCI_DMA_FROMDEVICE); - ((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 */ - ((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) { - ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0; - ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; - ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; - } else { - *skb = dev_alloc_skb(size); - - ((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 */ - ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1 = - pci_map_single( sp->pdev, (*skb)->data, - l3l4hdr_size + 4, - PCI_DMA_FROMDEVICE); - /* - * skb_shinfo(skb)->frag_list will have L4 - * data payload - */ - skb_shinfo(*skb)->frag_list = dev_alloc_skb(dev->mtu + - ALIGN_SIZE); - if (skb_shinfo(*skb)->frag_list == NULL) { - DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \ - failed\n ", dev->name); - return -ENOMEM ; - } - frag_list = skb_shinfo(*skb)->frag_list; - frag_list->next = NULL; - /* - * Buffer-2 receives L4 data payload - */ - ((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(nic_t *sp, RxD_t *rxdp, int size) -{ - struct net_device *dev = sp->dev; - if (sp->rxd_mode == RXD_MODE_1) { - rxdp->Control_2 = SET_BUFFER0_SIZE_1( size - NET_IP_ALIGN); - } else if (sp->rxd_mode == RXD_MODE_3B) { - rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); - rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); - rxdp->Control_2 |= SET_BUFFER2_SIZE_3( dev->mtu + 4); - } else { - rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); - rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); - rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu); - } -} - -static int rxd_owner_bit_reset(nic_t *sp) -{ - int i, j, k, blk_cnt = 0, size; - mac_info_t * mac_control = &sp->mac_control; - struct config_param *config = &sp->config; - struct net_device *dev = sp->dev; - RxD_t *rxdp = NULL; - struct sk_buff *skb = NULL; - buffAdd_t *ba = NULL; - u64 temp0_64 = 0, temp1_64 = 0, temp2_64 = 0; - - /* Calculate the size based on ring mode */ - size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE + - HEADER_802_2_SIZE + HEADER_SNAP_SIZE; - if (sp->rxd_mode == RXD_MODE_1) - size += NET_IP_ALIGN; - else if (sp->rxd_mode == RXD_MODE_3B) - size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; - else - size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4; - - for (i = 0; i < config->rx_ring_num; i++) { - blk_cnt = config->rx_cfg[i].num_rxd / - (rxd_count[sp->rxd_mode] +1); - - for (j = 0; j < blk_cnt; j++) { - for (k = 0; k < rxd_count[sp->rxd_mode]; k++) { - rxdp = mac_control->rings[i]. - rx_blocks[j].rxds[k].virt_addr; - if(sp->rxd_mode >= RXD_MODE_3A) - ba = &mac_control->rings[i].ba[j][k]; - set_rxd_buffer_pointer(sp, rxdp, ba, - &skb,(u64 *)&temp0_64, - (u64 *)&temp1_64, - (u64 *)&temp2_64, size); - - set_rxd_buffer_size(sp, rxdp, size); - wmb(); - /* flip the Ownership bit to Hardware */ - rxdp->Control_1 |= RXD_OWN_XENA; - } - } - } - return 0; - -} - -static void s2io_card_down(nic_t * sp, int flag) +static void s2io_card_down(nic_t * sp) { int cnt = 0; XENA_dev_config_t __iomem *bar0 = sp->bar0; unsigned long flags; register u64 val64 = 0; - struct net_device *dev = sp->dev; del_timer_sync(&sp->alarm_timer); /* If s2io_set_link task is executing, wait till it completes. */ @@ -6190,51 +5505,12 @@ static void s2io_card_down(nic_t * sp, int flag) /* disable Tx and Rx traffic on the NIC */ stop_nic(sp); - if (flag) { - if (sp->intr_type == MSI_X) { - int i; - u16 msi_control; - - for (i=1; (sp->s2io_entries[i].in_use == - MSIX_REGISTERED_SUCCESS); i++) { - int vector = sp->entries[i].vector; - void *arg = sp->s2io_entries[i].arg; - - free_irq(vector, arg); - } - pci_read_config_word(sp->pdev, 0x42, &msi_control); - msi_control &= 0xFFFE; /* Disable MSI */ - pci_write_config_word(sp->pdev, 0x42, msi_control); - pci_disable_msix(sp->pdev); - } else { - free_irq(sp->pdev->irq, dev); - if (sp->intr_type == MSI) - pci_disable_msi(sp->pdev); - } - } - /* Waiting till all Interrupt handlers are complete */ - cnt = 0; - do { - msleep(10); - if (!atomic_read(&sp->isr_cnt)) - break; - cnt++; - } while(cnt < 5); /* Kill tasklet. */ tasklet_kill(&sp->task); /* Check if the device is Quiescent and then Reset the NIC */ do { - /* As per the HW requirement we need to replenish the - * receive buffer to avoid the ring bump. Since there is - * no intention of processing the Rx frame at this pointwe are - * just settting the ownership bit of rxd in Each Rx - * ring to HW and set the appropriate buffer size - * based on the ring mode - */ - rxd_owner_bit_reset(sp); - val64 = readq(&bar0->adapter_status); if (verify_xena_quiescence(sp, val64, sp->device_enabled_once)) { break; @@ -6252,6 +5528,15 @@ static void s2io_card_down(nic_t * sp, int flag) } while (1); s2io_reset(sp); + /* Waiting till all Interrupt handlers are complete */ + cnt = 0; + do { + msleep(10); + if (!atomic_read(&sp->isr_cnt)) + break; + cnt++; + } while(cnt < 5); + spin_lock_irqsave(&sp->tx_lock, flags); /* Free all Tx buffers */ free_tx_buffers(sp); @@ -6352,7 +5637,7 @@ static void s2io_restart_nic(unsigned long data) struct net_device *dev = (struct net_device *) data; nic_t *sp = dev->priv; - s2io_card_down(sp, 0); + s2io_card_down(sp); if (s2io_card_up(sp)) { DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", dev->name); @@ -6382,7 +5667,6 @@ static void s2io_tx_watchdog(struct net_device *dev) if (netif_carrier_ok(dev)) { schedule_work(&sp->rst_timer_task); - sp->mac_control.stats_info->sw_stat.soft_reset_cnt++; } } @@ -6411,33 +5695,18 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) ((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; lro_t *lro; skb->dev = dev; - - if (err) { - /* Check for parity error */ - if (err & 0x1) { - sp->mac_control.stats_info->sw_stat.parity_err_cnt++; - } - - /* - * Drop the packet if bad transfer code. Exception being - * 0x5, which could be due to unsupported IPv6 extension header. - * In this case, we let stack handle the packet. - * Note that in this case, since checksum will be incorrect, - * stack will validate the same. - */ - if (err && ((err >> 48) != 0x5)) { - DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", - dev->name, err); - sp->stats.rx_crc_errors++; - dev_kfree_skb(skb); - atomic_dec(&sp->rx_bufs_left[ring_no]); - rxdp->Host_Control = 0; - return 0; - } + if (rxdp->Control_1 & RXD_T_CODE) { + unsigned long long err = rxdp->Control_1 & RXD_T_CODE; + DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", + dev->name, err); + dev_kfree_skb(skb); + sp->stats.rx_crc_errors++; + atomic_dec(&sp->rx_bufs_left[ring_no]); + rxdp->Host_Control = 0; + return 0; } /* Updating statistics */ @@ -6523,9 +5792,6 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) clear_lro_session(lro); goto send_up; case 0: /* sessions exceeded */ - case -1: /* non-TCP or not - * L2 aggregatable - */ case 5: /* * First pkt in session not * L3/L4 aggregatable @@ -6652,6 +5918,13 @@ static void s2io_init_pci(nic_t * sp) pci_write_config_word(sp->pdev, PCI_COMMAND, (pci_cmd | PCI_COMMAND_PARITY)); pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); + + /* Forcibly disabling relaxed ordering capability of the card. */ + pcix_cmd &= 0xfffd; + pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, + pcix_cmd); + pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, + &(pcix_cmd)); } MODULE_AUTHOR("Raghavendra Koushik "); @@ -6681,55 +5954,6 @@ module_param(intr_type, int, 0); module_param(lro, int, 0); module_param(lro_max_pkts, int, 0); -static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) -{ - if ( tx_fifo_num > 8) { - DBG_PRINT(ERR_DBG, "s2io: Requested number of Tx fifos not " - "supported\n"); - DBG_PRINT(ERR_DBG, "s2io: Default to 8 Tx fifos\n"); - tx_fifo_num = 8; - } - if ( rx_ring_num > 8) { - DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not " - "supported\n"); - DBG_PRINT(ERR_DBG, "s2io: Default to 8 Rx rings\n"); - rx_ring_num = 8; - } -#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" - "MSI/MSI-X. Defaulting to INTA\n"); - *dev_intr_type = INTA; - } -#else - if (*dev_intr_type > MSI_X) { - DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " - "Defaulting to INTA\n"); - *dev_intr_type = INTA; - } -#endif - if ((*dev_intr_type == MSI_X) && - ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && - (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { - DBG_PRINT(ERR_DBG, "s2io: Xframe I does not support MSI_X. " - "Defaulting to INTA\n"); - *dev_intr_type = INTA; - } - 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"); - rx_ring_mode = 3; - } - return SUCCESS; -} - /** * s2io_init_nic - Initialization of the adapter . * @pdev : structure containing the PCI related information of the device. @@ -6760,8 +5984,15 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) int mode; u8 dev_intr_type = intr_type; - if ((ret = s2io_verify_parm(pdev, &dev_intr_type))) - return ret; +#ifdef CONFIG_S2IO_NAPI + if (dev_intr_type != INTA) { + DBG_PRINT(ERR_DBG, "NAPI cannot be enabled when MSI/MSI-X \ +is enabled. Defaulting to INTA\n"); + dev_intr_type = INTA; + } + else + DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n"); +#endif if ((ret = pci_enable_device(pdev))) { DBG_PRINT(ERR_DBG, @@ -6786,6 +6017,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) pci_disable_device(pdev); return -ENOMEM; } + + if ((dev_intr_type == MSI_X) && + ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && + (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { + DBG_PRINT(ERR_DBG, "Xframe I does not support MSI_X. \ +Defaulting to INTA\n"); + dev_intr_type = INTA; + } if (dev_intr_type != MSI_X) { if (pci_request_regions(pdev, s2io_driver_name)) { DBG_PRINT(ERR_DBG, "Request Regions failed\n"), @@ -6861,6 +6100,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) config = &sp->config; /* Tx side parameters. */ + if (tx_fifo_len[0] == 0) + tx_fifo_len[0] = DEFAULT_FIFO_LEN; /* Default value. */ config->tx_fifo_num = tx_fifo_num; for (i = 0; i < MAX_TX_FIFOS; i++) { config->tx_cfg[i].fifo_len = tx_fifo_len[i]; @@ -6884,6 +6125,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) config->max_txds = MAX_SKB_FRAGS + 2; /* Rx side parameters. */ + if (rx_ring_sz[0] == 0) + rx_ring_sz[0] = SMALL_BLK_CNT; /* Default value. */ config->rx_ring_num = rx_ring_num; for (i = 0; i < MAX_RX_RINGS; i++) { config->rx_cfg[i].num_rxd = rx_ring_sz[i] * @@ -7024,8 +6267,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET); writeq(val64, &bar0->rmac_addr_cmd_mem); - wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING); + wait_for_cmd_complete(sp); + tmp64 = readq(&bar0->rmac_addr_data0_mem); mac_down = (u32) tmp64; mac_up = (u32) (tmp64 >> 32); @@ -7079,63 +6322,82 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) ret = -ENODEV; goto register_failed; } - s2io_vpd_read(sp); - DBG_PRINT(ERR_DBG, "%s: Neterion %s",dev->name, sp->product_name); - DBG_PRINT(ERR_DBG, "(rev %d), Driver version %s\n", + + if (sp->device_type & XFRAME_II_DEVICE) { + DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ", + dev->name); + DBG_PRINT(ERR_DBG, "(rev %d), Version %s", get_xena_rev_id(sp->pdev), s2io_driver_version); - DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); - DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " - "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, + switch(sp->intr_type) { + case INTA: + DBG_PRINT(ERR_DBG, ", Intr type INTA"); + break; + case MSI: + DBG_PRINT(ERR_DBG, ", Intr type MSI"); + break; + case MSI_X: + DBG_PRINT(ERR_DBG, ", Intr type MSI-X"); + break; + } + + DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); + DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", 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]); - if (sp->device_type & XFRAME_II_DEVICE) { mode = s2io_print_pci_mode(sp); if (mode < 0) { - DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n"); + DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode "); ret = -EBADSLT; - unregister_netdev(dev); goto set_swap_failed; } + } else { + DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ", + dev->name); + DBG_PRINT(ERR_DBG, "(rev %d), Version %s", + get_xena_rev_id(sp->pdev), + s2io_driver_version); + switch(sp->intr_type) { + case INTA: + DBG_PRINT(ERR_DBG, ", Intr type INTA"); + break; + case MSI: + DBG_PRINT(ERR_DBG, ", Intr type MSI"); + break; + case MSI_X: + DBG_PRINT(ERR_DBG, ", Intr type MSI-X"); + break; + } + DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); + DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", + 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]); } - switch(sp->rxd_mode) { - case RXD_MODE_1: - DBG_PRINT(ERR_DBG, "%s: 1-Buffer receive mode enabled\n", - dev->name); - break; - case RXD_MODE_3B: - DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n", - dev->name); - break; - case RXD_MODE_3A: - DBG_PRINT(ERR_DBG, "%s: 3-Buffer receive mode enabled\n", - dev->name); - break; - } -#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); - break; - case MSI: - DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n", dev->name); - break; - case MSI_X: - DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); - break; - } + if (sp->rxd_mode == RXD_MODE_3B) + DBG_PRINT(ERR_DBG, "%s: 2-Buffer mode support has been " + "enabled\n",dev->name); + if (sp->rxd_mode == RXD_MODE_3A) + DBG_PRINT(ERR_DBG, "%s: 3-Buffer mode support has been " + "enabled\n",dev->name); + if (sp->lro) DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", - dev->name); + dev->name); /* Initialize device name */ - sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name); + strcpy(sp->name, dev->name); + if (sp->device_type & XFRAME_II_DEVICE) + strcat(sp->name, ": Neterion Xframe II 10GbE adapter"); + else + strcat(sp->name, ": Neterion Xframe I 10GbE adapter"); /* Initialize bimodal Interrupts */ sp->config.bimodal = bimodal; diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index 3203732a668d..0a0b5b29d81e 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -31,8 +31,6 @@ #define SUCCESS 0 #define FAILURE -1 -#define CHECKBIT(value, nbit) (value & (1 << nbit)) - /* Maximum time to flicker LED when asked to identify NIC using ethtool */ #define MAX_FLICKER_TIME 60000 /* 60 Secs */ @@ -80,11 +78,6 @@ static int debug_level = ERR_DBG; typedef struct { unsigned long long single_ecc_errs; unsigned long long double_ecc_errs; - unsigned long long parity_err_cnt; - unsigned long long serious_err_cnt; - unsigned long long soft_reset_cnt; - unsigned long long fifo_full_cnt; - unsigned long long ring_full_cnt; /* LRO statistics */ unsigned long long clubbed_frms_cnt; unsigned long long sending_both; @@ -94,25 +87,6 @@ typedef struct { unsigned long long num_aggregations; } swStat_t; -/* Xpak releated alarm and warnings */ -typedef struct { - u64 alarm_transceiver_temp_high; - u64 alarm_transceiver_temp_low; - u64 alarm_laser_bias_current_high; - u64 alarm_laser_bias_current_low; - u64 alarm_laser_output_power_high; - u64 alarm_laser_output_power_low; - u64 warn_transceiver_temp_high; - u64 warn_transceiver_temp_low; - u64 warn_laser_bias_current_high; - u64 warn_laser_bias_current_low; - u64 warn_laser_output_power_high; - u64 warn_laser_output_power_low; - u64 xpak_regs_stat; - u32 xpak_timer_count; -} xpakStat_t; - - /* The statistics block of Xena */ typedef struct stat_block { /* Tx MAC statistics counters. */ @@ -289,9 +263,7 @@ typedef struct stat_block { u32 rmac_accepted_ip_oflow; u32 reserved_14; u32 link_fault_cnt; - u8 buffer[20]; swStat_t sw_stat; - xpakStat_t xpak_stat; } StatInfo_t; /* @@ -687,8 +659,7 @@ typedef struct { } usr_addr_t; /* Default Tunable parameters of the NIC. */ -#define DEFAULT_FIFO_0_LEN 4096 -#define DEFAULT_FIFO_1_7_LEN 512 +#define DEFAULT_FIFO_LEN 4096 #define SMALL_BLK_CNT 30 #define LARGE_BLK_CNT 100 @@ -761,7 +732,7 @@ struct s2io_nic { int device_close_flag; int device_enabled_once; - char name[60]; + char name[50]; struct tasklet_struct task; volatile unsigned long tasklet_status; @@ -832,8 +803,6 @@ struct s2io_nic { char desc1[35]; char desc2[35]; - int avail_msix_vectors; /* No. of MSI-X vectors granted by system */ - struct msix_info_st msix_info[0x3f]; #define XFRAME_I_DEVICE 1 @@ -855,8 +824,6 @@ struct s2io_nic { spinlock_t rx_lock; atomic_t isr_cnt; u64 *ufo_in_band_v; -#define VPD_PRODUCT_NAME_LEN 50 - u8 product_name[VPD_PRODUCT_NAME_LEN]; }; #define RESET_ERROR 1; @@ -881,32 +848,28 @@ static inline void writeq(u64 val, void __iomem *addr) writel((u32) (val), addr); writel((u32) (val >> 32), (addr + 4)); } -#endif -/* - * Some registers have to be written in a particular order to - * expect correct hardware operation. The macro SPECIAL_REG_WRITE - * is used to perform such ordered writes. Defines UF (Upper First) - * and LF (Lower First) will be used to specify the required write order. +/* In 32 bit modes, some registers have to be written in a + * particular order to expect correct hardware operation. The + * macro SPECIAL_REG_WRITE is used to perform such ordered + * writes. Defines UF (Upper First) and LF (Lower First) will + * be used to specify the required write order. */ #define UF 1 #define LF 2 static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order) { - u32 ret; - if (order == LF) { writel((u32) (val), addr); - ret = readl(addr); writel((u32) (val >> 32), (addr + 4)); - ret = readl(addr + 4); } else { writel((u32) (val >> 32), (addr + 4)); - ret = readl(addr + 4); writel((u32) (val), addr); - ret = readl(addr); } } +#else +#define SPECIAL_REG_WRITE(val, addr, dummy) writeq(val, addr) +#endif /* Interrupt related values of Xena */ @@ -1002,7 +965,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag); static struct ethtool_ops netdev_ethtool_ops; static void s2io_set_link(unsigned long data); static int s2io_set_swapper(nic_t * sp); -static void s2io_card_down(nic_t *nic, int flag); +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 void restore_xmsi_data(nic_t *nic); diff --git a/trunk/drivers/net/sis900.c b/trunk/drivers/net/sis900.c index d05874172209..b82191d2bee1 100644 --- a/trunk/drivers/net/sis900.c +++ b/trunk/drivers/net/sis900.c @@ -1,6 +1,6 @@ /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux. Copyright 1999 Silicon Integrated System Corporation - Revision: 1.08.10 Apr. 2 2006 + Revision: 1.08.09 Sep. 19 2005 Modified from the driver which is originally written by Donald Becker. @@ -17,10 +17,9 @@ SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution, preliminary Rev. 1.0 Jan. 18, 1998 - Rev 1.08.10 Apr. 2 2006 Daniele Venzano add vlan (jumbo packets) support Rev 1.08.09 Sep. 19 2005 Daniele Venzano add Wake on LAN support Rev 1.08.08 Jan. 22 2005 Daniele Venzano use netif_msg for debugging messages - Rev 1.08.07 Nov. 2 2003 Daniele Venzano add suspend/resume support + Rev 1.08.07 Nov. 2 2003 Daniele Venzano add suspend/resume support Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support Rev 1.08.05 Jun. 6 2002 Mufasa Yang bug fix for read_eeprom & Tx descriptor over-boundary Rev 1.08.04 Apr. 25 2002 Mufasa Yang added SiS962 support @@ -78,7 +77,7 @@ #include "sis900.h" #define SIS900_MODULE_NAME "sis900" -#define SIS900_DRV_VERSION "v1.08.10 Apr. 2 2006" +#define SIS900_DRV_VERSION "v1.08.09 Sep. 19 2005" static char version[] __devinitdata = KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n"; @@ -128,7 +127,6 @@ static const struct mii_chip_info { } mii_chip_table[] = { { "SiS 900 Internal MII PHY", 0x001d, 0x8000, LAN }, { "SiS 7014 Physical Layer Solution", 0x0016, 0xf830, LAN }, - { "SiS 900 on Foxconn 661 7MI", 0x0143, 0xBC70, LAN }, { "Altimata AC101LF PHY", 0x0022, 0x5520, LAN }, { "ADM 7001 LAN PHY", 0x002e, 0xcc60, LAN }, { "AMD 79C901 10BASE-T PHY", 0x0000, 0x6B70, LAN }, @@ -1403,11 +1401,6 @@ static void sis900_set_mode (long ioaddr, int speed, int duplex) rx_flags |= RxATX; } -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - /* Can accept Jumbo packet */ - rx_flags |= RxAJAB; -#endif - outl (tx_flags, ioaddr + txcfg); outl (rx_flags, ioaddr + rxcfg); } @@ -1720,26 +1713,18 @@ static int sis900_rx(struct net_device *net_dev) while (rx_status & OWN) { unsigned int rx_size; - unsigned int data_size; if (--rx_work_limit < 0) break; - data_size = rx_status & DSIZE; - rx_size = data_size - CRC_SIZE; - -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - /* ``TOOLONG'' flag means jumbo packet recived. */ - if ((rx_status & TOOLONG) && data_size <= MAX_FRAME_SIZE) - rx_status &= (~ ((unsigned int)TOOLONG)); -#endif + rx_size = (rx_status & DSIZE) - CRC_SIZE; if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) { /* corrupted packet received */ if (netif_msg_rx_err(sis_priv)) printk(KERN_DEBUG "%s: Corrupted packet " - "received, buffer status = 0x%8.8x/%d.\n", - net_dev->name, rx_status, data_size); + "received, buffer status = 0x%8.8x.\n", + net_dev->name, rx_status); sis_priv->stats.rx_errors++; if (rx_status & OVERRUN) sis_priv->stats.rx_over_errors++; diff --git a/trunk/drivers/net/sis900.h b/trunk/drivers/net/sis900.h index 4834e3a15694..50323941e3c0 100644 --- a/trunk/drivers/net/sis900.h +++ b/trunk/drivers/net/sis900.h @@ -310,14 +310,8 @@ enum sis630_revision_id { #define CRC_SIZE 4 #define MAC_HEADER_SIZE 14 -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -#define MAX_FRAME_SIZE (1518 + 4) -#else -#define MAX_FRAME_SIZE 1518 -#endif /* CONFIG_VLAN_802_1Q */ - -#define TX_BUF_SIZE (MAX_FRAME_SIZE+18) -#define RX_BUF_SIZE (MAX_FRAME_SIZE+18) +#define TX_BUF_SIZE 1536 +#define RX_BUF_SIZE 1536 #define NUM_TX_DESC 16 /* Number of Tx descriptor registers. */ #define NUM_RX_DESC 16 /* Number of Rx descriptor registers. */ diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index 5ca5a1b546a1..a70c2b0cc104 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -78,7 +78,8 @@ static const struct pci_device_id skge_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, /* DGE-530T */ + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, @@ -401,7 +402,7 @@ static int skge_set_ring_param(struct net_device *dev, int err; if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE || - p->tx_pending < MAX_SKB_FRAGS+1 || p->tx_pending > MAX_TX_RING_SIZE) + p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE) return -EINVAL; skge->rx_ring.count = p->rx_pending; @@ -2716,7 +2717,8 @@ static int skge_poll(struct net_device *dev, int *budget) if (control & BMU_OWN) break; - skb = skge_rx_get(skge, e, control, rd->status, rd->csum2); + skb = skge_rx_get(skge, e, control, rd->status, + le16_to_cpu(rd->csum2)); if (likely(skb)) { dev->last_rx = jiffies; netif_receive_skb(skb); diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 60779ebf2ff6..227df9876a2c 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -51,7 +51,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.4" +#define DRV_VERSION "1.2" #define PFX DRV_NAME " " /* @@ -79,8 +79,6 @@ #define NAPI_WEIGHT 64 #define PHY_RETRIES 1000 -#define RING_NEXT(x,s) (((x)+1) & ((s)-1)) - static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR @@ -98,14 +96,9 @@ static int disable_msi = 0; module_param(disable_msi, int, 0); MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); -static int idle_timeout = 100; -module_param(idle_timeout, int, 0); -MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)"); - static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, @@ -129,7 +122,6 @@ MODULE_DEVICE_TABLE(pci, sky2_id_table); /* Avoid conditionals by using array */ static const unsigned txqaddr[] = { Q_XA1, Q_XA2 }; static const unsigned rxqaddr[] = { Q_R1, Q_R2 }; -static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 }; /* This driver supports yukon2 chipset only */ static const char *yukon2_name[] = { @@ -236,7 +228,6 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) } if (hw->chip_id == CHIP_ID_YUKON_EC_U) { - sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON); sky2_pci_write32(hw, PCI_DEV_REG3, 0); reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); reg1 &= P_ASPM_CONTROL_MSK; @@ -307,8 +298,7 @@ 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; - if (sky2->autoneg == AUTONEG_ENABLE && - !(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { + if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) { u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | @@ -336,7 +326,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) 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_XL) { ctrl &= ~PHY_M_PC_DSC_MSK; ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; } @@ -452,11 +442,10 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); /* set LED Function Control register */ - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, - (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ - PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ - PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ - PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ + PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ + PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ + PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ /* set Polarity Control register */ gm_phy_write(hw, port, PHY_MARV_PHY_STAT, @@ -470,25 +459,6 @@ 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: - pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - - /* select page 3 to access LED control register */ - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - - /* set LED Function Control register */ - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, - (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ - PHY_M_LEDC_INIT_CTRL(8) | /* 10 Mbps */ - PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ - PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */ - - /* set Blink Rate in LED Timer Control Register */ - gm_phy_write(hw, port, PHY_MARV_INT_MASK, - ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS)); - /* restore page register */ - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); - break; default: /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ @@ -497,21 +467,19 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); } - if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) { + if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { /* apply fixes in PHY AFE */ - pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255); - + gm_phy_write(hw, port, 22, 255); /* increase differential signal amplitude in 10BASE-T */ - gm_phy_write(hw, port, 0x18, 0xaa99); - gm_phy_write(hw, port, 0x17, 0x2011); + gm_phy_write(hw, port, 24, 0xaa99); + gm_phy_write(hw, port, 23, 0x2011); /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ - gm_phy_write(hw, port, 0x18, 0xa204); - gm_phy_write(hw, port, 0x17, 0x2002); + gm_phy_write(hw, port, 24, 0xa204); + gm_phy_write(hw, port, 23, 0x2002); /* set page register to 0 */ - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); + gm_phy_write(hw, port, 22, 0); } else { gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); @@ -585,11 +553,6 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) if (sky2->duplex == DUPLEX_FULL) reg |= GM_GPCR_DUP_FULL; - - /* turn off pause in 10/100mbps half duplex */ - else if (sky2->speed != SPEED_1000 && - hw->chip_id != CHIP_ID_YUKON_EC_U) - sky2->tx_pause = sky2->rx_pause = 0; } else reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; @@ -756,7 +719,7 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2) { struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod; - sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE); + sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE; return le; } @@ -772,7 +735,7 @@ static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2) { struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put; - sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE); + sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE; return le; } @@ -1022,25 +985,7 @@ static int sky2_up(struct net_device *dev) struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; u32 ramsize, rxspace, imask; - int cap, err = -ENOMEM; - struct net_device *otherdev = hw->dev[sky2->port^1]; - - /* - * On dual port PCI-X card, there is an problem where status - * can be received out of order due to split transactions - */ - if (otherdev && netif_running(otherdev) && - (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) { - struct sky2_port *osky2 = netdev_priv(otherdev); - u16 cmd; - - cmd = sky2_pci_read16(hw, cap + PCI_X_CMD); - cmd &= ~PCI_X_CMD_MAX_SPLIT; - sky2_pci_write16(hw, cap + PCI_X_CMD, cmd); - - sky2->rx_csum = 0; - osky2->rx_csum = 0; - } + int err = -ENOMEM; if (netif_msg_ifup(sky2)) printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); @@ -1105,7 +1050,7 @@ static int sky2_up(struct net_device *dev) /* Enable interrupts from phy/mac for port */ imask = sky2_read32(hw, B0_IMSK); - imask |= portirq_msk[port]; + imask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; sky2_write32(hw, B0_IMSK, imask); return 0; @@ -1133,7 +1078,7 @@ static int sky2_up(struct net_device *dev) /* Modular subtraction in ring */ static inline int tx_dist(unsigned tail, unsigned head) { - return (head - tail) & (TX_RING_SIZE - 1); + return (head - tail) % TX_RING_SIZE; } /* Number of list elements available for next tx */ @@ -1310,7 +1255,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) le->opcode = OP_BUFFER | HW_OWNER; fre = sky2->tx_ring - + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE); + + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE; pci_unmap_addr_set(fre, mapaddr, mapping); } @@ -1370,7 +1315,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { struct tx_ring_info *fre; - fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE); + fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE; pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr), skb_shinfo(skb)->frags[i].size, PCI_DMA_TODEVICE); @@ -1456,7 +1401,7 @@ static int sky2_down(struct net_device *dev) /* Disable port IRQ */ imask = sky2_read32(hw, B0_IMSK); - imask &= ~portirq_msk[port]; + imask &= ~(sky2->port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; sky2_write32(hw, B0_IMSK, imask); /* turn off LED's */ @@ -1553,26 +1498,17 @@ 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) { + if (hw->chip_id == CHIP_ID_YUKON_XL) { u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ - - switch(sky2->speed) { - case SPEED_10: - led |= PHY_M_LEDC_INIT_CTRL(7); - break; - - case SPEED_100: - led |= PHY_M_LEDC_STA1_CTRL(7); - break; - - case SPEED_1000: - led |= PHY_M_LEDC_STA0_CTRL(7); - break; - } gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, led); + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ + PHY_M_LEDC_INIT_CTRL(sky2->speed == + SPEED_10 ? 7 : 0) | + PHY_M_LEDC_STA1_CTRL(sky2->speed == + SPEED_100 ? 7 : 0) | + PHY_M_LEDC_STA0_CTRL(sky2->speed == + SPEED_1000 ? 7 : 0)); gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); } @@ -1647,7 +1583,7 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) sky2->speed = sky2_phy_speed(hw, aux); /* Pause bits are offset (9..8) */ - if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) + if (hw->chip_id == CHIP_ID_YUKON_XL) aux >>= 6; sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; @@ -1919,38 +1855,39 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) } } -/* Is status ring empty or is there more to do? */ -static inline int sky2_more_work(const struct sky2_hw *hw) -{ - return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX)); -} - /* Process status response ring */ static int sky2_status_intr(struct sky2_hw *hw, int to_do) { int work_done = 0; - u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); rmb(); - while (hw->st_idx != hwidx) { + for(;;) { struct sky2_status_le *le = hw->st_le + hw->st_idx; struct net_device *dev; struct sky2_port *sky2; struct sk_buff *skb; u32 status; u16 length; + u8 link, opcode; - hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); + opcode = le->opcode; + if (!opcode) + break; + opcode &= ~HW_OWNER; - BUG_ON(le->link >= 2); - dev = hw->dev[le->link]; + hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE; + le->opcode = 0; + + link = le->link; + BUG_ON(link >= 2); + dev = hw->dev[link]; sky2 = netdev_priv(dev); length = le->length; status = le->status; - switch (le->opcode & ~HW_OWNER) { + switch (opcode) { case OP_RXSTAT: skb = sky2_receive(sky2, length, status); if (!skb) @@ -1990,8 +1927,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) case OP_TXINDEXLE: /* TX index reports status for both ports */ - BUILD_BUG_ON(TX_RING_SIZE > 0x1000); - sky2_tx_done(hw->dev[0], status & 0xfff); + sky2_tx_done(hw->dev[0], status & 0xffff); if (hw->dev[1]) sky2_tx_done(hw->dev[1], ((status >> 24) & 0xff) @@ -2001,8 +1937,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) default: if (net_ratelimit()) printk(KERN_WARNING PFX - "unknown status opcode 0x%x\n", le->opcode); - goto exit_loop; + "unknown status opcode 0x%x\n", opcode); + break; } } @@ -2153,13 +2089,12 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, */ static void sky2_idle(unsigned long arg) { - struct sky2_hw *hw = (struct sky2_hw *) arg; - struct net_device *dev = hw->dev[0]; + struct net_device *dev = (struct net_device *) arg; + local_irq_disable(); if (__netif_rx_schedule_prep(dev)) __netif_rx_schedule(dev); - - mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout)); + local_irq_enable(); } @@ -2170,46 +2105,65 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); - if (status & Y2_IS_HW_ERR) - sky2_hw_intr(hw); + restart_poll: + if (unlikely(status & ~Y2_IS_STAT_BMU)) { + if (status & Y2_IS_HW_ERR) + sky2_hw_intr(hw); - if (status & Y2_IS_IRQ_PHY1) - sky2_phy_intr(hw, 0); + if (status & Y2_IS_IRQ_PHY1) + sky2_phy_intr(hw, 0); - if (status & Y2_IS_IRQ_PHY2) - sky2_phy_intr(hw, 1); + if (status & Y2_IS_IRQ_PHY2) + sky2_phy_intr(hw, 1); - if (status & Y2_IS_IRQ_MAC1) - sky2_mac_intr(hw, 0); + if (status & Y2_IS_IRQ_MAC1) + sky2_mac_intr(hw, 0); - if (status & Y2_IS_IRQ_MAC2) - sky2_mac_intr(hw, 1); + if (status & Y2_IS_IRQ_MAC2) + sky2_mac_intr(hw, 1); - if (status & Y2_IS_CHK_RX1) - sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1); + if (status & Y2_IS_CHK_RX1) + sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1); - if (status & Y2_IS_CHK_RX2) - sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2); + if (status & Y2_IS_CHK_RX2) + sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2); - if (status & Y2_IS_CHK_TXA1) - sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1); + if (status & Y2_IS_CHK_TXA1) + sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1); - if (status & Y2_IS_CHK_TXA2) - sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); + if (status & Y2_IS_CHK_TXA2) + sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); + } + + if (status & Y2_IS_STAT_BMU) { + work_done += sky2_status_intr(hw, work_limit - work_done); + *budget -= work_done; + dev0->quota -= work_done; - work_done = sky2_status_intr(hw, work_limit); - *budget -= work_done; - dev0->quota -= work_done; + if (work_done >= work_limit) + return 1; - if (status & Y2_IS_STAT_BMU) sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); + } + + mod_timer(&hw->idle_timer, jiffies + HZ); - if (sky2_more_work(hw)) - return 1; + local_irq_disable(); + __netif_rx_complete(dev0); - netif_rx_complete(dev0); + status = sky2_read32(hw, B0_Y2_SP_LISR); + + if (unlikely(status)) { + /* More work pending, try and keep going */ + if (__netif_rx_schedule_prep(dev0)) { + __netif_rx_reschedule(dev0, work_done); + status = sky2_read32(hw, B0_Y2_SP_EISR); + local_irq_enable(); + goto restart_poll; + } + } - sky2_read32(hw, B0_Y2_SP_LISR); + local_irq_enable(); return 0; } @@ -2290,6 +2244,13 @@ static int __devinit sky2_reset(struct sky2_hw *hw) return -EOPNOTSUPP; } + /* This chip is new and not tested yet */ + if (hw->chip_id == CHIP_ID_YUKON_EC_U) { + pr_info(PFX "%s: is a version of Yukon 2 chipset that has not been tested yet.\n", + pci_name(hw->pdev)); + pr_info("Please report success/failure to maintainer \n"); + } + /* disable ASF */ if (hw->chip_id <= CHIP_ID_YUKON_EC) { sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); @@ -3093,7 +3054,12 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->duplex = -1; sky2->speed = -1; sky2->advertising = sky2_supported_modes(hw); - sky2->rx_csum = 1; + + /* Receive checksum disabled for Yukon XL + * because of observed problems with incorrect + * values when multiple packets are received in one interrupt + */ + sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); spin_lock_init(&sky2->phy_lock); sky2->tx_pending = TX_DEF_PENDING; @@ -3336,10 +3302,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, sky2_write32(hw, B0_IMSK, Y2_IS_BASE); - setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); - if (idle_timeout > 0) - mod_timer(&hw->idle_timer, - jiffies + msecs_to_jiffies(idle_timeout)); + setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev); pci_set_drvdata(pdev, hw); @@ -3379,8 +3342,6 @@ static void __devexit sky2_remove(struct pci_dev *pdev) del_timer_sync(&hw->idle_timer); sky2_write32(hw, B0_IMSK, 0); - synchronize_irq(hw->pdev->irq); - dev0 = hw->dev[0]; dev1 = hw->dev[1]; if (dev1) diff --git a/trunk/drivers/net/sky2.h b/trunk/drivers/net/sky2.h index 8a0bc5525f0a..b026f5653f04 100644 --- a/trunk/drivers/net/sky2.h +++ b/trunk/drivers/net/sky2.h @@ -214,8 +214,6 @@ enum csr_regs { enum { Y2_VMAIN_AVAIL = 1<<17,/* VMAIN available (YUKON-2 only) */ Y2_VAUX_AVAIL = 1<<16,/* VAUX available (YUKON-2 only) */ - Y2_HW_WOL_ON = 1<<15,/* HW WOL On (Yukon-EC Ultra A1 only) */ - Y2_HW_WOL_OFF = 1<<14,/* HW WOL On (Yukon-EC Ultra A1 only) */ Y2_ASF_ENABLE = 1<<13,/* ASF Unit Enable (YUKON-2 only) */ Y2_ASF_DISABLE = 1<<12,/* ASF Unit Disable (YUKON-2 only) */ Y2_CLK_RUN_ENA = 1<<11,/* CLK_RUN Enable (YUKON-2 only) */ @@ -380,9 +378,6 @@ enum { CHIP_REV_YU_EC_A1 = 0, /* Chip Rev. for Yukon-EC A1/A0 */ CHIP_REV_YU_EC_A2 = 1, /* Chip Rev. for Yukon-EC A2 */ CHIP_REV_YU_EC_A3 = 2, /* Chip Rev. for Yukon-EC A3 */ - - CHIP_REV_YU_EC_U_A0 = 0, - CHIP_REV_YU_EC_U_A1 = 1, }; /* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ diff --git a/trunk/drivers/net/smc911x.c b/trunk/drivers/net/smc911x.c deleted file mode 100644 index bdd8702ead54..000000000000 --- a/trunk/drivers/net/smc911x.c +++ /dev/null @@ -1,2307 +0,0 @@ -/* - * smc911x.c - * This is a driver for SMSC's LAN911{5,6,7,8} single-chip Ethernet devices. - * - * Copyright (C) 2005 Sensoria Corp - * Derived from the unified SMC91x driver by Nicolas Pitre - * and the smsc911x.c reference driver by SMSC - * - * 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 - * - * Arguments: - * watchdog = TX watchdog timeout - * tx_fifo_kb = Size of TX FIFO in KB - * - * History: - * 04/16/05 Dustin McIntire Initial version - */ -static const char version[] = - "smc911x.c: v1.0 04-16-2005 by Dustin McIntire \n"; - -/* Debugging options */ -#define ENABLE_SMC_DEBUG_RX 0 -#define ENABLE_SMC_DEBUG_TX 0 -#define ENABLE_SMC_DEBUG_DMA 0 -#define ENABLE_SMC_DEBUG_PKTS 0 -#define ENABLE_SMC_DEBUG_MISC 0 -#define ENABLE_SMC_DEBUG_FUNC 0 - -#define SMC_DEBUG_RX ((ENABLE_SMC_DEBUG_RX ? 1 : 0) << 0) -#define SMC_DEBUG_TX ((ENABLE_SMC_DEBUG_TX ? 1 : 0) << 1) -#define SMC_DEBUG_DMA ((ENABLE_SMC_DEBUG_DMA ? 1 : 0) << 2) -#define SMC_DEBUG_PKTS ((ENABLE_SMC_DEBUG_PKTS ? 1 : 0) << 3) -#define SMC_DEBUG_MISC ((ENABLE_SMC_DEBUG_MISC ? 1 : 0) << 4) -#define SMC_DEBUG_FUNC ((ENABLE_SMC_DEBUG_FUNC ? 1 : 0) << 5) - -#ifndef SMC_DEBUG -#define SMC_DEBUG ( SMC_DEBUG_RX | \ - SMC_DEBUG_TX | \ - SMC_DEBUG_DMA | \ - SMC_DEBUG_PKTS | \ - SMC_DEBUG_MISC | \ - SMC_DEBUG_FUNC \ - ) -#endif - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "smc911x.h" - -/* - * Transmit timeout, default 5 seconds. - */ -static int watchdog = 5000; -module_param(watchdog, int, 0400); -MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); - -static int tx_fifo_kb=8; -module_param(tx_fifo_kb, int, 0400); -MODULE_PARM_DESC(tx_fifo_kb,"transmit FIFO size in KB (1 0 -#define DBG(n, args...) \ - do { \ - if (SMC_DEBUG & (n)) \ - printk(args); \ - } while (0) - -#define PRINTK(args...) printk(args) -#else -#define DBG(n, args...) do { } while (0) -#define PRINTK(args...) printk(KERN_DEBUG args) -#endif - -#if SMC_DEBUG_PKTS > 0 -static void PRINT_PKT(u_char *buf, int length) -{ - int i; - int remainder; - int lines; - - lines = length / 16; - remainder = length % 16; - - for (i = 0; i < lines ; i ++) { - int cur; - for (cur = 0; cur < 8; cur++) { - u_char a, b; - a = *buf++; - b = *buf++; - printk("%02x%02x ", a, b); - } - printk("\n"); - } - for (i = 0; i < remainder/2 ; i++) { - u_char a, b; - a = *buf++; - b = *buf++; - printk("%02x%02x ", a, b); - } - printk("\n"); -} -#else -#define PRINT_PKT(x...) do { } while (0) -#endif - - -/* this enables an interrupt in the interrupt mask register */ -#define SMC_ENABLE_INT(x) do { \ - unsigned int __mask; \ - unsigned long __flags; \ - spin_lock_irqsave(&lp->lock, __flags); \ - __mask = SMC_GET_INT_EN(); \ - __mask |= (x); \ - SMC_SET_INT_EN(__mask); \ - spin_unlock_irqrestore(&lp->lock, __flags); \ -} while (0) - -/* this disables an interrupt from the interrupt mask register */ -#define SMC_DISABLE_INT(x) do { \ - unsigned int __mask; \ - unsigned long __flags; \ - spin_lock_irqsave(&lp->lock, __flags); \ - __mask = SMC_GET_INT_EN(); \ - __mask &= ~(x); \ - SMC_SET_INT_EN(__mask); \ - spin_unlock_irqrestore(&lp->lock, __flags); \ -} while (0) - -/* - * this does a soft reset on the device - */ -static void smc911x_reset(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - struct smc911x_local *lp = netdev_priv(dev); - unsigned int reg, timeout=0, resets=1; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - /* Take out of PM setting first */ - if ((SMC_GET_PMT_CTRL() & PMT_CTRL_READY_) == 0) { - /* Write to the bytetest will take out of powerdown */ - SMC_SET_BYTE_TEST(0); - timeout=10; - do { - udelay(10); - reg = SMC_GET_PMT_CTRL() & PMT_CTRL_READY_; - } while ( timeout-- && !reg); - if (timeout == 0) { - PRINTK("%s: smc911x_reset timeout waiting for PM restore\n", dev->name); - return; - } - } - - /* Disable all interrupts */ - spin_lock_irqsave(&lp->lock, flags); - SMC_SET_INT_EN(0); - spin_unlock_irqrestore(&lp->lock, flags); - - while (resets--) { - SMC_SET_HW_CFG(HW_CFG_SRST_); - timeout=10; - do { - udelay(10); - reg = SMC_GET_HW_CFG(); - /* If chip indicates reset timeout then try again */ - if (reg & HW_CFG_SRST_TO_) { - PRINTK("%s: chip reset timeout, retrying...\n", dev->name); - resets++; - break; - } - } while ( timeout-- && (reg & HW_CFG_SRST_)); - } - if (timeout == 0) { - PRINTK("%s: smc911x_reset timeout waiting for reset\n", dev->name); - return; - } - - /* make sure EEPROM has finished loading before setting GPIO_CFG */ - timeout=1000; - while ( timeout-- && (SMC_GET_E2P_CMD() & E2P_CMD_EPC_BUSY_)) { - udelay(10); - } - if (timeout == 0){ - PRINTK("%s: smc911x_reset timeout waiting for EEPROM busy\n", dev->name); - return; - } - - /* Initialize interrupts */ - SMC_SET_INT_EN(0); - SMC_ACK_INT(-1); - - /* Reset the FIFO level and flow control settings */ - SMC_SET_HW_CFG((lp->tx_fifo_kb & 0xF) << 16); -//TODO: Figure out what appropriate pause time is - SMC_SET_FLOW(FLOW_FCPT_ | FLOW_FCEN_); - SMC_SET_AFC_CFG(lp->afc_cfg); - - - /* Set to LED outputs */ - SMC_SET_GPIO_CFG(0x70070000); - - /* - * Deassert IRQ for 1*10us for edge type interrupts - * and drive IRQ pin push-pull - */ - SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ ); - - /* clear anything saved */ - if (lp->pending_tx_skb != NULL) { - dev_kfree_skb (lp->pending_tx_skb); - lp->pending_tx_skb = NULL; - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - } -} - -/* - * Enable Interrupts, Receive, and Transmit - */ -static void smc911x_enable(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - struct smc911x_local *lp = netdev_priv(dev); - unsigned mask, cfg, cr; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - SMC_SET_MAC_ADDR(dev->dev_addr); - - /* Enable TX */ - cfg = SMC_GET_HW_CFG(); - cfg &= HW_CFG_TX_FIF_SZ_ | 0xFFF; - cfg |= HW_CFG_SF_; - SMC_SET_HW_CFG(cfg); - SMC_SET_FIFO_TDA(0xFF); - /* Update TX stats on every 64 packets received or every 1 sec */ - SMC_SET_FIFO_TSL(64); - SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000); - - spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MAC_CR(cr); - cr |= MAC_CR_TXEN_ | MAC_CR_HBDIS_; - SMC_SET_MAC_CR(cr); - SMC_SET_TX_CFG(TX_CFG_TX_ON_); - spin_unlock_irqrestore(&lp->lock, flags); - - /* Add 2 byte padding to start of packets */ - SMC_SET_RX_CFG((2<<8) & RX_CFG_RXDOFF_); - - /* Turn on receiver and enable RX */ - if (cr & MAC_CR_RXEN_) - DBG(SMC_DEBUG_RX, "%s: Receiver already enabled\n", dev->name); - - spin_lock_irqsave(&lp->lock, flags); - SMC_SET_MAC_CR( cr | MAC_CR_RXEN_ ); - spin_unlock_irqrestore(&lp->lock, flags); - - /* Interrupt on every received packet */ - SMC_SET_FIFO_RSA(0x01); - SMC_SET_FIFO_RSL(0x00); - - /* now, enable interrupts */ - mask = INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_ | INT_EN_RSFL_EN_ | - INT_EN_GPT_INT_EN_ | INT_EN_RXDFH_INT_EN_ | INT_EN_RXE_EN_ | - INT_EN_PHY_INT_EN_; - if (IS_REV_A(lp->revision)) - mask|=INT_EN_RDFL_EN_; - else { - mask|=INT_EN_RDFO_EN_; - } - SMC_ENABLE_INT(mask); -} - -/* - * this puts the device in an inactive state - */ -static void smc911x_shutdown(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - struct smc911x_local *lp = netdev_priv(dev); - unsigned cr; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __FUNCTION__); - - /* Disable IRQ's */ - SMC_SET_INT_EN(0); - - /* Turn of Rx and TX */ - spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MAC_CR(cr); - cr &= ~(MAC_CR_TXEN_ | MAC_CR_RXEN_ | MAC_CR_HBDIS_); - SMC_SET_MAC_CR(cr); - SMC_SET_TX_CFG(TX_CFG_STOP_TX_); - spin_unlock_irqrestore(&lp->lock, flags); -} - -static inline void smc911x_drop_pkt(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - unsigned int fifo_count, timeout, reg; - - DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __FUNCTION__); - fifo_count = SMC_GET_RX_FIFO_INF() & 0xFFFF; - if (fifo_count <= 4) { - /* Manually dump the packet data */ - while (fifo_count--) - SMC_GET_RX_FIFO(); - } else { - /* Fast forward through the bad packet */ - SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_); - timeout=50; - do { - udelay(10); - reg = SMC_GET_RX_DP_CTRL() & RX_DP_CTRL_FFWD_BUSY_; - } while ( timeout-- && reg); - if (timeout == 0) { - PRINTK("%s: timeout waiting for RX fast forward\n", dev->name); - } - } -} - -/* - * This is the procedure to handle the receipt of a packet. - * It should be called after checking for packet presence in - * the RX status FIFO. It must be called with the spin lock - * already held. - */ -static inline void smc911x_rcv(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - unsigned int pkt_len, status; - struct sk_buff *skb; - unsigned char *data; - - DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", - dev->name, __FUNCTION__); - status = SMC_GET_RX_STS_FIFO(); - DBG(SMC_DEBUG_RX, "%s: Rx pkt len %d status 0x%08x \n", - dev->name, (status & 0x3fff0000) >> 16, status & 0xc000ffff); - pkt_len = (status & RX_STS_PKT_LEN_) >> 16; - if (status & RX_STS_ES_) { - /* Deal with a bad packet */ - lp->stats.rx_errors++; - if (status & RX_STS_CRC_ERR_) - lp->stats.rx_crc_errors++; - else { - if (status & RX_STS_LEN_ERR_) - lp->stats.rx_length_errors++; - if (status & RX_STS_MCAST_) - lp->stats.multicast++; - } - /* Remove the bad packet data from the RX FIFO */ - smc911x_drop_pkt(dev); - } else { - /* Receive a valid packet */ - /* Alloc a buffer with extra room for DMA alignment */ - skb=dev_alloc_skb(pkt_len+32); - if (unlikely(skb == NULL)) { - PRINTK( "%s: Low memory, rcvd packet dropped.\n", - dev->name); - lp->stats.rx_dropped++; - smc911x_drop_pkt(dev); - return; - } - /* Align IP header to 32 bits - * Note that the device is configured to add a 2 - * byte padding to the packet start, so we really - * want to write to the orignal data pointer */ - data = skb->data; - skb_reserve(skb, 2); - skb_put(skb,pkt_len-4); -#ifdef SMC_USE_DMA - { - unsigned int fifo; - /* Lower the FIFO threshold if possible */ - fifo = SMC_GET_FIFO_INT(); - if (fifo & 0xFF) fifo--; - DBG(SMC_DEBUG_RX, "%s: Setting RX stat FIFO threshold to %d\n", - dev->name, fifo & 0xff); - SMC_SET_FIFO_INT(fifo); - /* Setup RX DMA */ - SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN16_ | ((2<<8) & RX_CFG_RXDOFF_)); - lp->rxdma_active = 1; - lp->current_rx_skb = skb; - SMC_PULL_DATA(data, (pkt_len+2+15) & ~15); - /* Packet processing deferred to DMA RX interrupt */ - } -#else - SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_)); - SMC_PULL_DATA(data, pkt_len+2+3); - - DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name,); - PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64); - dev->last_rx = jiffies; - skb->dev = dev; - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len-4; -#endif - } -} - -/* - * This is called to actually send a packet to the chip. - */ -static void smc911x_hardware_send_pkt(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - struct sk_buff *skb; - unsigned int cmdA, cmdB, len; - unsigned char *buf; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __FUNCTION__); - BUG_ON(lp->pending_tx_skb == NULL); - - skb = lp->pending_tx_skb; - lp->pending_tx_skb = NULL; - - /* cmdA {25:24] data alignment [20:16] start offset [10:0] buffer length */ - /* cmdB {31:16] pkt tag [10:0] length */ -#ifdef SMC_USE_DMA - /* 16 byte buffer alignment mode */ - buf = (char*)((u32)(skb->data) & ~0xF); - len = (skb->len + 0xF + ((u32)skb->data & 0xF)) & ~0xF; - cmdA = (1<<24) | (((u32)skb->data & 0xF)<<16) | - TX_CMD_A_INT_FIRST_SEG_ | TX_CMD_A_INT_LAST_SEG_ | - skb->len; -#else - buf = (char*)((u32)skb->data & ~0x3); - len = (skb->len + 3 + ((u32)skb->data & 3)) & ~0x3; - cmdA = (((u32)skb->data & 0x3) << 16) | - TX_CMD_A_INT_FIRST_SEG_ | TX_CMD_A_INT_LAST_SEG_ | - skb->len; -#endif - /* tag is packet length so we can use this in stats update later */ - cmdB = (skb->len << 16) | (skb->len & 0x7FF); - - DBG(SMC_DEBUG_TX, "%s: TX PKT LENGTH 0x%04x (%d) BUF 0x%p CMDA 0x%08x CMDB 0x%08x\n", - dev->name, len, len, buf, cmdA, cmdB); - SMC_SET_TX_FIFO(cmdA); - SMC_SET_TX_FIFO(cmdB); - - DBG(SMC_DEBUG_PKTS, "%s: Transmitted packet\n", dev->name); - PRINT_PKT(buf, len <= 64 ? len : 64); - - /* Send pkt via PIO or DMA */ -#ifdef SMC_USE_DMA - lp->current_tx_skb = skb; - SMC_PUSH_DATA(buf, len); - /* DMA complete IRQ will free buffer and set jiffies */ -#else - SMC_PUSH_DATA(buf, len); - dev->trans_start = jiffies; - dev_kfree_skb(skb); -#endif - spin_lock_irqsave(&lp->lock, flags); - if (!lp->tx_throttle) { - netif_wake_queue(dev); - } - spin_unlock_irqrestore(&lp->lock, flags); - SMC_ENABLE_INT(INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_); -} - -/* - * Since I am not sure if I will have enough room in the chip's ram - * to store the packet, I call this routine which either sends it - * now, or set the card to generates an interrupt when ready - * for the packet. - */ -static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - unsigned int free; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", - dev->name, __FUNCTION__); - - BUG_ON(lp->pending_tx_skb != NULL); - - free = SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TDFREE_; - DBG(SMC_DEBUG_TX, "%s: TX free space %d\n", dev->name, free); - - /* Turn off the flow when running out of space in FIFO */ - if (free <= SMC911X_TX_FIFO_LOW_THRESHOLD) { - DBG(SMC_DEBUG_TX, "%s: Disabling data flow due to low FIFO space (%d)\n", - dev->name, free); - spin_lock_irqsave(&lp->lock, flags); - /* Reenable when at least 1 packet of size MTU present */ - SMC_SET_FIFO_TDA((SMC911X_TX_FIFO_LOW_THRESHOLD)/64); - lp->tx_throttle = 1; - netif_stop_queue(dev); - spin_unlock_irqrestore(&lp->lock, flags); - } - - /* Drop packets when we run out of space in TX FIFO - * Account for overhead required for: - * - * Tx command words 8 bytes - * Start offset 15 bytes - * End padding 15 bytes - */ - if (unlikely(free < (skb->len + 8 + 15 + 15))) { - printk("%s: No Tx free space %d < %d\n", - dev->name, free, skb->len); - lp->pending_tx_skb = NULL; - lp->stats.tx_errors++; - lp->stats.tx_dropped++; - dev_kfree_skb(skb); - return 0; - } - -#ifdef SMC_USE_DMA - { - /* If the DMA is already running then defer this packet Tx until - * the DMA IRQ starts it - */ - spin_lock_irqsave(&lp->lock, flags); - if (lp->txdma_active) { - DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Tx DMA running, deferring packet\n", dev->name); - lp->pending_tx_skb = skb; - netif_stop_queue(dev); - spin_unlock_irqrestore(&lp->lock, flags); - return 0; - } else { - DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Activating Tx DMA\n", dev->name); - lp->txdma_active = 1; - } - spin_unlock_irqrestore(&lp->lock, flags); - } -#endif - lp->pending_tx_skb = skb; - smc911x_hardware_send_pkt(dev); - - return 0; -} - -/* - * This handles a TX status interrupt, which is only called when: - * - a TX error occurred, or - * - TX of a packet completed. - */ -static void smc911x_tx(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - struct smc911x_local *lp = netdev_priv(dev); - unsigned int tx_status; - - DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", - dev->name, __FUNCTION__); - - /* Collect the TX status */ - while (((SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TSUSED_) >> 16) != 0) { - DBG(SMC_DEBUG_TX, "%s: Tx stat FIFO used 0x%04x\n", - dev->name, - (SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TSUSED_) >> 16); - tx_status = SMC_GET_TX_STS_FIFO(); - lp->stats.tx_packets++; - lp->stats.tx_bytes+=tx_status>>16; - DBG(SMC_DEBUG_TX, "%s: Tx FIFO tag 0x%04x status 0x%04x\n", - dev->name, (tx_status & 0xffff0000) >> 16, - tx_status & 0x0000ffff); - /* count Tx errors, but ignore lost carrier errors when in - * full-duplex mode */ - if ((tx_status & TX_STS_ES_) && !(lp->ctl_rfduplx && - !(tx_status & 0x00000306))) { - lp->stats.tx_errors++; - } - if (tx_status & TX_STS_MANY_COLL_) { - lp->stats.collisions+=16; - lp->stats.tx_aborted_errors++; - } else { - lp->stats.collisions+=(tx_status & TX_STS_COLL_CNT_) >> 3; - } - /* carrier error only has meaning for half-duplex communication */ - if ((tx_status & (TX_STS_LOC_ | TX_STS_NO_CARR_)) && - !lp->ctl_rfduplx) { - lp->stats.tx_carrier_errors++; - } - if (tx_status & TX_STS_LATE_COLL_) { - lp->stats.collisions++; - lp->stats.tx_aborted_errors++; - } - } -} - - -/*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/ -/* - * Reads a register from the MII Management serial interface - */ - -static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg) -{ - unsigned long ioaddr = dev->base_addr; - unsigned int phydata; - - SMC_GET_MII(phyreg, phyaddr, phydata); - - DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%02x, phydata=0x%04x\n", - __FUNCTION__, phyaddr, phyreg, phydata); - return phydata; -} - - -/* - * Writes a register to the MII Management serial interface - */ -static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg, - int phydata) -{ - unsigned long ioaddr = dev->base_addr; - - DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", - __FUNCTION__, phyaddr, phyreg, phydata); - - SMC_SET_MII(phyreg, phyaddr, phydata); -} - -/* - * Finds and reports the PHY address (115 and 117 have external - * PHY interface 118 has internal only - */ -static void smc911x_phy_detect(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - struct smc911x_local *lp = netdev_priv(dev); - int phyaddr; - unsigned int cfg, id1, id2; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - lp->phy_type = 0; - - /* - * Scan all 32 PHY addresses if necessary, starting at - * PHY#1 to PHY#31, and then PHY#0 last. - */ - switch(lp->version) { - case 0x115: - case 0x117: - cfg = SMC_GET_HW_CFG(); - if (cfg & HW_CFG_EXT_PHY_DET_) { - cfg &= ~HW_CFG_PHY_CLK_SEL_; - cfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_; - SMC_SET_HW_CFG(cfg); - udelay(10); /* Wait for clocks to stop */ - - cfg |= HW_CFG_EXT_PHY_EN_; - SMC_SET_HW_CFG(cfg); - udelay(10); /* Wait for clocks to stop */ - - cfg &= ~HW_CFG_PHY_CLK_SEL_; - cfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_; - SMC_SET_HW_CFG(cfg); - udelay(10); /* Wait for clocks to stop */ - - cfg |= HW_CFG_SMI_SEL_; - SMC_SET_HW_CFG(cfg); - - for (phyaddr = 1; phyaddr < 32; ++phyaddr) { - - /* Read the PHY identifiers */ - SMC_GET_PHY_ID1(phyaddr & 31, id1); - SMC_GET_PHY_ID2(phyaddr & 31, id2); - - /* Make sure it is a valid identifier */ - if (id1 != 0x0000 && id1 != 0xffff && - id1 != 0x8000 && id2 != 0x0000 && - id2 != 0xffff && id2 != 0x8000) { - /* Save the PHY's address */ - lp->mii.phy_id = phyaddr & 31; - lp->phy_type = id1 << 16 | id2; - break; - } - } - } - default: - /* Internal media only */ - SMC_GET_PHY_ID1(1, id1); - SMC_GET_PHY_ID2(1, id2); - /* Save the PHY's address */ - lp->mii.phy_id = 1; - lp->phy_type = id1 << 16 | id2; - } - - DBG(SMC_DEBUG_MISC, "%s: phy_id1=0x%x, phy_id2=0x%x phyaddr=0x%d\n", - dev->name, id1, id2, lp->mii.phy_id); -} - -/* - * Sets the PHY to a configuration as determined by the user. - * Called with spin_lock held. - */ -static int smc911x_phy_fixed(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - int phyaddr = lp->mii.phy_id; - int bmcr; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - /* Enter Link Disable state */ - SMC_GET_PHY_BMCR(phyaddr, bmcr); - bmcr |= BMCR_PDOWN; - SMC_SET_PHY_BMCR(phyaddr, bmcr); - - /* - * Set our fixed capabilities - * Disable auto-negotiation - */ - bmcr &= ~BMCR_ANENABLE; - if (lp->ctl_rfduplx) - bmcr |= BMCR_FULLDPLX; - - if (lp->ctl_rspeed == 100) - bmcr |= BMCR_SPEED100; - - /* Write our capabilities to the phy control register */ - SMC_SET_PHY_BMCR(phyaddr, bmcr); - - /* Re-Configure the Receive/Phy Control register */ - bmcr &= ~BMCR_PDOWN; - SMC_SET_PHY_BMCR(phyaddr, bmcr); - - return 1; -} - -/* - * smc911x_phy_reset - reset the phy - * @dev: net device - * @phy: phy address - * - * Issue a software reset for the specified PHY and - * wait up to 100ms for the reset to complete. We should - * not access the PHY for 50ms after issuing the reset. - * - * The time to wait appears to be dependent on the PHY. - * - */ -static int smc911x_phy_reset(struct net_device *dev, int phy) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - int timeout; - unsigned long flags; - unsigned int reg; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__); - - spin_lock_irqsave(&lp->lock, flags); - reg = SMC_GET_PMT_CTRL(); - reg &= ~0xfffff030; - reg |= PMT_CTRL_PHY_RST_; - SMC_SET_PMT_CTRL(reg); - spin_unlock_irqrestore(&lp->lock, flags); - for (timeout = 2; timeout; timeout--) { - msleep(50); - spin_lock_irqsave(&lp->lock, flags); - reg = SMC_GET_PMT_CTRL(); - spin_unlock_irqrestore(&lp->lock, flags); - if (!(reg & PMT_CTRL_PHY_RST_)) { - /* extra delay required because the phy may - * not be completed with its reset - * when PHY_BCR_RESET_ is cleared. 256us - * should suffice, but use 500us to be safe - */ - udelay(500); - break; - } - } - - return reg & PMT_CTRL_PHY_RST_; -} - -/* - * smc911x_phy_powerdown - powerdown phy - * @dev: net device - * @phy: phy address - * - * Power down the specified PHY - */ -static void smc911x_phy_powerdown(struct net_device *dev, int phy) -{ - unsigned long ioaddr = dev->base_addr; - unsigned int bmcr; - - /* Enter Link Disable state */ - SMC_GET_PHY_BMCR(phy, bmcr); - bmcr |= BMCR_PDOWN; - SMC_SET_PHY_BMCR(phy, bmcr); -} - -/* - * smc911x_phy_check_media - check the media status and adjust BMCR - * @dev: net device - * @init: set true for initialisation - * - * Select duplex mode depending on negotiation state. This - * also updates our carrier state. - */ -static void smc911x_phy_check_media(struct net_device *dev, int init) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - int phyaddr = lp->mii.phy_id; - unsigned int bmcr, cr; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) { - /* duplex state has changed */ - SMC_GET_PHY_BMCR(phyaddr, bmcr); - SMC_GET_MAC_CR(cr); - if (lp->mii.full_duplex) { - DBG(SMC_DEBUG_MISC, "%s: Configuring for full-duplex mode\n", dev->name); - bmcr |= BMCR_FULLDPLX; - cr |= MAC_CR_RCVOWN_; - } else { - DBG(SMC_DEBUG_MISC, "%s: Configuring for half-duplex mode\n", dev->name); - bmcr &= ~BMCR_FULLDPLX; - cr &= ~MAC_CR_RCVOWN_; - } - SMC_SET_PHY_BMCR(phyaddr, bmcr); - SMC_SET_MAC_CR(cr); - } -} - -/* - * Configures the specified PHY through the MII management interface - * using Autonegotiation. - * Calls smc911x_phy_fixed() if the user has requested a certain config. - * If RPC ANEG bit is set, the media selection is dependent purely on - * the selection by the MII (either in the MII BMCR reg or the result - * of autonegotiation.) If the RPC ANEG bit is cleared, the selection - * is controlled by the RPC SPEED and RPC DPLX bits. - */ -static void smc911x_phy_configure(void *data) -{ - struct net_device *dev = data; - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - int phyaddr = lp->mii.phy_id; - int my_phy_caps; /* My PHY capabilities */ - int my_ad_caps; /* My Advertised capabilities */ - int status; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__); - - /* - * We should not be called if phy_type is zero. - */ - if (lp->phy_type == 0) - goto smc911x_phy_configure_exit; - - if (smc911x_phy_reset(dev, phyaddr)) { - printk("%s: PHY reset timed out\n", dev->name); - goto smc911x_phy_configure_exit; - } - spin_lock_irqsave(&lp->lock, flags); - - /* - * Enable PHY Interrupts (for register 18) - * Interrupts listed here are enabled - */ - SMC_SET_PHY_INT_MASK(phyaddr, PHY_INT_MASK_ENERGY_ON_ | - PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_REMOTE_FAULT_ | - PHY_INT_MASK_LINK_DOWN_); - - /* If the user requested no auto neg, then go set his request */ - if (lp->mii.force_media) { - smc911x_phy_fixed(dev); - goto smc911x_phy_configure_exit; - } - - /* Copy our capabilities from MII_BMSR to MII_ADVERTISE */ - SMC_GET_PHY_BMSR(phyaddr, my_phy_caps); - if (!(my_phy_caps & BMSR_ANEGCAPABLE)) { - printk(KERN_INFO "Auto negotiation NOT supported\n"); - smc911x_phy_fixed(dev); - goto smc911x_phy_configure_exit; - } - - /* CSMA capable w/ both pauses */ - my_ad_caps = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; - - if (my_phy_caps & BMSR_100BASE4) - my_ad_caps |= ADVERTISE_100BASE4; - if (my_phy_caps & BMSR_100FULL) - my_ad_caps |= ADVERTISE_100FULL; - if (my_phy_caps & BMSR_100HALF) - my_ad_caps |= ADVERTISE_100HALF; - if (my_phy_caps & BMSR_10FULL) - my_ad_caps |= ADVERTISE_10FULL; - if (my_phy_caps & BMSR_10HALF) - my_ad_caps |= ADVERTISE_10HALF; - - /* Disable capabilities not selected by our user */ - if (lp->ctl_rspeed != 100) - my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF); - - if (!lp->ctl_rfduplx) - my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL); - - /* Update our Auto-Neg Advertisement Register */ - SMC_SET_PHY_MII_ADV(phyaddr, my_ad_caps); - lp->mii.advertising = my_ad_caps; - - /* - * Read the register back. Without this, it appears that when - * auto-negotiation is restarted, sometimes it isn't ready and - * the link does not come up. - */ - udelay(10); - SMC_GET_PHY_MII_ADV(phyaddr, status); - - DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps); - DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps); - - /* Restart auto-negotiation process in order to advertise my caps */ - SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART); - - smc911x_phy_check_media(dev, 1); - -smc911x_phy_configure_exit: - spin_unlock_irqrestore(&lp->lock, flags); - lp->work_pending = 0; -} - -/* - * smc911x_phy_interrupt - * - * Purpose: Handle interrupts relating to PHY register 18. This is - * called from the "hard" interrupt handler under our private spinlock. - */ -static void smc911x_phy_interrupt(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - int phyaddr = lp->mii.phy_id; - int status; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - if (lp->phy_type == 0) - return; - - smc911x_phy_check_media(dev, 0); - /* read to clear status bits */ - SMC_GET_PHY_INT_SRC(phyaddr,status); - DBG(SMC_DEBUG_MISC, "%s: PHY interrupt status 0x%04x\n", - dev->name, status & 0xffff); - DBG(SMC_DEBUG_MISC, "%s: AFC_CFG 0x%08x\n", - dev->name, SMC_GET_AFC_CFG()); -} - -/*--- END PHY CONTROL AND CONFIGURATION-------------------------------------*/ - -/* - * This is the main routine of the driver, to handle the device when - * it needs some attention. - */ -static irqreturn_t smc911x_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct net_device *dev = dev_id; - unsigned long ioaddr = dev->base_addr; - struct smc911x_local *lp = netdev_priv(dev); - unsigned int status, mask, timeout; - unsigned int rx_overrun=0, cr, pkts; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - spin_lock_irqsave(&lp->lock, flags); - - /* Spurious interrupt check */ - if ((SMC_GET_IRQ_CFG() & (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) != - (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) { - return IRQ_NONE; - } - - mask = SMC_GET_INT_EN(); - SMC_SET_INT_EN(0); - - /* set a timeout value, so I don't stay here forever */ - timeout = 8; - - - do { - status = SMC_GET_INT(); - - DBG(SMC_DEBUG_MISC, "%s: INT 0x%08x MASK 0x%08x OUTSIDE MASK 0x%08x\n", - dev->name, status, mask, status & ~mask); - - status &= mask; - if (!status) - break; - - /* Handle SW interrupt condition */ - if (status & INT_STS_SW_INT_) { - SMC_ACK_INT(INT_STS_SW_INT_); - mask &= ~INT_EN_SW_INT_EN_; - } - /* Handle various error conditions */ - if (status & INT_STS_RXE_) { - SMC_ACK_INT(INT_STS_RXE_); - lp->stats.rx_errors++; - } - if (status & INT_STS_RXDFH_INT_) { - SMC_ACK_INT(INT_STS_RXDFH_INT_); - lp->stats.rx_dropped+=SMC_GET_RX_DROP(); - } - /* Undocumented interrupt-what is the right thing to do here? */ - if (status & INT_STS_RXDF_INT_) { - SMC_ACK_INT(INT_STS_RXDF_INT_); - } - - /* Rx Data FIFO exceeds set level */ - if (status & INT_STS_RDFL_) { - if (IS_REV_A(lp->revision)) { - rx_overrun=1; - SMC_GET_MAC_CR(cr); - cr &= ~MAC_CR_RXEN_; - SMC_SET_MAC_CR(cr); - DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name); - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; - } - SMC_ACK_INT(INT_STS_RDFL_); - } - if (status & INT_STS_RDFO_) { - if (!IS_REV_A(lp->revision)) { - SMC_GET_MAC_CR(cr); - cr &= ~MAC_CR_RXEN_; - SMC_SET_MAC_CR(cr); - rx_overrun=1; - DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name); - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; - } - SMC_ACK_INT(INT_STS_RDFO_); - } - /* Handle receive condition */ - if ((status & INT_STS_RSFL_) || rx_overrun) { - unsigned int fifo; - DBG(SMC_DEBUG_RX, "%s: RX irq\n", dev->name); - fifo = SMC_GET_RX_FIFO_INF(); - pkts = (fifo & RX_FIFO_INF_RXSUSED_) >> 16; - DBG(SMC_DEBUG_RX, "%s: Rx FIFO pkts %d, bytes %d\n", - dev->name, pkts, fifo & 0xFFFF ); - if (pkts != 0) { -#ifdef SMC_USE_DMA - unsigned int fifo; - if (lp->rxdma_active){ - DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, - "%s: RX DMA active\n", dev->name); - /* The DMA is already running so up the IRQ threshold */ - fifo = SMC_GET_FIFO_INT() & ~0xFF; - fifo |= pkts & 0xFF; - DBG(SMC_DEBUG_RX, - "%s: Setting RX stat FIFO threshold to %d\n", - dev->name, fifo & 0xff); - SMC_SET_FIFO_INT(fifo); - } else -#endif - smc911x_rcv(dev); - } - SMC_ACK_INT(INT_STS_RSFL_); - } - /* Handle transmit FIFO available */ - if (status & INT_STS_TDFA_) { - DBG(SMC_DEBUG_TX, "%s: TX data FIFO space available irq\n", dev->name); - SMC_SET_FIFO_TDA(0xFF); - lp->tx_throttle = 0; -#ifdef SMC_USE_DMA - if (!lp->txdma_active) -#endif - netif_wake_queue(dev); - SMC_ACK_INT(INT_STS_TDFA_); - } - /* Handle transmit done condition */ -#if 1 - if (status & (INT_STS_TSFL_ | INT_STS_GPT_INT_)) { - DBG(SMC_DEBUG_TX | SMC_DEBUG_MISC, - "%s: Tx stat FIFO limit (%d) /GPT irq\n", - dev->name, (SMC_GET_FIFO_INT() & 0x00ff0000) >> 16); - smc911x_tx(dev); - SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000); - SMC_ACK_INT(INT_STS_TSFL_); - SMC_ACK_INT(INT_STS_TSFL_ | INT_STS_GPT_INT_); - } -#else - if (status & INT_STS_TSFL_) { - DBG(SMC_DEBUG_TX, "%s: TX status FIFO limit (%d) irq \n", dev->name, ); - smc911x_tx(dev); - SMC_ACK_INT(INT_STS_TSFL_); - } - - if (status & INT_STS_GPT_INT_) { - DBG(SMC_DEBUG_RX, "%s: IRQ_CFG 0x%08x FIFO_INT 0x%08x RX_CFG 0x%08x\n", - dev->name, - SMC_GET_IRQ_CFG(), - SMC_GET_FIFO_INT(), - SMC_GET_RX_CFG()); - DBG(SMC_DEBUG_RX, "%s: Rx Stat FIFO Used 0x%02x " - "Data FIFO Used 0x%04x Stat FIFO 0x%08x\n", - dev->name, - (SMC_GET_RX_FIFO_INF() & 0x00ff0000) >> 16, - SMC_GET_RX_FIFO_INF() & 0xffff, - SMC_GET_RX_STS_FIFO_PEEK()); - SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000); - SMC_ACK_INT(INT_STS_GPT_INT_); - } -#endif - - /* Handle PHY interupt condition */ - if (status & INT_STS_PHY_INT_) { - DBG(SMC_DEBUG_MISC, "%s: PHY irq\n", dev->name); - smc911x_phy_interrupt(dev); - SMC_ACK_INT(INT_STS_PHY_INT_); - } - } while (--timeout); - - /* restore mask state */ - SMC_SET_INT_EN(mask); - - DBG(SMC_DEBUG_MISC, "%s: Interrupt done (%d loops)\n", - dev->name, 8-timeout); - - spin_unlock_irqrestore(&lp->lock, flags); - - DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout); - - return IRQ_HANDLED; -} - -#ifdef SMC_USE_DMA -static void -smc911x_tx_dma_irq(int dma, void *data, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *)data; - struct smc911x_local *lp = netdev_priv(dev); - struct sk_buff *skb = lp->current_tx_skb; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: TX DMA irq handler\n", dev->name); - /* Clear the DMA interrupt sources */ - SMC_DMA_ACK_IRQ(dev, dma); - BUG_ON(skb == NULL); - dma_unmap_single(NULL, tx_dmabuf, tx_dmalen, DMA_TO_DEVICE); - dev->trans_start = jiffies; - dev_kfree_skb_irq(skb); - lp->current_tx_skb = NULL; - if (lp->pending_tx_skb != NULL) - smc911x_hardware_send_pkt(dev); - else { - DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, - "%s: No pending Tx packets. DMA disabled\n", dev->name); - spin_lock_irqsave(&lp->lock, flags); - lp->txdma_active = 0; - if (!lp->tx_throttle) { - netif_wake_queue(dev); - } - spin_unlock_irqrestore(&lp->lock, flags); - } - - DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, - "%s: TX DMA irq completed\n", dev->name); -} -static void -smc911x_rx_dma_irq(int dma, void *data, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *)data; - unsigned long ioaddr = dev->base_addr; - struct smc911x_local *lp = netdev_priv(dev); - struct sk_buff *skb = lp->current_rx_skb; - unsigned long flags; - unsigned int pkts; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, "%s: RX DMA irq handler\n", dev->name); - /* Clear the DMA interrupt sources */ - SMC_DMA_ACK_IRQ(dev, dma); - dma_unmap_single(NULL, rx_dmabuf, rx_dmalen, DMA_FROM_DEVICE); - BUG_ON(skb == NULL); - lp->current_rx_skb = NULL; - PRINT_PKT(skb->data, skb->len); - dev->last_rx = jiffies; - skb->dev = dev; - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - lp->stats.rx_packets++; - lp->stats.rx_bytes += skb->len; - - spin_lock_irqsave(&lp->lock, flags); - pkts = (SMC_GET_RX_FIFO_INF() & RX_FIFO_INF_RXSUSED_) >> 16; - if (pkts != 0) { - smc911x_rcv(dev); - }else { - lp->rxdma_active = 0; - } - spin_unlock_irqrestore(&lp->lock, flags); - DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, - "%s: RX DMA irq completed. DMA RX FIFO PKTS %d\n", - dev->name, pkts); -} -#endif /* SMC_USE_DMA */ - -#ifdef CONFIG_NET_POLL_CONTROLLER -/* - * Polling receive - used by netconsole and other diagnostic tools - * to allow network i/o with interrupts disabled. - */ -static void smc911x_poll_controller(struct net_device *dev) -{ - disable_irq(dev->irq); - smc911x_interrupt(dev->irq, dev, NULL); - enable_irq(dev->irq); -} -#endif - -/* Our watchdog timed out. Called by the networking layer */ -static void smc911x_timeout(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - int status, mask; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - spin_lock_irqsave(&lp->lock, flags); - status = SMC_GET_INT(); - mask = SMC_GET_INT_EN(); - spin_unlock_irqrestore(&lp->lock, flags); - DBG(SMC_DEBUG_MISC, "%s: INT 0x%02x MASK 0x%02x \n", - dev->name, status, mask); - - /* Dump the current TX FIFO contents and restart */ - mask = SMC_GET_TX_CFG(); - SMC_SET_TX_CFG(mask | TX_CFG_TXS_DUMP_ | TX_CFG_TXD_DUMP_); - /* - * Reconfiguring the PHY doesn't seem like a bad idea here, but - * smc911x_phy_configure() calls msleep() which calls schedule_timeout() - * which calls schedule(). Hence we use a work queue. - */ - if (lp->phy_type != 0) { - if (schedule_work(&lp->phy_configure)) { - lp->work_pending = 1; - } - } - - /* We can accept TX packets again */ - dev->trans_start = jiffies; - netif_wake_queue(dev); -} - -/* - * This routine will, depending on the values passed to it, - * either make it accept multicast packets, go into - * promiscuous mode (for TCPDUMP and cousins) or accept - * a select set of multicast packets - */ -static void smc911x_set_multicast_list(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - unsigned int multicast_table[2]; - unsigned int mcr, update_multicast = 0; - unsigned long flags; - /* table for flipping the order of 5 bits */ - static const unsigned char invert5[] = - {0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0C, 0x1C, - 0x02, 0x12, 0x0A, 0x1A, 0x06, 0x16, 0x0E, 0x1E, - 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0D, 0x1D, - 0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F}; - - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MAC_CR(mcr); - spin_unlock_irqrestore(&lp->lock, flags); - - if (dev->flags & IFF_PROMISC) { - - DBG(SMC_DEBUG_MISC, "%s: RCR_PRMS\n", dev->name); - mcr |= MAC_CR_PRMS_; - } - /* - * Here, I am setting this to accept all multicast packets. - * I don't need to zero the multicast table, because the flag is - * checked before the table is - */ - else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) { - DBG(SMC_DEBUG_MISC, "%s: RCR_ALMUL\n", dev->name); - mcr |= MAC_CR_MCPAS_; - } - - /* - * This sets the internal hardware table to filter out unwanted - * multicast packets before they take up memory. - * - * The SMC chip uses a hash table where the high 6 bits of the CRC of - * address are the offset into the table. If that bit is 1, then the - * multicast packet is accepted. Otherwise, it's dropped silently. - * - * To use the 6 bits as an offset into the table, the high 1 bit is - * the number of the 32 bit register, while the low 5 bits are the bit - * within that register. - */ - else if (dev->mc_count) { - int i; - struct dev_mc_list *cur_addr; - - /* Set the Hash perfec mode */ - mcr |= MAC_CR_HPFILT_; - - /* start with a table of all zeros: reject all */ - memset(multicast_table, 0, sizeof(multicast_table)); - - cur_addr = dev->mc_list; - for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) { - int position; - - /* do we have a pointer here? */ - if (!cur_addr) - break; - /* make sure this is a multicast address - - shouldn't this be a given if we have it here ? */ - if (!(*cur_addr->dmi_addr & 1)) - continue; - - /* only use the low order bits */ - position = crc32_le(~0, cur_addr->dmi_addr, 6) & 0x3f; - - /* do some messy swapping to put the bit in the right spot */ - multicast_table[invert5[position&0x1F]&0x1] |= - (1<>1)&0x1F]); - } - - /* be sure I get rid of flags I might have set */ - mcr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_); - - /* now, the table can be loaded into the chipset */ - update_multicast = 1; - } else { - DBG(SMC_DEBUG_MISC, "%s: ~(MAC_CR_PRMS_|MAC_CR_MCPAS_)\n", - dev->name); - mcr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_); - - /* - * since I'm disabling all multicast entirely, I need to - * clear the multicast list - */ - memset(multicast_table, 0, sizeof(multicast_table)); - update_multicast = 1; - } - - spin_lock_irqsave(&lp->lock, flags); - SMC_SET_MAC_CR(mcr); - if (update_multicast) { - DBG(SMC_DEBUG_MISC, - "%s: update mcast hash table 0x%08x 0x%08x\n", - dev->name, multicast_table[0], multicast_table[1]); - SMC_SET_HASHL(multicast_table[0]); - SMC_SET_HASHH(multicast_table[1]); - } - spin_unlock_irqrestore(&lp->lock, flags); -} - - -/* - * Open and Initialize the board - * - * Set up everything, reset the card, etc.. - */ -static int -smc911x_open(struct net_device *dev) -{ - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - /* - * Check that the address is valid. If its not, refuse - * to bring the device up. The user must specify an - * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx - */ - if (!is_valid_ether_addr(dev->dev_addr)) { - PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__); - return -EINVAL; - } - - /* reset the hardware */ - smc911x_reset(dev); - - /* Configure the PHY, initialize the link state */ - smc911x_phy_configure(dev); - - /* Turn on Tx + Rx */ - smc911x_enable(dev); - - netif_start_queue(dev); - - return 0; -} - -/* - * smc911x_close - * - * this makes the board clean up everything that it can - * and not talk to the outside world. Caused by - * an 'ifconfig ethX down' - */ -static int smc911x_close(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - netif_stop_queue(dev); - netif_carrier_off(dev); - - /* clear everything */ - smc911x_shutdown(dev); - - if (lp->phy_type != 0) { - /* We need to ensure that no calls to - * smc911x_phy_configure are pending. - - * flush_scheduled_work() cannot be called because we - * are running with the netlink semaphore held (from - * devinet_ioctl()) and the pending work queue - * contains linkwatch_event() (scheduled by - * netif_carrier_off() above). linkwatch_event() also - * wants the netlink semaphore. - */ - while (lp->work_pending) - schedule(); - smc911x_phy_powerdown(dev, lp->mii.phy_id); - } - - if (lp->pending_tx_skb) { - dev_kfree_skb(lp->pending_tx_skb); - lp->pending_tx_skb = NULL; - } - - return 0; -} - -/* - * Get the current statistics. - * This may be called with the card open or closed. - */ -static struct net_device_stats *smc911x_query_statistics(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - - return &lp->stats; -} - -/* - * Ethtool support - */ -static int -smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct smc911x_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - int ret, status; - unsigned long flags; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - cmd->maxtxpkt = 1; - cmd->maxrxpkt = 1; - - if (lp->phy_type != 0) { - spin_lock_irqsave(&lp->lock, flags); - ret = mii_ethtool_gset(&lp->mii, cmd); - spin_unlock_irqrestore(&lp->lock, flags); - } else { - cmd->supported = SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_TP | SUPPORTED_AUI; - - if (lp->ctl_rspeed == 10) - cmd->speed = SPEED_10; - else if (lp->ctl_rspeed == 100) - cmd->speed = SPEED_100; - - cmd->autoneg = AUTONEG_DISABLE; - if (lp->mii.phy_id==1) - cmd->transceiver = XCVR_INTERNAL; - else - cmd->transceiver = XCVR_EXTERNAL; - cmd->port = 0; - SMC_GET_PHY_SPECIAL(lp->mii.phy_id, status); - cmd->duplex = - (status & (PHY_SPECIAL_SPD_10FULL_ | PHY_SPECIAL_SPD_100FULL_)) ? - DUPLEX_FULL : DUPLEX_HALF; - ret = 0; - } - - return ret; -} - -static int -smc911x_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct smc911x_local *lp = netdev_priv(dev); - int ret; - unsigned long flags; - - if (lp->phy_type != 0) { - spin_lock_irqsave(&lp->lock, flags); - ret = mii_ethtool_sset(&lp->mii, cmd); - spin_unlock_irqrestore(&lp->lock, flags); - } else { - if (cmd->autoneg != AUTONEG_DISABLE || - cmd->speed != SPEED_10 || - (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) || - (cmd->port != PORT_TP && cmd->port != PORT_AUI)) - return -EINVAL; - - lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL; - - ret = 0; - } - - return ret; -} - -static void -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->class_dev.dev->bus_id, sizeof(info->bus_info)); -} - -static int smc911x_ethtool_nwayreset(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - int ret = -EINVAL; - unsigned long flags; - - if (lp->phy_type != 0) { - spin_lock_irqsave(&lp->lock, flags); - ret = mii_nway_restart(&lp->mii); - spin_unlock_irqrestore(&lp->lock, flags); - } - - return ret; -} - -static u32 smc911x_ethtool_getmsglevel(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - return lp->msg_enable; -} - -static void smc911x_ethtool_setmsglevel(struct net_device *dev, u32 level) -{ - struct smc911x_local *lp = netdev_priv(dev); - lp->msg_enable = level; -} - -static int smc911x_ethtool_getregslen(struct net_device *dev) -{ - /* System regs + MAC regs + PHY regs */ - return (((E2P_CMD - ID_REV)/4 + 1) + - (WUCSR - MAC_CR)+1 + 32) * sizeof(u32); -} - -static void smc911x_ethtool_getregs(struct net_device *dev, - struct ethtool_regs* regs, void *buf) -{ - unsigned long ioaddr = dev->base_addr; - struct smc911x_local *lp = netdev_priv(dev); - unsigned long flags; - u32 reg,i,j=0; - u32 *data = (u32*)buf; - - regs->version = lp->version; - for(i=ID_REV;i<=E2P_CMD;i+=4) { - data[j++] = SMC_inl(ioaddr,i); - } - for(i=MAC_CR;i<=WUCSR;i++) { - spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MAC_CSR(i, reg); - spin_unlock_irqrestore(&lp->lock, flags); - data[j++] = reg; - } - for(i=0;i<=31;i++) { - spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MII(i, lp->mii.phy_id, reg); - spin_unlock_irqrestore(&lp->lock, flags); - data[j++] = reg & 0xFFFF; - } -} - -static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - unsigned int timeout; - int e2p_cmd; - - e2p_cmd = SMC_GET_E2P_CMD(); - for(timeout=10;(e2p_cmd & E2P_CMD_EPC_BUSY_) && timeout; timeout--) { - if (e2p_cmd & E2P_CMD_EPC_TIMEOUT_) { - PRINTK("%s: %s timeout waiting for EEPROM to respond\n", - dev->name, __FUNCTION__); - return -EFAULT; - } - mdelay(1); - e2p_cmd = SMC_GET_E2P_CMD(); - } - if (timeout == 0) { - PRINTK("%s: %s timeout waiting for EEPROM CMD not busy\n", - dev->name, __FUNCTION__); - return -ETIMEDOUT; - } - return 0; -} - -static inline int smc911x_ethtool_write_eeprom_cmd(struct net_device *dev, - int cmd, int addr) -{ - unsigned long ioaddr = dev->base_addr; - int ret; - - if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0) - return ret; - SMC_SET_E2P_CMD(E2P_CMD_EPC_BUSY_ | - ((cmd) & (0x7<<28)) | - ((addr) & 0xFF)); - return 0; -} - -static inline int smc911x_ethtool_read_eeprom_byte(struct net_device *dev, - u8 *data) -{ - unsigned long ioaddr = dev->base_addr; - int ret; - - if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0) - return ret; - *data = SMC_GET_E2P_DATA(); - return 0; -} - -static inline int smc911x_ethtool_write_eeprom_byte(struct net_device *dev, - u8 data) -{ - unsigned long ioaddr = dev->base_addr; - int ret; - - if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0) - return ret; - SMC_SET_E2P_DATA(data); - return 0; -} - -static int smc911x_ethtool_geteeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data) -{ - u8 eebuf[SMC911X_EEPROM_LEN]; - int i, ret; - - for(i=0;ioffset, eeprom->len); - return 0; -} - -static int smc911x_ethtool_seteeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data) -{ - int i, ret; - - /* Enable erase */ - if ((ret=smc911x_ethtool_write_eeprom_cmd(dev, E2P_CMD_EPC_CMD_EWEN_, 0 ))!=0) - return ret; - for(i=eeprom->offset;i<(eeprom->offset+eeprom->len);i++) { - /* erase byte */ - if ((ret=smc911x_ethtool_write_eeprom_cmd(dev, E2P_CMD_EPC_CMD_ERASE_, i ))!=0) - return ret; - /* write byte */ - if ((ret=smc911x_ethtool_write_eeprom_byte(dev, *data))!=0) - return ret; - if ((ret=smc911x_ethtool_write_eeprom_cmd(dev, E2P_CMD_EPC_CMD_WRITE_, i ))!=0) - return ret; - } - return 0; -} - -static int smc911x_ethtool_geteeprom_len(struct net_device *dev) -{ - return SMC911X_EEPROM_LEN; -} - -static struct ethtool_ops smc911x_ethtool_ops = { - .get_settings = smc911x_ethtool_getsettings, - .set_settings = smc911x_ethtool_setsettings, - .get_drvinfo = smc911x_ethtool_getdrvinfo, - .get_msglevel = smc911x_ethtool_getmsglevel, - .set_msglevel = smc911x_ethtool_setmsglevel, - .nway_reset = smc911x_ethtool_nwayreset, - .get_link = ethtool_op_get_link, - .get_regs_len = smc911x_ethtool_getregslen, - .get_regs = smc911x_ethtool_getregs, - .get_eeprom_len = smc911x_ethtool_geteeprom_len, - .get_eeprom = smc911x_ethtool_geteeprom, - .set_eeprom = smc911x_ethtool_seteeprom, -}; - -/* - * smc911x_findirq - * - * This routine has a simple purpose -- make the SMC chip generate an - * interrupt, so an auto-detect routine can detect it, and find the IRQ, - */ -static int __init smc911x_findirq(unsigned long ioaddr) -{ - int timeout = 20; - unsigned long cookie; - - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); - - cookie = probe_irq_on(); - - /* - * Force a SW interrupt - */ - - SMC_SET_INT_EN(INT_EN_SW_INT_EN_); - - /* - * Wait until positive that the interrupt has been generated - */ - do { - int int_status; - udelay(10); - int_status = SMC_GET_INT_EN(); - if (int_status & INT_EN_SW_INT_EN_) - break; /* got the interrupt */ - } while (--timeout); - - /* - * there is really nothing that I can do here if timeout fails, - * as autoirq_report will return a 0 anyway, which is what I - * want in this case. Plus, the clean up is needed in both - * cases. - */ - - /* and disable all interrupts again */ - SMC_SET_INT_EN(0); - - /* and return what I found */ - return probe_irq_off(cookie); -} - -/* - * Function: smc911x_probe(unsigned long ioaddr) - * - * Purpose: - * Tests to see if a given ioaddr points to an SMC911x chip. - * Returns a 0 on success - * - * Algorithm: - * (1) see if the endian word is OK - * (1) see if I recognize the chip ID in the appropriate register - * - * Here I do typical initialization tasks. - * - * o Initialize the structure if needed - * o print out my vanity message if not done so already - * o print out what type of hardware is detected - * o print out the ethernet address - * o find the IRQ - * o set up my private data - * o configure the dev structure with my subroutines - * o actually GRAB the irq. - * o GRAB the region - */ -static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr) -{ - struct smc911x_local *lp = netdev_priv(dev); - int i, retval; - unsigned int val, chip_id, revision; - const char *version_string; - - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - /* First, see if the endian word is recognized */ - val = SMC_GET_BYTE_TEST(); - DBG(SMC_DEBUG_MISC, "%s: endian probe returned 0x%04x\n", CARDNAME, val); - if (val != 0x87654321) { - printk(KERN_ERR "Invalid chip endian 0x08%x\n",val); - retval = -ENODEV; - goto err_out; - } - - /* - * check if the revision register is something that I - * recognize. These might need to be added to later, - * as future revisions could be added. - */ - chip_id = SMC_GET_PN(); - DBG(SMC_DEBUG_MISC, "%s: id probe returned 0x%04x\n", CARDNAME, chip_id); - for(i=0;chip_ids[i].id != 0; i++) { - if (chip_ids[i].id == chip_id) break; - } - if (!chip_ids[i].id) { - printk(KERN_ERR "Unknown chip ID %04x\n", chip_id); - retval = -ENODEV; - goto err_out; - } - version_string = chip_ids[i].name; - - revision = SMC_GET_REV(); - DBG(SMC_DEBUG_MISC, "%s: revision = 0x%04x\n", CARDNAME, revision); - - /* At this point I'll assume that the chip is an SMC911x. */ - DBG(SMC_DEBUG_MISC, "%s: Found a %s\n", CARDNAME, chip_ids[i].name); - - /* Validate the TX FIFO size requested */ - if ((tx_fifo_kb < 2) || (tx_fifo_kb > 14)) { - printk(KERN_ERR "Invalid TX FIFO size requested %d\n", tx_fifo_kb); - retval = -EINVAL; - goto err_out; - } - - /* fill in some of the fields */ - dev->base_addr = ioaddr; - lp->version = chip_ids[i].id; - lp->revision = revision; - lp->tx_fifo_kb = tx_fifo_kb; - /* Reverse calculate the RX FIFO size from the TX */ - lp->tx_fifo_size=(lp->tx_fifo_kb<<10) - 512; - lp->rx_fifo_size= ((0x4000 - 512 - lp->tx_fifo_size) / 16) * 15; - - /* Set the automatic flow control values */ - switch(lp->tx_fifo_kb) { - /* - * AFC_HI is about ((Rx Data Fifo Size)*2/3)/64 - * AFC_LO is AFC_HI/2 - * BACK_DUR is about 5uS*(AFC_LO) rounded down - */ - case 2:/* 13440 Rx Data Fifo Size */ - lp->afc_cfg=0x008C46AF;break; - case 3:/* 12480 Rx Data Fifo Size */ - lp->afc_cfg=0x0082419F;break; - case 4:/* 11520 Rx Data Fifo Size */ - lp->afc_cfg=0x00783C9F;break; - case 5:/* 10560 Rx Data Fifo Size */ - lp->afc_cfg=0x006E374F;break; - case 6:/* 9600 Rx Data Fifo Size */ - lp->afc_cfg=0x0064328F;break; - case 7:/* 8640 Rx Data Fifo Size */ - lp->afc_cfg=0x005A2D7F;break; - case 8:/* 7680 Rx Data Fifo Size */ - lp->afc_cfg=0x0050287F;break; - case 9:/* 6720 Rx Data Fifo Size */ - lp->afc_cfg=0x0046236F;break; - case 10:/* 5760 Rx Data Fifo Size */ - lp->afc_cfg=0x003C1E6F;break; - case 11:/* 4800 Rx Data Fifo Size */ - lp->afc_cfg=0x0032195F;break; - /* - * AFC_HI is ~1520 bytes less than RX Data Fifo Size - * AFC_LO is AFC_HI/2 - * BACK_DUR is about 5uS*(AFC_LO) rounded down - */ - case 12:/* 3840 Rx Data Fifo Size */ - lp->afc_cfg=0x0024124F;break; - case 13:/* 2880 Rx Data Fifo Size */ - lp->afc_cfg=0x0015073F;break; - case 14:/* 1920 Rx Data Fifo Size */ - lp->afc_cfg=0x0006032F;break; - default: - PRINTK("%s: ERROR -- no AFC_CFG setting found", - dev->name); - break; - } - - DBG(SMC_DEBUG_MISC | SMC_DEBUG_TX | SMC_DEBUG_RX, - "%s: tx_fifo %d rx_fifo %d afc_cfg 0x%08x\n", CARDNAME, - lp->tx_fifo_size, lp->rx_fifo_size, lp->afc_cfg); - - spin_lock_init(&lp->lock); - - /* Get the MAC address */ - SMC_GET_MAC_ADDR(dev->dev_addr); - - /* now, reset the chip, and put it into a known state */ - smc911x_reset(dev); - - /* - * If dev->irq is 0, then the device has to be banged on to see - * what the IRQ is. - * - * Specifying an IRQ is done with the assumption that the user knows - * what (s)he is doing. No checking is done!!!! - */ - if (dev->irq < 1) { - int trials; - - trials = 3; - while (trials--) { - dev->irq = smc911x_findirq(ioaddr); - if (dev->irq) - break; - /* kick the card and try again */ - smc911x_reset(dev); - } - } - if (dev->irq == 0) { - printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n", - dev->name); - retval = -ENODEV; - goto err_out; - } - dev->irq = irq_canonicalize(dev->irq); - - /* Fill in the fields of the device structure with ethernet values. */ - ether_setup(dev); - - dev->open = smc911x_open; - dev->stop = smc911x_close; - dev->hard_start_xmit = smc911x_hard_start_xmit; - dev->tx_timeout = smc911x_timeout; - dev->watchdog_timeo = msecs_to_jiffies(watchdog); - dev->get_stats = smc911x_query_statistics; - dev->set_multicast_list = smc911x_set_multicast_list; - dev->ethtool_ops = &smc911x_ethtool_ops; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = smc911x_poll_controller; -#endif - - INIT_WORK(&lp->phy_configure, smc911x_phy_configure, dev); - lp->mii.phy_id_mask = 0x1f; - lp->mii.reg_num_mask = 0x1f; - lp->mii.force_media = 0; - lp->mii.full_duplex = 0; - lp->mii.dev = dev; - lp->mii.mdio_read = smc911x_phy_read; - lp->mii.mdio_write = smc911x_phy_write; - - /* - * Locate the phy, if any. - */ - smc911x_phy_detect(dev); - - /* Set default parameters */ - lp->msg_enable = NETIF_MSG_LINK; - lp->ctl_rfduplx = 1; - lp->ctl_rspeed = 100; - - /* Grab the IRQ */ - retval = request_irq(dev->irq, &smc911x_interrupt, SA_SHIRQ, dev->name, dev); - if (retval) - goto err_out; - - set_irq_type(dev->irq, IRQT_FALLING); - -#ifdef SMC_USE_DMA - lp->rxdma = SMC_DMA_REQUEST(dev, smc911x_rx_dma_irq); - lp->txdma = SMC_DMA_REQUEST(dev, smc911x_tx_dma_irq); - lp->rxdma_active = 0; - lp->txdma_active = 0; - dev->dma = lp->rxdma; -#endif - - retval = register_netdev(dev); - if (retval == 0) { - /* now, print out the card info, in a short format.. */ - printk("%s: %s (rev %d) at %#lx IRQ %d", - dev->name, version_string, lp->revision, - dev->base_addr, dev->irq); - -#ifdef SMC_USE_DMA - if (lp->rxdma != -1) - printk(" RXDMA %d ", lp->rxdma); - - if (lp->txdma != -1) - printk("TXDMA %d", lp->txdma); -#endif - printk("\n"); - if (!is_valid_ether_addr(dev->dev_addr)) { - printk("%s: Invalid ethernet MAC address. Please " - "set using ifconfig\n", dev->name); - } else { - /* Print the Ethernet address */ - printk("%s: Ethernet addr: ", dev->name); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x\n", dev->dev_addr[5]); - } - - if (lp->phy_type == 0) { - PRINTK("%s: No PHY found\n", dev->name); - } else if ((lp->phy_type & ~0xff) == LAN911X_INTERNAL_PHY_ID) { - PRINTK("%s: LAN911x Internal PHY\n", dev->name); - } else { - PRINTK("%s: External PHY 0x%08x\n", dev->name, lp->phy_type); - } - } - -err_out: -#ifdef SMC_USE_DMA - if (retval) { - if (lp->rxdma != -1) { - SMC_DMA_FREE(dev, lp->rxdma); - } - if (lp->txdma != -1) { - SMC_DMA_FREE(dev, lp->txdma); - } - } -#endif - return retval; -} - -/* - * smc911x_init(void) - * - * Output: - * 0 --> there is a device - * anything else, error - */ -static int smc911x_drv_probe(struct platform_device *pdev) -{ - struct net_device *ndev; - struct resource *res; - unsigned int *addr; - int ret; - - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENODEV; - goto out; - } - - /* - * Request the regions. - */ - if (!request_mem_region(res->start, SMC911X_IO_EXTENT, CARDNAME)) { - ret = -EBUSY; - goto out; - } - - ndev = alloc_etherdev(sizeof(struct smc911x_local)); - if (!ndev) { - printk("%s: could not allocate device.\n", CARDNAME); - ret = -ENOMEM; - goto release_1; - } - SET_MODULE_OWNER(ndev); - SET_NETDEV_DEV(ndev, &pdev->dev); - - ndev->dma = (unsigned char)-1; - ndev->irq = platform_get_irq(pdev, 0); - - addr = ioremap(res->start, SMC911X_IO_EXTENT); - if (!addr) { - ret = -ENOMEM; - goto release_both; - } - - platform_set_drvdata(pdev, ndev); - ret = smc911x_probe(ndev, (unsigned long)addr); - if (ret != 0) { - platform_set_drvdata(pdev, NULL); - iounmap(addr); -release_both: - free_netdev(ndev); -release_1: - release_mem_region(res->start, SMC911X_IO_EXTENT); -out: - printk("%s: not found (%d).\n", CARDNAME, ret); - } -#ifdef SMC_USE_DMA - else { - struct smc911x_local *lp = netdev_priv(ndev); - lp->physaddr = res->start; - lp->dev = &pdev->dev; - } -#endif - - return ret; -} - -static int smc911x_drv_remove(struct platform_device *pdev) -{ - struct net_device *ndev = platform_get_drvdata(pdev); - struct resource *res; - - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); - platform_set_drvdata(pdev, NULL); - - unregister_netdev(ndev); - - free_irq(ndev->irq, ndev); - -#ifdef SMC_USE_DMA - { - struct smc911x_local *lp = netdev_priv(ndev); - if (lp->rxdma != -1) { - SMC_DMA_FREE(dev, lp->rxdma); - } - if (lp->txdma != -1) { - SMC_DMA_FREE(dev, lp->txdma); - } - } -#endif - iounmap((void *)ndev->base_addr); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, SMC911X_IO_EXTENT); - - free_netdev(ndev); - return 0; -} - -static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state) -{ - struct net_device *ndev = platform_get_drvdata(dev); - unsigned long ioaddr = ndev->base_addr; - - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); - if (ndev) { - if (netif_running(ndev)) { - netif_device_detach(ndev); - smc911x_shutdown(ndev); -#if POWER_DOWN - /* Set D2 - Energy detect only setting */ - SMC_SET_PMT_CTRL(2<<12); -#endif - } - } - return 0; -} - -static int smc911x_drv_resume(struct platform_device *dev) -{ - struct net_device *ndev = platform_get_drvdata(dev); - - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); - if (ndev) { - struct smc911x_local *lp = netdev_priv(ndev); - - if (netif_running(ndev)) { - smc911x_reset(ndev); - smc911x_enable(ndev); - if (lp->phy_type != 0) - smc911x_phy_configure(ndev); - netif_device_attach(ndev); - } - } - return 0; -} - -static struct platform_driver smc911x_driver = { - .probe = smc911x_drv_probe, - .remove = smc911x_drv_remove, - .suspend = smc911x_drv_suspend, - .resume = smc911x_drv_resume, - .driver = { - .name = CARDNAME, - }, -}; - -static int __init smc911x_init(void) -{ - return platform_driver_register(&smc911x_driver); -} - -static void __exit smc911x_cleanup(void) -{ - platform_driver_unregister(&smc911x_driver); -} - -module_init(smc911x_init); -module_exit(smc911x_cleanup); diff --git a/trunk/drivers/net/smc911x.h b/trunk/drivers/net/smc911x.h deleted file mode 100644 index 962a710459fc..000000000000 --- a/trunk/drivers/net/smc911x.h +++ /dev/null @@ -1,835 +0,0 @@ -/*------------------------------------------------------------------------ - . smc911x.h - macros for SMSC's LAN911{5,6,7,8} single-chip Ethernet device. - . - . Copyright (C) 2005 Sensoria Corp. - . Derived from the unified SMC91x driver by Nicolas Pitre - . - . 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 - . - . Information contained in this file was obtained from the LAN9118 - . manual from SMC. To get a copy, if you really want one, you can find - . information under www.smsc.com. - . - . Authors - . Dustin McIntire - . - ---------------------------------------------------------------------------*/ -#ifndef _SMC911X_H_ -#define _SMC911X_H_ - -/* - * Use the DMA feature on PXA chips - */ -#ifdef CONFIG_ARCH_PXA - #define SMC_USE_PXA_DMA 1 - #define SMC_USE_16BIT 0 - #define SMC_USE_32BIT 1 -#endif - - -/* - * Define the bus width specific IO macros - */ - -#if SMC_USE_16BIT -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16)) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_outl(v, a, r) \ - do{ \ - writel(v & 0xFFFF, (a) + (r)); \ - writel(v >> 16, (a) + (r) + 2); \ - } while (0) -#define SMC_insl(a, r, p, l) readsw((short*)((a) + (r)), p, l*2) -#define SMC_outsl(a, r, p, l) writesw((short*)((a) + (r)), p, l*2) - -#elif SMC_USE_32BIT -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insl(a, r, p, l) readsl((int*)((a) + (r)), p, l) -#define SMC_outsl(a, r, p, l) writesl((int*)((a) + (r)), p, l) - -#endif /* SMC_USE_16BIT */ - - - -#if SMC_USE_PXA_DMA -#define SMC_USE_DMA - -/* - * Define the request and free functions - * These are unfortunately architecture specific as no generic allocation - * mechanism exits - */ -#define SMC_DMA_REQUEST(dev, handler) \ - pxa_request_dma(dev->name, DMA_PRIO_LOW, handler, dev) - -#define SMC_DMA_FREE(dev, dma) \ - pxa_free_dma(dma) - -#define SMC_DMA_ACK_IRQ(dev, dma) \ -{ \ - if (DCSR(dma) & DCSR_BUSERR) { \ - printk("%s: DMA %d bus error!\n", dev->name, dma); \ - } \ - DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; \ -} - -/* - * Use a DMA for RX and TX packets. - */ -#include -#include -#include - -static dma_addr_t rx_dmabuf, tx_dmabuf; -static int rx_dmalen, tx_dmalen; - -#ifdef SMC_insl -#undef SMC_insl -#define SMC_insl(a, r, p, l) \ - smc_pxa_dma_insl(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l) - -static inline void -smc_pxa_dma_insl(struct device *dev, u_long ioaddr, u_long physaddr, - int reg, int dma, u_char *buf, int len) -{ - /* 64 bit alignment is required for memory to memory DMA */ - if ((long)buf & 4) { - *((u32 *)buf) = SMC_inl(ioaddr, reg); - buf += 4; - len--; - } - - len *= 4; - rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE); - rx_dmalen = len; - DCSR(dma) = DCSR_NODESC; - DTADR(dma) = rx_dmabuf; - DSADR(dma) = physaddr + reg; - DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | - DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen)); - DCSR(dma) = DCSR_NODESC | DCSR_RUN; -} -#endif - -#ifdef SMC_insw -#undef SMC_insw -#define SMC_insw(a, r, p, l) \ - smc_pxa_dma_insw(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l) - -static inline void -smc_pxa_dma_insw(struct device *dev, u_long ioaddr, u_long physaddr, - int reg, int dma, u_char *buf, int len) -{ - /* 64 bit alignment is required for memory to memory DMA */ - while ((long)buf & 6) { - *((u16 *)buf) = SMC_inw(ioaddr, reg); - buf += 2; - len--; - } - - len *= 2; - rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE); - rx_dmalen = len; - DCSR(dma) = DCSR_NODESC; - DTADR(dma) = rx_dmabuf; - DSADR(dma) = physaddr + reg; - DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | - DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen)); - DCSR(dma) = DCSR_NODESC | DCSR_RUN; -} -#endif - -#ifdef SMC_outsl -#undef SMC_outsl -#define SMC_outsl(a, r, p, l) \ - smc_pxa_dma_outsl(lp->dev, a, lp->physaddr, r, lp->txdma, p, l) - -static inline void -smc_pxa_dma_outsl(struct device *dev, u_long ioaddr, u_long physaddr, - int reg, int dma, u_char *buf, int len) -{ - /* 64 bit alignment is required for memory to memory DMA */ - if ((long)buf & 4) { - SMC_outl(*((u32 *)buf), ioaddr, reg); - buf += 4; - len--; - } - - len *= 4; - tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE); - tx_dmalen = len; - DCSR(dma) = DCSR_NODESC; - DSADR(dma) = tx_dmabuf; - DTADR(dma) = physaddr + reg; - DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 | - DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen)); - DCSR(dma) = DCSR_NODESC | DCSR_RUN; -} -#endif - -#ifdef SMC_outsw -#undef SMC_outsw -#define SMC_outsw(a, r, p, l) \ - smc_pxa_dma_outsw(lp->dev, a, lp->physaddr, r, lp->txdma, p, l) - -static inline void -smc_pxa_dma_outsw(struct device *dev, u_long ioaddr, u_long physaddr, - int reg, int dma, u_char *buf, int len) -{ - /* 64 bit alignment is required for memory to memory DMA */ - while ((long)buf & 6) { - SMC_outw(*((u16 *)buf), ioaddr, reg); - buf += 2; - len--; - } - - len *= 2; - tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE); - tx_dmalen = len; - DCSR(dma) = DCSR_NODESC; - DSADR(dma) = tx_dmabuf; - DTADR(dma) = physaddr + reg; - DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 | - DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen)); - DCSR(dma) = DCSR_NODESC | DCSR_RUN; -} -#endif - -#endif /* SMC_USE_PXA_DMA */ - - -/* Chip Parameters and Register Definitions */ - -#define SMC911X_TX_FIFO_LOW_THRESHOLD (1536*2) - -#define SMC911X_IO_EXTENT 0x100 - -#define SMC911X_EEPROM_LEN 7 - -/* Below are the register offsets and bit definitions - * of the Lan911x memory space - */ -#define RX_DATA_FIFO (0x00) - -#define TX_DATA_FIFO (0x20) -#define TX_CMD_A_INT_ON_COMP_ (0x80000000) -#define TX_CMD_A_INT_BUF_END_ALGN_ (0x03000000) -#define TX_CMD_A_INT_4_BYTE_ALGN_ (0x00000000) -#define TX_CMD_A_INT_16_BYTE_ALGN_ (0x01000000) -#define TX_CMD_A_INT_32_BYTE_ALGN_ (0x02000000) -#define TX_CMD_A_INT_DATA_OFFSET_ (0x001F0000) -#define TX_CMD_A_INT_FIRST_SEG_ (0x00002000) -#define TX_CMD_A_INT_LAST_SEG_ (0x00001000) -#define TX_CMD_A_BUF_SIZE_ (0x000007FF) -#define TX_CMD_B_PKT_TAG_ (0xFFFF0000) -#define TX_CMD_B_ADD_CRC_DISABLE_ (0x00002000) -#define TX_CMD_B_DISABLE_PADDING_ (0x00001000) -#define TX_CMD_B_PKT_BYTE_LENGTH_ (0x000007FF) - -#define RX_STATUS_FIFO (0x40) -#define RX_STS_PKT_LEN_ (0x3FFF0000) -#define RX_STS_ES_ (0x00008000) -#define RX_STS_BCST_ (0x00002000) -#define RX_STS_LEN_ERR_ (0x00001000) -#define RX_STS_RUNT_ERR_ (0x00000800) -#define RX_STS_MCAST_ (0x00000400) -#define RX_STS_TOO_LONG_ (0x00000080) -#define RX_STS_COLL_ (0x00000040) -#define RX_STS_ETH_TYPE_ (0x00000020) -#define RX_STS_WDOG_TMT_ (0x00000010) -#define RX_STS_MII_ERR_ (0x00000008) -#define RX_STS_DRIBBLING_ (0x00000004) -#define RX_STS_CRC_ERR_ (0x00000002) -#define RX_STATUS_FIFO_PEEK (0x44) -#define TX_STATUS_FIFO (0x48) -#define TX_STS_TAG_ (0xFFFF0000) -#define TX_STS_ES_ (0x00008000) -#define TX_STS_LOC_ (0x00000800) -#define TX_STS_NO_CARR_ (0x00000400) -#define TX_STS_LATE_COLL_ (0x00000200) -#define TX_STS_MANY_COLL_ (0x00000100) -#define TX_STS_COLL_CNT_ (0x00000078) -#define TX_STS_MANY_DEFER_ (0x00000004) -#define TX_STS_UNDERRUN_ (0x00000002) -#define TX_STS_DEFERRED_ (0x00000001) -#define TX_STATUS_FIFO_PEEK (0x4C) -#define ID_REV (0x50) -#define ID_REV_CHIP_ID_ (0xFFFF0000) /* RO */ -#define ID_REV_REV_ID_ (0x0000FFFF) /* RO */ - -#define INT_CFG (0x54) -#define INT_CFG_INT_DEAS_ (0xFF000000) /* R/W */ -#define INT_CFG_INT_DEAS_CLR_ (0x00004000) -#define INT_CFG_INT_DEAS_STS_ (0x00002000) -#define INT_CFG_IRQ_INT_ (0x00001000) /* RO */ -#define INT_CFG_IRQ_EN_ (0x00000100) /* R/W */ -#define INT_CFG_IRQ_POL_ (0x00000010) /* R/W Not Affected by SW Reset */ -#define INT_CFG_IRQ_TYPE_ (0x00000001) /* R/W Not Affected by SW Reset */ - -#define INT_STS (0x58) -#define INT_STS_SW_INT_ (0x80000000) /* R/WC */ -#define INT_STS_TXSTOP_INT_ (0x02000000) /* R/WC */ -#define INT_STS_RXSTOP_INT_ (0x01000000) /* R/WC */ -#define INT_STS_RXDFH_INT_ (0x00800000) /* R/WC */ -#define INT_STS_RXDF_INT_ (0x00400000) /* R/WC */ -#define INT_STS_TX_IOC_ (0x00200000) /* R/WC */ -#define INT_STS_RXD_INT_ (0x00100000) /* R/WC */ -#define INT_STS_GPT_INT_ (0x00080000) /* R/WC */ -#define INT_STS_PHY_INT_ (0x00040000) /* RO */ -#define INT_STS_PME_INT_ (0x00020000) /* R/WC */ -#define INT_STS_TXSO_ (0x00010000) /* R/WC */ -#define INT_STS_RWT_ (0x00008000) /* R/WC */ -#define INT_STS_RXE_ (0x00004000) /* R/WC */ -#define INT_STS_TXE_ (0x00002000) /* R/WC */ -//#define INT_STS_ERX_ (0x00001000) /* R/WC */ -#define INT_STS_TDFU_ (0x00000800) /* R/WC */ -#define INT_STS_TDFO_ (0x00000400) /* R/WC */ -#define INT_STS_TDFA_ (0x00000200) /* R/WC */ -#define INT_STS_TSFF_ (0x00000100) /* R/WC */ -#define INT_STS_TSFL_ (0x00000080) /* R/WC */ -//#define INT_STS_RXDF_ (0x00000040) /* R/WC */ -#define INT_STS_RDFO_ (0x00000040) /* R/WC */ -#define INT_STS_RDFL_ (0x00000020) /* R/WC */ -#define INT_STS_RSFF_ (0x00000010) /* R/WC */ -#define INT_STS_RSFL_ (0x00000008) /* R/WC */ -#define INT_STS_GPIO2_INT_ (0x00000004) /* R/WC */ -#define INT_STS_GPIO1_INT_ (0x00000002) /* R/WC */ -#define INT_STS_GPIO0_INT_ (0x00000001) /* R/WC */ - -#define INT_EN (0x5C) -#define INT_EN_SW_INT_EN_ (0x80000000) /* R/W */ -#define INT_EN_TXSTOP_INT_EN_ (0x02000000) /* R/W */ -#define INT_EN_RXSTOP_INT_EN_ (0x01000000) /* R/W */ -#define INT_EN_RXDFH_INT_EN_ (0x00800000) /* R/W */ -//#define INT_EN_RXDF_INT_EN_ (0x00400000) /* R/W */ -#define INT_EN_TIOC_INT_EN_ (0x00200000) /* R/W */ -#define INT_EN_RXD_INT_EN_ (0x00100000) /* R/W */ -#define INT_EN_GPT_INT_EN_ (0x00080000) /* R/W */ -#define INT_EN_PHY_INT_EN_ (0x00040000) /* R/W */ -#define INT_EN_PME_INT_EN_ (0x00020000) /* R/W */ -#define INT_EN_TXSO_EN_ (0x00010000) /* R/W */ -#define INT_EN_RWT_EN_ (0x00008000) /* R/W */ -#define INT_EN_RXE_EN_ (0x00004000) /* R/W */ -#define INT_EN_TXE_EN_ (0x00002000) /* R/W */ -//#define INT_EN_ERX_EN_ (0x00001000) /* R/W */ -#define INT_EN_TDFU_EN_ (0x00000800) /* R/W */ -#define INT_EN_TDFO_EN_ (0x00000400) /* R/W */ -#define INT_EN_TDFA_EN_ (0x00000200) /* R/W */ -#define INT_EN_TSFF_EN_ (0x00000100) /* R/W */ -#define INT_EN_TSFL_EN_ (0x00000080) /* R/W */ -//#define INT_EN_RXDF_EN_ (0x00000040) /* R/W */ -#define INT_EN_RDFO_EN_ (0x00000040) /* R/W */ -#define INT_EN_RDFL_EN_ (0x00000020) /* R/W */ -#define INT_EN_RSFF_EN_ (0x00000010) /* R/W */ -#define INT_EN_RSFL_EN_ (0x00000008) /* R/W */ -#define INT_EN_GPIO2_INT_ (0x00000004) /* R/W */ -#define INT_EN_GPIO1_INT_ (0x00000002) /* R/W */ -#define INT_EN_GPIO0_INT_ (0x00000001) /* R/W */ - -#define BYTE_TEST (0x64) -#define FIFO_INT (0x68) -#define FIFO_INT_TX_AVAIL_LEVEL_ (0xFF000000) /* R/W */ -#define FIFO_INT_TX_STS_LEVEL_ (0x00FF0000) /* R/W */ -#define FIFO_INT_RX_AVAIL_LEVEL_ (0x0000FF00) /* R/W */ -#define FIFO_INT_RX_STS_LEVEL_ (0x000000FF) /* R/W */ - -#define RX_CFG (0x6C) -#define RX_CFG_RX_END_ALGN_ (0xC0000000) /* R/W */ -#define RX_CFG_RX_END_ALGN4_ (0x00000000) /* R/W */ -#define RX_CFG_RX_END_ALGN16_ (0x40000000) /* R/W */ -#define RX_CFG_RX_END_ALGN32_ (0x80000000) /* R/W */ -#define RX_CFG_RX_DMA_CNT_ (0x0FFF0000) /* R/W */ -#define RX_CFG_RX_DUMP_ (0x00008000) /* R/W */ -#define RX_CFG_RXDOFF_ (0x00001F00) /* R/W */ -//#define RX_CFG_RXBAD_ (0x00000001) /* R/W */ - -#define TX_CFG (0x70) -//#define TX_CFG_TX_DMA_LVL_ (0xE0000000) /* R/W */ -//#define TX_CFG_TX_DMA_CNT_ (0x0FFF0000) /* R/W Self Clearing */ -#define TX_CFG_TXS_DUMP_ (0x00008000) /* Self Clearing */ -#define TX_CFG_TXD_DUMP_ (0x00004000) /* Self Clearing */ -#define TX_CFG_TXSAO_ (0x00000004) /* R/W */ -#define TX_CFG_TX_ON_ (0x00000002) /* R/W */ -#define TX_CFG_STOP_TX_ (0x00000001) /* Self Clearing */ - -#define HW_CFG (0x74) -#define HW_CFG_TTM_ (0x00200000) /* R/W */ -#define HW_CFG_SF_ (0x00100000) /* R/W */ -#define HW_CFG_TX_FIF_SZ_ (0x000F0000) /* R/W */ -#define HW_CFG_TR_ (0x00003000) /* R/W */ -#define HW_CFG_PHY_CLK_SEL_ (0x00000060) /* R/W */ -#define HW_CFG_PHY_CLK_SEL_INT_PHY_ (0x00000000) /* R/W */ -#define HW_CFG_PHY_CLK_SEL_EXT_PHY_ (0x00000020) /* R/W */ -#define HW_CFG_PHY_CLK_SEL_CLK_DIS_ (0x00000040) /* R/W */ -#define HW_CFG_SMI_SEL_ (0x00000010) /* R/W */ -#define HW_CFG_EXT_PHY_DET_ (0x00000008) /* RO */ -#define HW_CFG_EXT_PHY_EN_ (0x00000004) /* R/W */ -#define HW_CFG_32_16_BIT_MODE_ (0x00000004) /* RO */ -#define HW_CFG_SRST_TO_ (0x00000002) /* RO */ -#define HW_CFG_SRST_ (0x00000001) /* Self Clearing */ - -#define RX_DP_CTRL (0x78) -#define RX_DP_CTRL_RX_FFWD_ (0x80000000) /* R/W */ -#define RX_DP_CTRL_FFWD_BUSY_ (0x80000000) /* RO */ - -#define RX_FIFO_INF (0x7C) -#define RX_FIFO_INF_RXSUSED_ (0x00FF0000) /* RO */ -#define RX_FIFO_INF_RXDUSED_ (0x0000FFFF) /* RO */ - -#define TX_FIFO_INF (0x80) -#define TX_FIFO_INF_TSUSED_ (0x00FF0000) /* RO */ -#define TX_FIFO_INF_TDFREE_ (0x0000FFFF) /* RO */ - -#define PMT_CTRL (0x84) -#define PMT_CTRL_PM_MODE_ (0x00003000) /* Self Clearing */ -#define PMT_CTRL_PHY_RST_ (0x00000400) /* Self Clearing */ -#define PMT_CTRL_WOL_EN_ (0x00000200) /* R/W */ -#define PMT_CTRL_ED_EN_ (0x00000100) /* R/W */ -#define PMT_CTRL_PME_TYPE_ (0x00000040) /* R/W Not Affected by SW Reset */ -#define PMT_CTRL_WUPS_ (0x00000030) /* R/WC */ -#define PMT_CTRL_WUPS_NOWAKE_ (0x00000000) /* R/WC */ -#define PMT_CTRL_WUPS_ED_ (0x00000010) /* R/WC */ -#define PMT_CTRL_WUPS_WOL_ (0x00000020) /* R/WC */ -#define PMT_CTRL_WUPS_MULTI_ (0x00000030) /* R/WC */ -#define PMT_CTRL_PME_IND_ (0x00000008) /* R/W */ -#define PMT_CTRL_PME_POL_ (0x00000004) /* R/W */ -#define PMT_CTRL_PME_EN_ (0x00000002) /* R/W Not Affected by SW Reset */ -#define PMT_CTRL_READY_ (0x00000001) /* RO */ - -#define GPIO_CFG (0x88) -#define GPIO_CFG_LED3_EN_ (0x40000000) /* R/W */ -#define GPIO_CFG_LED2_EN_ (0x20000000) /* R/W */ -#define GPIO_CFG_LED1_EN_ (0x10000000) /* R/W */ -#define GPIO_CFG_GPIO2_INT_POL_ (0x04000000) /* R/W */ -#define GPIO_CFG_GPIO1_INT_POL_ (0x02000000) /* R/W */ -#define GPIO_CFG_GPIO0_INT_POL_ (0x01000000) /* R/W */ -#define GPIO_CFG_EEPR_EN_ (0x00700000) /* R/W */ -#define GPIO_CFG_GPIOBUF2_ (0x00040000) /* R/W */ -#define GPIO_CFG_GPIOBUF1_ (0x00020000) /* R/W */ -#define GPIO_CFG_GPIOBUF0_ (0x00010000) /* R/W */ -#define GPIO_CFG_GPIODIR2_ (0x00000400) /* R/W */ -#define GPIO_CFG_GPIODIR1_ (0x00000200) /* R/W */ -#define GPIO_CFG_GPIODIR0_ (0x00000100) /* R/W */ -#define GPIO_CFG_GPIOD4_ (0x00000010) /* R/W */ -#define GPIO_CFG_GPIOD3_ (0x00000008) /* R/W */ -#define GPIO_CFG_GPIOD2_ (0x00000004) /* R/W */ -#define GPIO_CFG_GPIOD1_ (0x00000002) /* R/W */ -#define GPIO_CFG_GPIOD0_ (0x00000001) /* R/W */ - -#define GPT_CFG (0x8C) -#define GPT_CFG_TIMER_EN_ (0x20000000) /* R/W */ -#define GPT_CFG_GPT_LOAD_ (0x0000FFFF) /* R/W */ - -#define GPT_CNT (0x90) -#define GPT_CNT_GPT_CNT_ (0x0000FFFF) /* RO */ - -#define ENDIAN (0x98) -#define FREE_RUN (0x9C) -#define RX_DROP (0xA0) -#define MAC_CSR_CMD (0xA4) -#define MAC_CSR_CMD_CSR_BUSY_ (0x80000000) /* Self Clearing */ -#define MAC_CSR_CMD_R_NOT_W_ (0x40000000) /* R/W */ -#define MAC_CSR_CMD_CSR_ADDR_ (0x000000FF) /* R/W */ - -#define MAC_CSR_DATA (0xA8) -#define AFC_CFG (0xAC) -#define AFC_CFG_AFC_HI_ (0x00FF0000) /* R/W */ -#define AFC_CFG_AFC_LO_ (0x0000FF00) /* R/W */ -#define AFC_CFG_BACK_DUR_ (0x000000F0) /* R/W */ -#define AFC_CFG_FCMULT_ (0x00000008) /* R/W */ -#define AFC_CFG_FCBRD_ (0x00000004) /* R/W */ -#define AFC_CFG_FCADD_ (0x00000002) /* R/W */ -#define AFC_CFG_FCANY_ (0x00000001) /* R/W */ - -#define E2P_CMD (0xB0) -#define E2P_CMD_EPC_BUSY_ (0x80000000) /* Self Clearing */ -#define E2P_CMD_EPC_CMD_ (0x70000000) /* R/W */ -#define E2P_CMD_EPC_CMD_READ_ (0x00000000) /* R/W */ -#define E2P_CMD_EPC_CMD_EWDS_ (0x10000000) /* R/W */ -#define E2P_CMD_EPC_CMD_EWEN_ (0x20000000) /* R/W */ -#define E2P_CMD_EPC_CMD_WRITE_ (0x30000000) /* R/W */ -#define E2P_CMD_EPC_CMD_WRAL_ (0x40000000) /* R/W */ -#define E2P_CMD_EPC_CMD_ERASE_ (0x50000000) /* R/W */ -#define E2P_CMD_EPC_CMD_ERAL_ (0x60000000) /* R/W */ -#define E2P_CMD_EPC_CMD_RELOAD_ (0x70000000) /* R/W */ -#define E2P_CMD_EPC_TIMEOUT_ (0x00000200) /* RO */ -#define E2P_CMD_MAC_ADDR_LOADED_ (0x00000100) /* RO */ -#define E2P_CMD_EPC_ADDR_ (0x000000FF) /* R/W */ - -#define E2P_DATA (0xB4) -#define E2P_DATA_EEPROM_DATA_ (0x000000FF) /* R/W */ -/* end of LAN register offsets and bit definitions */ - -/* - **************************************************************************** - **************************************************************************** - * MAC Control and Status Register (Indirect Address) - * Offset (through the MAC_CSR CMD and DATA port) - **************************************************************************** - **************************************************************************** - * - */ -#define MAC_CR (0x01) /* R/W */ - -/* MAC_CR - MAC Control Register */ -#define MAC_CR_RXALL_ (0x80000000) -// TODO: delete this bit? It is not described in the data sheet. -#define MAC_CR_HBDIS_ (0x10000000) -#define MAC_CR_RCVOWN_ (0x00800000) -#define MAC_CR_LOOPBK_ (0x00200000) -#define MAC_CR_FDPX_ (0x00100000) -#define MAC_CR_MCPAS_ (0x00080000) -#define MAC_CR_PRMS_ (0x00040000) -#define MAC_CR_INVFILT_ (0x00020000) -#define MAC_CR_PASSBAD_ (0x00010000) -#define MAC_CR_HFILT_ (0x00008000) -#define MAC_CR_HPFILT_ (0x00002000) -#define MAC_CR_LCOLL_ (0x00001000) -#define MAC_CR_BCAST_ (0x00000800) -#define MAC_CR_DISRTY_ (0x00000400) -#define MAC_CR_PADSTR_ (0x00000100) -#define MAC_CR_BOLMT_MASK_ (0x000000C0) -#define MAC_CR_DFCHK_ (0x00000020) -#define MAC_CR_TXEN_ (0x00000008) -#define MAC_CR_RXEN_ (0x00000004) - -#define ADDRH (0x02) /* R/W mask 0x0000FFFFUL */ -#define ADDRL (0x03) /* R/W mask 0xFFFFFFFFUL */ -#define HASHH (0x04) /* R/W */ -#define HASHL (0x05) /* R/W */ - -#define MII_ACC (0x06) /* R/W */ -#define MII_ACC_PHY_ADDR_ (0x0000F800) -#define MII_ACC_MIIRINDA_ (0x000007C0) -#define MII_ACC_MII_WRITE_ (0x00000002) -#define MII_ACC_MII_BUSY_ (0x00000001) - -#define MII_DATA (0x07) /* R/W mask 0x0000FFFFUL */ - -#define FLOW (0x08) /* R/W */ -#define FLOW_FCPT_ (0xFFFF0000) -#define FLOW_FCPASS_ (0x00000004) -#define FLOW_FCEN_ (0x00000002) -#define FLOW_FCBSY_ (0x00000001) - -#define VLAN1 (0x09) /* R/W mask 0x0000FFFFUL */ -#define VLAN1_VTI1_ (0x0000ffff) - -#define VLAN2 (0x0A) /* R/W mask 0x0000FFFFUL */ -#define VLAN2_VTI2_ (0x0000ffff) - -#define WUFF (0x0B) /* WO */ - -#define WUCSR (0x0C) /* R/W */ -#define WUCSR_GUE_ (0x00000200) -#define WUCSR_WUFR_ (0x00000040) -#define WUCSR_MPR_ (0x00000020) -#define WUCSR_WAKE_EN_ (0x00000004) -#define WUCSR_MPEN_ (0x00000002) - -/* - **************************************************************************** - * Chip Specific MII Defines - **************************************************************************** - * - * Phy register offsets and bit definitions - * - */ - -#define PHY_MODE_CTRL_STS ((u32)17) /* Mode Control/Status Register */ -//#define MODE_CTRL_STS_FASTRIP_ ((u16)0x4000) -#define MODE_CTRL_STS_EDPWRDOWN_ ((u16)0x2000) -//#define MODE_CTRL_STS_LOWSQEN_ ((u16)0x0800) -//#define MODE_CTRL_STS_MDPREBP_ ((u16)0x0400) -//#define MODE_CTRL_STS_FARLOOPBACK_ ((u16)0x0200) -//#define MODE_CTRL_STS_FASTEST_ ((u16)0x0100) -//#define MODE_CTRL_STS_REFCLKEN_ ((u16)0x0010) -//#define MODE_CTRL_STS_PHYADBP_ ((u16)0x0008) -//#define MODE_CTRL_STS_FORCE_G_LINK_ ((u16)0x0004) -#define MODE_CTRL_STS_ENERGYON_ ((u16)0x0002) - -#define PHY_INT_SRC ((u32)29) -#define PHY_INT_SRC_ENERGY_ON_ ((u16)0x0080) -#define PHY_INT_SRC_ANEG_COMP_ ((u16)0x0040) -#define PHY_INT_SRC_REMOTE_FAULT_ ((u16)0x0020) -#define PHY_INT_SRC_LINK_DOWN_ ((u16)0x0010) -#define PHY_INT_SRC_ANEG_LP_ACK_ ((u16)0x0008) -#define PHY_INT_SRC_PAR_DET_FAULT_ ((u16)0x0004) -#define PHY_INT_SRC_ANEG_PGRX_ ((u16)0x0002) - -#define PHY_INT_MASK ((u32)30) -#define PHY_INT_MASK_ENERGY_ON_ ((u16)0x0080) -#define PHY_INT_MASK_ANEG_COMP_ ((u16)0x0040) -#define PHY_INT_MASK_REMOTE_FAULT_ ((u16)0x0020) -#define PHY_INT_MASK_LINK_DOWN_ ((u16)0x0010) -#define PHY_INT_MASK_ANEG_LP_ACK_ ((u16)0x0008) -#define PHY_INT_MASK_PAR_DET_FAULT_ ((u16)0x0004) -#define PHY_INT_MASK_ANEG_PGRX_ ((u16)0x0002) - -#define PHY_SPECIAL ((u32)31) -#define PHY_SPECIAL_ANEG_DONE_ ((u16)0x1000) -#define PHY_SPECIAL_RES_ ((u16)0x0040) -#define PHY_SPECIAL_RES_MASK_ ((u16)0x0FE1) -#define PHY_SPECIAL_SPD_ ((u16)0x001C) -#define PHY_SPECIAL_SPD_10HALF_ ((u16)0x0004) -#define PHY_SPECIAL_SPD_10FULL_ ((u16)0x0014) -#define PHY_SPECIAL_SPD_100HALF_ ((u16)0x0008) -#define PHY_SPECIAL_SPD_100FULL_ ((u16)0x0018) - -#define LAN911X_INTERNAL_PHY_ID (0x0007C000) - -/* Chip ID values */ -#define CHIP_9115 0x115 -#define CHIP_9116 0x116 -#define CHIP_9117 0x117 -#define CHIP_9118 0x118 - -struct chip_id { - u16 id; - char *name; -}; - -static const struct chip_id chip_ids[] = { - { CHIP_9115, "LAN9115" }, - { CHIP_9116, "LAN9116" }, - { CHIP_9117, "LAN9117" }, - { CHIP_9118, "LAN9118" }, - { 0, NULL }, -}; - -#define IS_REV_A(x) ((x & 0xFFFF)==0) - -/* - * Macros to abstract register access according to the data bus - * capabilities. Please use those and not the in/out primitives. - */ -/* FIFO read/write macros */ -#define SMC_PUSH_DATA(p, l) SMC_outsl( ioaddr, TX_DATA_FIFO, p, (l) >> 2 ) -#define SMC_PULL_DATA(p, l) SMC_insl ( ioaddr, RX_DATA_FIFO, p, (l) >> 2 ) -#define SMC_SET_TX_FIFO(x) SMC_outl( x, ioaddr, TX_DATA_FIFO ) -#define SMC_GET_RX_FIFO() SMC_inl( ioaddr, RX_DATA_FIFO ) - - -/* I/O mapped register read/write macros */ -#define SMC_GET_TX_STS_FIFO() SMC_inl( ioaddr, TX_STATUS_FIFO ) -#define SMC_GET_RX_STS_FIFO() SMC_inl( ioaddr, RX_STATUS_FIFO ) -#define SMC_GET_RX_STS_FIFO_PEEK() SMC_inl( ioaddr, RX_STATUS_FIFO_PEEK ) -#define SMC_GET_PN() (SMC_inl( ioaddr, ID_REV ) >> 16) -#define SMC_GET_REV() (SMC_inl( ioaddr, ID_REV ) & 0xFFFF) -#define SMC_GET_IRQ_CFG() SMC_inl( ioaddr, INT_CFG ) -#define SMC_SET_IRQ_CFG(x) SMC_outl( x, ioaddr, INT_CFG ) -#define SMC_GET_INT() SMC_inl( ioaddr, INT_STS ) -#define SMC_ACK_INT(x) SMC_outl( x, ioaddr, INT_STS ) -#define SMC_GET_INT_EN() SMC_inl( ioaddr, INT_EN ) -#define SMC_SET_INT_EN(x) SMC_outl( x, ioaddr, INT_EN ) -#define SMC_GET_BYTE_TEST() SMC_inl( ioaddr, BYTE_TEST ) -#define SMC_SET_BYTE_TEST(x) SMC_outl( x, ioaddr, BYTE_TEST ) -#define SMC_GET_FIFO_INT() SMC_inl( ioaddr, FIFO_INT ) -#define SMC_SET_FIFO_INT(x) SMC_outl( x, ioaddr, FIFO_INT ) -#define SMC_SET_FIFO_TDA(x) \ - do { \ - unsigned long __flags; \ - int __mask; \ - local_irq_save(__flags); \ - __mask = SMC_GET_FIFO_INT() & ~(0xFF<<24); \ - SMC_SET_FIFO_INT( __mask | (x)<<24 ); \ - local_irq_restore(__flags); \ - } while (0) -#define SMC_SET_FIFO_TSL(x) \ - do { \ - unsigned long __flags; \ - int __mask; \ - local_irq_save(__flags); \ - __mask = SMC_GET_FIFO_INT() & ~(0xFF<<16); \ - SMC_SET_FIFO_INT( __mask | (((x) & 0xFF)<<16)); \ - local_irq_restore(__flags); \ - } while (0) -#define SMC_SET_FIFO_RSA(x) \ - do { \ - unsigned long __flags; \ - int __mask; \ - local_irq_save(__flags); \ - __mask = SMC_GET_FIFO_INT() & ~(0xFF<<8); \ - SMC_SET_FIFO_INT( __mask | (((x) & 0xFF)<<8)); \ - local_irq_restore(__flags); \ - } while (0) -#define SMC_SET_FIFO_RSL(x) \ - do { \ - unsigned long __flags; \ - int __mask; \ - local_irq_save(__flags); \ - __mask = SMC_GET_FIFO_INT() & ~0xFF; \ - SMC_SET_FIFO_INT( __mask | ((x) & 0xFF)); \ - local_irq_restore(__flags); \ - } while (0) -#define SMC_GET_RX_CFG() SMC_inl( ioaddr, RX_CFG ) -#define SMC_SET_RX_CFG(x) SMC_outl( x, ioaddr, RX_CFG ) -#define SMC_GET_TX_CFG() SMC_inl( ioaddr, TX_CFG ) -#define SMC_SET_TX_CFG(x) SMC_outl( x, ioaddr, TX_CFG ) -#define SMC_GET_HW_CFG() SMC_inl( ioaddr, HW_CFG ) -#define SMC_SET_HW_CFG(x) SMC_outl( x, ioaddr, HW_CFG ) -#define SMC_GET_RX_DP_CTRL() SMC_inl( ioaddr, RX_DP_CTRL ) -#define SMC_SET_RX_DP_CTRL(x) SMC_outl( x, ioaddr, RX_DP_CTRL ) -#define SMC_GET_PMT_CTRL() SMC_inl( ioaddr, PMT_CTRL ) -#define SMC_SET_PMT_CTRL(x) SMC_outl( x, ioaddr, PMT_CTRL ) -#define SMC_GET_GPIO_CFG() SMC_inl( ioaddr, GPIO_CFG ) -#define SMC_SET_GPIO_CFG(x) SMC_outl( x, ioaddr, GPIO_CFG ) -#define SMC_GET_RX_FIFO_INF() SMC_inl( ioaddr, RX_FIFO_INF ) -#define SMC_SET_RX_FIFO_INF(x) SMC_outl( x, ioaddr, RX_FIFO_INF ) -#define SMC_GET_TX_FIFO_INF() SMC_inl( ioaddr, TX_FIFO_INF ) -#define SMC_SET_TX_FIFO_INF(x) SMC_outl( x, ioaddr, TX_FIFO_INF ) -#define SMC_GET_GPT_CFG() SMC_inl( ioaddr, GPT_CFG ) -#define SMC_SET_GPT_CFG(x) SMC_outl( x, ioaddr, GPT_CFG ) -#define SMC_GET_RX_DROP() SMC_inl( ioaddr, RX_DROP ) -#define SMC_SET_RX_DROP(x) SMC_outl( x, ioaddr, RX_DROP ) -#define SMC_GET_MAC_CMD() SMC_inl( ioaddr, MAC_CSR_CMD ) -#define SMC_SET_MAC_CMD(x) SMC_outl( x, ioaddr, MAC_CSR_CMD ) -#define SMC_GET_MAC_DATA() SMC_inl( ioaddr, MAC_CSR_DATA ) -#define SMC_SET_MAC_DATA(x) SMC_outl( x, ioaddr, MAC_CSR_DATA ) -#define SMC_GET_AFC_CFG() SMC_inl( ioaddr, AFC_CFG ) -#define SMC_SET_AFC_CFG(x) SMC_outl( x, ioaddr, AFC_CFG ) -#define SMC_GET_E2P_CMD() SMC_inl( ioaddr, E2P_CMD ) -#define SMC_SET_E2P_CMD(x) SMC_outl( x, ioaddr, E2P_CMD ) -#define SMC_GET_E2P_DATA() SMC_inl( ioaddr, E2P_DATA ) -#define SMC_SET_E2P_DATA(x) SMC_outl( x, ioaddr, E2P_DATA ) - -/* MAC register read/write macros */ -#define SMC_GET_MAC_CSR(a,v) \ - do { \ - while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ - SMC_SET_MAC_CMD(MAC_CSR_CMD_CSR_BUSY_ | \ - MAC_CSR_CMD_R_NOT_W_ | (a) ); \ - while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ - v = SMC_GET_MAC_DATA(); \ - } while (0) -#define SMC_SET_MAC_CSR(a,v) \ - do { \ - while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ - SMC_SET_MAC_DATA(v); \ - SMC_SET_MAC_CMD(MAC_CSR_CMD_CSR_BUSY_ | (a) ); \ - while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ - } while (0) -#define SMC_GET_MAC_CR(x) SMC_GET_MAC_CSR( MAC_CR, x ) -#define SMC_SET_MAC_CR(x) SMC_SET_MAC_CSR( MAC_CR, x ) -#define SMC_GET_ADDRH(x) SMC_GET_MAC_CSR( ADDRH, x ) -#define SMC_SET_ADDRH(x) SMC_SET_MAC_CSR( ADDRH, x ) -#define SMC_GET_ADDRL(x) SMC_GET_MAC_CSR( ADDRL, x ) -#define SMC_SET_ADDRL(x) SMC_SET_MAC_CSR( ADDRL, x ) -#define SMC_GET_HASHH(x) SMC_GET_MAC_CSR( HASHH, x ) -#define SMC_SET_HASHH(x) SMC_SET_MAC_CSR( HASHH, x ) -#define SMC_GET_HASHL(x) SMC_GET_MAC_CSR( HASHL, x ) -#define SMC_SET_HASHL(x) SMC_SET_MAC_CSR( HASHL, x ) -#define SMC_GET_MII_ACC(x) SMC_GET_MAC_CSR( MII_ACC, x ) -#define SMC_SET_MII_ACC(x) SMC_SET_MAC_CSR( MII_ACC, x ) -#define SMC_GET_MII_DATA(x) SMC_GET_MAC_CSR( MII_DATA, x ) -#define SMC_SET_MII_DATA(x) SMC_SET_MAC_CSR( MII_DATA, x ) -#define SMC_GET_FLOW(x) SMC_GET_MAC_CSR( FLOW, x ) -#define SMC_SET_FLOW(x) SMC_SET_MAC_CSR( FLOW, x ) -#define SMC_GET_VLAN1(x) SMC_GET_MAC_CSR( VLAN1, x ) -#define SMC_SET_VLAN1(x) SMC_SET_MAC_CSR( VLAN1, x ) -#define SMC_GET_VLAN2(x) SMC_GET_MAC_CSR( VLAN2, x ) -#define SMC_SET_VLAN2(x) SMC_SET_MAC_CSR( VLAN2, x ) -#define SMC_SET_WUFF(x) SMC_SET_MAC_CSR( WUFF, x ) -#define SMC_GET_WUCSR(x) SMC_GET_MAC_CSR( WUCSR, x ) -#define SMC_SET_WUCSR(x) SMC_SET_MAC_CSR( WUCSR, x ) - -/* PHY register read/write macros */ -#define SMC_GET_MII(a,phy,v) \ - do { \ - u32 __v; \ - do { \ - SMC_GET_MII_ACC(__v); \ - } while ( __v & MII_ACC_MII_BUSY_ ); \ - SMC_SET_MII_ACC( ((phy)<<11) | ((a)<<6) | \ - MII_ACC_MII_BUSY_); \ - do { \ - SMC_GET_MII_ACC(__v); \ - } while ( __v & MII_ACC_MII_BUSY_ ); \ - SMC_GET_MII_DATA(v); \ - } while (0) -#define SMC_SET_MII(a,phy,v) \ - do { \ - u32 __v; \ - do { \ - SMC_GET_MII_ACC(__v); \ - } while ( __v & MII_ACC_MII_BUSY_ ); \ - SMC_SET_MII_DATA(v); \ - SMC_SET_MII_ACC( ((phy)<<11) | ((a)<<6) | \ - MII_ACC_MII_BUSY_ | \ - MII_ACC_MII_WRITE_ ); \ - do { \ - SMC_GET_MII_ACC(__v); \ - } while ( __v & MII_ACC_MII_BUSY_ ); \ - } while (0) -#define SMC_GET_PHY_BMCR(phy,x) SMC_GET_MII( MII_BMCR, phy, x ) -#define SMC_SET_PHY_BMCR(phy,x) SMC_SET_MII( MII_BMCR, phy, x ) -#define SMC_GET_PHY_BMSR(phy,x) SMC_GET_MII( MII_BMSR, phy, x ) -#define SMC_GET_PHY_ID1(phy,x) SMC_GET_MII( MII_PHYSID1, phy, x ) -#define SMC_GET_PHY_ID2(phy,x) SMC_GET_MII( MII_PHYSID2, phy, x ) -#define SMC_GET_PHY_MII_ADV(phy,x) SMC_GET_MII( MII_ADVERTISE, phy, x ) -#define SMC_SET_PHY_MII_ADV(phy,x) SMC_SET_MII( MII_ADVERTISE, phy, x ) -#define SMC_GET_PHY_MII_LPA(phy,x) SMC_GET_MII( MII_LPA, phy, x ) -#define SMC_SET_PHY_MII_LPA(phy,x) SMC_SET_MII( MII_LPA, phy, x ) -#define SMC_GET_PHY_CTRL_STS(phy,x) SMC_GET_MII( PHY_MODE_CTRL_STS, phy, x ) -#define SMC_SET_PHY_CTRL_STS(phy,x) SMC_SET_MII( PHY_MODE_CTRL_STS, phy, x ) -#define SMC_GET_PHY_INT_SRC(phy,x) SMC_GET_MII( PHY_INT_SRC, phy, x ) -#define SMC_SET_PHY_INT_SRC(phy,x) SMC_SET_MII( PHY_INT_SRC, phy, x ) -#define SMC_GET_PHY_INT_MASK(phy,x) SMC_GET_MII( PHY_INT_MASK, phy, x ) -#define SMC_SET_PHY_INT_MASK(phy,x) SMC_SET_MII( PHY_INT_MASK, phy, x ) -#define SMC_GET_PHY_SPECIAL(phy,x) SMC_GET_MII( PHY_SPECIAL, phy, x ) - - - -/* Misc read/write macros */ - -#ifndef SMC_GET_MAC_ADDR -#define SMC_GET_MAC_ADDR(addr) \ - do { \ - unsigned int __v; \ - \ - SMC_GET_MAC_CSR(ADDRL, __v); \ - addr[0] = __v; addr[1] = __v >> 8; \ - addr[2] = __v >> 16; addr[3] = __v >> 24; \ - SMC_GET_MAC_CSR(ADDRH, __v); \ - addr[4] = __v; addr[5] = __v >> 8; \ - } while (0) -#endif - -#define SMC_SET_MAC_ADDR(addr) \ - do { \ - SMC_SET_MAC_CSR(ADDRL, \ - addr[0] | \ - (addr[1] << 8) | \ - (addr[2] << 16) | \ - (addr[3] << 24)); \ - SMC_SET_MAC_CSR(ADDRH, addr[4]|(addr[5] << 8));\ - } while (0) - - -#define SMC_WRITE_EEPROM_CMD(cmd, addr) \ - do { \ - while (SMC_GET_E2P_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ - SMC_SET_MAC_CMD(MAC_CSR_CMD_R_NOT_W_ | a ); \ - while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ - } while (0) - -#endif /* _SMC911X_H_ */ diff --git a/trunk/drivers/net/smc91x.h b/trunk/drivers/net/smc91x.h index f72a4f57905a..e1be1af51201 100644 --- a/trunk/drivers/net/smc91x.h +++ b/trunk/drivers/net/smc91x.h @@ -129,24 +129,6 @@ #define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) -#elif defined(CONFIG_MACH_LOGICPD_PXA270) - -#define SMC_CAN_USE_8BIT 0 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 -#define SMC_IO_SHIFT 0 -#define SMC_NOWAIT 1 -#define SMC_USE_PXA_DMA 1 - -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) -#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) - #elif defined(CONFIG_ARCH_INNOKOM) || \ defined(CONFIG_MACH_MAINSTONE) || \ defined(CONFIG_ARCH_PXA_IDP) || \ diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index 394339d5e87c..43f5e86fc559 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -1652,8 +1652,6 @@ spider_net_enable_card(struct spider_net_card *card) { SPIDER_NET_GFTRESTRT, SPIDER_NET_RESTART_VALUE }, { SPIDER_NET_GMRWOLCTRL, 0 }, - { SPIDER_NET_GTESTMD, 0x10000000 }, - { SPIDER_NET_GTTQMSK, 0x00400040 }, { SPIDER_NET_GTESTMD, 0 }, { SPIDER_NET_GMACINTEN, 0 }, @@ -1794,7 +1792,15 @@ spider_net_setup_phy(struct spider_net_card *card) if (phy->def->ops->setup_forced) phy->def->ops->setup_forced(phy, SPEED_1000, DUPLEX_FULL); - phy->def->ops->enable_fiber(phy); + /* the following two writes could be moved to sungem_phy.c */ + /* enable fiber mode */ + spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x9020); + /* LEDs active in both modes, autosense prio = fiber */ + spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x945f); + + /* switch off fibre autoneg */ + spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0xfc01); + spider_net_write_phy(card->netdev, 1, 0x0b, 0x0004); phy->def->ops->read_link(phy); pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name, diff --git a/trunk/drivers/net/spider_net.h b/trunk/drivers/net/spider_net.h index 3b8d951cf73c..5922b529a048 100644 --- a/trunk/drivers/net/spider_net.h +++ b/trunk/drivers/net/spider_net.h @@ -120,8 +120,6 @@ extern char spider_net_driver_name[]; #define SPIDER_NET_GMRUAFILnR 0x00000500 #define SPIDER_NET_GMRUA0FIL15R 0x00000578 -#define SPIDER_NET_GTTQMSK 0x00000934 - /* RX DMA controller registers, all 0x00000a.. are for DMA controller A, * 0x00000b.. for DMA controller B, etc. */ #define SPIDER_NET_GDADCHA 0x00000a00 diff --git a/trunk/drivers/net/sungem_phy.c b/trunk/drivers/net/sungem_phy.c index b2ddd5e79303..046371ee5bbe 100644 --- a/trunk/drivers/net/sungem_phy.c +++ b/trunk/drivers/net/sungem_phy.c @@ -329,30 +329,6 @@ static int bcm5421_init(struct mii_phy* phy) return 0; } -static int bcm5421_enable_fiber(struct mii_phy* phy) -{ - /* enable fiber mode */ - phy_write(phy, MII_NCONFIG, 0x9020); - /* LEDs active in both modes, autosense prio = fiber */ - phy_write(phy, MII_NCONFIG, 0x945f); - - /* switch off fibre autoneg */ - phy_write(phy, MII_NCONFIG, 0xfc01); - phy_write(phy, 0x0b, 0x0004); - - return 0; -} - -static int bcm5461_enable_fiber(struct mii_phy* phy) -{ - phy_write(phy, MII_NCONFIG, 0xfc0c); - phy_write(phy, MII_BMCR, 0x4140); - phy_write(phy, MII_NCONFIG, 0xfc0b); - phy_write(phy, MII_BMCR, 0x0140); - - return 0; -} - static int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise) { u16 ctl, adv; @@ -786,7 +762,6 @@ static struct mii_phy_ops bcm5421_phy_ops = { .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, .read_link = bcm54xx_read_link, - .enable_fiber = bcm5421_enable_fiber, }; static struct mii_phy_def bcm5421_phy_def = { @@ -817,25 +792,6 @@ static struct mii_phy_def bcm5421k2_phy_def = { .ops = &bcm5421k2_phy_ops }; -static struct mii_phy_ops bcm5461_phy_ops = { - .init = bcm5421_init, - .suspend = generic_suspend, - .setup_aneg = bcm54xx_setup_aneg, - .setup_forced = bcm54xx_setup_forced, - .poll_link = genmii_poll_link, - .read_link = bcm54xx_read_link, - .enable_fiber = bcm5461_enable_fiber, -}; - -static struct mii_phy_def bcm5461_phy_def = { - .phy_id = 0x002060c0, - .phy_id_mask = 0xfffffff0, - .name = "BCM5461", - .features = MII_GBIT_FEATURES, - .magic_aneg = 1, - .ops = &bcm5461_phy_ops -}; - /* Broadcom BCM 5462 built-in Vesta */ static struct mii_phy_ops bcm5462V_phy_ops = { .init = bcm5421_init, @@ -901,7 +857,6 @@ static struct mii_phy_def* mii_phy_table[] = { &bcm5411_phy_def, &bcm5421_phy_def, &bcm5421k2_phy_def, - &bcm5461_phy_def, &bcm5462V_phy_def, &marvell_phy_def, &genmii_phy_def, diff --git a/trunk/drivers/net/sungem_phy.h b/trunk/drivers/net/sungem_phy.h index 69e125197fcf..430544496c52 100644 --- a/trunk/drivers/net/sungem_phy.h +++ b/trunk/drivers/net/sungem_phy.h @@ -12,7 +12,6 @@ struct mii_phy_ops int (*setup_forced)(struct mii_phy *phy, int speed, int fd); int (*poll_link)(struct mii_phy *phy); int (*read_link)(struct mii_phy *phy); - int (*enable_fiber)(struct mii_phy *phy); }; /* Structure used to statically define an mii/gii based PHY */ diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 49ad60b72657..beeb612be98f 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -69,8 +69,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.58" -#define DRV_MODULE_RELDATE "May 22, 2006" +#define DRV_MODULE_VERSION "3.57" +#define DRV_MODULE_RELDATE "Apr 28, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -6488,10 +6488,6 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp) TG3_STAT_ADD32(&sp->rx_frame_too_long_errors, MAC_RX_STATS_FRAME_TOO_LONG); TG3_STAT_ADD32(&sp->rx_jabbers, MAC_RX_STATS_JABBERS); TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE); - - TG3_STAT_ADD32(&sp->rxbds_empty, RCVLPC_NO_RCV_BD_CNT); - TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT); - TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT); } static void tg3_timer(unsigned long __opaque) @@ -7657,23 +7653,21 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->supported |= (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); - if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) { + if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) cmd->supported |= (SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_MII); - cmd->port = PORT_TP; - } else { + else cmd->supported |= SUPPORTED_FIBRE; - cmd->port = PORT_FIBRE; - } cmd->advertising = tp->link_config.advertising; if (netif_running(dev)) { cmd->speed = tp->link_config.active_speed; cmd->duplex = tp->link_config.active_duplex; } + cmd->port = 0; cmd->phy_address = PHY_ADDR; cmd->transceiver = 0; cmd->autoneg = tp->link_config.autoneg; @@ -8460,9 +8454,6 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) tx_len = 1514; skb = dev_alloc_skb(tx_len); - if (!skb) - return -ENOMEM; - tx_data = skb_put(skb, tx_len); memcpy(tx_data, tp->dev->dev_addr, 6); memset(tx_data + 6, 0x0, 8); diff --git a/trunk/drivers/net/tulip/winbond-840.c b/trunk/drivers/net/tulip/winbond-840.c index 136a70c4d5e4..ba05dedf29d3 100644 --- a/trunk/drivers/net/tulip/winbond-840.c +++ b/trunk/drivers/net/tulip/winbond-840.c @@ -850,7 +850,7 @@ static void init_rxtx_rings(struct net_device *dev) break; skb->dev = dev; /* Mark as being used by this device. */ np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data, - np->rx_buf_sz,PCI_DMA_FROMDEVICE); + skb->len,PCI_DMA_FROMDEVICE); np->rx_ring[i].buffer1 = np->rx_addr[i]; np->rx_ring[i].status = DescOwn; @@ -1316,7 +1316,7 @@ static int netdev_rx(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ np->rx_addr[entry] = pci_map_single(np->pci_dev, skb->data, - np->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->len, PCI_DMA_FROMDEVICE); np->rx_ring[entry].buffer1 = np->rx_addr[entry]; } wmb(); diff --git a/trunk/drivers/net/via-rhine.c b/trunk/drivers/net/via-rhine.c index fdc21037f6dc..a6dc53b4250d 100644 --- a/trunk/drivers/net/via-rhine.c +++ b/trunk/drivers/net/via-rhine.c @@ -491,6 +491,8 @@ struct rhine_private { u8 tx_thresh, rx_thresh; struct mii_if_info mii_if; + struct work_struct tx_timeout_task; + struct work_struct check_media_task; void __iomem *base; }; @@ -498,6 +500,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location); static void mdio_write(struct net_device *dev, int phy_id, int location, int value); static int rhine_open(struct net_device *dev); static void rhine_tx_timeout(struct net_device *dev); +static void rhine_tx_timeout_task(struct net_device *dev); +static void rhine_check_media_task(struct net_device *dev); static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev); static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static void rhine_tx(struct net_device *dev); @@ -852,6 +856,12 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, if (rp->quirks & rqRhineI) dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; + INIT_WORK(&rp->tx_timeout_task, + (void (*)(void *))rhine_tx_timeout_task, dev); + + INIT_WORK(&rp->check_media_task, + (void (*)(void *))rhine_check_media_task, dev); + /* dev->name not defined before register_netdev()! */ rc = register_netdev(dev); if (rc) @@ -1098,6 +1108,11 @@ static void rhine_set_carrier(struct mii_if_info *mii) netif_carrier_ok(mii->dev)); } +static void rhine_check_media_task(struct net_device *dev) +{ + rhine_check_media(dev, 0); +} + static void init_registers(struct net_device *dev) { struct rhine_private *rp = netdev_priv(dev); @@ -1151,8 +1166,8 @@ static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks) if (quirks & rqRhineI) { iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR - /* Can be called from ISR. Evil. */ - mdelay(1); + /* Do not call from ISR! */ + msleep(1); /* 0x80 must be set immediately before turning it off */ iowrite8(0x80, ioaddr + MIICmd); @@ -1240,6 +1255,16 @@ static int rhine_open(struct net_device *dev) } static void rhine_tx_timeout(struct net_device *dev) +{ + struct rhine_private *rp = netdev_priv(dev); + + /* + * Move bulk of work outside of interrupt context + */ + schedule_work(&rp->tx_timeout_task); +} + +static void rhine_tx_timeout_task(struct net_device *dev) { struct rhine_private *rp = netdev_priv(dev); void __iomem *ioaddr = rp->base; @@ -1652,7 +1677,7 @@ static void rhine_error(struct net_device *dev, int intr_status) spin_lock(&rp->lock); if (intr_status & IntrLinkChange) - rhine_check_media(dev, 0); + schedule_work(&rp->check_media_task); if (intr_status & IntrStatsMax) { rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs); rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed); @@ -1902,6 +1927,9 @@ static int rhine_close(struct net_device *dev) spin_unlock_irq(&rp->lock); free_irq(rp->pdev->irq, dev); + + flush_scheduled_work(); + free_rbufs(dev); free_tbufs(dev); free_ring(dev); diff --git a/trunk/drivers/net/wan/pci200syn.c b/trunk/drivers/net/wan/pci200syn.c index f485a97844cc..eba8e5cfacc2 100644 --- a/trunk/drivers/net/wan/pci200syn.c +++ b/trunk/drivers/net/wan/pci200syn.c @@ -50,6 +50,10 @@ static const char* devname = "PCI200SYN"; static int pci_clock_freq = 33000000; #define CLOCK_BASE pci_clock_freq +#define PCI_VENDOR_ID_GORAMO 0x10B5 /* uses PLX:9050 ID - this card */ +#define PCI_DEVICE_ID_PCI200SYN 0x9050 /* doesn't have its own ID */ + + /* * PLX PCI9052 local configuration and shared runtime registers. * This structure can be used to access 9052 registers (memory mapped). @@ -258,7 +262,7 @@ static void pci200_pci_remove_one(struct pci_dev *pdev) int i; card_t *card = pci_get_drvdata(pdev); - for (i = 0; i < 2; i++) + 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); @@ -381,15 +385,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, " %u RX packets rings\n", ramsize / 1024, ramphys, pdev->irq, card->tx_ring_buffers, card->rx_ring_buffers); - if (pdev->subsystem_device == PCI_DEVICE_ID_PLX_9050) { - printk(KERN_ERR "Detected PCI200SYN card with old " - "configuration data.\n"); - printk(KERN_ERR "See for update.\n"); - printk(KERN_ERR "The card will stop working with" - " future versions of Linux if not updated.\n"); - } - if (card->tx_ring_buffers < 1) { printk(KERN_ERR "pci200syn: RAM test failed\n"); pci200_pci_remove_one(pdev); @@ -401,7 +396,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, writew(readw(p) | 0x0040, p); /* Allocate IRQ */ - if (request_irq(pdev->irq, sca_intr, SA_SHIRQ, devname, card)) { + if(request_irq(pdev->irq, sca_intr, SA_SHIRQ, devname, card)) { printk(KERN_WARNING "pci200syn: could not allocate IRQ%d.\n", pdev->irq); pci200_pci_remove_one(pdev); @@ -411,7 +406,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, sca_init(card, 0); - for (i = 0; i < 2; i++) { + for(i = 0; i < 2; i++) { port_t *port = &card->ports[i]; struct net_device *dev = port_to_dev(port); hdlc_device *hdlc = dev_to_hdlc(dev); @@ -430,7 +425,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, hdlc->xmit = sca_xmit; port->settings.clock_type = CLOCK_EXT; port->card = card; - if (register_hdlc_device(dev)) { + if(register_hdlc_device(dev)) { printk(KERN_ERR "pci200syn: unable to register hdlc " "device\n"); port->card = NULL; @@ -450,10 +445,8 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, static struct pci_device_id pci200_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX, - PCI_DEVICE_ID_PLX_9050, 0, 0, 0 }, - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX, - PCI_DEVICE_ID_PLX_PCI200SYN, 0, 0, 0 }, + { PCI_VENDOR_ID_GORAMO, PCI_DEVICE_ID_PCI200SYN, PCI_ANY_ID, + PCI_ANY_ID, 0, 0, 0 }, { 0, } }; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 2adf02ac400e..198528660721 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -939,9 +939,9 @@ static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm) return 0; } -static int bcm43xx_geo_init(struct bcm43xx_private *bcm) +static void bcm43xx_geo_init(struct bcm43xx_private *bcm) { - struct ieee80211_geo *geo; + struct ieee80211_geo geo; struct ieee80211_channel *chan; int have_a = 0, have_bg = 0; int i; @@ -949,10 +949,7 @@ static int bcm43xx_geo_init(struct bcm43xx_private *bcm) struct bcm43xx_phyinfo *phy; const char *iso_country; - geo = kzalloc(sizeof(*geo), GFP_KERNEL); - if (!geo) - return -ENOMEM; - + memset(&geo, 0, sizeof(geo)); for (i = 0; i < bcm->nr_80211_available; i++) { phy = &(bcm->core_80211_ext[i].phy); switch (phy->type) { @@ -970,36 +967,31 @@ static int bcm43xx_geo_init(struct bcm43xx_private *bcm) iso_country = bcm43xx_locale_iso(bcm->sprom.locale); if (have_a) { - for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL; - channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) { - chan = &geo->a[i++]; + for (i = 0, channel = 0; channel < 201; channel++) { + chan = &geo.a[i++]; chan->freq = bcm43xx_channel_to_freq_a(channel); chan->channel = channel; } - geo->a_channels = i; + geo.a_channels = i; } if (have_bg) { - for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL; - channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) { - chan = &geo->bg[i++]; + for (i = 0, channel = 1; channel < 15; channel++) { + chan = &geo.bg[i++]; chan->freq = bcm43xx_channel_to_freq_bg(channel); chan->channel = channel; } - geo->bg_channels = i; + geo.bg_channels = i; } - memcpy(geo->name, iso_country, 2); + memcpy(geo.name, iso_country, 2); if (0 /*TODO: Outdoor use only */) - geo->name[2] = 'O'; + geo.name[2] = 'O'; else if (0 /*TODO: Indoor use only */) - geo->name[2] = 'I'; + geo.name[2] = 'I'; else - geo->name[2] = ' '; - geo->name[3] = '\0'; - - ieee80211_set_geo(bcm->ieee, geo); - kfree(geo); + geo.name[2] = ' '; + geo.name[3] = '\0'; - return 0; + ieee80211_set_geo(bcm->ieee, &geo); } /* DummyTransmission function, as documented on @@ -3271,9 +3263,6 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) bcm43xx_sysfs_register(bcm); //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though... - /*FIXME: This should be handled by softmac instead. */ - schedule_work(&bcm->softmac->associnfo.work); - assert(err == 0); out: return err; @@ -3475,17 +3464,16 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm) goto err_80211_unwind; bcm43xx_wireless_core_disable(bcm); } - err = bcm43xx_geo_init(bcm); - if (err) - goto err_80211_unwind; bcm43xx_pctl_set_crystal(bcm, 0); /* Set the MAC address in the networking subsystem */ - if (is_valid_ether_addr(bcm->sprom.et1macaddr)) + if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6); else memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6); + bcm43xx_geo_init(bcm); + snprintf(bcm->nick, IW_ESSID_MAX_SIZE, "Broadcom %04X", bcm->chip_id); @@ -3934,6 +3922,9 @@ static int bcm43xx_resume(struct pci_dev *pdev) netif_device_attach(net_dev); + /*FIXME: This should be handled by softmac instead. */ + schedule_work(&bcm->softmac->associnfo.work); + dprintk(KERN_INFO PFX "Device resumed.\n"); return 0; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.h index 30a202b258b5..eca79a38594a 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.h +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.h @@ -118,14 +118,12 @@ int bcm43xx_channel_to_freq(struct bcm43xx_private *bcm, static inline int bcm43xx_is_valid_channel_a(u8 channel) { - return (channel >= IEEE80211_52GHZ_MIN_CHANNEL - && channel <= IEEE80211_52GHZ_MAX_CHANNEL); + return (channel <= 200); } static inline int bcm43xx_is_valid_channel_bg(u8 channel) { - return (channel >= IEEE80211_24GHZ_MIN_CHANNEL - && channel <= IEEE80211_24GHZ_MAX_CHANNEL); + return (channel >= 1 && channel <= 14); } static inline int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm, diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index b0abac515530..33137165727f 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c @@ -1287,7 +1287,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm) if (radio->revision == 8) bcm43xx_phy_write(bcm, 0x0805, 0x3230); bcm43xx_phy_init_pctl(bcm); - if (bcm->chip_id == 0x4306 && bcm->chip_package == 2) { + if (bcm->chip_id == 0x4306 && bcm->chip_package != 2) { bcm43xx_phy_write(bcm, 0x0429, bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF); bcm43xx_phy_write(bcm, 0x04C3, diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index b45063974ae9..3edbb481a0a0 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c @@ -182,11 +182,8 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev, mode = BCM43xx_INITIAL_IWMODE; bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { - if (bcm->ieee->iw_mode != mode) - bcm43xx_set_iwmode(bcm, mode); - } else - bcm->ieee->iw_mode = mode; + if (bcm->ieee->iw_mode != mode) + bcm43xx_set_iwmode(bcm, mode); bcm43xx_unlock_mmio(bcm, flags); return 0; diff --git a/trunk/drivers/net/wireless/orinoco.c b/trunk/drivers/net/wireless/orinoco.c index b563decf599e..d4c13ff4d8a1 100644 --- a/trunk/drivers/net/wireless/orinoco.c +++ b/trunk/drivers/net/wireless/orinoco.c @@ -757,6 +757,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, if (datalen > IEEE80211_DATA_LEN + 12) { printk(KERN_DEBUG "%s: oversized monitor frame, " "data length = %d\n", dev->name, datalen); + err = -EIO; stats->rx_length_errors++; goto update_stats; } @@ -765,7 +766,8 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, if (!skb) { printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n", dev->name); - goto update_stats; + err = -ENOMEM; + goto drop; } /* Copy the 802.11 header to the skb */ diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index c2ecae5ff0c1..6917c6cb0912 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -33,10 +33,13 @@ acpi_query_osc ( acpi_status status; struct acpi_object_list input; union acpi_object in_params[4]; - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object *out_obj; + struct acpi_buffer output; + union acpi_object out_obj; u32 osc_dw0; + /* Setting up output buffer */ + output.length = sizeof(out_obj) + 3*sizeof(u32); + output.pointer = &out_obj; /* Setting up input parameters */ input.count = 4; @@ -58,15 +61,12 @@ acpi_query_osc ( "Evaluate _OSC Set fails. Status = 0x%04x\n", status); return status; } - out_obj = output.pointer; - - if (out_obj->type != ACPI_TYPE_BUFFER) { + if (out_obj.type != ACPI_TYPE_BUFFER) { printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n"); - status = AE_TYPE; - goto query_osc_out; + return AE_TYPE; } - osc_dw0 = *((u32 *) out_obj->buffer.pointer); + osc_dw0 = *((u32 *) out_obj.buffer.pointer); if (osc_dw0) { if (osc_dw0 & OSC_REQUEST_ERROR) printk(KERN_DEBUG "_OSC request fails\n"); @@ -76,21 +76,15 @@ acpi_query_osc ( printk(KERN_DEBUG "_OSC invalid revision\n"); if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { /* Update Global Control Set */ - global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8)); - status = AE_OK; - goto query_osc_out; + global_ctrlsets = *((u32 *)(out_obj.buffer.pointer+8)); + return AE_OK; } - status = AE_ERROR; - goto query_osc_out; + return AE_ERROR; } /* Update Global Control Set */ - global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8)); - status = AE_OK; - -query_osc_out: - kfree(output.pointer); - return status; + global_ctrlsets = *((u32 *)(out_obj.buffer.pointer + 8)); + return AE_OK; } @@ -102,10 +96,14 @@ acpi_run_osc ( acpi_status status; struct acpi_object_list input; union acpi_object in_params[4]; - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object *out_obj; + struct acpi_buffer output; + union acpi_object out_obj; u32 osc_dw0; + /* Setting up output buffer */ + output.length = sizeof(out_obj) + 3*sizeof(u32); + output.pointer = &out_obj; + /* Setting up input parameters */ input.count = 4; input.pointer = in_params; @@ -126,14 +124,12 @@ acpi_run_osc ( "Evaluate _OSC Set fails. Status = 0x%04x\n", status); return status; } - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) { + if (out_obj.type != ACPI_TYPE_BUFFER) { printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n"); - status = AE_TYPE; - goto run_osc_out; + return AE_TYPE; } - osc_dw0 = *((u32 *) out_obj->buffer.pointer); + osc_dw0 = *((u32 *) out_obj.buffer.pointer); if (osc_dw0) { if (osc_dw0 & OSC_REQUEST_ERROR) printk(KERN_DEBUG "_OSC request fails\n"); @@ -143,17 +139,11 @@ acpi_run_osc ( printk(KERN_DEBUG "_OSC invalid revision\n"); if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { printk(KERN_DEBUG "_OSC FW not grant req. control\n"); - status = AE_SUPPORT; - goto run_osc_out; + return AE_SUPPORT; } - status = AE_ERROR; - goto run_osc_out; + return AE_ERROR; } - status = AE_OK; - -run_osc_out: - kfree(output.pointer); - return status; + return AE_OK; } /** diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 8d107c6c2c70..2329f941a0dc 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -164,6 +164,7 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap); } +#if 0 /** * pci_find_ext_capability - Find an extended capability * @dev: PCI device to query @@ -211,7 +212,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) return 0; } -EXPORT_SYMBOL_GPL(pci_find_ext_capability); +#endif /* 0 */ /** * pci_find_parent_resource - return resource region of parent bus of given region diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index d378478612fb..19e2b174d33c 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -634,9 +634,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vi * non-x86 architectures (yes Via exists on PPC among other places), * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get * interrupts delivered properly. - * - * Some of the on-chip devices are actually '586 devices' so they are - * listed here. */ static void quirk_via_irq(struct pci_dev *dev) { @@ -651,10 +648,6 @@ static void quirk_via_irq(struct pci_dev *dev) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); } } -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq); DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq); DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq); DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq); @@ -902,7 +895,6 @@ static void __init k8t_sound_hostbridge(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); -#ifndef CONFIG_ACPI_SLEEP /* * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge * is not activated. The myth is that Asus said that they do not want the @@ -914,12 +906,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it * becomes necessary to do this tweak in two steps -- I've chosen the Host * bridge as trigger. - * - * Actually, leaving it unhidden and not redoing the quirk over suspend2ram - * will cause thermal management to break down, and causing machine to - * overheat. */ -static int __initdata asus_hides_smbus; +static int __initdata asus_hides_smbus = 0; static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) { @@ -1062,8 +1050,6 @@ static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); -#endif - /* * SiS 96x south bridge: BIOS typically hides SMBus device... */ diff --git a/trunk/drivers/pcmcia/pcmcia_ioctl.c b/trunk/drivers/pcmcia/pcmcia_ioctl.c index 738b1ef595a3..c53db7ceda5e 100644 --- a/trunk/drivers/pcmcia/pcmcia_ioctl.c +++ b/trunk/drivers/pcmcia/pcmcia_ioctl.c @@ -426,7 +426,7 @@ static int ds_open(struct inode *inode, struct file *file) if (!warning_printed) { printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl " - "usage from process: %s.\n", current->comm); + "usage.\n"); printk(KERN_INFO "pcmcia: This interface will soon be removed from " "the kernel; please expect breakage unless you upgrade " "to new tools.\n"); @@ -601,12 +601,8 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); - if (p_dev == NULL) - ret = CS_BAD_ARGS; - else { - ret = pccard_get_configuration_info(s, p_dev, &buf->config); - pcmcia_put_dev(p_dev); - } + ret = pccard_get_configuration_info(s, p_dev, &buf->config); + pcmcia_put_dev(p_dev); } break; case DS_GET_FIRST_TUPLE: @@ -636,12 +632,8 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); - if (p_dev == NULL) - ret = CS_BAD_ARGS; - else { - ret = pccard_get_status(s, p_dev, &buf->status); - pcmcia_put_dev(p_dev); - } + ret = pccard_get_status(s, p_dev, &buf->status); + pcmcia_put_dev(p_dev); } break; case DS_VALIDATE_CIS: @@ -673,10 +665,9 @@ static int ds_ioctl(struct inode * inode, struct file * file, if (!(buf->conf_reg.Function && (buf->conf_reg.Function >= s->functions))) { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function); - if (p_dev) { + if (p_dev) ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg); - pcmcia_put_dev(p_dev); - } + pcmcia_put_dev(p_dev); } break; case DS_GET_FIRST_REGION: diff --git a/trunk/drivers/pcmcia/pd6729.c b/trunk/drivers/pcmcia/pd6729.c index 247ab837f841..16d1ea7b0a18 100644 --- a/trunk/drivers/pcmcia/pd6729.c +++ b/trunk/drivers/pcmcia/pd6729.c @@ -589,7 +589,7 @@ static int pd6729_check_irq(int irq, int flags) return 0; } -static u_int __devinit pd6729_isa_scan(void) +static u_int __init pd6729_isa_scan(void) { u_int mask0, mask = 0; int i; diff --git a/trunk/drivers/rtc/rtc-dev.c b/trunk/drivers/rtc/rtc-dev.c index 2011567005f9..6c9ad92747fd 100644 --- a/trunk/drivers/rtc/rtc-dev.c +++ b/trunk/drivers/rtc/rtc-dev.c @@ -141,13 +141,13 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, /* try the driver's ioctl interface */ if (ops->ioctl) { err = ops->ioctl(class_dev->dev, cmd, arg); - if (err != -ENOIOCTLCMD) + if (err != -EINVAL) return err; } /* if the driver does not provide the ioctl interface * or if that particular ioctl was not implemented - * (-ENOIOCTLCMD), we will try to emulate here. + * (-EINVAL), we will try to emulate here. */ switch (cmd) { @@ -233,7 +233,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, break; default: - err = -ENOTTY; + err = -EINVAL; break; } diff --git a/trunk/drivers/rtc/rtc-sa1100.c b/trunk/drivers/rtc/rtc-sa1100.c index a997529f8926..a23ec54989f6 100644 --- a/trunk/drivers/rtc/rtc-sa1100.c +++ b/trunk/drivers/rtc/rtc-sa1100.c @@ -178,9 +178,9 @@ static int sa1100_rtc_open(struct device *dev) return 0; fail_pi: - free_irq(IRQ_RTCAlrm, dev); + free_irq(IRQ_RTCAlrm, NULL); fail_ai: - free_irq(IRQ_RTC1Hz, dev); + free_irq(IRQ_RTC1Hz, NULL); fail_ui: return ret; } @@ -247,7 +247,7 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, rtc_freq = arg; return 0; } - return -ENOIOCTLCMD; + return -EINVAL; } static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) @@ -295,7 +295,7 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) { - seq_printf(seq, "trim/divider\t: 0x%08lx\n", RTTR); + seq_printf(seq, "trim/divider\t: 0x%08x\n", RTTR); seq_printf(seq, "alarm_IRQ\t: %s\n", (RTSR & RTSR_ALE) ? "yes" : "no" ); seq_printf(seq, "update_IRQ\t: %s\n", diff --git a/trunk/drivers/rtc/rtc-test.c b/trunk/drivers/rtc/rtc-test.c index e1fa5fe7901f..e1f7e8e86daf 100644 --- a/trunk/drivers/rtc/rtc-test.c +++ b/trunk/drivers/rtc/rtc-test.c @@ -71,7 +71,7 @@ static int test_rtc_ioctl(struct device *dev, unsigned int cmd, return 0; default: - return -ENOIOCTLCMD; + return -EINVAL; } } diff --git a/trunk/drivers/rtc/rtc-vr41xx.c b/trunk/drivers/rtc/rtc-vr41xx.c index 277596c302e3..4d49fd501198 100644 --- a/trunk/drivers/rtc/rtc-vr41xx.c +++ b/trunk/drivers/rtc/rtc-vr41xx.c @@ -270,7 +270,7 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long epoch = arg; break; default: - return -ENOIOCTLCMD; + return -EINVAL; } return 0; diff --git a/trunk/drivers/s390/net/Makefile b/trunk/drivers/s390/net/Makefile index 6775a837d646..90d4d0ef3dd4 100644 --- a/trunk/drivers/s390/net/Makefile +++ b/trunk/drivers/s390/net/Makefile @@ -2,7 +2,7 @@ # S/390 network devices # -ctc-objs := ctcmain.o ctcdbug.o +ctc-objs := ctcmain.o ctctty.o ctcdbug.o obj-$(CONFIG_IUCV) += iucv.o obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o @@ -10,7 +10,6 @@ obj-$(CONFIG_SMSGIUCV) += smsgiucv.o obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o obj-$(CONFIG_LCS) += lcs.o cu3088.o obj-$(CONFIG_CLAW) += claw.o cu3088.o -obj-$(CONFIG_MPC) += ctcmpc.o fsm.o cu3088.o qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o qeth-$(CONFIG_PROC_FS) += qeth_proc.o obj-$(CONFIG_QETH) += qeth.o diff --git a/trunk/drivers/s390/net/ctcmain.c b/trunk/drivers/s390/net/ctcmain.c index e2ccaf55961c..af9f212314b3 100644 --- a/trunk/drivers/s390/net/ctcmain.c +++ b/trunk/drivers/s390/net/ctcmain.c @@ -6,7 +6,7 @@ * Fixes by : Jochen Röhrig (roehrig@de.ibm.com) * Arnaldo Carvalho de Melo Peter Tiedemann (ptiedem@de.ibm.com) - * Driver Model stuff by : Cornelia Huck + * Driver Model stuff by : Cornelia Huck * * Documentation used: * - Principles of Operation (IBM doc#: SA22-7201-06) @@ -65,6 +65,7 @@ #include +#include "ctctty.h" #include "fsm.h" #include "cu3088.h" @@ -478,7 +479,10 @@ ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb) skb->dev = pskb->dev; skb->protocol = pskb->protocol; pskb->ip_summed = CHECKSUM_UNNECESSARY; - netif_rx_ni(skb); + if (ch->protocol == CTC_PROTO_LINUX_TTY) + ctc_tty_netif_rx(skb); + else + netif_rx_ni(skb); /** * Successful rx; reset logflags */ @@ -553,7 +557,8 @@ ccw_unit_check(struct channel *ch, unsigned char sense) DBF_TEXT(trace, 5, __FUNCTION__); if (sense & SNS0_INTERVENTION_REQ) { if (sense & 0x01) { - ctc_pr_debug("%s: Interface disc. or Sel. reset " + if (ch->protocol != CTC_PROTO_LINUX_TTY) + ctc_pr_debug("%s: Interface disc. or Sel. reset " "(remote)\n", ch->id); fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch); } else { @@ -2029,6 +2034,7 @@ static void dev_action_chup(fsm_instance * fi, int event, void *arg) { struct net_device *dev = (struct net_device *) arg; + struct ctc_priv *privptr = dev->priv; DBF_TEXT(trace, 3, __FUNCTION__); switch (fsm_getstate(fi)) { @@ -2043,6 +2049,8 @@ dev_action_chup(fsm_instance * fi, int event, void *arg) fsm_newstate(fi, DEV_STATE_RUNNING); ctc_pr_info("%s: connected with remote side\n", dev->name); + if (privptr->protocol == CTC_PROTO_LINUX_TTY) + ctc_tty_setcarrier(dev, 1); ctc_clear_busy(dev); } break; @@ -2051,6 +2059,8 @@ dev_action_chup(fsm_instance * fi, int event, void *arg) fsm_newstate(fi, DEV_STATE_RUNNING); ctc_pr_info("%s: connected with remote side\n", dev->name); + if (privptr->protocol == CTC_PROTO_LINUX_TTY) + ctc_tty_setcarrier(dev, 1); ctc_clear_busy(dev); } break; @@ -2076,10 +2086,14 @@ dev_action_chup(fsm_instance * fi, int event, void *arg) static void dev_action_chdown(fsm_instance * fi, int event, void *arg) { + struct net_device *dev = (struct net_device *) arg; + struct ctc_priv *privptr = dev->priv; DBF_TEXT(trace, 3, __FUNCTION__); switch (fsm_getstate(fi)) { case DEV_STATE_RUNNING: + if (privptr->protocol == CTC_PROTO_LINUX_TTY) + ctc_tty_setcarrier(dev, 0); if (event == DEV_EVENT_TXDOWN) fsm_newstate(fi, DEV_STATE_STARTWAIT_TX); else @@ -2383,6 +2397,8 @@ ctc_tx(struct sk_buff *skb, struct net_device * dev) */ if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { fsm_event(privptr->fsm, DEV_EVENT_START, dev); + if (privptr->protocol == CTC_PROTO_LINUX_TTY) + return -EBUSY; dev_kfree_skb(skb); privptr->stats.tx_dropped++; privptr->stats.tx_errors++; @@ -2592,13 +2608,20 @@ ctc_netdev_unregister(struct net_device * dev) if (!dev) return; privptr = (struct ctc_priv *) dev->priv; - unregister_netdev(dev); + if (privptr->protocol != CTC_PROTO_LINUX_TTY) + unregister_netdev(dev); + else + ctc_tty_unregister_netdev(dev); } static int ctc_netdev_register(struct net_device * dev) { - return register_netdev(dev); + struct ctc_priv *privptr = (struct ctc_priv *) dev->priv; + if (privptr->protocol != CTC_PROTO_LINUX_TTY) + return register_netdev(dev); + else + return ctc_tty_register_netdev(dev); } static void @@ -2644,9 +2667,7 @@ ctc_proto_store(struct device *dev, struct device_attribute *attr, const char *b if (!priv) return -ENODEV; sscanf(buf, "%u", &value); - if (!((value == CTC_PROTO_S390) || - (value == CTC_PROTO_LINUX) || - (value == CTC_PROTO_OS390))) + if ((value < 0) || (value > CTC_PROTO_MAX)) return -EINVAL; priv->protocol = value; @@ -2876,7 +2897,10 @@ ctc_new_device(struct ccwgroup_device *cgdev) goto out; } - strlcpy(dev->name, "ctc%d", IFNAMSIZ); + if (privptr->protocol == CTC_PROTO_LINUX_TTY) + strlcpy(dev->name, "ctctty%d", IFNAMSIZ); + else + strlcpy(dev->name, "ctc%d", IFNAMSIZ); for (direction = READ; direction <= WRITE; direction++) { privptr->channel[direction] = @@ -3022,6 +3046,7 @@ ctc_exit(void) { DBF_TEXT(setup, 3, __FUNCTION__); unregister_cu3088_discipline(&ctc_group_driver); + ctc_tty_cleanup(); ctc_unregister_dbf_views(); ctc_pr_info("CTC driver unloaded\n"); } @@ -3048,8 +3073,10 @@ ctc_init(void) ctc_pr_crit("ctc_init failed with ctc_register_dbf_views rc = %d\n", ret); return ret; } + ctc_tty_init(); ret = register_cu3088_discipline(&ctc_group_driver); if (ret) { + ctc_tty_cleanup(); ctc_unregister_dbf_views(); } return ret; diff --git a/trunk/drivers/s390/net/ctcmain.h b/trunk/drivers/s390/net/ctcmain.h index 7f305d119f3d..d2e835c0c134 100644 --- a/trunk/drivers/s390/net/ctcmain.h +++ b/trunk/drivers/s390/net/ctcmain.h @@ -35,9 +35,7 @@ #include #include -#include -#include - +#include "ctctty.h" #include "fsm.h" #include "cu3088.h" @@ -52,7 +50,9 @@ #define CTC_PROTO_S390 0 #define CTC_PROTO_LINUX 1 +#define CTC_PROTO_LINUX_TTY 2 #define CTC_PROTO_OS390 3 +#define CTC_PROTO_MAX 3 #define CTC_BUFSIZE_LIMIT 65535 #define CTC_BUFSIZE_DEFAULT 32768 @@ -257,13 +257,15 @@ static __inline__ void ctc_clear_busy(struct net_device * dev) { clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy)); - netif_wake_queue(dev); + if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) + netif_wake_queue(dev); } static __inline__ int ctc_test_and_set_busy(struct net_device * dev) { - netif_stop_queue(dev); + if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) + netif_stop_queue(dev); return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy); } diff --git a/trunk/drivers/s390/net/ctctty.c b/trunk/drivers/s390/net/ctctty.c new file mode 100644 index 000000000000..5cdcdbf92962 --- /dev/null +++ b/trunk/drivers/s390/net/ctctty.c @@ -0,0 +1,1259 @@ +/* + * CTC / ESCON network driver, tty interface. + * + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ctctty.h" +#include "ctcdbug.h" + +#define CTC_TTY_MAJOR 43 +#define CTC_TTY_MAX_DEVICES 64 + +#define CTC_ASYNC_MAGIC 0x49344C01 /* for paranoia-checking */ +#define CTC_ASYNC_INITIALIZED 0x80000000 /* port was initialized */ +#define CTC_ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device active */ +#define CTC_ASYNC_CLOSING 0x08000000 /* Serial port is closing */ +#define CTC_ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */ +#define CTC_ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */ +#define CTC_ASYNC_HUP_NOTIFY 0x0001 /* Notify tty on hangups/closes */ +#define CTC_ASYNC_NETDEV_OPEN 0x0002 /* Underlying netdev is open */ +#define CTC_ASYNC_TX_LINESTAT 0x0004 /* Must send line status */ +#define CTC_ASYNC_SPLIT_TERMIOS 0x0008 /* Sep. termios for dialin/out */ +#define CTC_TTY_XMIT_SIZE 1024 /* Default bufsize for write */ +#define CTC_SERIAL_XMIT_MAX 4000 /* Maximum bufsize for write */ + +/* Private data (similar to async_struct in ) */ +typedef struct { + int magic; + int flags; /* defined in tty.h */ + int mcr; /* Modem control register */ + int msr; /* Modem status register */ + int lsr; /* Line status register */ + int line; + int count; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + struct net_device *netdev; + struct sk_buff_head tx_queue; /* transmit queue */ + struct sk_buff_head rx_queue; /* receive queue */ + struct tty_struct *tty; /* Pointer to corresponding tty */ + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; + struct semaphore write_sem; + struct tasklet_struct tasklet; + struct timer_list stoptimer; +} ctc_tty_info; + +/* Description of one CTC-tty */ +typedef struct { + struct tty_driver *ctc_tty_device; /* tty-device */ + ctc_tty_info info[CTC_TTY_MAX_DEVICES]; /* Private data */ +} ctc_tty_driver; + +static ctc_tty_driver *driver; + +/* Leave this unchanged unless you know what you do! */ +#define MODEM_PARANOIA_CHECK +#define MODEM_DO_RESTART + +#define CTC_TTY_NAME "ctctty" + +static __u32 ctc_tty_magic = CTC_ASYNC_MAGIC; +static int ctc_tty_shuttingdown = 0; + +static spinlock_t ctc_tty_lock; + +/* ctc_tty_try_read() is called from within ctc_tty_rcv_skb() + * to stuff incoming data directly into a tty's flip-buffer. If the + * flip buffer is full, the packet gets queued up. + * + * Return: + * 1 = Success + * 0 = Failure, data has to be buffered and later processed by + * ctc_tty_readmodem(). + */ +static int +ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb) +{ + int len; + struct tty_struct *tty; + + DBF_TEXT(trace, 5, __FUNCTION__); + if ((tty = info->tty)) { + if (info->mcr & UART_MCR_RTS) { + len = skb->len; + tty_insert_flip_string(tty, skb->data, len); + tty_flip_buffer_push(tty); + kfree_skb(skb); + return 1; + } + } + return 0; +} + +/* ctc_tty_readmodem() is called periodically from within timer-interrupt. + * It tries getting received data from the receive queue an stuff it into + * the tty's flip-buffer. + */ +static int +ctc_tty_readmodem(ctc_tty_info *info) +{ + int ret = 1; + struct tty_struct *tty; + + DBF_TEXT(trace, 5, __FUNCTION__); + if ((tty = info->tty)) { + if (info->mcr & UART_MCR_RTS) { + struct sk_buff *skb; + + if ((skb = skb_dequeue(&info->rx_queue))) { + int len = skb->len; + tty_insert_flip_string(tty, skb->data, len); + skb_pull(skb, len); + tty_flip_buffer_push(tty); + if (skb->len > 0) + skb_queue_head(&info->rx_queue, skb); + else { + kfree_skb(skb); + ret = !skb_queue_empty(&info->rx_queue); + } + } + } + } + return ret; +} + +void +ctc_tty_setcarrier(struct net_device *netdev, int on) +{ + int i; + + DBF_TEXT(trace, 4, __FUNCTION__); + if ((!driver) || ctc_tty_shuttingdown) + return; + for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) + if (driver->info[i].netdev == netdev) { + ctc_tty_info *info = &driver->info[i]; + if (on) + info->msr |= UART_MSR_DCD; + else + info->msr &= ~UART_MSR_DCD; + if ((info->flags & CTC_ASYNC_CHECK_CD) && (!on)) + tty_hangup(info->tty); + } +} + +void +ctc_tty_netif_rx(struct sk_buff *skb) +{ + int i; + ctc_tty_info *info = NULL; + + DBF_TEXT(trace, 5, __FUNCTION__); + if (!skb) + return; + if ((!skb->dev) || (!driver) || ctc_tty_shuttingdown) { + dev_kfree_skb(skb); + return; + } + for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) + if (driver->info[i].netdev == skb->dev) { + info = &driver->info[i]; + break; + } + if (!info) { + dev_kfree_skb(skb); + return; + } + if (skb->len < 6) { + dev_kfree_skb(skb); + return; + } + if (memcmp(skb->data, &ctc_tty_magic, sizeof(__u32))) { + dev_kfree_skb(skb); + return; + } + skb_pull(skb, sizeof(__u32)); + + i = *((int *)skb->data); + skb_pull(skb, sizeof(info->mcr)); + if (i & UART_MCR_RTS) { + info->msr |= UART_MSR_CTS; + if (info->flags & CTC_ASYNC_CTS_FLOW) + info->tty->hw_stopped = 0; + } else { + info->msr &= ~UART_MSR_CTS; + if (info->flags & CTC_ASYNC_CTS_FLOW) + info->tty->hw_stopped = 1; + } + if (i & UART_MCR_DTR) + info->msr |= UART_MSR_DSR; + else + info->msr &= ~UART_MSR_DSR; + if (skb->len <= 0) { + kfree_skb(skb); + return; + } + /* Try to deliver directly via tty-flip-buf if queue is empty */ + if (skb_queue_empty(&info->rx_queue)) + if (ctc_tty_try_read(info, skb)) + return; + /* Direct deliver failed or queue wasn't empty. + * Queue up for later dequeueing via timer-irq. + */ + skb_queue_tail(&info->rx_queue, skb); + /* Schedule dequeuing */ + tasklet_schedule(&info->tasklet); +} + +static int +ctc_tty_tint(ctc_tty_info * info) +{ + struct sk_buff *skb = skb_dequeue(&info->tx_queue); + int stopped = (info->tty->hw_stopped || info->tty->stopped); + int wake = 1; + int rc; + + DBF_TEXT(trace, 4, __FUNCTION__); + if (!info->netdev) { + if (skb) + kfree_skb(skb); + return 0; + } + if (info->flags & CTC_ASYNC_TX_LINESTAT) { + int skb_res = info->netdev->hard_header_len + + sizeof(info->mcr) + sizeof(__u32); + /* If we must update line status, + * create an empty dummy skb and insert it. + */ + if (skb) + skb_queue_head(&info->tx_queue, skb); + + skb = dev_alloc_skb(skb_res); + if (!skb) { + printk(KERN_WARNING + "ctc_tty: Out of memory in %s%d tint\n", + CTC_TTY_NAME, info->line); + return 1; + } + skb_reserve(skb, skb_res); + stopped = 0; + wake = 0; + } + if (!skb) + return 0; + if (stopped) { + skb_queue_head(&info->tx_queue, skb); + return 1; + } +#if 0 + if (skb->len > 0) + printk(KERN_DEBUG "tint: %d %02x\n", skb->len, *(skb->data)); + else + printk(KERN_DEBUG "tint: %d STAT\n", skb->len); +#endif + memcpy(skb_push(skb, sizeof(info->mcr)), &info->mcr, sizeof(info->mcr)); + memcpy(skb_push(skb, sizeof(__u32)), &ctc_tty_magic, sizeof(__u32)); + rc = info->netdev->hard_start_xmit(skb, info->netdev); + if (rc) { + skb_pull(skb, sizeof(info->mcr) + sizeof(__u32)); + if (skb->len > 0) + skb_queue_head(&info->tx_queue, skb); + else + kfree_skb(skb); + } else { + struct tty_struct *tty = info->tty; + + info->flags &= ~CTC_ASYNC_TX_LINESTAT; + if (tty) { + tty_wakeup(tty); + } + } + return (skb_queue_empty(&info->tx_queue) ? 0 : 1); +} + +/************************************************************ + * + * Modem-functions + * + * mostly "stolen" from original Linux-serial.c and friends. + * + ************************************************************/ + +static inline int +ctc_tty_paranoia_check(ctc_tty_info * info, char *name, const char *routine) +{ +#ifdef MODEM_PARANOIA_CHECK + if (!info) { + printk(KERN_WARNING "ctc_tty: null info_struct for %s in %s\n", + name, routine); + return 1; + } + if (info->magic != CTC_ASYNC_MAGIC) { + printk(KERN_WARNING "ctc_tty: bad magic for info struct %s in %s\n", + name, routine); + return 1; + } +#endif + return 0; +} + +static void +ctc_tty_inject(ctc_tty_info *info, char c) +{ + int skb_res; + struct sk_buff *skb; + + DBF_TEXT(trace, 4, __FUNCTION__); + if (ctc_tty_shuttingdown) + return; + skb_res = info->netdev->hard_header_len + sizeof(info->mcr) + + sizeof(__u32) + 1; + skb = dev_alloc_skb(skb_res); + if (!skb) { + printk(KERN_WARNING + "ctc_tty: Out of memory in %s%d tx_inject\n", + CTC_TTY_NAME, info->line); + return; + } + skb_reserve(skb, skb_res); + *(skb_put(skb, 1)) = c; + skb_queue_head(&info->tx_queue, skb); + tasklet_schedule(&info->tasklet); +} + +static void +ctc_tty_transmit_status(ctc_tty_info *info) +{ + DBF_TEXT(trace, 5, __FUNCTION__); + if (ctc_tty_shuttingdown) + return; + info->flags |= CTC_ASYNC_TX_LINESTAT; + tasklet_schedule(&info->tasklet); +} + +static void +ctc_tty_change_speed(ctc_tty_info * info) +{ + unsigned int cflag; + unsigned int quot; + int i; + + DBF_TEXT(trace, 3, __FUNCTION__); + if (!info->tty || !info->tty->termios) + return; + cflag = info->tty->termios->c_cflag; + + quot = i = cflag & CBAUD; + if (i & CBAUDEX) { + i &= ~CBAUDEX; + if (i < 1 || i > 2) + info->tty->termios->c_cflag &= ~CBAUDEX; + else + i += 15; + } + if (quot) { + info->mcr |= UART_MCR_DTR; + info->mcr |= UART_MCR_RTS; + ctc_tty_transmit_status(info); + } else { + info->mcr &= ~UART_MCR_DTR; + info->mcr &= ~UART_MCR_RTS; + ctc_tty_transmit_status(info); + return; + } + + /* CTS flow control flag and modem status interrupts */ + if (cflag & CRTSCTS) { + info->flags |= CTC_ASYNC_CTS_FLOW; + } else + info->flags &= ~CTC_ASYNC_CTS_FLOW; + if (cflag & CLOCAL) + info->flags &= ~CTC_ASYNC_CHECK_CD; + else { + info->flags |= CTC_ASYNC_CHECK_CD; + } +} + +static int +ctc_tty_startup(ctc_tty_info * info) +{ + DBF_TEXT(trace, 3, __FUNCTION__); + if (info->flags & CTC_ASYNC_INITIALIZED) + return 0; +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "starting up %s%d ...\n", CTC_TTY_NAME, info->line); +#endif + /* + * Now, initialize the UART + */ + info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + /* + * and set the speed of the serial port + */ + ctc_tty_change_speed(info); + + info->flags |= CTC_ASYNC_INITIALIZED; + if (!(info->flags & CTC_ASYNC_NETDEV_OPEN)) + info->netdev->open(info->netdev); + info->flags |= CTC_ASYNC_NETDEV_OPEN; + return 0; +} + +static void +ctc_tty_stopdev(unsigned long data) +{ + ctc_tty_info *info = (ctc_tty_info *)data; + + if ((!info) || (!info->netdev) || + (info->flags & CTC_ASYNC_INITIALIZED)) + return; + info->netdev->stop(info->netdev); + info->flags &= ~CTC_ASYNC_NETDEV_OPEN; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void +ctc_tty_shutdown(ctc_tty_info * info) +{ + DBF_TEXT(trace, 3, __FUNCTION__); + if (!(info->flags & CTC_ASYNC_INITIALIZED)) + return; +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "Shutting down %s%d ....\n", CTC_TTY_NAME, info->line); +#endif + info->msr &= ~UART_MSR_RI; + if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) + info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + mod_timer(&info->stoptimer, jiffies + (10 * HZ)); + skb_queue_purge(&info->tx_queue); + skb_queue_purge(&info->rx_queue); + info->flags &= ~CTC_ASYNC_INITIALIZED; +} + +/* ctc_tty_write() is the main send-routine. It is called from the upper + * levels within the kernel to perform sending data. Depending on the + * online-flag it either directs output to the at-command-interpreter or + * to the lower level. Additional tasks done here: + * - If online, check for escape-sequence (+++) + * - If sending audio-data, call ctc_tty_DLEdown() to parse DLE-codes. + * - If receiving audio-data, call ctc_tty_end_vrx() to abort if needed. + * - If dialing, abort dial. + */ +static int +ctc_tty_write(struct tty_struct *tty, const u_char * buf, int count) +{ + int c; + int total = 0; + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + + DBF_TEXT(trace, 5, __FUNCTION__); + if (ctc_tty_shuttingdown) + goto ex; + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write")) + goto ex; + if (!tty) + goto ex; + if (!info->netdev) { + total = -ENODEV; + goto ex; + } + while (1) { + struct sk_buff *skb; + int skb_res; + + c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE; + if (c <= 0) + break; + + skb_res = info->netdev->hard_header_len + sizeof(info->mcr) + + + sizeof(__u32); + skb = dev_alloc_skb(skb_res + c); + if (!skb) { + printk(KERN_WARNING + "ctc_tty: Out of memory in %s%d write\n", + CTC_TTY_NAME, info->line); + break; + } + skb_reserve(skb, skb_res); + memcpy(skb_put(skb, c), buf, c); + skb_queue_tail(&info->tx_queue, skb); + buf += c; + total += c; + count -= c; + } + if (!skb_queue_empty(&info->tx_queue)) { + info->lsr &= ~UART_LSR_TEMT; + tasklet_schedule(&info->tasklet); + } +ex: + DBF_TEXT(trace, 6, __FUNCTION__); + return total; +} + +static int +ctc_tty_write_room(struct tty_struct *tty) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write_room")) + return 0; + return CTC_TTY_XMIT_SIZE; +} + +static int +ctc_tty_chars_in_buffer(struct tty_struct *tty) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_chars_in_buffer")) + return 0; + return 0; +} + +static void +ctc_tty_flush_buffer(struct tty_struct *tty) +{ + ctc_tty_info *info; + unsigned long flags; + + DBF_TEXT(trace, 4, __FUNCTION__); + if (!tty) + goto ex; + spin_lock_irqsave(&ctc_tty_lock, flags); + info = (ctc_tty_info *) tty->driver_data; + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_buffer")) { + spin_unlock_irqrestore(&ctc_tty_lock, flags); + goto ex; + } + skb_queue_purge(&info->tx_queue); + info->lsr |= UART_LSR_TEMT; + spin_unlock_irqrestore(&ctc_tty_lock, flags); + wake_up_interruptible(&tty->write_wait); + tty_wakeup(tty); +ex: + DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__); + return; +} + +static void +ctc_tty_flush_chars(struct tty_struct *tty) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + + DBF_TEXT(trace, 4, __FUNCTION__); + if (ctc_tty_shuttingdown) + return; + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars")) + return; + if (tty->stopped || tty->hw_stopped || skb_queue_empty(&info->tx_queue)) + return; + tasklet_schedule(&info->tasklet); +} + +/* + * ------------------------------------------------------------ + * ctc_tty_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void +ctc_tty_throttle(struct tty_struct *tty) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + + DBF_TEXT(trace, 4, __FUNCTION__); + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_throttle")) + return; + info->mcr &= ~UART_MCR_RTS; + if (I_IXOFF(tty)) + ctc_tty_inject(info, STOP_CHAR(tty)); + ctc_tty_transmit_status(info); +} + +static void +ctc_tty_unthrottle(struct tty_struct *tty) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + + DBF_TEXT(trace, 4, __FUNCTION__); + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_unthrottle")) + return; + info->mcr |= UART_MCR_RTS; + if (I_IXOFF(tty)) + ctc_tty_inject(info, START_CHAR(tty)); + ctc_tty_transmit_status(info); +} + +/* + * ------------------------------------------------------------ + * ctc_tty_ioctl() and friends + * ------------------------------------------------------------ + */ + +/* + * ctc_tty_get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows RS485 driver to be written in user space. + */ +static int +ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value) +{ + u_char status; + uint result; + ulong flags; + + DBF_TEXT(trace, 4, __FUNCTION__); + spin_lock_irqsave(&ctc_tty_lock, flags); + status = info->lsr; + spin_unlock_irqrestore(&ctc_tty_lock, flags); + result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); + put_user(result, value); + return 0; +} + + +static int ctc_tty_tiocmget(struct tty_struct *tty, struct file *file) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + u_char control, + status; + uint result; + ulong flags; + + DBF_TEXT(trace, 4, __FUNCTION__); + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl")) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + control = info->mcr; + spin_lock_irqsave(&ctc_tty_lock, flags); + status = info->msr; + spin_unlock_irqrestore(&ctc_tty_lock, flags); + result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) + | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) + | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) + | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) + | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) + | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); + return result; +} + +static int +ctc_tty_tiocmset(struct tty_struct *tty, struct file *file, + unsigned int set, unsigned int clear) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + + DBF_TEXT(trace, 4, __FUNCTION__); + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl")) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + if (set & TIOCM_RTS) + info->mcr |= UART_MCR_RTS; + if (set & TIOCM_DTR) + info->mcr |= UART_MCR_DTR; + + if (clear & TIOCM_RTS) + info->mcr &= ~UART_MCR_RTS; + if (clear & TIOCM_DTR) + info->mcr &= ~UART_MCR_DTR; + + if ((set | clear) & (TIOCM_RTS|TIOCM_DTR)) + ctc_tty_transmit_status(info); + return 0; +} + +static int +ctc_tty_ioctl(struct tty_struct *tty, struct file *file, + uint cmd, ulong arg) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + int error; + int retval; + + DBF_TEXT(trace, 4, __FUNCTION__); + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl")) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + switch (cmd) { + case TCSBRK: /* SVID version: non-zero arg --> no break */ +#ifdef CTC_DEBUG_MODEM_IOCTL + printk(KERN_DEBUG "%s%d ioctl TCSBRK\n", CTC_TTY_NAME, info->line); +#endif + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + return 0; + case TCSBRKP: /* support for POSIX tcsendbreak() */ +#ifdef CTC_DEBUG_MODEM_IOCTL + printk(KERN_DEBUG "%s%d ioctl TCSBRKP\n", CTC_TTY_NAME, info->line); +#endif + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + return 0; + case TIOCGSOFTCAR: +#ifdef CTC_DEBUG_MODEM_IOCTL + printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME, + info->line); +#endif + error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg); + return error; + case TIOCSSOFTCAR: +#ifdef CTC_DEBUG_MODEM_IOCTL + printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME, + info->line); +#endif + error = get_user(arg, (ulong __user *) arg); + if (error) + return error; + tty->termios->c_cflag = + ((tty->termios->c_cflag & ~CLOCAL) | + (arg ? CLOCAL : 0)); + return 0; + case TIOCSERGETLSR: /* Get line status register */ +#ifdef CTC_DEBUG_MODEM_IOCTL + printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME, + info->line); +#endif + if (access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(uint))) + return ctc_tty_get_lsr_info(info, (uint __user *) arg); + else + return -EFAULT; + default: +#ifdef CTC_DEBUG_MODEM_IOCTL + printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd, + CTC_TTY_NAME, info->line); +#endif + return -ENOIOCTLCMD; + } + return 0; +} + +static void +ctc_tty_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + unsigned int cflag = tty->termios->c_cflag; + + DBF_TEXT(trace, 4, __FUNCTION__); + ctc_tty_change_speed(info); + + /* Handle transition to B0 */ + if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) { + info->mcr &= ~(UART_MCR_DTR|UART_MCR_RTS); + ctc_tty_transmit_status(info); + } + + /* Handle transition from B0 to other */ + if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { + info->mcr |= UART_MCR_DTR; + if (!(tty->termios->c_cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) { + info->mcr |= UART_MCR_RTS; + } + ctc_tty_transmit_status(info); + } + + /* Handle turning off CRTSCTS */ + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) + tty->hw_stopped = 0; +} + +/* + * ------------------------------------------------------------ + * ctc_tty_open() and friends + * ------------------------------------------------------------ + */ +static int +ctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info *info) +{ + DECLARE_WAITQUEUE(wait, NULL); + int do_clocal = 0; + unsigned long flags; + int retval; + + DBF_TEXT(trace, 4, __FUNCTION__); + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || + (info->flags & CTC_ASYNC_CLOSING)) { + if (info->flags & CTC_ASYNC_CLOSING) + wait_event(info->close_wait, + !(info->flags & CTC_ASYNC_CLOSING)); +#ifdef MODEM_DO_RESTART + if (info->flags & CTC_ASYNC_HUP_NOTIFY) + return -EAGAIN; + else + return -ERESTARTSYS; +#else + return -EAGAIN; +#endif + } + /* + * If non-blocking mode is set, then make the check up front + * and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + info->flags |= CTC_ASYNC_NORMAL_ACTIVE; + return 0; + } + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, info->count is dropped by one, so that + * ctc_tty_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_block_til_ready before block: %s%d, count = %d\n", + CTC_TTY_NAME, info->line, info->count); +#endif + spin_lock_irqsave(&ctc_tty_lock, flags); + if (!(tty_hung_up_p(filp))) + info->count--; + spin_unlock_irqrestore(&ctc_tty_lock, flags); + info->blocked_open++; + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(info->flags & CTC_ASYNC_INITIALIZED)) { +#ifdef MODEM_DO_RESTART + if (info->flags & CTC_ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & CTC_ASYNC_CLOSING) && + (do_clocal || (info->msr & UART_MSR_DCD))) { + break; + } + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_block_til_ready blocking: %s%d, count = %d\n", + CTC_TTY_NAME, info->line, info->count); +#endif + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&info->open_wait, &wait); + if (!tty_hung_up_p(filp)) + info->count++; + info->blocked_open--; +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_block_til_ready after blocking: %s%d, count = %d\n", + CTC_TTY_NAME, info->line, info->count); +#endif + if (retval) + return retval; + info->flags |= CTC_ASYNC_NORMAL_ACTIVE; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its async structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +static int +ctc_tty_open(struct tty_struct *tty, struct file *filp) +{ + ctc_tty_info *info; + unsigned long saveflags; + int retval, + line; + + DBF_TEXT(trace, 3, __FUNCTION__); + line = tty->index; + if (line < 0 || line > CTC_TTY_MAX_DEVICES) + return -ENODEV; + info = &driver->info[line]; + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_open")) + return -ENODEV; + if (!info->netdev) + return -ENODEV; +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_open %s, count = %d\n", tty->name, + info->count); +#endif + spin_lock_irqsave(&ctc_tty_lock, saveflags); + info->count++; + tty->driver_data = info; + info->tty = tty; + spin_unlock_irqrestore(&ctc_tty_lock, saveflags); + /* + * Start up serial port + */ + retval = ctc_tty_startup(info); + if (retval) { +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_open return after startup\n"); +#endif + return retval; + } + retval = ctc_tty_block_til_ready(tty, filp, info); + if (retval) { +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_open return after ctc_tty_block_til_ready \n"); +#endif + return retval; + } +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_open %s successful...\n", tty->name); +#endif + return 0; +} + +static void +ctc_tty_close(struct tty_struct *tty, struct file *filp) +{ + ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; + ulong flags; + ulong timeout; + DBF_TEXT(trace, 3, __FUNCTION__); + if (!info || ctc_tty_paranoia_check(info, tty->name, "ctc_tty_close")) + return; + spin_lock_irqsave(&ctc_tty_lock, flags); + if (tty_hung_up_p(filp)) { + spin_unlock_irqrestore(&ctc_tty_lock, flags); +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_close return after tty_hung_up_p\n"); +#endif + return; + } + if ((tty->count == 1) && (info->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. Info->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk(KERN_ERR "ctc_tty_close: bad port count; tty->count is 1, " + "info->count is %d\n", info->count); + info->count = 1; + } + if (--info->count < 0) { + printk(KERN_ERR "ctc_tty_close: bad port count for %s%d: %d\n", + CTC_TTY_NAME, info->line, info->count); + info->count = 0; + } + if (info->count) { + local_irq_restore(flags); +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_close after info->count != 0\n"); +#endif + return; + } + info->flags |= CTC_ASYNC_CLOSING; + tty->closing = 1; + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + if (info->flags & CTC_ASYNC_INITIALIZED) { + tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */ + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + timeout = jiffies + HZ; + while (!(info->lsr & UART_LSR_TEMT)) { + spin_unlock_irqrestore(&ctc_tty_lock, flags); + msleep(500); + spin_lock_irqsave(&ctc_tty_lock, flags); + if (time_after(jiffies,timeout)) + break; + } + } + ctc_tty_shutdown(info); + if (tty->driver->flush_buffer) { + skb_queue_purge(&info->tx_queue); + info->lsr |= UART_LSR_TEMT; + } + tty_ldisc_flush(tty); + info->tty = 0; + tty->closing = 0; + if (info->blocked_open) { + msleep_interruptible(500); + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + spin_unlock_irqrestore(&ctc_tty_lock, flags); +#ifdef CTC_DEBUG_MODEM_OPEN + printk(KERN_DEBUG "ctc_tty_close normal exit\n"); +#endif +} + +/* + * ctc_tty_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void +ctc_tty_hangup(struct tty_struct *tty) +{ + ctc_tty_info *info = (ctc_tty_info *)tty->driver_data; + unsigned long saveflags; + DBF_TEXT(trace, 3, __FUNCTION__); + if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_hangup")) + return; + ctc_tty_shutdown(info); + info->count = 0; + info->flags &= ~CTC_ASYNC_NORMAL_ACTIVE; + spin_lock_irqsave(&ctc_tty_lock, saveflags); + info->tty = 0; + spin_unlock_irqrestore(&ctc_tty_lock, saveflags); + wake_up_interruptible(&info->open_wait); +} + + +/* + * For all online tty's, try sending data to + * the lower levels. + */ +static void +ctc_tty_task(unsigned long arg) +{ + ctc_tty_info *info = (void *)arg; + unsigned long saveflags; + int again; + + DBF_TEXT(trace, 3, __FUNCTION__); + spin_lock_irqsave(&ctc_tty_lock, saveflags); + if ((!ctc_tty_shuttingdown) && info) { + again = ctc_tty_tint(info); + if (!again) + info->lsr |= UART_LSR_TEMT; + again |= ctc_tty_readmodem(info); + if (again) { + tasklet_schedule(&info->tasklet); + } + } + spin_unlock_irqrestore(&ctc_tty_lock, saveflags); +} + +static struct tty_operations ctc_ops = { + .open = ctc_tty_open, + .close = ctc_tty_close, + .write = ctc_tty_write, + .flush_chars = ctc_tty_flush_chars, + .write_room = ctc_tty_write_room, + .chars_in_buffer = ctc_tty_chars_in_buffer, + .flush_buffer = ctc_tty_flush_buffer, + .ioctl = ctc_tty_ioctl, + .throttle = ctc_tty_throttle, + .unthrottle = ctc_tty_unthrottle, + .set_termios = ctc_tty_set_termios, + .hangup = ctc_tty_hangup, + .tiocmget = ctc_tty_tiocmget, + .tiocmset = ctc_tty_tiocmset, +}; + +int +ctc_tty_init(void) +{ + int i; + ctc_tty_info *info; + struct tty_driver *device; + + DBF_TEXT(trace, 2, __FUNCTION__); + driver = kmalloc(sizeof(ctc_tty_driver), GFP_KERNEL); + if (driver == NULL) { + printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n"); + return -ENOMEM; + } + memset(driver, 0, sizeof(ctc_tty_driver)); + device = alloc_tty_driver(CTC_TTY_MAX_DEVICES); + if (!device) { + kfree(driver); + printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n"); + return -ENOMEM; + } + + device->devfs_name = "ctc/" CTC_TTY_NAME; + device->name = CTC_TTY_NAME; + device->major = CTC_TTY_MAJOR; + device->minor_start = 0; + device->type = TTY_DRIVER_TYPE_SERIAL; + device->subtype = SERIAL_TYPE_NORMAL; + device->init_termios = tty_std_termios; + device->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + device->flags = TTY_DRIVER_REAL_RAW; + device->driver_name = "ctc_tty", + tty_set_operations(device, &ctc_ops); + if (tty_register_driver(device)) { + printk(KERN_WARNING "ctc_tty: Couldn't register serial-device\n"); + put_tty_driver(device); + kfree(driver); + return -1; + } + driver->ctc_tty_device = device; + for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) { + info = &driver->info[i]; + init_MUTEX(&info->write_sem); + tasklet_init(&info->tasklet, ctc_tty_task, + (unsigned long) info); + info->magic = CTC_ASYNC_MAGIC; + info->line = i; + info->tty = 0; + info->count = 0; + info->blocked_open = 0; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + skb_queue_head_init(&info->tx_queue); + skb_queue_head_init(&info->rx_queue); + init_timer(&info->stoptimer); + info->stoptimer.function = ctc_tty_stopdev; + info->stoptimer.data = (unsigned long)info; + info->mcr = UART_MCR_RTS; + } + return 0; +} + +int +ctc_tty_register_netdev(struct net_device *dev) { + int ttynum; + char *err; + char *p; + + DBF_TEXT(trace, 2, __FUNCTION__); + if ((!dev) || (!dev->name)) { + printk(KERN_WARNING + "ctc_tty_register_netdev called " + "with NULL dev or NULL dev-name\n"); + return -1; + } + + /* + * If the name is a format string the caller wants us to + * do a name allocation : format string must end with %d + */ + if (strchr(dev->name, '%')) + { + int err = dev_alloc_name(dev, dev->name); // dev->name is changed by this + if (err < 0) { + printk(KERN_DEBUG "dev_alloc returned error %d\n", err); + return err; + } + + } + + for (p = dev->name; p && ((*p < '0') || (*p > '9')); p++); + ttynum = simple_strtoul(p, &err, 0); + if ((ttynum < 0) || (ttynum >= CTC_TTY_MAX_DEVICES) || + (err && *err)) { + printk(KERN_WARNING + "ctc_tty_register_netdev called " + "with number in name '%s'\n", dev->name); + return -1; + } + if (driver->info[ttynum].netdev) { + printk(KERN_WARNING + "ctc_tty_register_netdev called " + "for already registered device '%s'\n", + dev->name); + return -1; + } + driver->info[ttynum].netdev = dev; + return 0; +} + +void +ctc_tty_unregister_netdev(struct net_device *dev) { + int i; + unsigned long saveflags; + ctc_tty_info *info = NULL; + + DBF_TEXT(trace, 2, __FUNCTION__); + spin_lock_irqsave(&ctc_tty_lock, saveflags); + for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) + if (driver->info[i].netdev == dev) { + info = &driver->info[i]; + break; + } + if (info) { + info->netdev = NULL; + skb_queue_purge(&info->tx_queue); + skb_queue_purge(&info->rx_queue); + } + spin_unlock_irqrestore(&ctc_tty_lock, saveflags); +} + +void +ctc_tty_cleanup(void) { + unsigned long saveflags; + + DBF_TEXT(trace, 2, __FUNCTION__); + spin_lock_irqsave(&ctc_tty_lock, saveflags); + ctc_tty_shuttingdown = 1; + spin_unlock_irqrestore(&ctc_tty_lock, saveflags); + tty_unregister_driver(driver->ctc_tty_device); + put_tty_driver(driver->ctc_tty_device); + kfree(driver); + driver = NULL; +} diff --git a/trunk/drivers/s390/net/ctctty.h b/trunk/drivers/s390/net/ctctty.h new file mode 100644 index 000000000000..7254dc006311 --- /dev/null +++ b/trunk/drivers/s390/net/ctctty.h @@ -0,0 +1,35 @@ +/* + * CTC / ESCON network driver, tty interface. + * + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _CTCTTY_H_ +#define _CTCTTY_H_ + +#include +#include + +extern int ctc_tty_register_netdev(struct net_device *); +extern void ctc_tty_unregister_netdev(struct net_device *); +extern void ctc_tty_netif_rx(struct sk_buff *); +extern int ctc_tty_init(void); +extern void ctc_tty_cleanup(void); +extern void ctc_tty_setcarrier(struct net_device *, int); + +#endif diff --git a/trunk/drivers/s390/net/lcs.c b/trunk/drivers/s390/net/lcs.c index e65da921a827..5d6b7a57b02f 100644 --- a/trunk/drivers/s390/net/lcs.c +++ b/trunk/drivers/s390/net/lcs.c @@ -1348,7 +1348,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa) - channel->ccws; if ((irb->scsw.actl & SCSW_ACTL_SUSPENDED) || - (irb->scsw.cstat & SCHN_STAT_PCI)) + (irb->scsw.cstat | SCHN_STAT_PCI)) /* Bloody io subsystem tells us lies about cpa... */ index = (index - 1) & (LCS_NUM_BUFFS - 1); while (channel->io_idx != index) { diff --git a/trunk/drivers/sbus/char/openprom.c b/trunk/drivers/sbus/char/openprom.c index 239e108b8ed1..383a95f34a0d 100644 --- a/trunk/drivers/sbus/char/openprom.c +++ b/trunk/drivers/sbus/char/openprom.c @@ -392,16 +392,13 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file, return -ENOMEM; } - cnt = prom_getproperty(op.op_nodeid, str, tmp, len); - if (cnt <= 0) { - error = -EINVAL; - } else { - tmp[len] = '\0'; + prom_getproperty(op.op_nodeid, str, tmp, len); - if (__copy_to_user(argp, &op, sizeof(op)) != 0 || - copy_to_user(op.op_buf, tmp, len) != 0) - error = -EFAULT; - } + tmp[len] = '\0'; + + if (__copy_to_user(argp, &op, sizeof(op)) != 0 + || copy_to_user(op.op_buf, tmp, len) != 0) + error = -EFAULT; kfree(tmp); kfree(str); diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index 0c9c2f400bf6..cb30d9c1153d 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -219,7 +219,6 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ahc->flags |= AHC_39BIT_ADDRESSING; } else { if (dma_set_mask(dev, DMA_32BIT_MASK)) { - ahc_free(ahc); printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); return (-ENODEV); } diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c index 3adecef21783..5f586140e057 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c @@ -2036,12 +2036,12 @@ ahc_pci_resume(struct ahc_softc *ahc) * that the OS doesn't know about and rely on our chip * reset handler to handle the rest. */ - ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, - ahc->bus_softc.pci_softc.devconfig, /*bytes*/4); - ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, - ahc->bus_softc.pci_softc.command, /*bytes*/1); - ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, - ahc->bus_softc.pci_softc.csize_lattime, /*bytes*/1); + ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4, + ahc->bus_softc.pci_softc.devconfig); + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1, + ahc->bus_softc.pci_softc.command); + ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1, + ahc->bus_softc.pci_softc.csize_lattime); if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) { struct seeprom_descriptor sd; u_int sxfrctl1; diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index 2e9be83a697f..0a8ad37ae899 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -739,8 +739,7 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) { struct viosrp_adapter_info *req; struct srp_event_struct *evt_struct; - dma_addr_t addr; - + evt_struct = get_event_struct(&hostdata->pool); if (!evt_struct) { printk(KERN_ERR "ibmvscsi: couldn't allocate an event " @@ -758,10 +757,10 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) req->common.type = VIOSRP_ADAPTER_INFO_TYPE; req->common.length = sizeof(hostdata->madapter_info); - req->buffer = addr = dma_map_single(hostdata->dev, - &hostdata->madapter_info, - sizeof(hostdata->madapter_info), - DMA_BIDIRECTIONAL); + req->buffer = dma_map_single(hostdata->dev, + &hostdata->madapter_info, + sizeof(hostdata->madapter_info), + DMA_BIDIRECTIONAL); if (dma_mapping_error(req->buffer)) { printk(KERN_ERR @@ -771,13 +770,8 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) return; } - if (ibmvscsi_send_srp_event(evt_struct, hostdata)) { + if (ibmvscsi_send_srp_event(evt_struct, hostdata)) printk(KERN_ERR "ibmvscsi: couldn't send ADAPTER_INFO_REQ!\n"); - dma_unmap_single(hostdata->dev, - addr, - sizeof(hostdata->madapter_info), - DMA_BIDIRECTIONAL); - } }; /** @@ -1265,7 +1259,6 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, { struct viosrp_host_config *host_config; struct srp_event_struct *evt_struct; - dma_addr_t addr; int rc; evt_struct = get_event_struct(&hostdata->pool); @@ -1286,9 +1279,8 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, memset(host_config, 0x00, sizeof(*host_config)); host_config->common.type = VIOSRP_HOST_CONFIG_TYPE; host_config->common.length = length; - host_config->buffer = addr = dma_map_single(hostdata->dev, buffer, - length, - DMA_BIDIRECTIONAL); + host_config->buffer = dma_map_single(hostdata->dev, buffer, length, + DMA_BIDIRECTIONAL); if (dma_mapping_error(host_config->buffer)) { printk(KERN_ERR @@ -1299,9 +1291,11 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, init_completion(&evt_struct->comp); rc = ibmvscsi_send_srp_event(evt_struct, hostdata); - if (rc == 0) + if (rc == 0) { wait_for_completion(&evt_struct->comp); - dma_unmap_single(hostdata->dev, addr, length, DMA_BIDIRECTIONAL); + dma_unmap_single(hostdata->dev, host_config->buffer, + length, DMA_BIDIRECTIONAL); + } return rc; } diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c index 823dfa78c0ba..bd147207f25d 100644 --- a/trunk/drivers/scsi/libata-core.c +++ b/trunk/drivers/scsi/libata-core.c @@ -864,9 +864,6 @@ static unsigned int ata_id_xfermask(const u16 *id) /** * ata_port_queue_task - Queue port_task * @ap: The ata_port to queue port_task for - * @fn: workqueue function to be scheduled - * @data: data value to pass to workqueue function - * @delay: delay time for workqueue function * * Schedule @fn(@data) for execution after @delay jiffies using * port_task. There is one port_task per port and it's the @@ -2742,8 +2739,6 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap, * ata_dev_init_params - Issue INIT DEV PARAMS command * @ap: Port associated with device @dev * @dev: Device to which command will be sent - * @heads: Number of heads (taskfile parameter) - * @sectors: Number of sectors (taskfile parameter) * * LOCKING: * Kernel thread context (may sleep) @@ -4307,7 +4302,6 @@ int ata_device_resume(struct ata_port *ap, struct ata_device *dev) * ata_device_suspend - prepare a device for suspend * @ap: port the device is connected to * @dev: the device to suspend - * @state: target power management state * * Flush the cache on the drive, if appropriate, then issue a * standbynow command. diff --git a/trunk/drivers/scsi/lpfc/lpfc_crtn.h b/trunk/drivers/scsi/lpfc/lpfc_crtn.h index ee22173fce43..fad607b2e6f4 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_crtn.h +++ b/trunk/drivers/scsi/lpfc/lpfc_crtn.h @@ -27,6 +27,7 @@ void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *); +void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *, uint32_t); void lpfc_unreg_login(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *); diff --git a/trunk/drivers/scsi/lpfc/lpfc_disc.h b/trunk/drivers/scsi/lpfc/lpfc_disc.h index 41cf5d3ea6ce..8932b1be2b60 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_disc.h +++ b/trunk/drivers/scsi/lpfc/lpfc_disc.h @@ -113,7 +113,6 @@ struct lpfc_nodelist { #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from NPR list */ #define NLP_DELAY_REMOVE 0x4000000 /* Defer removal till end of DSM */ -#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ /* Defines for list searchs */ #define NLP_SEARCH_MAPPED 0x1 /* search mapped */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index 283b7d824c34..4813beaaca8f 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -302,6 +302,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, if (lpfc_reg_login(phba, Fabric_DID, (uint8_t *) sp, mbox, 0)) goto fail_free_mbox; + /* + * set_slim mailbox command needs to execute first, + * queue this command to be processed later. + */ mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; mbox->context2 = ndlp; @@ -777,26 +781,25 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, if (disc && phba->num_disc_nodes) { /* Check to see if there are more PLOGIs to be sent */ lpfc_more_plogi(phba); + } - if (phba->num_disc_nodes == 0) { - spin_lock_irq(phba->host->host_lock); - phba->fc_flag &= ~FC_NDISC_ACTIVE; - spin_unlock_irq(phba->host->host_lock); + if (phba->num_disc_nodes == 0) { + spin_lock_irq(phba->host->host_lock); + phba->fc_flag &= ~FC_NDISC_ACTIVE; + spin_unlock_irq(phba->host->host_lock); - lpfc_can_disctmo(phba); - if (phba->fc_flag & FC_RSCN_MODE) { - /* - * Check to see if more RSCNs came in while - * we were processing this one. - */ - if ((phba->fc_rscn_id_cnt == 0) && - (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { - spin_lock_irq(phba->host->host_lock); - phba->fc_flag &= ~FC_RSCN_MODE; - spin_unlock_irq(phba->host->host_lock); - } else { - lpfc_els_handle_rscn(phba); - } + lpfc_can_disctmo(phba); + if (phba->fc_flag & FC_RSCN_MODE) { + /* Check to see if more RSCNs came in while we were + * processing this one. + */ + if ((phba->fc_rscn_id_cnt == 0) && + (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { + spin_lock_irq(phba->host->host_lock); + phba->fc_flag &= ~FC_RSCN_MODE; + spin_unlock_irq(phba->host->host_lock); + } else { + lpfc_els_handle_rscn(phba); } } } @@ -1260,7 +1263,7 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, psli = &phba->sli; pring = &psli->ring[LPFC_ELS_RING]; - cmdsize = (2 * sizeof (uint32_t)) + sizeof (struct lpfc_name); + cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name)); elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, ndlp->nlp_DID, ELS_CMD_LOGO); if (!elsiocb) @@ -1448,23 +1451,22 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp) * PLOGIs to be sent */ lpfc_more_plogi(phba); + } - if (phba->num_disc_nodes == 0) { - phba->fc_flag &= ~FC_NDISC_ACTIVE; - lpfc_can_disctmo(phba); - if (phba->fc_flag & FC_RSCN_MODE) { - /* - * Check to see if more RSCNs - * came in while we were - * processing this one. - */ - if((phba->fc_rscn_id_cnt==0) && - !(phba->fc_flag & FC_RSCN_DISCOVERY)) { - phba->fc_flag &= ~FC_RSCN_MODE; - } - else { - lpfc_els_handle_rscn(phba); - } + if (phba->num_disc_nodes == 0) { + phba->fc_flag &= ~FC_NDISC_ACTIVE; + lpfc_can_disctmo(phba); + if (phba->fc_flag & FC_RSCN_MODE) { + /* Check to see if more RSCNs + * came in while we were + * processing this one. + */ + if((phba->fc_rscn_id_cnt==0) && + (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { + phba->fc_flag &= ~FC_RSCN_MODE; + } + else { + lpfc_els_handle_rscn(phba); } } } @@ -1870,6 +1872,9 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, if (mbox) { if ((rspiocb->iocb.ulpStatus == 0) && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { + /* set_slim mailbox command needs to execute first, + * queue this command to be processed later. + */ lpfc_unreg_rpi(phba, ndlp); mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; mbox->context2 = ndlp; @@ -1915,7 +1920,6 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, uint8_t *pcmd; uint16_t cmdsize; int rc; - ELS_PKT *els_pkt_ptr; psli = &phba->sli; pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ @@ -1954,23 +1958,6 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, pcmd += sizeof (uint32_t); memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); break; - case ELS_CMD_PRLO: - cmdsize = sizeof (uint32_t) + sizeof (PRLO); - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, - ndlp, ndlp->nlp_DID, ELS_CMD_PRLO); - if (!elsiocb) - return 1; - - icmd = &elsiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri */ - pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); - - memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt, - sizeof (uint32_t) + sizeof (PRLO)); - *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC; - els_pkt_ptr = (ELS_PKT *) pcmd; - els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED; - break; default: return 1; } @@ -2511,7 +2498,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, /* If we are about to begin discovery, just ACC the RSCN. * Discovery processing will satisfy it. */ - if (phba->hba_state <= LPFC_NS_QRY) { + if (phba->hba_state < LPFC_NS_QRY) { lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode); return 0; diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index adb086009ae0..6721e679df62 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -311,8 +311,8 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2, evtp->evt_arg2 = arg2; evtp->evt = evt; - spin_lock_irq(phba->host->host_lock); list_add_tail(&evtp->evt_listp, &phba->work_list); + spin_lock_irq(phba->host->host_lock); if (phba->work_wait) wake_up(phba->work_wait); spin_unlock_irq(phba->host->host_lock); @@ -1071,6 +1071,10 @@ lpfc_register_remote_port(struct lpfc_hba * phba, /* initialize static port data */ rport->maxframe_size = ndlp->nlp_maxframe; rport->supported_classes = ndlp->nlp_class_sup; + if ((rport->scsi_target_id != -1) && + (rport->scsi_target_id < MAX_FCP_TARGET)) { + ndlp->nlp_sid = rport->scsi_target_id; + } rdata = rport->dd_data; rdata->pnode = ndlp; @@ -1083,10 +1087,6 @@ lpfc_register_remote_port(struct lpfc_hba * phba, if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) fc_remote_port_rolechg(rport, rport_ids.roles); - if ((rport->scsi_target_id != -1) && - (rport->scsi_target_id < MAX_FCP_TARGET)) { - ndlp->nlp_sid = rport->scsi_target_id; - } return; } @@ -1238,7 +1238,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) evt_listp); } - nlp->nlp_flag &= ~NLP_NODEV_REMOVE; nlp->nlp_type |= NLP_FC_NODE; break; case NLP_MAPPED_LIST: @@ -1259,7 +1258,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) evt_listp); } - nlp->nlp_flag &= ~NLP_NODEV_REMOVE; break; case NLP_NPR_LIST: nlp->nlp_flag |= list; @@ -1404,8 +1402,6 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) return 1; case CMD_ELS_REQUEST64_CR: - if (icmd->un.elsreq64.remoteID == ndlp->nlp_DID) - return 1; case CMD_XMIT_ELS_RSP64_CX: if (iocb->context1 == (uint8_t *) ndlp) return 1; @@ -1905,8 +1901,10 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) */ if (ndlp->nlp_flag & NLP_DELAY_TMO) lpfc_cancel_retry_delay_tmo(phba, ndlp); - } else + } else { + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp = NULL; + } } else { flg = ndlp->nlp_flag & NLP_LIST_MASK; if ((flg == NLP_ADISC_LIST) || (flg == NLP_PLOGI_LIST)) diff --git a/trunk/drivers/scsi/lpfc/lpfc_hw.h b/trunk/drivers/scsi/lpfc/lpfc_hw.h index eedf98801366..54d04188f7cc 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hw.h +++ b/trunk/drivers/scsi/lpfc/lpfc_hw.h @@ -449,7 +449,6 @@ struct serv_parm { /* Structure is in Big Endian format */ #define ELS_CMD_RRQ 0x12000000 #define ELS_CMD_PRLI 0x20100014 #define ELS_CMD_PRLO 0x21100014 -#define ELS_CMD_PRLO_ACC 0x02100014 #define ELS_CMD_PDISC 0x50000000 #define ELS_CMD_FDISC 0x51000000 #define ELS_CMD_ADISC 0x52000000 @@ -485,7 +484,6 @@ struct serv_parm { /* Structure is in Big Endian format */ #define ELS_CMD_RRQ 0x12 #define ELS_CMD_PRLI 0x14001020 #define ELS_CMD_PRLO 0x14001021 -#define ELS_CMD_PRLO_ACC 0x14001002 #define ELS_CMD_PDISC 0x50 #define ELS_CMD_FDISC 0x51 #define ELS_CMD_ADISC 0x52 @@ -1541,7 +1539,6 @@ typedef struct { #define FLAGS_TOPOLOGY_FAILOVER 0x0400 /* Bit 10 */ #define FLAGS_LINK_SPEED 0x0800 /* Bit 11 */ -#define FLAGS_IMED_ABORT 0x04000 /* Bit 14 */ uint32_t link_speed; #define LINK_SPEED_AUTO 0 /* Auto selection */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index 908d0f27706f..66d5d003555d 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -294,6 +294,15 @@ lpfc_config_port_post(struct lpfc_hba * phba) } } + /* This should turn on DELAYED ABTS for ELS timeouts */ + lpfc_set_slim(phba, pmb, 0x052198, 0x1); + if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { + phba->hba_state = LPFC_HBA_ERROR; + mempool_free( pmb, phba->mbox_mem_pool); + return -EIO; + } + + lpfc_read_config(phba, pmb); if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { lpfc_printf_log(phba, @@ -795,7 +804,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) int max_speed; char * ports; char * bus; - } m = {"", 0, "", ""}; + } m; pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype); ports = (hdrtype == 0x80) ? "2-port " : ""; @@ -1618,7 +1627,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) error = lpfc_alloc_sysfs_attr(phba); if (error) - goto out_remove_host; + goto out_kthread_stop; error = request_irq(phba->pcidev->irq, lpfc_intr_handler, SA_SHIRQ, LPFC_DRIVER_NAME, phba); @@ -1635,10 +1644,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; error = lpfc_sli_hba_setup(phba); - if (error) { - error = -ENODEV; + if (error) goto out_free_irq; - } if (phba->cfg_poll & DISABLE_FCP_RING_INT) { spin_lock_irq(phba->host->host_lock); @@ -1693,9 +1700,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) free_irq(phba->pcidev->irq, phba); out_free_sysfs_attr: lpfc_free_sysfs_attr(phba); -out_remove_host: - fc_remove_host(phba->host); - scsi_remove_host(phba->host); out_kthread_stop: kthread_stop(phba->worker_thread); out_free_iocbq: @@ -1717,14 +1721,12 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) out_idr_remove: idr_remove(&lpfc_hba_index, phba->brd_no); out_put_host: - phba->host = NULL; scsi_host_put(host); out_release_regions: pci_release_regions(pdev); out_disable_device: pci_disable_device(pdev); out: - pci_set_drvdata(pdev, NULL); return error; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_mbox.c b/trunk/drivers/scsi/lpfc/lpfc_mbox.c index e42f22aaf71b..c585e2b2e589 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_mbox.c +++ b/trunk/drivers/scsi/lpfc/lpfc_mbox.c @@ -200,9 +200,6 @@ lpfc_init_link(struct lpfc_hba * phba, break; } - /* Enable asynchronous ABTS responses from firmware */ - mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT; - /* NEW_FEATURE * Setting up the link speed */ @@ -295,6 +292,36 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb) return; } +/***********************************************/ + +/* command to write slim */ +/***********************************************/ +void +lpfc_set_slim(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint32_t addr, + uint32_t value) +{ + MAILBOX_t *mb; + + mb = &pmb->mb; + memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); + + /* addr = 0x090597 is AUTO ABTS disable for ELS commands */ + /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */ + + /* + * Always turn on DELAYED ABTS for ELS timeouts + */ + if ((addr == 0x052198) && (value == 0)) + value = 1; + + mb->un.varWords[0] = addr; + mb->un.varWords[1] = value; + + mb->mbxCommand = MBX_SET_SLIM; + mb->mbxOwner = OWN_HOST; + return; +} + /**********************************************/ /* lpfc_read_nv Issue a READ CONFIG */ /* mailbox command */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c index 27d60ad897cd..3d77bd999b70 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -465,18 +465,14 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, static int lpfc_rcv_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, - struct lpfc_iocbq *cmdiocb, - uint32_t els_cmd) + struct lpfc_iocbq *cmdiocb) { /* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */ /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary * PLOGIs during LOGO storms from a device. */ ndlp->nlp_flag |= NLP_LOGO_ACC; - if (els_cmd == ELS_CMD_PRLO) - lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); - else - lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); if (!(ndlp->nlp_type & NLP_FABRIC) || (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { @@ -685,7 +681,7 @@ lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba, /* software abort outstanding PLOGI */ lpfc_els_abort(phba, ndlp, 1); - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); + lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state; } @@ -792,6 +788,10 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, if (lpfc_reg_login (phba, irsp->un.elsreq64.remoteID, (uint8_t *) sp, mbox, 0) == 0) { + /* set_slim mailbox command needs to + * execute first, queue this command to + * be processed later. + */ switch (ndlp->nlp_DID) { case NameServer_DID: mbox->mbox_cmpl = @@ -832,17 +832,11 @@ static uint32_t lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } - else { - /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp, 1); + /* software abort outstanding PLOGI */ + lpfc_els_abort(phba, ndlp, 1); - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + return NLP_STE_FREED_NODE; } static uint32_t @@ -857,7 +851,7 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); return ndlp->nlp_state; @@ -911,7 +905,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, /* software abort outstanding ADISC */ lpfc_els_abort(phba, ndlp, 0); - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); + lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state; } @@ -938,7 +932,7 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; /* Treat like rcv logo */ - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); + lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state; } @@ -993,17 +987,11 @@ lpfc_device_rm_adisc_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } - else { - /* software abort outstanding ADISC */ - lpfc_els_abort(phba, ndlp, 1); + /* software abort outstanding ADISC */ + lpfc_els_abort(phba, ndlp, 1); - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + return NLP_STE_FREED_NODE; } static uint32_t @@ -1018,7 +1006,7 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp->nlp_flag |= NLP_NPR_ADISC; spin_unlock_irq(phba->host->host_lock); @@ -1060,7 +1048,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); + lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state; } @@ -1085,7 +1073,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba, struct lpfc_iocbq *cmdiocb; cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); return ndlp->nlp_state; } @@ -1145,14 +1133,8 @@ lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } - else { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + return NLP_STE_FREED_NODE; } static uint32_t @@ -1164,7 +1146,7 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); return ndlp->nlp_state; } @@ -1204,7 +1186,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, /* Software abort outstanding PRLI before sending acc */ lpfc_els_abort(phba, ndlp, 1); - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); + lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state; } @@ -1232,7 +1214,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba, struct lpfc_iocbq *cmdiocb; cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); return ndlp->nlp_state; } @@ -1296,17 +1278,11 @@ static uint32_t lpfc_device_rm_prli_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } - else { - /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp, 1); + /* software abort outstanding PRLI */ + lpfc_els_abort(phba, ndlp, 1); - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + return NLP_STE_FREED_NODE; } @@ -1337,7 +1313,7 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba, ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); return ndlp->nlp_state; } @@ -1375,7 +1351,7 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); + lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state; } @@ -1399,7 +1375,7 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); return ndlp->nlp_state; } @@ -1410,7 +1386,7 @@ lpfc_device_recov_unmap_node(struct lpfc_hba * phba, ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; lpfc_disc_set_adisc(phba, ndlp); return ndlp->nlp_state; @@ -1448,7 +1424,7 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); + lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state; } @@ -1480,7 +1456,7 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba, spin_unlock_irq(phba->host->host_lock); /* Treat like rcv logo */ - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); + lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state; } @@ -1493,7 +1469,7 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba, ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); lpfc_disc_set_adisc(phba, ndlp); return ndlp->nlp_state; @@ -1575,7 +1551,7 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); + lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state; } @@ -1641,16 +1617,9 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; - - irsp = &rspiocb->iocb; - if (irsp->ulpStatus) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } return ndlp->nlp_state; } @@ -1659,16 +1628,9 @@ lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; - - irsp = &rspiocb->iocb; - if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } return ndlp->nlp_state; } @@ -1687,16 +1649,9 @@ lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, uint32_t evt) { struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; - - irsp = &rspiocb->iocb; - if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } return ndlp->nlp_state; } @@ -1713,12 +1668,7 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, if (!mb->mbxStatus) ndlp->nlp_rpi = mb->un.varWords[0]; - else { - if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } - } + return ndlp->nlp_state; } @@ -1727,10 +1677,6 @@ lpfc_device_rm_npr_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } @@ -1741,7 +1687,7 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, uint32_t evt) { spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); if (ndlp->nlp_flag & NLP_DELAY_TMO) { lpfc_cancel_retry_delay_tmo(phba, ndlp); diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index 7dc4c2e6bed2..f93799873721 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -629,7 +629,8 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq; IOCB_t *piocb; struct fcp_cmnd *fcp_cmnd; - struct lpfc_rport_data *rdata = lpfc_cmd->rdata; + struct scsi_device *scsi_dev = lpfc_cmd->pCmd->device; + struct lpfc_rport_data *rdata = scsi_dev->hostdata; struct lpfc_nodelist *ndlp = rdata->pnode; if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { @@ -664,18 +665,56 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, piocb->ulpTimeout = lpfc_cmd->timeout; } + lpfc_cmd->rdata = rdata; + + switch (task_mgmt_cmd) { + case FCP_LUN_RESET: + /* Issue LUN Reset to TGT LUN */ + lpfc_printf_log(phba, + KERN_INFO, + LOG_FCP, + "%d:0703 Issue LUN Reset to TGT %d LUN %d " + "Data: x%x x%x\n", + phba->brd_no, + scsi_dev->id, scsi_dev->lun, + ndlp->nlp_rpi, ndlp->nlp_flag); + + break; + case FCP_ABORT_TASK_SET: + /* Issue Abort Task Set to TGT LUN */ + lpfc_printf_log(phba, + KERN_INFO, + LOG_FCP, + "%d:0701 Issue Abort Task Set to TGT %d LUN %d " + "Data: x%x x%x\n", + phba->brd_no, + scsi_dev->id, scsi_dev->lun, + ndlp->nlp_rpi, ndlp->nlp_flag); + + break; + case FCP_TARGET_RESET: + /* Issue Target Reset to TGT */ + lpfc_printf_log(phba, + KERN_INFO, + LOG_FCP, + "%d:0702 Issue Target Reset to TGT %d " + "Data: x%x x%x\n", + phba->brd_no, + scsi_dev->id, ndlp->nlp_rpi, + ndlp->nlp_flag); + break; + } + return (1); } static int -lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, - unsigned tgt_id, struct lpfc_rport_data *rdata) +lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) { struct lpfc_iocbq *iocbq; struct lpfc_iocbq *iocbqrsp; int ret; - lpfc_cmd->rdata = rdata; ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); if (!ret) return FAILED; @@ -687,13 +726,6 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, if (!iocbqrsp) return FAILED; - /* Issue Target Reset to TGT */ - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d:0702 Issue Target Reset to TGT %d " - "Data: x%x x%x\n", - phba->brd_no, tgt_id, rdata->pnode->nlp_rpi, - rdata->pnode->nlp_flag); - ret = lpfc_sli_issue_iocb_wait(phba, &phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout); @@ -989,7 +1021,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) lpfc_cmd->pCmd = cmnd; lpfc_cmd->timeout = 60; lpfc_cmd->scsi_hba = phba; - lpfc_cmd->rdata = rdata; ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET); if (!ret) @@ -1002,11 +1033,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) if (iocbqrsp == NULL) goto out_free_scsi_buf; - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d:0703 Issue LUN Reset to TGT %d LUN %d " - "Data: x%x x%x\n", phba->brd_no, cmnd->device->id, - cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); - ret = lpfc_sli_issue_iocb_wait(phba, &phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout); @@ -1078,6 +1104,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) int match; int ret = FAILED, i, err_count = 0; int cnt, loopcnt; + unsigned int midlayer_id = 0; struct lpfc_scsi_buf * lpfc_cmd; lpfc_block_requests(phba); @@ -1097,6 +1124,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) * targets known to the driver. Should any target reset * fail, this routine returns failure to the midlayer. */ + midlayer_id = cmnd->device->id; for (i = 0; i < MAX_FCP_TARGET; i++) { /* Search the mapped list for this target ID */ match = 0; @@ -1109,8 +1137,9 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) if (!match) continue; - ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, - i, ndlp->rport->dd_data); + lpfc_cmd->pCmd->device->id = i; + lpfc_cmd->pCmd->device->hostdata = ndlp->rport->dd_data; + ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba); if (ret != SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "%d:0713 Bus Reset on target %d failed\n", @@ -1129,6 +1158,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) * the targets. Unfortunately, some targets do not abide by * this forcing the driver to double check. */ + cmnd->device->id = midlayer_id; cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], 0, 0, LPFC_CTX_HOST); if (cnt) diff --git a/trunk/drivers/scsi/lpfc/lpfc_version.h b/trunk/drivers/scsi/lpfc/lpfc_version.h index 6b737568b831..4cf1366108b7 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_version.h +++ b/trunk/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.1.6" +#define LPFC_DRIVER_VERSION "8.1.4" #define LPFC_DRIVER_NAME "lpfc" diff --git a/trunk/drivers/scsi/megaraid.c b/trunk/drivers/scsi/megaraid.c index de35ffe2f79d..80b68a2481b3 100644 --- a/trunk/drivers/scsi/megaraid.c +++ b/trunk/drivers/scsi/megaraid.c @@ -4471,6 +4471,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) { Scsi_Cmnd *scmd; struct scsi_device *sdev; + unsigned long flags = 0; scb_t *scb; int rval; diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.c b/trunk/drivers/scsi/megaraid/megaraid_mbox.c index bec1424eda85..c11e5ce6865e 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_mbox.c - * Version : v2.20.4.8 (Apr 11 2006) + * Version : v2.20.4.7 (Nov 14 2005) * * Authors: * Atul Mukker @@ -2278,7 +2278,6 @@ megaraid_mbox_dpc(unsigned long devp) unsigned long flags; uint8_t c; int status; - uioc_t *kioc; if (!adapter) return; @@ -2321,9 +2320,6 @@ megaraid_mbox_dpc(unsigned long devp) // remove from local clist list_del_init(&scb->list); - kioc = (uioc_t *)scb->gp; - kioc->status = 0; - megaraid_mbox_mm_done(adapter, scb); continue; @@ -2640,7 +2636,6 @@ megaraid_reset_handler(struct scsi_cmnd *scp) int recovery_window; int recovering; int i; - uioc_t *kioc; adapter = SCP2ADAPTER(scp); raid_dev = ADAP2RAIDDEV(adapter); @@ -2660,51 +2655,32 @@ megaraid_reset_handler(struct scsi_cmnd *scp) // Also, reset all the commands currently owned by the driver spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags); list_for_each_entry_safe(scb, tmp, &adapter->pend_list, list) { - list_del_init(&scb->list); // from pending list - - if (scb->sno >= MBOX_MAX_SCSI_CMDS) { - con_log(CL_ANN, (KERN_WARNING - "megaraid: IOCTL packet with %d[%d:%d] being reset\n", - scb->sno, scb->dev_channel, scb->dev_target)); - - scb->status = -1; - kioc = (uioc_t *)scb->gp; - kioc->status = -EFAULT; + list_del_init(&scb->list); // from pending list - megaraid_mbox_mm_done(adapter, scb); - } else { - if (scb->scp == scp) { // Found command - con_log(CL_ANN, (KERN_WARNING - "megaraid: %ld:%d[%d:%d], reset from pending list\n", - scp->serial_number, scb->sno, - scb->dev_channel, scb->dev_target)); - } else { - con_log(CL_ANN, (KERN_WARNING - "megaraid: IO packet with %d[%d:%d] being reset\n", - scb->sno, scb->dev_channel, scb->dev_target)); - } + con_log(CL_ANN, (KERN_WARNING + "megaraid: %ld:%d[%d:%d], reset from pending list\n", + scp->serial_number, scb->sno, + scb->dev_channel, scb->dev_target)); - scb->scp->result = (DID_RESET << 16); - scb->scp->scsi_done(scb->scp); + scp->result = (DID_RESET << 16); + scp->scsi_done(scp); - megaraid_dealloc_scb(adapter, scb); - } + megaraid_dealloc_scb(adapter, scb); } spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); if (adapter->outstanding_cmds) { con_log(CL_ANN, (KERN_NOTICE "megaraid: %d outstanding commands. Max wait %d sec\n", - adapter->outstanding_cmds, - (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT))); + adapter->outstanding_cmds, MBOX_RESET_WAIT)); } recovery_window = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT; recovering = adapter->outstanding_cmds; - for (i = 0; i < recovery_window; i++) { + for (i = 0; i < recovery_window && adapter->outstanding_cmds; i++) { megaraid_ack_sequence(adapter); @@ -2713,11 +2689,12 @@ megaraid_reset_handler(struct scsi_cmnd *scp) con_log(CL_ANN, ( "megaraid mbox: Wait for %d commands to complete:%d\n", adapter->outstanding_cmds, - (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT) - i)); + MBOX_RESET_WAIT - i)); } // bailout if no recovery happended in reset time - if (adapter->outstanding_cmds == 0) { + if ((i == MBOX_RESET_WAIT) && + (recovering == adapter->outstanding_cmds)) { break; } @@ -2941,13 +2918,12 @@ mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[]) wmb(); WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1); - for (i = 0; i < MBOX_SYNC_WAIT_CNT; i++) { + for (i = 0; i < 0xFFFFF; i++) { if (mbox->numstatus != 0xFF) break; rmb(); - udelay(MBOX_SYNC_DELAY_200); } - if (i == MBOX_SYNC_WAIT_CNT) { + if (i == 0xFFFFF) { // We may need to re-calibrate the counter con_log(CL_ANN, (KERN_CRIT "megaraid: fast sync command timed out\n")); @@ -3499,7 +3475,7 @@ megaraid_cmm_register(adapter_t *adapter) adp.drvr_data = (unsigned long)adapter; adp.pdev = adapter->pdev; adp.issue_uioc = megaraid_mbox_mm_handler; - adp.timeout = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT; + adp.timeout = 300; adp.max_kioc = MBOX_MAX_USER_CMDS; if ((rval = mraid_mm_register_adp(&adp)) != 0) { @@ -3726,6 +3702,7 @@ megaraid_mbox_mm_done(adapter_t *adapter, scb_t *scb) unsigned long flags; kioc = (uioc_t *)scb->gp; + kioc->status = 0; mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf; mbox64->mbox32.status = scb->status; raw_mbox = (uint8_t *)&mbox64->mbox32; diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.h b/trunk/drivers/scsi/megaraid/megaraid_mbox.h index 868fb0ec93e7..882fb1a0b575 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.h +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.h @@ -21,8 +21,8 @@ #include "megaraid_ioctl.h" -#define MEGARAID_VERSION "2.20.4.8" -#define MEGARAID_EXT_VERSION "(Release Date: Mon Apr 11 12:27:22 EST 2006)" +#define MEGARAID_VERSION "2.20.4.7" +#define MEGARAID_EXT_VERSION "(Release Date: Mon Nov 14 12:27:22 EST 2005)" /* @@ -100,9 +100,6 @@ #define MBOX_BUSY_WAIT 10 // max usec to wait for busy mailbox #define MBOX_RESET_WAIT 180 // wait these many seconds in reset #define MBOX_RESET_EXT_WAIT 120 // extended wait reset -#define MBOX_SYNC_WAIT_CNT 0xFFFF // wait loop index for synchronous mode - -#define MBOX_SYNC_DELAY_200 200 // 200 micro-seconds /* * maximum transfer that can happen through the firmware commands issued diff --git a/trunk/drivers/scsi/megaraid/megaraid_mm.c b/trunk/drivers/scsi/megaraid/megaraid_mm.c index e8f534fb336b..8f3ce0432295 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mm.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mm.c @@ -898,8 +898,10 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) adapter = kmalloc(sizeof(mraid_mmadp_t), GFP_KERNEL); - if (!adapter) - return -ENOMEM; + if (!adapter) { + rval = -ENOMEM; + goto memalloc_error; + } memset(adapter, 0, sizeof(mraid_mmadp_t)); diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 584fe5d8e507..017729c59a49 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -599,7 +599,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) * Either SUCCESS or FAILED. * * Note: -* Only return FAILED if command not returned by firmware. **************************************************************************/ int qla2xxx_eh_abort(struct scsi_cmnd *cmd) @@ -610,12 +609,11 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) unsigned int id, lun; unsigned long serial; unsigned long flags; - int wait = 0; if (!CMD_SP(cmd)) - return SUCCESS; + return FAILED; - ret = SUCCESS; + ret = FAILED; id = cmd->device->id; lun = cmd->device->lun; @@ -644,7 +642,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) } else { DEBUG3(printk("%s(%ld): abort_command " "mbx success.\n", __func__, ha->host_no)); - wait = 1; + ret = SUCCESS; } spin_lock_irqsave(&ha->hardware_lock, flags); @@ -653,18 +651,17 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Wait for the command to be returned. */ - if (wait) { + if (ret == SUCCESS) { if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) { qla_printk(KERN_ERR, ha, "scsi(%ld:%d:%d): Abort handler timed out -- %lx " "%x.\n", ha->host_no, id, lun, serial, ret); - ret = FAILED; } } qla_printk(KERN_INFO, ha, - "scsi(%ld:%d:%d): Abort command issued -- %d %lx %x.\n", - ha->host_no, id, lun, wait, serial, ret); + "scsi(%ld:%d:%d): Abort command issued -- %lx %x.\n", ha->host_no, + id, lun, serial, ret); return ret; } @@ -1703,8 +1700,8 @@ qla2x00_free_device(scsi_qla_host_t *ha) ha->flags.online = 0; /* Detach interrupts */ - if (ha->host->irq) - free_irq(ha->host->irq, ha); + if (ha->pdev->irq) + free_irq(ha->pdev->irq, ha); /* release io space registers */ if (ha->iobase) diff --git a/trunk/drivers/scsi/sata_mv.c b/trunk/drivers/scsi/sata_mv.c index 9b8bca1ac1f0..d5fdcb9a8842 100644 --- a/trunk/drivers/scsi/sata_mv.c +++ b/trunk/drivers/scsi/sata_mv.c @@ -37,7 +37,7 @@ #include #define DRV_NAME "sata_mv" -#define DRV_VERSION "0.7" +#define DRV_VERSION "0.6" enum { /* BAR's are enumerated in terms of pci_resource_start() terms */ @@ -50,12 +50,6 @@ enum { MV_PCI_REG_BASE = 0, MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */ - MV_IRQ_COAL_CAUSE = (MV_IRQ_COAL_REG_BASE + 0x08), - MV_IRQ_COAL_CAUSE_LO = (MV_IRQ_COAL_REG_BASE + 0x88), - MV_IRQ_COAL_CAUSE_HI = (MV_IRQ_COAL_REG_BASE + 0x8c), - MV_IRQ_COAL_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xcc), - MV_IRQ_COAL_TIME_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xd0), - MV_SATAHC0_REG_BASE = 0x20000, MV_FLASH_CTL = 0x1046c, MV_GPIO_PORT_CTL = 0x104f0, @@ -308,6 +302,9 @@ struct mv_port_priv { dma_addr_t crpb_dma; struct mv_sg *sg_tbl; dma_addr_t sg_tbl_dma; + + unsigned req_producer; /* cp of req_in_ptr */ + unsigned rsp_consumer; /* cp of rsp_out_ptr */ u32 pp_flags; }; @@ -940,6 +937,8 @@ static int mv_port_start(struct ata_port *ap) writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); + pp->req_producer = pp->rsp_consumer = 0; + /* Don't turn on EDMA here...do it before DMA commands only. Else * we'll be unable to send non-data, PIO, etc due to restricted access * to shadow regs. @@ -1023,16 +1022,16 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) } } -static inline unsigned mv_inc_q_index(unsigned index) +static inline unsigned mv_inc_q_index(unsigned *index) { - return (index + 1) & MV_MAX_Q_DEPTH_MASK; + *index = (*index + 1) & MV_MAX_Q_DEPTH_MASK; + return *index; } static inline void mv_crqb_pack_cmd(u16 *cmdw, u8 data, u8 addr, unsigned last) { - u16 tmp = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS | + *cmdw = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS | (last ? CRQB_CMD_LAST : 0); - *cmdw = cpu_to_le16(tmp); } /** @@ -1054,11 +1053,15 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) u16 *cw; struct ata_taskfile *tf; u16 flags = 0; - unsigned in_index; if (ATA_PROT_DMA != qc->tf.protocol) return; + /* the req producer index should be the same as we remember it */ + WARN_ON(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> + EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != + pp->req_producer); + /* Fill in command request block */ if (!(qc->tf.flags & ATA_TFLAG_WRITE)) @@ -1066,17 +1069,13 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); flags |= qc->tag << CRQB_TAG_SHIFT; - /* get current queue index from hardware */ - in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) - >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; - - pp->crqb[in_index].sg_addr = + pp->crqb[pp->req_producer].sg_addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff); - pp->crqb[in_index].sg_addr_hi = + pp->crqb[pp->req_producer].sg_addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16); - pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags); + pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags); - cw = &pp->crqb[in_index].ata_cmd[0]; + cw = &pp->crqb[pp->req_producer].ata_cmd[0]; tf = &qc->tf; /* Sadly, the CRQB cannot accomodate all registers--there are @@ -1145,12 +1144,16 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) struct mv_port_priv *pp = ap->private_data; struct mv_crqb_iie *crqb; struct ata_taskfile *tf; - unsigned in_index; u32 flags = 0; if (ATA_PROT_DMA != qc->tf.protocol) return; + /* the req producer index should be the same as we remember it */ + WARN_ON(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> + EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != + pp->req_producer); + /* Fill in Gen IIE command request block */ if (!(qc->tf.flags & ATA_TFLAG_WRITE)) @@ -1159,11 +1162,7 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); flags |= qc->tag << CRQB_TAG_SHIFT; - /* get current queue index from hardware */ - in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) - >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; - - crqb = (struct mv_crqb_iie *) &pp->crqb[in_index]; + crqb = (struct mv_crqb_iie *) &pp->crqb[pp->req_producer]; crqb->addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff); crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16); crqb->flags = cpu_to_le32(flags); @@ -1211,7 +1210,6 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) { void __iomem *port_mmio = mv_ap_base(qc->ap); struct mv_port_priv *pp = qc->ap->private_data; - unsigned in_index; u32 in_ptr; if (ATA_PROT_DMA != qc->tf.protocol) { @@ -1223,20 +1221,23 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) return ata_qc_issue_prot(qc); } - in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS); - in_index = (in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; + in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS); + /* the req producer index should be the same as we remember it */ + WARN_ON(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != + pp->req_producer); /* until we do queuing, the queue should be empty at this point */ - WARN_ON(in_index != ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) - >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); + WARN_ON(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != + ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >> + EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); - in_index = mv_inc_q_index(in_index); /* now incr producer index */ + mv_inc_q_index(&pp->req_producer); /* now incr producer index */ mv_start_dma(port_mmio, pp); /* and write the request in pointer to kick the EDMA to life */ in_ptr &= EDMA_REQ_Q_BASE_LO_MASK; - in_ptr |= in_index << EDMA_REQ_Q_PTR_SHIFT; + in_ptr |= pp->req_producer << EDMA_REQ_Q_PTR_SHIFT; writelfl(in_ptr, port_mmio + EDMA_REQ_Q_IN_PTR_OFS); return 0; @@ -1259,26 +1260,28 @@ static u8 mv_get_crpb_status(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); struct mv_port_priv *pp = ap->private_data; - unsigned out_index; u32 out_ptr; u8 ata_status; - out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); - out_index = (out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; + out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); - ata_status = le16_to_cpu(pp->crpb[out_index].flags) - >> CRPB_FLAG_STATUS_SHIFT; + /* the response consumer index should be the same as we remember it */ + WARN_ON(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != + pp->rsp_consumer); + + ata_status = pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT; /* increment our consumer index... */ - out_index = mv_inc_q_index(out_index); + pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); /* and, until we do NCQ, there should only be 1 CRPB waiting */ - WARN_ON(out_index != ((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) - >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); + WARN_ON(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >> + EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != + pp->rsp_consumer); /* write out our inc'd consumer index so EDMA knows we're caught up */ out_ptr &= EDMA_RSP_Q_BASE_LO_MASK; - out_ptr |= out_index << EDMA_RSP_Q_PTR_SHIFT; + out_ptr |= pp->rsp_consumer << EDMA_RSP_Q_PTR_SHIFT; writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); /* Return ATA status register for completed CRPB */ @@ -1288,7 +1291,6 @@ static u8 mv_get_crpb_status(struct ata_port *ap) /** * mv_err_intr - Handle error interrupts on the port * @ap: ATA channel to manipulate - * @reset_allowed: bool: 0 == don't trigger from reset here * * In most cases, just clear the interrupt and move on. However, * some cases require an eDMA reset, which is done right before @@ -1299,7 +1301,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap) * LOCKING: * Inherited from caller. */ -static void mv_err_intr(struct ata_port *ap, int reset_allowed) +static void mv_err_intr(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); u32 edma_err_cause, serr = 0; @@ -1321,8 +1323,9 @@ static void mv_err_intr(struct ata_port *ap, int reset_allowed) writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); /* check for fatal here and recover if needed */ - if (reset_allowed && (EDMA_ERR_FATAL & edma_err_cause)) + if (EDMA_ERR_FATAL & edma_err_cause) { mv_stop_and_reset(ap); + } } /** @@ -1371,12 +1374,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, struct ata_port *ap = host_set->ports[port]; struct mv_port_priv *pp = ap->private_data; - hard_port = mv_hardport_from_port(port); /* range 0..3 */ + hard_port = port & MV_PORT_MASK; /* range 0-3 */ handled = 0; /* ensure ata_status is set if handled++ */ /* Note that DEV_IRQ might happen spuriously during EDMA, - * and should be ignored in such cases. - * The cause of this is still under investigation. + * and should be ignored in such cases. We could mask it, + * but it's pretty rare and may not be worth the overhead. */ if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { /* EDMA: check for response queue interrupt */ @@ -1390,11 +1393,6 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, ata_status = readb((void __iomem *) ap->ioaddr.status_addr); handled = 1; - /* ignore spurious intr if drive still BUSY */ - if (ata_status & ATA_BUSY) { - ata_status = 0; - handled = 0; - } } } @@ -1408,7 +1406,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, shift++; /* skip bit 8 in the HC Main IRQ reg */ } if ((PORT0_ERR << shift) & relevant) { - mv_err_intr(ap, 1); + mv_err_intr(ap); err_mask |= AC_ERR_OTHER; handled = 1; } @@ -1450,7 +1448,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, struct ata_host_set *host_set = dev_instance; unsigned int hc, handled = 0, n_hcs; void __iomem *mmio = host_set->mmio_base; - struct mv_host_priv *hpriv; u32 irq_stat; irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS); @@ -1472,17 +1469,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, handled++; } } - - hpriv = host_set->private_data; - if (IS_60XX(hpriv)) { - /* deal with the interrupt coalescing bits */ - if (irq_stat & (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE)) { - writelfl(0, mmio + MV_IRQ_COAL_CAUSE_LO); - writelfl(0, mmio + MV_IRQ_COAL_CAUSE_HI); - writelfl(0, mmio + MV_IRQ_COAL_CAUSE); - } - } - if (PCI_ERR & irq_stat) { printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n", readl(mmio + PCI_IRQ_CAUSE_OFS)); @@ -1881,8 +1867,7 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, if (IS_60XX(hpriv)) { u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); - ifctl |= (1 << 7); /* enable gen2i speed */ - ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */ + ifctl |= (1 << 12) | (1 << 7); writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); } @@ -2046,14 +2031,11 @@ static void mv_eng_timeout(struct ata_port *ap) ap->host_set->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd); - mv_err_intr(ap, 0); + mv_err_intr(ap); mv_stop_and_reset(ap); - WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); - if (qc->flags & ATA_QCFLAG_ACTIVE) { - qc->err_mask |= AC_ERR_TIMEOUT; - ata_eh_qc_complete(qc); - } + qc->err_mask |= AC_ERR_TIMEOUT; + ata_eh_qc_complete(qc); } /** @@ -2247,8 +2229,7 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, void __iomem *port_mmio = mv_port_base(mmio, port); u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); - ifctl |= (1 << 7); /* enable gen2i speed */ - ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */ + ifctl |= (1 << 12); writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); } @@ -2349,7 +2330,6 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) { return rc; } - pci_set_master(pdev); rc = pci_request_regions(pdev, DRV_NAME); if (rc) { diff --git a/trunk/drivers/scsi/scsi_devinfo.c b/trunk/drivers/scsi/scsi_devinfo.c index 941c1e15c899..c750d3399a97 100644 --- a/trunk/drivers/scsi/scsi_devinfo.c +++ b/trunk/drivers/scsi/scsi_devinfo.c @@ -56,8 +56,6 @@ static struct { {"DENON", "DRD-25X", "V", BLIST_NOLUN}, /* locks up */ {"HITACHI", "DK312C", "CM81", BLIST_NOLUN}, /* responds to all lun */ {"HITACHI", "DK314C", "CR21", BLIST_NOLUN}, /* responds to all lun */ - {"IBM", "2104-DU3", NULL, BLIST_NOLUN}, /* locks up */ - {"IBM", "2104-TU3", NULL, BLIST_NOLUN}, /* locks up */ {"IMS", "CDD521/10", "2.06", BLIST_NOLUN}, /* locks up */ {"MAXTOR", "XT-3280", "PR02", BLIST_NOLUN}, /* locks up */ {"MAXTOR", "XT-4380S", "B3C", BLIST_NOLUN}, /* locks up */ diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 764a8b375ead..7b0f9a3810d2 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -1067,29 +1067,16 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, break; case NOT_READY: /* - * If the device is in the process of becoming - * ready, or has a temporary blockage, retry. + * If the device is in the process of becoming ready, + * retry. */ - if (sshdr.asc == 0x04) { - switch (sshdr.ascq) { - case 0x01: /* becoming ready */ - case 0x04: /* format in progress */ - case 0x05: /* rebuild in progress */ - case 0x06: /* recalculation in progress */ - case 0x07: /* operation in progress */ - case 0x08: /* Long write in progress */ - case 0x09: /* self test in progress */ - scsi_requeue_command(q, cmd); - return; - default: - break; - } + if (sshdr.asc == 0x04 && sshdr.ascq == 0x01) { + scsi_requeue_command(q, cmd); + return; } - if (!(req->flags & REQ_QUIET)) { + if (!(req->flags & REQ_QUIET)) scmd_printk(KERN_INFO, cmd, - "Device not ready: "); - scsi_print_sense_hdr("", &sshdr); - } + "Device not ready.\n"); scsi_end_request(cmd, 0, this_count, 1); return; case VOLUME_OVERFLOW: diff --git a/trunk/drivers/scsi/sim710.c b/trunk/drivers/scsi/sim710.c index 255886a9ac55..3274ab76c8d3 100644 --- a/trunk/drivers/scsi/sim710.c +++ b/trunk/drivers/scsi/sim710.c @@ -75,7 +75,7 @@ param_setup(char *str) else if(!strncmp(pos, "id:", 3)) { if(slot == -1) { printk(KERN_WARNING "sim710: Must specify slot for id parameter\n"); - } else if(slot >= MAX_SLOTS) { + } else if(slot > MAX_SLOTS) { printk(KERN_WARNING "sim710: Illegal slot %d for id %d\n", slot, val); } else { id_array[slot] = val; diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index 56cb49006116..d40e7c871c36 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -4054,7 +4054,7 @@ static int st_probe(struct device *dev) } sdev_printk(KERN_WARNING, SDp, - "Attached scsi tape %s\n", tape_name(tpnt)); + "Attached scsi tape %s", tape_name(tpnt)); printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n", tape_name(tpnt), tpnt->try_dio ? "yes" : "no", queue_dma_alignment(SDp->request_queue) + 1); diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index bbf78aaf9e01..674b15c78f68 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -362,40 +362,6 @@ serial_out(struct uart_8250_port *up, int offset, int value) #define serial_inp(up, offset) serial_in(up, offset) #define serial_outp(up, offset, value) serial_out(up, offset, value) -/* Uart divisor latch read */ -static inline int _serial_dl_read(struct uart_8250_port *up) -{ - return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8; -} - -/* Uart divisor latch write */ -static inline void _serial_dl_write(struct uart_8250_port *up, int value) -{ - serial_outp(up, UART_DLL, value & 0xff); - serial_outp(up, UART_DLM, value >> 8 & 0xff); -} - -#ifdef CONFIG_SERIAL_8250_AU1X00 -/* Au1x00 haven't got a standard divisor latch */ -static int serial_dl_read(struct uart_8250_port *up) -{ - if (up->port.iotype == UPIO_AU) - return __raw_readl(up->port.membase + 0x28); - else - return _serial_dl_read(up); -} - -static void serial_dl_write(struct uart_8250_port *up, int value) -{ - if (up->port.iotype == UPIO_AU) - __raw_writel(value, up->port.membase + 0x28); - else - _serial_dl_write(up, value); -} -#else -#define serial_dl_read(up) _serial_dl_read(up) -#define serial_dl_write(up, value) _serial_dl_write(up, value) -#endif /* * For the 16C950 @@ -528,8 +494,7 @@ static void disable_rsa(struct uart_8250_port *up) */ static int size_fifo(struct uart_8250_port *up) { - unsigned char old_fcr, old_mcr, old_lcr; - unsigned short old_dl; + unsigned char old_fcr, old_mcr, old_dll, old_dlm, old_lcr; int count; old_lcr = serial_inp(up, UART_LCR); @@ -540,8 +505,10 @@ static int size_fifo(struct uart_8250_port *up) UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); serial_outp(up, UART_MCR, UART_MCR_LOOP); serial_outp(up, UART_LCR, UART_LCR_DLAB); - old_dl = serial_dl_read(up); - serial_dl_write(up, 0x0001); + old_dll = serial_inp(up, UART_DLL); + old_dlm = serial_inp(up, UART_DLM); + serial_outp(up, UART_DLL, 0x01); + serial_outp(up, UART_DLM, 0x00); serial_outp(up, UART_LCR, 0x03); for (count = 0; count < 256; count++) serial_outp(up, UART_TX, count); @@ -552,7 +519,8 @@ static int size_fifo(struct uart_8250_port *up) serial_outp(up, UART_FCR, old_fcr); serial_outp(up, UART_MCR, old_mcr); serial_outp(up, UART_LCR, UART_LCR_DLAB); - serial_dl_write(up, old_dl); + serial_outp(up, UART_DLL, old_dll); + serial_outp(up, UART_DLM, old_dlm); serial_outp(up, UART_LCR, old_lcr); return count; @@ -782,7 +750,8 @@ static void autoconfig_16550a(struct uart_8250_port *up) serial_outp(up, UART_LCR, 0xE0); - quot = serial_dl_read(up); + quot = serial_inp(up, UART_DLM) << 8; + quot += serial_inp(up, UART_DLL); quot <<= 3; status1 = serial_in(up, 0x04); /* EXCR1 */ @@ -790,7 +759,8 @@ static void autoconfig_16550a(struct uart_8250_port *up) status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ serial_outp(up, 0x04, status1); - serial_dl_write(up, quot); + serial_outp(up, UART_DLL, quot & 0xff); + serial_outp(up, UART_DLM, quot >> 8); serial_outp(up, UART_LCR, 0); @@ -1892,7 +1862,8 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ } - serial_dl_write(up, quot); + serial_outp(up, UART_DLL, quot & 0xff); /* LS of divisor */ + serial_outp(up, UART_DLM, quot >> 8); /* MS of divisor */ /* * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR @@ -1935,9 +1906,6 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) int ret = 0; switch (up->port.iotype) { - case UPIO_AU: - size = 0x100000; - /* fall thru */ case UPIO_MEM: if (!up->port.mapbase) break; @@ -1970,9 +1938,6 @@ static void serial8250_release_std_resource(struct uart_8250_port *up) unsigned int size = 8 << up->port.regshift; switch (up->port.iotype) { - case UPIO_AU: - size = 0x100000; - /* fall thru */ case UPIO_MEM: if (!up->port.mapbase) break; @@ -2235,17 +2200,10 @@ static void serial8250_console_write(struct console *co, const char *s, unsigned int count) { struct uart_8250_port *up = &serial8250_ports[co->index]; - unsigned long flags; unsigned int ier; - int locked = 1; touch_nmi_watchdog(); - if (oops_in_progress) { - locked = spin_trylock_irqsave(&up->port.lock, flags); - } else - spin_lock_irqsave(&up->port.lock, flags); - /* * First save the IER then disable the interrupts */ @@ -2263,10 +2221,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) * and restore the IER */ wait_for_xmitr(up, BOTH_EMPTY); - serial_out(up, UART_IER, ier); - - if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + up->ier |= UART_IER_THRI; + serial_out(up, UART_IER, ier | UART_IER_THRI); } static int serial8250_console_setup(struct console *co, char *options) diff --git a/trunk/drivers/serial/8250_au1x00.c b/trunk/drivers/serial/8250_au1x00.c index 58015fd14be9..3d1bfd07208d 100644 --- a/trunk/drivers/serial/8250_au1x00.c +++ b/trunk/drivers/serial/8250_au1x00.c @@ -30,12 +30,13 @@ { \ .iobase = _base, \ .membase = (void __iomem *)_base,\ - .mapbase = CPHYSADDR(_base), \ + .mapbase = _base, \ .irq = _irq, \ .uartclk = 0, /* filled */ \ .regshift = 2, \ .iotype = UPIO_AU, \ - .flags = UPF_SKIP_TEST \ + .flags = UPF_SKIP_TEST | \ + UPF_IOREMAP, \ } static struct plat_serial8250_port au1x00_data[] = { diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index 17839e753e4c..fcd7744c4253 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -1500,18 +1500,20 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) static struct uart_state *uart_get(struct uart_driver *drv, int line) { struct uart_state *state; - int ret = 0; + mutex_lock(&port_mutex); state = drv->state + line; if (mutex_lock_interruptible(&state->mutex)) { - ret = -ERESTARTSYS; - goto err; + state = ERR_PTR(-ERESTARTSYS); + goto out; } state->count++; - if (!state->port || state->port->flags & UPF_DEAD) { - ret = -ENXIO; - goto err_unlock; + if (!state->port) { + state->count--; + mutex_unlock(&state->mutex); + state = ERR_PTR(-ENXIO); + goto out; } if (!state->info) { @@ -1529,17 +1531,15 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line) tasklet_init(&state->info->tlet, uart_tasklet_action, (unsigned long)state); } else { - ret = -ENOMEM; - goto err_unlock; + state->count--; + mutex_unlock(&state->mutex); + state = ERR_PTR(-ENOMEM); } } - return state; - err_unlock: - state->count--; - mutex_unlock(&state->mutex); - err: - return ERR_PTR(ret); + out: + mutex_unlock(&port_mutex); + return state; } /* @@ -1907,12 +1907,9 @@ uart_set_options(struct uart_port *port, struct console *co, static void uart_change_pm(struct uart_state *state, int pm_state) { struct uart_port *port = state->port; - - if (state->pm_state != pm_state) { - if (port->ops->pm) - port->ops->pm(port, pm_state, state->pm_state); - state->pm_state = pm_state; - } + if (port->ops->pm) + port->ops->pm(port, pm_state, state->pm_state); + state->pm_state = pm_state; } int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) @@ -2088,6 +2085,45 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, } } +/* + * This reverses the effects of uart_configure_port, hanging up the + * port before removal. + */ +static void +uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state) +{ + struct uart_port *port = state->port; + struct uart_info *info = state->info; + + if (info && info->tty) + tty_vhangup(info->tty); + + mutex_lock(&state->mutex); + + state->info = NULL; + + /* + * Free the port IO and memory resources, if any. + */ + if (port->type != PORT_UNKNOWN) + port->ops->release_port(port); + + /* + * Indicate that there isn't a port here anymore. + */ + port->type = PORT_UNKNOWN; + + /* + * Kill the tasklet, and free resources. + */ + if (info) { + tasklet_kill(&info->tlet); + kfree(info); + } + + mutex_unlock(&state->mutex); +} + static struct tty_operations uart_ops = { .open = uart_open, .close = uart_close, @@ -2234,7 +2270,6 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) state = drv->state + port->line; mutex_lock(&port_mutex); - mutex_lock(&state->mutex); if (state->port) { ret = -EINVAL; goto out; @@ -2269,13 +2304,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) port->cons && !(port->cons->flags & CON_ENABLED)) register_console(port->cons); - /* - * Ensure UPF_DEAD is not set. - */ - port->flags &= ~UPF_DEAD; - out: - mutex_unlock(&state->mutex); mutex_unlock(&port_mutex); return ret; @@ -2293,7 +2322,6 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) { struct uart_state *state = drv->state + port->line; - struct uart_info *info; BUG_ON(in_interrupt()); @@ -2303,49 +2331,12 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) mutex_lock(&port_mutex); - /* - * Mark the port "dead" - this prevents any opens from - * succeeding while we shut down the port. - */ - mutex_lock(&state->mutex); - port->flags |= UPF_DEAD; - mutex_unlock(&state->mutex); - /* * Remove the devices from devfs */ tty_unregister_device(drv->tty_driver, port->line); - info = state->info; - if (info && info->tty) - tty_vhangup(info->tty); - - /* - * All users of this port should now be disconnected from - * this driver, and the port shut down. We should be the - * only thread fiddling with this port from now on. - */ - state->info = NULL; - - /* - * Free the port IO and memory resources, if any. - */ - if (port->type != PORT_UNKNOWN) - port->ops->release_port(port); - - /* - * Indicate that there isn't a port here anymore. - */ - port->type = PORT_UNKNOWN; - - /* - * Kill the tasklet, and free resources. - */ - if (info) { - tasklet_kill(&info->tlet); - kfree(info); - } - + uart_unconfigure_port(drv, state); state->port = NULL; mutex_unlock(&port_mutex); diff --git a/trunk/drivers/serial/sunsu.c b/trunk/drivers/serial/sunsu.c index 2b4f96541b8e..1c4396c2962d 100644 --- a/trunk/drivers/serial/sunsu.c +++ b/trunk/drivers/serial/sunsu.c @@ -1730,4 +1730,3 @@ static void __exit sunsu_exit(void) module_init(sunsu_probe); module_exit(sunsu_exit); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index 23334c8bc4c7..7a75faeb0526 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -75,45 +75,11 @@ config SPI_BUTTERFLY inexpensive battery powered microcontroller evaluation board. This same cable can be used to flash new firmware. -config SPI_MPC83xx - tristate "Freescale MPC83xx SPI controller" - depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL - select SPI_BITBANG - help - This enables using the Freescale MPC83xx SPI controller in master - mode. - - Note, this driver uniquely supports the SPI controller on the MPC83xx - family of PowerPC processors. The MPC83xx uses a simple set of shift - registers for data (opposed to the CPM based descriptor model). - -config SPI_PXA2XX - tristate "PXA2xx SSP SPI master" - depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL - help - This enables using a PXA2xx SSP port as a SPI master controller. - The driver can be configured to use any SSP port and additional - documentation can be found a Documentation/spi/pxa2xx. - -config SPI_S3C24XX_GPIO - tristate "Samsung S3C24XX series SPI by GPIO" - depends on SPI_MASTER && ARCH_S3C2410 && SPI_BITBANG && EXPERIMENTAL - help - SPI driver for Samsung S3C24XX series ARM SoCs using - GPIO lines to provide the SPI bus. This can be used where - the inbuilt hardware cannot provide the transfer mode, or - where the board is using non hardware connected pins. # # Add new SPI master controllers in alphabetical order above this line # -config SPI_S3C24XX - tristate "Samsung S3C24XX series SPI" - depends on SPI_MASTER && ARCH_S3C2410 && EXPERIMENTAL - help - SPI driver for Samsung S3C24XX series ARM SoCs - # # There are lots of SPI device types, with sensors and memory # being probably the most widely used ones. diff --git a/trunk/drivers/spi/Makefile b/trunk/drivers/spi/Makefile index 8f4cb67997b3..c2c87e845abf 100644 --- a/trunk/drivers/spi/Makefile +++ b/trunk/drivers/spi/Makefile @@ -13,10 +13,6 @@ obj-$(CONFIG_SPI_MASTER) += spi.o # SPI master controller drivers (bus) obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o -obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o -obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o -obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o -obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o # ... add above this line ... # SPI protocol drivers (device/link on bus) diff --git a/trunk/drivers/spi/pxa2xx_spi.c b/trunk/drivers/spi/pxa2xx_spi.c deleted file mode 100644 index 29aec77f98be..000000000000 --- a/trunk/drivers/spi/pxa2xx_spi.c +++ /dev/null @@ -1,1486 +0,0 @@ -/* - * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -MODULE_AUTHOR("Stephen Street"); -MODULE_DESCRIPTION("PXA2xx SSP SPI Contoller"); -MODULE_LICENSE("GPL"); - -#define MAX_BUSES 3 - -#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) -#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) -#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) - -#define DEFINE_SSP_REG(reg, off) \ -static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \ -static inline void write_##reg(u32 v, void *p) { __raw_writel(v, p + (off)); } - -DEFINE_SSP_REG(SSCR0, 0x00) -DEFINE_SSP_REG(SSCR1, 0x04) -DEFINE_SSP_REG(SSSR, 0x08) -DEFINE_SSP_REG(SSITR, 0x0c) -DEFINE_SSP_REG(SSDR, 0x10) -DEFINE_SSP_REG(SSTO, 0x28) -DEFINE_SSP_REG(SSPSP, 0x2c) - -#define START_STATE ((void*)0) -#define RUNNING_STATE ((void*)1) -#define DONE_STATE ((void*)2) -#define ERROR_STATE ((void*)-1) - -#define QUEUE_RUNNING 0 -#define QUEUE_STOPPED 1 - -struct driver_data { - /* Driver model hookup */ - struct platform_device *pdev; - - /* SPI framework hookup */ - enum pxa_ssp_type ssp_type; - struct spi_master *master; - - /* PXA hookup */ - struct pxa2xx_spi_master *master_info; - - /* DMA setup stuff */ - int rx_channel; - int tx_channel; - u32 *null_dma_buf; - - /* SSP register addresses */ - void *ioaddr; - u32 ssdr_physical; - - /* SSP masks*/ - u32 dma_cr1; - u32 int_cr1; - u32 clear_sr; - u32 mask_sr; - - /* Driver message queue */ - struct workqueue_struct *workqueue; - struct work_struct pump_messages; - spinlock_t lock; - struct list_head queue; - int busy; - int run; - - /* Message Transfer pump */ - struct tasklet_struct pump_transfers; - - /* Current message transfer state info */ - struct spi_message* cur_msg; - struct spi_transfer* cur_transfer; - struct chip_data *cur_chip; - size_t len; - void *tx; - void *tx_end; - void *rx; - void *rx_end; - int dma_mapped; - dma_addr_t rx_dma; - dma_addr_t tx_dma; - size_t rx_map_len; - size_t tx_map_len; - u8 n_bytes; - u32 dma_width; - int cs_change; - void (*write)(struct driver_data *drv_data); - void (*read)(struct driver_data *drv_data); - irqreturn_t (*transfer_handler)(struct driver_data *drv_data); - void (*cs_control)(u32 command); -}; - -struct chip_data { - u32 cr0; - u32 cr1; - u32 to; - u32 psp; - u32 timeout; - u8 n_bytes; - u32 dma_width; - u32 dma_burst_size; - u32 threshold; - u32 dma_threshold; - u8 enable_dma; - u8 bits_per_word; - u32 speed_hz; - void (*write)(struct driver_data *drv_data); - void (*read)(struct driver_data *drv_data); - void (*cs_control)(u32 command); -}; - -static void pump_messages(void *data); - -static int flush(struct driver_data *drv_data) -{ - unsigned long limit = loops_per_jiffy << 1; - - void *reg = drv_data->ioaddr; - - do { - while (read_SSSR(reg) & SSSR_RNE) { - read_SSDR(reg); - } - } while ((read_SSSR(reg) & SSSR_BSY) && limit--); - write_SSSR(SSSR_ROR, reg); - - return limit; -} - -static void restore_state(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - /* Clear status and disable clock */ - write_SSSR(drv_data->clear_sr, reg); - write_SSCR0(drv_data->cur_chip->cr0 & ~SSCR0_SSE, reg); - - /* Load the registers */ - write_SSCR1(drv_data->cur_chip->cr1, reg); - write_SSCR0(drv_data->cur_chip->cr0, reg); - if (drv_data->ssp_type != PXA25x_SSP) { - write_SSTO(0, reg); - write_SSPSP(drv_data->cur_chip->psp, reg); - } -} - -static void null_cs_control(u32 command) -{ -} - -static void null_writer(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - u8 n_bytes = drv_data->n_bytes; - - while ((read_SSSR(reg) & SSSR_TNF) - && (drv_data->tx < drv_data->tx_end)) { - write_SSDR(0, reg); - drv_data->tx += n_bytes; - } -} - -static void null_reader(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - u8 n_bytes = drv_data->n_bytes; - - while ((read_SSSR(reg) & SSSR_RNE) - && (drv_data->rx < drv_data->rx_end)) { - read_SSDR(reg); - drv_data->rx += n_bytes; - } -} - -static void u8_writer(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_TNF) - && (drv_data->tx < drv_data->tx_end)) { - write_SSDR(*(u8 *)(drv_data->tx), reg); - ++drv_data->tx; - } -} - -static void u8_reader(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_RNE) - && (drv_data->rx < drv_data->rx_end)) { - *(u8 *)(drv_data->rx) = read_SSDR(reg); - ++drv_data->rx; - } -} - -static void u16_writer(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_TNF) - && (drv_data->tx < drv_data->tx_end)) { - write_SSDR(*(u16 *)(drv_data->tx), reg); - drv_data->tx += 2; - } -} - -static void u16_reader(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_RNE) - && (drv_data->rx < drv_data->rx_end)) { - *(u16 *)(drv_data->rx) = read_SSDR(reg); - drv_data->rx += 2; - } -} -static void u32_writer(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_TNF) - && (drv_data->tx < drv_data->tx_end)) { - write_SSDR(*(u32 *)(drv_data->tx), reg); - drv_data->tx += 4; - } -} - -static void u32_reader(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_RNE) - && (drv_data->rx < drv_data->rx_end)) { - *(u32 *)(drv_data->rx) = read_SSDR(reg); - drv_data->rx += 4; - } -} - -static void *next_transfer(struct driver_data *drv_data) -{ - struct spi_message *msg = drv_data->cur_msg; - struct spi_transfer *trans = drv_data->cur_transfer; - - /* Move to next transfer */ - if (trans->transfer_list.next != &msg->transfers) { - drv_data->cur_transfer = - list_entry(trans->transfer_list.next, - struct spi_transfer, - transfer_list); - return RUNNING_STATE; - } else - return DONE_STATE; -} - -static int map_dma_buffers(struct driver_data *drv_data) -{ - struct spi_message *msg = drv_data->cur_msg; - struct device *dev = &msg->spi->dev; - - if (!drv_data->cur_chip->enable_dma) - return 0; - - if (msg->is_dma_mapped) - return drv_data->rx_dma && drv_data->tx_dma; - - if (!IS_DMA_ALIGNED(drv_data->rx) || !IS_DMA_ALIGNED(drv_data->tx)) - return 0; - - /* Modify setup if rx buffer is null */ - if (drv_data->rx == NULL) { - *drv_data->null_dma_buf = 0; - drv_data->rx = drv_data->null_dma_buf; - drv_data->rx_map_len = 4; - } else - drv_data->rx_map_len = drv_data->len; - - - /* Modify setup if tx buffer is null */ - if (drv_data->tx == NULL) { - *drv_data->null_dma_buf = 0; - drv_data->tx = drv_data->null_dma_buf; - drv_data->tx_map_len = 4; - } else - drv_data->tx_map_len = drv_data->len; - - /* Stream map the rx buffer */ - drv_data->rx_dma = dma_map_single(dev, drv_data->rx, - drv_data->rx_map_len, - DMA_FROM_DEVICE); - if (dma_mapping_error(drv_data->rx_dma)) - return 0; - - /* Stream map the tx buffer */ - drv_data->tx_dma = dma_map_single(dev, drv_data->tx, - drv_data->tx_map_len, - DMA_TO_DEVICE); - - if (dma_mapping_error(drv_data->tx_dma)) { - dma_unmap_single(dev, drv_data->rx_dma, - drv_data->rx_map_len, DMA_FROM_DEVICE); - return 0; - } - - return 1; -} - -static void unmap_dma_buffers(struct driver_data *drv_data) -{ - struct device *dev; - - if (!drv_data->dma_mapped) - return; - - if (!drv_data->cur_msg->is_dma_mapped) { - dev = &drv_data->cur_msg->spi->dev; - dma_unmap_single(dev, drv_data->rx_dma, - drv_data->rx_map_len, DMA_FROM_DEVICE); - dma_unmap_single(dev, drv_data->tx_dma, - drv_data->tx_map_len, DMA_TO_DEVICE); - } - - drv_data->dma_mapped = 0; -} - -/* caller already set message->status; dma and pio irqs are blocked */ -static void giveback(struct driver_data *drv_data) -{ - struct spi_transfer* last_transfer; - unsigned long flags; - struct spi_message *msg; - - spin_lock_irqsave(&drv_data->lock, flags); - msg = drv_data->cur_msg; - drv_data->cur_msg = NULL; - drv_data->cur_transfer = NULL; - drv_data->cur_chip = NULL; - queue_work(drv_data->workqueue, &drv_data->pump_messages); - spin_unlock_irqrestore(&drv_data->lock, flags); - - last_transfer = list_entry(msg->transfers.prev, - struct spi_transfer, - transfer_list); - - if (!last_transfer->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); - - msg->state = NULL; - if (msg->complete) - msg->complete(msg->context); -} - -static int wait_ssp_rx_stall(void *ioaddr) -{ - unsigned long limit = loops_per_jiffy << 1; - - while ((read_SSSR(ioaddr) & SSSR_BSY) && limit--) - cpu_relax(); - - return limit; -} - -static int wait_dma_channel_stop(int channel) -{ - unsigned long limit = loops_per_jiffy << 1; - - while (!(DCSR(channel) & DCSR_STOPSTATE) && limit--) - cpu_relax(); - - return limit; -} - -static void dma_handler(int channel, void *data, struct pt_regs *regs) -{ - struct driver_data *drv_data = data; - struct spi_message *msg = drv_data->cur_msg; - void *reg = drv_data->ioaddr; - u32 irq_status = DCSR(channel) & DMA_INT_MASK; - u32 trailing_sssr = 0; - - if (irq_status & DCSR_BUSERR) { - - /* Disable interrupts, clear status and reset DMA */ - write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); - write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - - if (flush(drv_data) == 0) - dev_err(&drv_data->pdev->dev, - "dma_handler: flush fail\n"); - - unmap_dma_buffers(drv_data); - - if (channel == drv_data->tx_channel) - dev_err(&drv_data->pdev->dev, - "dma_handler: bad bus address on " - "tx channel %d, source %x target = %x\n", - channel, DSADR(channel), DTADR(channel)); - else - dev_err(&drv_data->pdev->dev, - "dma_handler: bad bus address on " - "rx channel %d, source %x target = %x\n", - channel, DSADR(channel), DTADR(channel)); - - msg->state = ERROR_STATE; - tasklet_schedule(&drv_data->pump_transfers); - } - - /* PXA255x_SSP has no timeout interrupt, wait for tailing bytes */ - if ((drv_data->ssp_type == PXA25x_SSP) - && (channel == drv_data->tx_channel) - && (irq_status & DCSR_ENDINTR)) { - - /* Wait for rx to stall */ - if (wait_ssp_rx_stall(drv_data->ioaddr) == 0) - dev_err(&drv_data->pdev->dev, - "dma_handler: ssp rx stall failed\n"); - - /* Clear and disable interrupts on SSP and DMA channels*/ - write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - if (wait_dma_channel_stop(drv_data->rx_channel) == 0) - dev_err(&drv_data->pdev->dev, - "dma_handler: dma rx channel stop failed\n"); - - unmap_dma_buffers(drv_data); - - /* Read trailing bytes */ - /* Calculate number of trailing bytes, read them */ - trailing_sssr = read_SSSR(reg); - if ((trailing_sssr & 0xf008) != 0xf000) { - drv_data->rx = drv_data->rx_end - - (((trailing_sssr >> 12) & 0x0f) + 1); - drv_data->read(drv_data); - } - msg->actual_length += drv_data->len; - - /* Release chip select if requested, transfer delays are - * handled in pump_transfers */ - if (drv_data->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); - - /* Move to next transfer */ - msg->state = next_transfer(drv_data); - - /* Schedule transfer tasklet */ - tasklet_schedule(&drv_data->pump_transfers); - } -} - -static irqreturn_t dma_transfer(struct driver_data *drv_data) -{ - u32 irq_status; - u32 trailing_sssr = 0; - struct spi_message *msg = drv_data->cur_msg; - void *reg = drv_data->ioaddr; - - irq_status = read_SSSR(reg) & drv_data->mask_sr; - if (irq_status & SSSR_ROR) { - /* Clear and disable interrupts on SSP and DMA channels*/ - write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); - write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - unmap_dma_buffers(drv_data); - - if (flush(drv_data) == 0) - dev_err(&drv_data->pdev->dev, - "dma_transfer: flush fail\n"); - - dev_warn(&drv_data->pdev->dev, "dma_transfer: fifo overun\n"); - - drv_data->cur_msg->state = ERROR_STATE; - tasklet_schedule(&drv_data->pump_transfers); - - return IRQ_HANDLED; - } - - /* Check for false positive timeout */ - if ((irq_status & SSSR_TINT) && DCSR(drv_data->tx_channel) & DCSR_RUN) { - write_SSSR(SSSR_TINT, reg); - return IRQ_HANDLED; - } - - if (irq_status & SSSR_TINT || drv_data->rx == drv_data->rx_end) { - - /* Clear and disable interrupts on SSP and DMA channels*/ - write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - - if (wait_dma_channel_stop(drv_data->rx_channel) == 0) - dev_err(&drv_data->pdev->dev, - "dma_transfer: dma rx channel stop failed\n"); - - if (wait_ssp_rx_stall(drv_data->ioaddr) == 0) - dev_err(&drv_data->pdev->dev, - "dma_transfer: ssp rx stall failed\n"); - - unmap_dma_buffers(drv_data); - - /* Calculate number of trailing bytes, read them */ - trailing_sssr = read_SSSR(reg); - if ((trailing_sssr & 0xf008) != 0xf000) { - drv_data->rx = drv_data->rx_end - - (((trailing_sssr >> 12) & 0x0f) + 1); - drv_data->read(drv_data); - } - msg->actual_length += drv_data->len; - - /* Release chip select if requested, transfer delays are - * handled in pump_transfers */ - if (drv_data->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); - - /* Move to next transfer */ - msg->state = next_transfer(drv_data); - - /* Schedule transfer tasklet */ - tasklet_schedule(&drv_data->pump_transfers); - - return IRQ_HANDLED; - } - - /* Opps problem detected */ - return IRQ_NONE; -} - -static irqreturn_t interrupt_transfer(struct driver_data *drv_data) -{ - struct spi_message *msg = drv_data->cur_msg; - void *reg = drv_data->ioaddr; - unsigned long limit = loops_per_jiffy << 1; - u32 irq_status; - u32 irq_mask = (read_SSCR1(reg) & SSCR1_TIE) ? - drv_data->mask_sr : drv_data->mask_sr & ~SSSR_TFS; - - while ((irq_status = read_SSSR(reg) & irq_mask)) { - - if (irq_status & SSSR_ROR) { - - /* Clear and disable interrupts */ - write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); - write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - - if (flush(drv_data) == 0) - dev_err(&drv_data->pdev->dev, - "interrupt_transfer: flush fail\n"); - - /* Stop the SSP */ - - dev_warn(&drv_data->pdev->dev, - "interrupt_transfer: fifo overun\n"); - - msg->state = ERROR_STATE; - tasklet_schedule(&drv_data->pump_transfers); - - return IRQ_HANDLED; - } - - /* Look for false positive timeout */ - if ((irq_status & SSSR_TINT) - && (drv_data->rx < drv_data->rx_end)) - write_SSSR(SSSR_TINT, reg); - - /* Pump data */ - drv_data->read(drv_data); - drv_data->write(drv_data); - - if (drv_data->tx == drv_data->tx_end) { - /* Disable tx interrupt */ - write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg); - irq_mask = drv_data->mask_sr & ~SSSR_TFS; - - /* PXA25x_SSP has no timeout, read trailing bytes */ - if (drv_data->ssp_type == PXA25x_SSP) { - while ((read_SSSR(reg) & SSSR_BSY) && limit--) - drv_data->read(drv_data); - - if (limit == 0) - dev_err(&drv_data->pdev->dev, - "interrupt_transfer: " - "trailing byte read failed\n"); - } - } - - if ((irq_status & SSSR_TINT) - || (drv_data->rx == drv_data->rx_end)) { - - /* Clear timeout */ - write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - - /* Update total byte transfered */ - msg->actual_length += drv_data->len; - - /* Release chip select if requested, transfer delays are - * handled in pump_transfers */ - if (drv_data->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); - - /* Move to next transfer */ - msg->state = next_transfer(drv_data); - - /* Schedule transfer tasklet */ - tasklet_schedule(&drv_data->pump_transfers); - } - } - - /* We did something */ - return IRQ_HANDLED; -} - -static irqreturn_t ssp_int(int irq, void *dev_id, struct pt_regs *regs) -{ - struct driver_data *drv_data = (struct driver_data *)dev_id; - void *reg = drv_data->ioaddr; - - if (!drv_data->cur_msg) { - - write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); - write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - - dev_err(&drv_data->pdev->dev, "bad message state " - "in interrupt handler"); - - /* Never fail */ - return IRQ_HANDLED; - } - - return drv_data->transfer_handler(drv_data); -} - -static void pump_transfers(unsigned long data) -{ - struct driver_data *drv_data = (struct driver_data *)data; - struct spi_message *message = NULL; - struct spi_transfer *transfer = NULL; - struct spi_transfer *previous = NULL; - struct chip_data *chip = NULL; - void *reg = drv_data->ioaddr; - u32 clk_div = 0; - u8 bits = 0; - u32 speed = 0; - u32 cr0; - - /* Get current state information */ - message = drv_data->cur_msg; - transfer = drv_data->cur_transfer; - chip = drv_data->cur_chip; - - /* Handle for abort */ - if (message->state == ERROR_STATE) { - message->status = -EIO; - giveback(drv_data); - return; - } - - /* Handle end of message */ - if (message->state == DONE_STATE) { - message->status = 0; - giveback(drv_data); - return; - } - - /* Delay if requested at end of transfer*/ - if (message->state == RUNNING_STATE) { - previous = list_entry(transfer->transfer_list.prev, - struct spi_transfer, - transfer_list); - if (previous->delay_usecs) - udelay(previous->delay_usecs); - } - - /* Setup the transfer state based on the type of transfer */ - if (flush(drv_data) == 0) { - dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n"); - message->status = -EIO; - giveback(drv_data); - return; - } - drv_data->n_bytes = chip->n_bytes; - drv_data->dma_width = chip->dma_width; - drv_data->cs_control = chip->cs_control; - drv_data->tx = (void *)transfer->tx_buf; - drv_data->tx_end = drv_data->tx + transfer->len; - drv_data->rx = transfer->rx_buf; - drv_data->rx_end = drv_data->rx + transfer->len; - drv_data->rx_dma = transfer->rx_dma; - drv_data->tx_dma = transfer->tx_dma; - drv_data->len = transfer->len; - drv_data->write = drv_data->tx ? chip->write : null_writer; - drv_data->read = drv_data->rx ? chip->read : null_reader; - drv_data->cs_change = transfer->cs_change; - - /* Change speed and bit per word on a per transfer */ - if (transfer->speed_hz || transfer->bits_per_word) { - - /* Disable clock */ - write_SSCR0(chip->cr0 & ~SSCR0_SSE, reg); - cr0 = chip->cr0; - bits = chip->bits_per_word; - speed = chip->speed_hz; - - if (transfer->speed_hz) - speed = transfer->speed_hz; - - if (transfer->bits_per_word) - bits = transfer->bits_per_word; - - if (reg == SSP1_VIRT) - clk_div = SSP1_SerClkDiv(speed); - else if (reg == SSP2_VIRT) - clk_div = SSP2_SerClkDiv(speed); - else if (reg == SSP3_VIRT) - clk_div = SSP3_SerClkDiv(speed); - - if (bits <= 8) { - drv_data->n_bytes = 1; - drv_data->dma_width = DCMD_WIDTH1; - drv_data->read = drv_data->read != null_reader ? - u8_reader : null_reader; - drv_data->write = drv_data->write != null_writer ? - u8_writer : null_writer; - } else if (bits <= 16) { - drv_data->n_bytes = 2; - drv_data->dma_width = DCMD_WIDTH2; - drv_data->read = drv_data->read != null_reader ? - u16_reader : null_reader; - drv_data->write = drv_data->write != null_writer ? - u16_writer : null_writer; - } else if (bits <= 32) { - drv_data->n_bytes = 4; - drv_data->dma_width = DCMD_WIDTH4; - drv_data->read = drv_data->read != null_reader ? - u32_reader : null_reader; - drv_data->write = drv_data->write != null_writer ? - u32_writer : null_writer; - } - - cr0 = clk_div - | SSCR0_Motorola - | SSCR0_DataSize(bits > 16 ? bits - 16 : bits) - | SSCR0_SSE - | (bits > 16 ? SSCR0_EDSS : 0); - - /* Start it back up */ - write_SSCR0(cr0, reg); - } - - message->state = RUNNING_STATE; - - /* Try to map dma buffer and do a dma transfer if successful */ - if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) { - - /* Ensure we have the correct interrupt handler */ - drv_data->transfer_handler = dma_transfer; - - /* Setup rx DMA Channel */ - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - DSADR(drv_data->rx_channel) = drv_data->ssdr_physical; - DTADR(drv_data->rx_channel) = drv_data->rx_dma; - if (drv_data->rx == drv_data->null_dma_buf) - /* No target address increment */ - DCMD(drv_data->rx_channel) = DCMD_FLOWSRC - | drv_data->dma_width - | chip->dma_burst_size - | drv_data->len; - else - DCMD(drv_data->rx_channel) = DCMD_INCTRGADDR - | DCMD_FLOWSRC - | drv_data->dma_width - | chip->dma_burst_size - | drv_data->len; - - /* Setup tx DMA Channel */ - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - DSADR(drv_data->tx_channel) = drv_data->tx_dma; - DTADR(drv_data->tx_channel) = drv_data->ssdr_physical; - if (drv_data->tx == drv_data->null_dma_buf) - /* No source address increment */ - DCMD(drv_data->tx_channel) = DCMD_FLOWTRG - | drv_data->dma_width - | chip->dma_burst_size - | drv_data->len; - else - DCMD(drv_data->tx_channel) = DCMD_INCSRCADDR - | DCMD_FLOWTRG - | drv_data->dma_width - | chip->dma_burst_size - | drv_data->len; - - /* Enable dma end irqs on SSP to detect end of transfer */ - if (drv_data->ssp_type == PXA25x_SSP) - DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN; - - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - - /* Go baby, go */ - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->rx_channel) |= DCSR_RUN; - DCSR(drv_data->tx_channel) |= DCSR_RUN; - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(chip->timeout, reg); - write_SSCR1(chip->cr1 - | chip->dma_threshold - | drv_data->dma_cr1, - reg); - } else { - /* Ensure we have the correct interrupt handler */ - drv_data->transfer_handler = interrupt_transfer; - - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - - /* Go baby, go */ - write_SSSR(drv_data->clear_sr, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(chip->timeout, reg); - write_SSCR1(chip->cr1 - | chip->threshold - | drv_data->int_cr1, - reg); - } -} - -static void pump_messages(void *data) -{ - struct driver_data *drv_data = data; - unsigned long flags; - - /* Lock queue and check for queue work */ - spin_lock_irqsave(&drv_data->lock, flags); - if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) { - drv_data->busy = 0; - spin_unlock_irqrestore(&drv_data->lock, flags); - return; - } - - /* Make sure we are not already running a message */ - if (drv_data->cur_msg) { - spin_unlock_irqrestore(&drv_data->lock, flags); - return; - } - - /* Extract head of queue */ - drv_data->cur_msg = list_entry(drv_data->queue.next, - struct spi_message, queue); - list_del_init(&drv_data->cur_msg->queue); - - /* Initial message state*/ - drv_data->cur_msg->state = START_STATE; - drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, - struct spi_transfer, - transfer_list); - - /* Setup the SSP using the per chip configuration */ - drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); - restore_state(drv_data); - - /* Mark as busy and launch transfers */ - tasklet_schedule(&drv_data->pump_transfers); - - drv_data->busy = 1; - spin_unlock_irqrestore(&drv_data->lock, flags); -} - -static int transfer(struct spi_device *spi, struct spi_message *msg) -{ - struct driver_data *drv_data = spi_master_get_devdata(spi->master); - unsigned long flags; - - spin_lock_irqsave(&drv_data->lock, flags); - - if (drv_data->run == QUEUE_STOPPED) { - spin_unlock_irqrestore(&drv_data->lock, flags); - return -ESHUTDOWN; - } - - msg->actual_length = 0; - msg->status = -EINPROGRESS; - msg->state = START_STATE; - - list_add_tail(&msg->queue, &drv_data->queue); - - if (drv_data->run == QUEUE_RUNNING && !drv_data->busy) - queue_work(drv_data->workqueue, &drv_data->pump_messages); - - spin_unlock_irqrestore(&drv_data->lock, flags); - - return 0; -} - -static int setup(struct spi_device *spi) -{ - struct pxa2xx_spi_chip *chip_info = NULL; - struct chip_data *chip; - struct driver_data *drv_data = spi_master_get_devdata(spi->master); - unsigned int clk_div; - - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - if (drv_data->ssp_type != PXA25x_SSP - && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) - return -EINVAL; - else if (spi->bits_per_word < 4 || spi->bits_per_word > 16) - return -EINVAL; - - /* Only alloc (or use chip_info) on first setup */ - chip = spi_get_ctldata(spi); - if (chip == NULL) { - chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - chip->cs_control = null_cs_control; - chip->enable_dma = 0; - chip->timeout = SSP_TIMEOUT(1000); - chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1); - chip->dma_burst_size = drv_data->master_info->enable_dma ? - DCMD_BURST8 : 0; - - chip_info = spi->controller_data; - } - - /* chip_info isn't always needed */ - if (chip_info) { - if (chip_info->cs_control) - chip->cs_control = chip_info->cs_control; - - chip->timeout = SSP_TIMEOUT(chip_info->timeout_microsecs); - - chip->threshold = SSCR1_RxTresh(chip_info->rx_threshold) - | SSCR1_TxTresh(chip_info->tx_threshold); - - chip->enable_dma = chip_info->dma_burst_size != 0 - && drv_data->master_info->enable_dma; - chip->dma_threshold = 0; - - if (chip->enable_dma) { - if (chip_info->dma_burst_size <= 8) { - chip->dma_threshold = SSCR1_RxTresh(8) - | SSCR1_TxTresh(8); - chip->dma_burst_size = DCMD_BURST8; - } else if (chip_info->dma_burst_size <= 16) { - chip->dma_threshold = SSCR1_RxTresh(16) - | SSCR1_TxTresh(16); - chip->dma_burst_size = DCMD_BURST16; - } else { - chip->dma_threshold = SSCR1_RxTresh(32) - | SSCR1_TxTresh(32); - chip->dma_burst_size = DCMD_BURST32; - } - } - - - if (chip_info->enable_loopback) - chip->cr1 = SSCR1_LBM; - } - - if (drv_data->ioaddr == SSP1_VIRT) - clk_div = SSP1_SerClkDiv(spi->max_speed_hz); - else if (drv_data->ioaddr == SSP2_VIRT) - clk_div = SSP2_SerClkDiv(spi->max_speed_hz); - else if (drv_data->ioaddr == SSP3_VIRT) - clk_div = SSP3_SerClkDiv(spi->max_speed_hz); - else - return -ENODEV; - chip->speed_hz = spi->max_speed_hz; - - chip->cr0 = clk_div - | SSCR0_Motorola - | SSCR0_DataSize(spi->bits_per_word > 16 ? - spi->bits_per_word - 16 : spi->bits_per_word) - | SSCR0_SSE - | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0); - chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) << 4) - | (((spi->mode & SPI_CPOL) != 0) << 3); - - /* NOTE: PXA25x_SSP _could_ use external clocking ... */ - if (drv_data->ssp_type != PXA25x_SSP) - dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n", - spi->bits_per_word, - (CLOCK_SPEED_HZ) - / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - spi->mode & 0x3); - else - dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n", - spi->bits_per_word, - (CLOCK_SPEED_HZ/2) - / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - spi->mode & 0x3); - - if (spi->bits_per_word <= 8) { - chip->n_bytes = 1; - chip->dma_width = DCMD_WIDTH1; - chip->read = u8_reader; - chip->write = u8_writer; - } else if (spi->bits_per_word <= 16) { - chip->n_bytes = 2; - chip->dma_width = DCMD_WIDTH2; - chip->read = u16_reader; - chip->write = u16_writer; - } else if (spi->bits_per_word <= 32) { - chip->cr0 |= SSCR0_EDSS; - chip->n_bytes = 4; - chip->dma_width = DCMD_WIDTH4; - chip->read = u32_reader; - chip->write = u32_writer; - } else { - dev_err(&spi->dev, "invalid wordsize\n"); - kfree(chip); - return -ENODEV; - } - chip->bits_per_word = spi->bits_per_word; - - spi_set_ctldata(spi, chip); - - return 0; -} - -static void cleanup(const struct spi_device *spi) -{ - struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi); - - kfree(chip); -} - -static int init_queue(struct driver_data *drv_data) -{ - INIT_LIST_HEAD(&drv_data->queue); - spin_lock_init(&drv_data->lock); - - drv_data->run = QUEUE_STOPPED; - drv_data->busy = 0; - - tasklet_init(&drv_data->pump_transfers, - pump_transfers, (unsigned long)drv_data); - - INIT_WORK(&drv_data->pump_messages, pump_messages, drv_data); - drv_data->workqueue = create_singlethread_workqueue( - drv_data->master->cdev.dev->bus_id); - if (drv_data->workqueue == NULL) - return -EBUSY; - - return 0; -} - -static int start_queue(struct driver_data *drv_data) -{ - unsigned long flags; - - spin_lock_irqsave(&drv_data->lock, flags); - - if (drv_data->run == QUEUE_RUNNING || drv_data->busy) { - spin_unlock_irqrestore(&drv_data->lock, flags); - return -EBUSY; - } - - drv_data->run = QUEUE_RUNNING; - drv_data->cur_msg = NULL; - drv_data->cur_transfer = NULL; - drv_data->cur_chip = NULL; - spin_unlock_irqrestore(&drv_data->lock, flags); - - queue_work(drv_data->workqueue, &drv_data->pump_messages); - - return 0; -} - -static int stop_queue(struct driver_data *drv_data) -{ - unsigned long flags; - unsigned limit = 500; - int status = 0; - - spin_lock_irqsave(&drv_data->lock, flags); - - /* This is a bit lame, but is optimized for the common execution path. - * A wait_queue on the drv_data->busy could be used, but then the common - * execution path (pump_messages) would be required to call wake_up or - * friends on every SPI message. Do this instead */ - drv_data->run = QUEUE_STOPPED; - while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { - spin_unlock_irqrestore(&drv_data->lock, flags); - msleep(10); - spin_lock_irqsave(&drv_data->lock, flags); - } - - if (!list_empty(&drv_data->queue) || drv_data->busy) - status = -EBUSY; - - spin_unlock_irqrestore(&drv_data->lock, flags); - - return status; -} - -static int destroy_queue(struct driver_data *drv_data) -{ - int status; - - status = stop_queue(drv_data); - if (status != 0) - return status; - - destroy_workqueue(drv_data->workqueue); - - return 0; -} - -static int pxa2xx_spi_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct pxa2xx_spi_master *platform_info; - struct spi_master *master; - struct driver_data *drv_data = 0; - struct resource *memory_resource; - int irq; - int status = 0; - - platform_info = dev->platform_data; - - if (platform_info->ssp_type == SSP_UNDEFINED) { - dev_err(&pdev->dev, "undefined SSP\n"); - return -ENODEV; - } - - /* Allocate master with space for drv_data and null dma buffer */ - master = spi_alloc_master(dev, sizeof(struct driver_data) + 16); - if (!master) { - dev_err(&pdev->dev, "can not alloc spi_master\n"); - return -ENOMEM; - } - drv_data = spi_master_get_devdata(master); - drv_data->master = master; - drv_data->master_info = platform_info; - drv_data->pdev = pdev; - - master->bus_num = pdev->id; - master->num_chipselect = platform_info->num_chipselect; - master->cleanup = cleanup; - master->setup = setup; - master->transfer = transfer; - - drv_data->ssp_type = platform_info->ssp_type; - drv_data->null_dma_buf = (u32 *)ALIGN((u32)(drv_data + - sizeof(struct driver_data)), 8); - - /* Setup register addresses */ - memory_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!memory_resource) { - dev_err(&pdev->dev, "memory resources not defined\n"); - status = -ENODEV; - goto out_error_master_alloc; - } - - drv_data->ioaddr = (void *)io_p2v((unsigned long)(memory_resource->start)); - drv_data->ssdr_physical = memory_resource->start + 0x00000010; - if (platform_info->ssp_type == PXA25x_SSP) { - drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; - drv_data->dma_cr1 = 0; - drv_data->clear_sr = SSSR_ROR; - drv_data->mask_sr = SSSR_RFS | SSSR_TFS | SSSR_ROR; - } else { - drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE; - drv_data->dma_cr1 = SSCR1_TSRE | SSCR1_RSRE | SSCR1_TINTE; - drv_data->clear_sr = SSSR_ROR | SSSR_TINT; - drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR; - } - - /* Attach to IRQ */ - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "irq resource not defined\n"); - status = -ENODEV; - goto out_error_master_alloc; - } - - status = request_irq(irq, ssp_int, 0, dev->bus_id, drv_data); - if (status < 0) { - dev_err(&pdev->dev, "can not get IRQ\n"); - goto out_error_master_alloc; - } - - /* Setup DMA if requested */ - drv_data->tx_channel = -1; - drv_data->rx_channel = -1; - if (platform_info->enable_dma) { - - /* Get two DMA channels (rx and tx) */ - drv_data->rx_channel = pxa_request_dma("pxa2xx_spi_ssp_rx", - DMA_PRIO_HIGH, - dma_handler, - drv_data); - if (drv_data->rx_channel < 0) { - dev_err(dev, "problem (%d) requesting rx channel\n", - drv_data->rx_channel); - status = -ENODEV; - goto out_error_irq_alloc; - } - drv_data->tx_channel = pxa_request_dma("pxa2xx_spi_ssp_tx", - DMA_PRIO_MEDIUM, - dma_handler, - drv_data); - if (drv_data->tx_channel < 0) { - dev_err(dev, "problem (%d) requesting tx channel\n", - drv_data->tx_channel); - status = -ENODEV; - goto out_error_dma_alloc; - } - - if (drv_data->ioaddr == SSP1_VIRT) { - DRCMRRXSSDR = DRCMR_MAPVLD - | drv_data->rx_channel; - DRCMRTXSSDR = DRCMR_MAPVLD - | drv_data->tx_channel; - } else if (drv_data->ioaddr == SSP2_VIRT) { - DRCMRRXSS2DR = DRCMR_MAPVLD - | drv_data->rx_channel; - DRCMRTXSS2DR = DRCMR_MAPVLD - | drv_data->tx_channel; - } else if (drv_data->ioaddr == SSP3_VIRT) { - DRCMRRXSS3DR = DRCMR_MAPVLD - | drv_data->rx_channel; - DRCMRTXSS3DR = DRCMR_MAPVLD - | drv_data->tx_channel; - } else { - dev_err(dev, "bad SSP type\n"); - goto out_error_dma_alloc; - } - } - - /* Enable SOC clock */ - pxa_set_cken(platform_info->clock_enable, 1); - - /* Load default SSP configuration */ - write_SSCR0(0, drv_data->ioaddr); - write_SSCR1(SSCR1_RxTresh(4) | SSCR1_TxTresh(12), drv_data->ioaddr); - write_SSCR0(SSCR0_SerClkDiv(2) - | SSCR0_Motorola - | SSCR0_DataSize(8), - drv_data->ioaddr); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, drv_data->ioaddr); - write_SSPSP(0, drv_data->ioaddr); - - /* Initial and start queue */ - status = init_queue(drv_data); - if (status != 0) { - dev_err(&pdev->dev, "problem initializing queue\n"); - goto out_error_clock_enabled; - } - status = start_queue(drv_data); - if (status != 0) { - dev_err(&pdev->dev, "problem starting queue\n"); - goto out_error_clock_enabled; - } - - /* Register with the SPI framework */ - platform_set_drvdata(pdev, drv_data); - status = spi_register_master(master); - if (status != 0) { - dev_err(&pdev->dev, "problem registering spi master\n"); - goto out_error_queue_alloc; - } - - return status; - -out_error_queue_alloc: - destroy_queue(drv_data); - -out_error_clock_enabled: - pxa_set_cken(platform_info->clock_enable, 0); - -out_error_dma_alloc: - if (drv_data->tx_channel != -1) - pxa_free_dma(drv_data->tx_channel); - if (drv_data->rx_channel != -1) - pxa_free_dma(drv_data->rx_channel); - -out_error_irq_alloc: - free_irq(irq, drv_data); - -out_error_master_alloc: - spi_master_put(master); - return status; -} - -static int pxa2xx_spi_remove(struct platform_device *pdev) -{ - struct driver_data *drv_data = platform_get_drvdata(pdev); - int irq; - int status = 0; - - if (!drv_data) - return 0; - - /* Remove the queue */ - status = destroy_queue(drv_data); - if (status != 0) - return status; - - /* Disable the SSP at the peripheral and SOC level */ - write_SSCR0(0, drv_data->ioaddr); - pxa_set_cken(drv_data->master_info->clock_enable, 0); - - /* Release DMA */ - if (drv_data->master_info->enable_dma) { - if (drv_data->ioaddr == SSP1_VIRT) { - DRCMRRXSSDR = 0; - DRCMRTXSSDR = 0; - } else if (drv_data->ioaddr == SSP2_VIRT) { - DRCMRRXSS2DR = 0; - DRCMRTXSS2DR = 0; - } else if (drv_data->ioaddr == SSP3_VIRT) { - DRCMRRXSS3DR = 0; - DRCMRTXSS3DR = 0; - } - pxa_free_dma(drv_data->tx_channel); - pxa_free_dma(drv_data->rx_channel); - } - - /* Release IRQ */ - irq = platform_get_irq(pdev, 0); - if (irq >= 0) - free_irq(irq, drv_data); - - /* Disconnect from the SPI framework */ - spi_unregister_master(drv_data->master); - - /* Prevent double remove */ - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static void pxa2xx_spi_shutdown(struct platform_device *pdev) -{ - int status = 0; - - if ((status = pxa2xx_spi_remove(pdev)) != 0) - dev_err(&pdev->dev, "shutdown failed with %d\n", status); -} - -#ifdef CONFIG_PM -static int suspend_devices(struct device *dev, void *pm_message) -{ - pm_message_t *state = pm_message; - - if (dev->power.power_state.event != state->event) { - dev_warn(dev, "pm state does not match request\n"); - return -1; - } - - return 0; -} - -static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct driver_data *drv_data = platform_get_drvdata(pdev); - int status = 0; - - /* Check all childern for current power state */ - if (device_for_each_child(&pdev->dev, &state, suspend_devices) != 0) { - dev_warn(&pdev->dev, "suspend aborted\n"); - return -1; - } - - status = stop_queue(drv_data); - if (status != 0) - return status; - write_SSCR0(0, drv_data->ioaddr); - pxa_set_cken(drv_data->master_info->clock_enable, 0); - - return 0; -} - -static int pxa2xx_spi_resume(struct platform_device *pdev) -{ - struct driver_data *drv_data = platform_get_drvdata(pdev); - int status = 0; - - /* Enable the SSP clock */ - pxa_set_cken(drv_data->master_info->clock_enable, 1); - - /* Start the queue running */ - status = start_queue(drv_data); - if (status != 0) { - dev_err(&pdev->dev, "problem starting queue (%d)\n", status); - return status; - } - - return 0; -} -#else -#define pxa2xx_spi_suspend NULL -#define pxa2xx_spi_resume NULL -#endif /* CONFIG_PM */ - -static struct platform_driver driver = { - .driver = { - .name = "pxa2xx-spi", - .bus = &platform_bus_type, - .owner = THIS_MODULE, - }, - .probe = pxa2xx_spi_probe, - .remove = __devexit_p(pxa2xx_spi_remove), - .shutdown = pxa2xx_spi_shutdown, - .suspend = pxa2xx_spi_suspend, - .resume = pxa2xx_spi_resume, -}; - -static int __init pxa2xx_spi_init(void) -{ - platform_driver_register(&driver); - - return 0; -} -module_init(pxa2xx_spi_init); - -static void __exit pxa2xx_spi_exit(void) -{ - platform_driver_unregister(&driver); -} -module_exit(pxa2xx_spi_exit); diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 1cea4a6799fe..94f5e8ed83a7 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -338,18 +338,18 @@ static struct class spi_master_class = { * spi_alloc_master - allocate SPI master controller * @dev: the controller, possibly using the platform_bus * @size: how much driver-private data to preallocate; the pointer to this - * memory is in the class_data field of the returned class_device, + * memory is in the class_data field of the returned class_device, * accessible with spi_master_get_devdata(). * * This call is used only by SPI master controller drivers, which are the * only ones directly touching chip registers. It's how they allocate - * an spi_master structure, prior to calling spi_register_master(). + * an spi_master structure, prior to calling spi_add_master(). * * This must be called from context that can sleep. It returns the SPI * master structure on success, else NULL. * * The caller is responsible for assigning the bus number and initializing - * the master's methods before calling spi_register_master(); and (after errors + * the master's methods before calling spi_add_master(); and (after errors * adding the device) calling spi_master_put() to prevent a memory leak. */ struct spi_master * __init_or_module @@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master); int __init_or_module spi_register_master(struct spi_master *master) { - static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1); + static atomic_t dyn_bus_id = ATOMIC_INIT(0); struct device *dev = master->cdev.dev; int status = -ENODEV; int dynamic = 0; @@ -404,7 +404,7 @@ spi_register_master(struct spi_master *master) return -ENODEV; /* convention: dynamically assigned bus IDs count down from the max */ - if (master->bus_num < 0) { + if (master->bus_num == 0) { master->bus_num = atomic_dec_return(&dyn_bus_id); dynamic = 1; } @@ -522,8 +522,7 @@ int spi_sync(struct spi_device *spi, struct spi_message *message) } EXPORT_SYMBOL_GPL(spi_sync); -/* portable code must never pass more than 32 bytes */ -#define SPI_BUFSIZ max(32,SMP_CACHE_BYTES) +#define SPI_BUFSIZ (SMP_CACHE_BYTES) static u8 *buf; diff --git a/trunk/drivers/spi/spi_bitbang.c b/trunk/drivers/spi/spi_bitbang.c index dd2f950b21a7..f037e5593269 100644 --- a/trunk/drivers/spi/spi_bitbang.c +++ b/trunk/drivers/spi/spi_bitbang.c @@ -138,45 +138,6 @@ static unsigned bitbang_txrx_32( return t->len - count; } -int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t) -{ - struct spi_bitbang_cs *cs = spi->controller_state; - u8 bits_per_word; - u32 hz; - - if (t) { - bits_per_word = t->bits_per_word; - hz = t->speed_hz; - } else { - bits_per_word = 0; - hz = 0; - } - - /* spi_transfer level calls that work per-word */ - if (!bits_per_word) - bits_per_word = spi->bits_per_word; - if (bits_per_word <= 8) - cs->txrx_bufs = bitbang_txrx_8; - else if (bits_per_word <= 16) - cs->txrx_bufs = bitbang_txrx_16; - else if (bits_per_word <= 32) - cs->txrx_bufs = bitbang_txrx_32; - else - return -EINVAL; - - /* nsecs = (clock period)/2 */ - if (!hz) - hz = spi->max_speed_hz; - if (hz) { - cs->nsecs = (1000000000/2) / hz; - if (cs->nsecs > (MAX_UDELAY_MS * 1000 * 1000)) - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL_GPL(spi_bitbang_setup_transfer); - /** * spi_bitbang_setup - default setup for per-word I/O loops */ @@ -184,16 +145,8 @@ int spi_bitbang_setup(struct spi_device *spi) { struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang *bitbang; - int retval; - bitbang = spi_master_get_devdata(spi->master); - - /* REVISIT: some systems will want to support devices using lsb-first - * bit encodings on the wire. In pure software that would be trivial, - * just bitbang_txrx_le_cphaX() routines shifting the other way, and - * some hardware controllers also have this support. - */ - if ((spi->mode & SPI_LSB_FIRST) != 0) + if (!spi->max_speed_hz) return -EINVAL; if (!cs) { @@ -202,20 +155,32 @@ int spi_bitbang_setup(struct spi_device *spi) return -ENOMEM; spi->controller_state = cs; } + bitbang = spi_master_get_devdata(spi->master); if (!spi->bits_per_word) spi->bits_per_word = 8; + /* spi_transfer level calls that work per-word */ + if (spi->bits_per_word <= 8) + cs->txrx_bufs = bitbang_txrx_8; + else if (spi->bits_per_word <= 16) + cs->txrx_bufs = bitbang_txrx_16; + else if (spi->bits_per_word <= 32) + cs->txrx_bufs = bitbang_txrx_32; + else + return -EINVAL; + /* per-word shift register access, in hardware or bitbanging */ cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; if (!cs->txrx_word) return -EINVAL; - retval = spi_bitbang_setup_transfer(spi, NULL); - if (retval < 0) - return retval; + /* nsecs = (clock period)/2 */ + cs->nsecs = (1000000000/2) / (spi->max_speed_hz); + if (cs->nsecs > MAX_UDELAY_MS * 1000) + return -EINVAL; - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n", + dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA), spi->bits_per_word, 2 * cs->nsecs); @@ -281,8 +246,6 @@ static void bitbang_work(void *_bitbang) unsigned tmp; unsigned cs_change; int status; - int (*setup_transfer)(struct spi_device *, - struct spi_transfer *); m = container_of(bitbang->queue.next, struct spi_message, queue); @@ -299,7 +262,6 @@ static void bitbang_work(void *_bitbang) tmp = 0; cs_change = 1; status = 0; - setup_transfer = NULL; list_for_each_entry (t, &m->transfers, transfer_list) { if (bitbang->shutdown) { @@ -307,20 +269,6 @@ static void bitbang_work(void *_bitbang) break; } - /* override or restore speed and wordsize */ - if (t->speed_hz || t->bits_per_word) { - setup_transfer = bitbang->setup_transfer; - if (!setup_transfer) { - status = -ENOPROTOOPT; - break; - } - } - if (setup_transfer) { - status = setup_transfer(spi, t); - if (status < 0) - break; - } - /* set up default clock polarity, and activate chip; * this implicitly updates clock and spi modes as * previously recorded for this device via setup(). @@ -377,10 +325,6 @@ static void bitbang_work(void *_bitbang) m->status = status; m->complete(m->context); - /* restore speed and wordsize */ - if (setup_transfer) - setup_transfer(spi, NULL); - /* normally deactivate chipselect ... unless no error and * cs_change has hinted that the next message will probably * be for this chip too. @@ -404,7 +348,6 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) { struct spi_bitbang *bitbang; unsigned long flags; - int status = 0; m->actual_length = 0; m->status = -EINPROGRESS; @@ -414,15 +357,11 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) return -ESHUTDOWN; spin_lock_irqsave(&bitbang->lock, flags); - if (!spi->max_speed_hz) - status = -ENETDOWN; - else { - list_add_tail(&m->queue, &bitbang->queue); - queue_work(bitbang->workqueue, &bitbang->work); - } + list_add_tail(&m->queue, &bitbang->queue); + queue_work(bitbang->workqueue, &bitbang->work); spin_unlock_irqrestore(&bitbang->lock, flags); - return status; + return 0; } EXPORT_SYMBOL_GPL(spi_bitbang_transfer); @@ -467,9 +406,6 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) bitbang->use_dma = 0; bitbang->txrx_bufs = spi_bitbang_bufs; if (!bitbang->master->setup) { - if (!bitbang->setup_transfer) - bitbang->setup_transfer = - spi_bitbang_setup_transfer; bitbang->master->setup = spi_bitbang_setup; bitbang->master->cleanup = spi_bitbang_cleanup; } diff --git a/trunk/drivers/spi/spi_butterfly.c b/trunk/drivers/spi/spi_butterfly.c index a006a1ee27ac..ff9e5faa4dc9 100644 --- a/trunk/drivers/spi/spi_butterfly.c +++ b/trunk/drivers/spi/spi_butterfly.c @@ -321,7 +321,6 @@ static void butterfly_attach(struct parport *p) * (firmware resets at45, acts as spi slave) or neither (we ignore * both, AVR uses AT45). Here we expect firmware for the first option. */ - pp->info[0].max_speed_hz = 15 * 1000 * 1000; strcpy(pp->info[0].modalias, "mtd_dataflash"); pp->info[0].platform_data = &flash; diff --git a/trunk/drivers/spi/spi_mpc83xx.c b/trunk/drivers/spi/spi_mpc83xx.c deleted file mode 100644 index 5d92a7e5cb41..000000000000 --- a/trunk/drivers/spi/spi_mpc83xx.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * MPC83xx SPI controller driver. - * - * Maintainer: Kumar Gala - * - * Copyright (C) 2006 Polycom, 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. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* SPI Controller registers */ -struct mpc83xx_spi_reg { - u8 res1[0x20]; - __be32 mode; - __be32 event; - __be32 mask; - __be32 command; - __be32 transmit; - __be32 receive; -}; - -/* SPI Controller mode register definitions */ -#define SPMODE_CI_INACTIVEHIGH (1 << 29) -#define SPMODE_CP_BEGIN_EDGECLK (1 << 28) -#define SPMODE_DIV16 (1 << 27) -#define SPMODE_REV (1 << 26) -#define SPMODE_MS (1 << 25) -#define SPMODE_ENABLE (1 << 24) -#define SPMODE_LEN(x) ((x) << 20) -#define SPMODE_PM(x) ((x) << 16) - -/* - * Default for SPI Mode: - * SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk - */ -#define SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_DIV16 | SPMODE_REV | \ - SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf)) - -/* SPIE register values */ -#define SPIE_NE 0x00000200 /* Not empty */ -#define SPIE_NF 0x00000100 /* Not full */ - -/* SPIM register values */ -#define SPIM_NE 0x00000200 /* Not empty */ -#define SPIM_NF 0x00000100 /* Not full */ - -/* SPI Controller driver's private data. */ -struct mpc83xx_spi { - /* bitbang has to be first */ - struct spi_bitbang bitbang; - struct completion done; - - struct mpc83xx_spi_reg __iomem *base; - - /* rx & tx bufs from the spi_transfer */ - const void *tx; - void *rx; - - /* functions to deal with different sized buffers */ - void (*get_rx) (u32 rx_data, struct mpc83xx_spi *); - u32(*get_tx) (struct mpc83xx_spi *); - - unsigned int count; - u32 irq; - - unsigned nsecs; /* (clock cycle time)/2 */ - - u32 sysclk; - void (*activate_cs) (u8 cs, u8 polarity); - void (*deactivate_cs) (u8 cs, u8 polarity); -}; - -static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val) -{ - out_be32(reg, val); -} - -static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg) -{ - return in_be32(reg); -} - -#define MPC83XX_SPI_RX_BUF(type) \ -void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \ -{ \ - type * rx = mpc83xx_spi->rx; \ - *rx++ = (type)data; \ - mpc83xx_spi->rx = rx; \ -} - -#define MPC83XX_SPI_TX_BUF(type) \ -u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \ -{ \ - u32 data; \ - const type * tx = mpc83xx_spi->tx; \ - data = *tx++; \ - mpc83xx_spi->tx = tx; \ - return data; \ -} - -MPC83XX_SPI_RX_BUF(u8) -MPC83XX_SPI_RX_BUF(u16) -MPC83XX_SPI_RX_BUF(u32) -MPC83XX_SPI_TX_BUF(u8) -MPC83XX_SPI_TX_BUF(u16) -MPC83XX_SPI_TX_BUF(u32) - -static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) -{ - struct mpc83xx_spi *mpc83xx_spi; - u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0; - - mpc83xx_spi = spi_master_get_devdata(spi->master); - - if (value == BITBANG_CS_INACTIVE) { - if (mpc83xx_spi->deactivate_cs) - mpc83xx_spi->deactivate_cs(spi->chip_select, pol); - } - - if (value == BITBANG_CS_ACTIVE) { - u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); - u32 len = spi->bits_per_word; - if (len == 32) - len = 0; - else - len = len - 1; - - /* mask out bits we are going to set */ - regval &= ~0x38ff0000; - - if (spi->mode & SPI_CPHA) - regval |= SPMODE_CP_BEGIN_EDGECLK; - if (spi->mode & SPI_CPOL) - regval |= SPMODE_CI_INACTIVEHIGH; - - regval |= SPMODE_LEN(len); - - if ((mpc83xx_spi->sysclk / spi->max_speed_hz) >= 64) { - u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 64); - regval |= SPMODE_PM(pm) | SPMODE_DIV16; - } else { - u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 4); - regval |= SPMODE_PM(pm); - } - - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); - if (mpc83xx_spi->activate_cs) - mpc83xx_spi->activate_cs(spi->chip_select, pol); - } -} - -static -int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) -{ - struct mpc83xx_spi *mpc83xx_spi; - u32 regval; - u8 bits_per_word; - u32 hz; - - mpc83xx_spi = spi_master_get_devdata(spi->master); - - if (t) { - bits_per_word = t->bits_per_word; - hz = t->speed_hz; - } else { - bits_per_word = 0; - hz = 0; - } - - /* spi_transfer level calls that work per-word */ - if (!bits_per_word) - bits_per_word = spi->bits_per_word; - - /* Make sure its a bit width we support [4..16, 32] */ - if ((bits_per_word < 4) - || ((bits_per_word > 16) && (bits_per_word != 32))) - return -EINVAL; - - if (bits_per_word <= 8) { - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; - } else if (bits_per_word <= 16) { - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16; - } else if (bits_per_word <= 32) { - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32; - } else - return -EINVAL; - - /* nsecs = (clock period)/2 */ - if (!hz) - hz = spi->max_speed_hz; - mpc83xx_spi->nsecs = (1000000000 / 2) / hz; - if (mpc83xx_spi->nsecs > MAX_UDELAY_MS * 1000) - return -EINVAL; - - if (bits_per_word == 32) - bits_per_word = 0; - else - bits_per_word = bits_per_word - 1; - - regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); - - /* Mask out bits_per_wordgth */ - regval &= 0xff0fffff; - regval |= SPMODE_LEN(bits_per_word); - - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); - - return 0; -} - -static int mpc83xx_spi_setup(struct spi_device *spi) -{ - struct spi_bitbang *bitbang; - struct mpc83xx_spi *mpc83xx_spi; - int retval; - - if (!spi->max_speed_hz) - return -EINVAL; - - bitbang = spi_master_get_devdata(spi->master); - mpc83xx_spi = spi_master_get_devdata(spi->master); - - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - retval = mpc83xx_spi_setup_transfer(spi, NULL); - if (retval < 0) - return retval; - - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", - __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA), - spi->bits_per_word, 2 * mpc83xx_spi->nsecs); - - /* NOTE we _need_ to call chipselect() early, ideally with adapter - * setup, unless the hardware defaults cooperate to avoid confusion - * between normal (active low) and inverted chipselects. - */ - - /* deselect chip (low or high) */ - spin_lock(&bitbang->lock); - if (!bitbang->busy) { - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(mpc83xx_spi->nsecs); - } - spin_unlock(&bitbang->lock); - - return 0; -} - -static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) -{ - struct mpc83xx_spi *mpc83xx_spi; - u32 word; - - mpc83xx_spi = spi_master_get_devdata(spi->master); - - mpc83xx_spi->tx = t->tx_buf; - mpc83xx_spi->rx = t->rx_buf; - mpc83xx_spi->count = t->len; - INIT_COMPLETION(mpc83xx_spi->done); - - /* enable rx ints */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE); - - /* transmit word */ - word = mpc83xx_spi->get_tx(mpc83xx_spi); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); - - wait_for_completion(&mpc83xx_spi->done); - - /* disable rx ints */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); - - return t->len - mpc83xx_spi->count; -} - -irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data, - struct pt_regs * ptregs) -{ - struct mpc83xx_spi *mpc83xx_spi = context_data; - u32 event; - irqreturn_t ret = IRQ_NONE; - - /* Get interrupt events(tx/rx) */ - event = mpc83xx_spi_read_reg(&mpc83xx_spi->base->event); - - /* We need handle RX first */ - if (event & SPIE_NE) { - u32 rx_data = mpc83xx_spi_read_reg(&mpc83xx_spi->base->receive); - - if (mpc83xx_spi->rx) - mpc83xx_spi->get_rx(rx_data, mpc83xx_spi); - - ret = IRQ_HANDLED; - } - - if ((event & SPIE_NF) == 0) - /* spin until TX is done */ - while (((event = - mpc83xx_spi_read_reg(&mpc83xx_spi->base->event)) & - SPIE_NF) == 0) - cpu_relax(); - - mpc83xx_spi->count -= 1; - if (mpc83xx_spi->count) { - if (mpc83xx_spi->tx) { - u32 word = mpc83xx_spi->get_tx(mpc83xx_spi); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, - word); - } - } else { - complete(&mpc83xx_spi->done); - } - - /* Clear the events */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, event); - - return ret; -} - -static int __init mpc83xx_spi_probe(struct platform_device *dev) -{ - struct spi_master *master; - struct mpc83xx_spi *mpc83xx_spi; - struct fsl_spi_platform_data *pdata; - struct resource *r; - u32 regval; - int ret = 0; - - /* Get resources(memory, IRQ) associated with the device */ - master = spi_alloc_master(&dev->dev, sizeof(struct mpc83xx_spi)); - - if (master == NULL) { - ret = -ENOMEM; - goto err; - } - - platform_set_drvdata(dev, master); - pdata = dev->dev.platform_data; - - if (pdata == NULL) { - ret = -ENODEV; - goto free_master; - } - - r = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (r == NULL) { - ret = -ENODEV; - goto free_master; - } - - mpc83xx_spi = spi_master_get_devdata(master); - mpc83xx_spi->bitbang.master = spi_master_get(master); - mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect; - mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer; - mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs; - mpc83xx_spi->sysclk = pdata->sysclk; - mpc83xx_spi->activate_cs = pdata->activate_cs; - mpc83xx_spi->deactivate_cs = pdata->deactivate_cs; - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; - - mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup; - init_completion(&mpc83xx_spi->done); - - mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1); - if (mpc83xx_spi->base == NULL) { - ret = -ENOMEM; - goto put_master; - } - - mpc83xx_spi->irq = platform_get_irq(dev, 0); - - if (mpc83xx_spi->irq < 0) { - ret = -ENXIO; - goto unmap_io; - } - - /* Register for SPI Interrupt */ - ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq, - 0, "mpc83xx_spi", mpc83xx_spi); - - if (ret != 0) - goto unmap_io; - - master->bus_num = pdata->bus_num; - master->num_chipselect = pdata->max_chipselect; - - /* SPI controller initializations */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->command, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, 0xffffffff); - - /* Enable SPI interface */ - regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); - - ret = spi_bitbang_start(&mpc83xx_spi->bitbang); - - if (ret != 0) - goto free_irq; - - printk(KERN_INFO - "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n", - dev->dev.bus_id, mpc83xx_spi->base, mpc83xx_spi->irq); - - return ret; - -free_irq: - free_irq(mpc83xx_spi->irq, mpc83xx_spi); -unmap_io: - iounmap(mpc83xx_spi->base); -put_master: - spi_master_put(master); -free_master: - kfree(master); -err: - return ret; -} - -static int __devexit mpc83xx_spi_remove(struct platform_device *dev) -{ - struct mpc83xx_spi *mpc83xx_spi; - struct spi_master *master; - - master = platform_get_drvdata(dev); - mpc83xx_spi = spi_master_get_devdata(master); - - spi_bitbang_stop(&mpc83xx_spi->bitbang); - free_irq(mpc83xx_spi->irq, mpc83xx_spi); - iounmap(mpc83xx_spi->base); - spi_master_put(mpc83xx_spi->bitbang.master); - - return 0; -} - -static struct platform_driver mpc83xx_spi_driver = { - .probe = mpc83xx_spi_probe, - .remove = __devexit_p(mpc83xx_spi_remove), - .driver = { - .name = "mpc83xx_spi", - }, -}; - -static int __init mpc83xx_spi_init(void) -{ - return platform_driver_register(&mpc83xx_spi_driver); -} - -static void __exit mpc83xx_spi_exit(void) -{ - platform_driver_unregister(&mpc83xx_spi_driver); -} - -module_init(mpc83xx_spi_init); -module_exit(mpc83xx_spi_exit); - -MODULE_AUTHOR("Kumar Gala"); -MODULE_DESCRIPTION("Simple MPC83xx SPI Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/spi_s3c24xx.c b/trunk/drivers/spi/spi_s3c24xx.c deleted file mode 100644 index 9de4b5a04d70..000000000000 --- a/trunk/drivers/spi/spi_s3c24xx.c +++ /dev/null @@ -1,453 +0,0 @@ -/* linux/drivers/spi/spi_s3c24xx.c - * - * Copyright (c) 2006 Ben Dooks - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * 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. - * -*/ - - -//#define DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -struct s3c24xx_spi { - /* bitbang has to be first */ - struct spi_bitbang bitbang; - struct completion done; - - void __iomem *regs; - int irq; - int len; - int count; - - /* data buffers */ - const unsigned char *tx; - unsigned char *rx; - - struct clk *clk; - struct resource *ioarea; - struct spi_master *master; - struct spi_device *curdev; - struct device *dev; - struct s3c2410_spi_info *pdata; -}; - -#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT) -#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP) - -static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev) -{ - return spi_master_get_devdata(sdev->master); -} - -static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) -{ - struct s3c24xx_spi *hw = to_hw(spi); - unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0; - unsigned int spcon; - - switch (value) { - case BITBANG_CS_INACTIVE: - if (hw->pdata->set_cs) - hw->pdata->set_cs(hw->pdata, value, cspol); - else - s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol ^ 1); - break; - - case BITBANG_CS_ACTIVE: - spcon = readb(hw->regs + S3C2410_SPCON); - - if (spi->mode & SPI_CPHA) - spcon |= S3C2410_SPCON_CPHA_FMTB; - else - spcon &= ~S3C2410_SPCON_CPHA_FMTB; - - if (spi->mode & SPI_CPOL) - spcon |= S3C2410_SPCON_CPOL_HIGH; - else - spcon &= ~S3C2410_SPCON_CPOL_HIGH; - - spcon |= S3C2410_SPCON_ENSCK; - - /* write new configration */ - - writeb(spcon, hw->regs + S3C2410_SPCON); - - if (hw->pdata->set_cs) - hw->pdata->set_cs(hw->pdata, value, cspol); - else - s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol); - - break; - - } -} - -static int s3c24xx_spi_setupxfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct s3c24xx_spi *hw = to_hw(spi); - unsigned int bpw; - unsigned int hz; - unsigned int div; - - bpw = t ? t->bits_per_word : spi->bits_per_word; - hz = t ? t->speed_hz : spi->max_speed_hz; - - if (bpw != 8) { - dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw); - return -EINVAL; - } - - div = clk_get_rate(hw->clk) / hz; - - /* is clk = pclk / (2 * (pre+1)), or is it - * clk = (pclk * 2) / ( pre + 1) */ - - div = (div / 2) - 1; - - if (div < 0) - div = 1; - - if (div > 255) - div = 255; - - dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", div, hz); - writeb(div, hw->regs + S3C2410_SPPRE); - - spin_lock(&hw->bitbang.lock); - if (!hw->bitbang.busy) { - hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); - /* need to ndelay for 0.5 clocktick ? */ - } - spin_unlock(&hw->bitbang.lock); - - return 0; -} - -static int s3c24xx_spi_setup(struct spi_device *spi) -{ - int ret; - - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - if ((spi->mode & SPI_LSB_FIRST) != 0) - return -EINVAL; - - ret = s3c24xx_spi_setupxfer(spi, NULL); - if (ret < 0) { - dev_err(&spi->dev, "setupxfer returned %d\n", ret); - return ret; - } - - dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", - __FUNCTION__, spi->mode, spi->bits_per_word, - spi->max_speed_hz); - - return 0; -} - -static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count) -{ - return hw->tx ? hw->tx[count] : 0xff; -} - -static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) -{ - struct s3c24xx_spi *hw = to_hw(spi); - - dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", - t->tx_buf, t->rx_buf, t->len); - - hw->tx = t->tx_buf; - hw->rx = t->rx_buf; - hw->len = t->len; - hw->count = 0; - - /* send the first byte */ - writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT); - wait_for_completion(&hw->done); - - return hw->count; -} - -static irqreturn_t s3c24xx_spi_irq(int irq, void *dev, struct pt_regs *regs) -{ - struct s3c24xx_spi *hw = dev; - unsigned int spsta = readb(hw->regs + S3C2410_SPSTA); - unsigned int count = hw->count; - - if (spsta & S3C2410_SPSTA_DCOL) { - dev_dbg(hw->dev, "data-collision\n"); - complete(&hw->done); - goto irq_done; - } - - if (!(spsta & S3C2410_SPSTA_READY)) { - dev_dbg(hw->dev, "spi not ready for tx?\n"); - complete(&hw->done); - goto irq_done; - } - - hw->count++; - - if (hw->rx) - hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); - - count++; - - if (count < hw->len) - writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); - else - complete(&hw->done); - - irq_done: - return IRQ_HANDLED; -} - -static int s3c24xx_spi_probe(struct platform_device *pdev) -{ - struct s3c24xx_spi *hw; - struct spi_master *master; - struct spi_board_info *bi; - struct resource *res; - int err = 0; - int i; - - master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); - if (master == NULL) { - dev_err(&pdev->dev, "No memory for spi_master\n"); - err = -ENOMEM; - goto err_nomem; - } - - hw = spi_master_get_devdata(master); - memset(hw, 0, sizeof(struct s3c24xx_spi)); - - hw->master = spi_master_get(master); - hw->pdata = pdev->dev.platform_data; - hw->dev = &pdev->dev; - - if (hw->pdata == NULL) { - dev_err(&pdev->dev, "No platform data supplied\n"); - err = -ENOENT; - goto err_no_pdata; - } - - platform_set_drvdata(pdev, hw); - init_completion(&hw->done); - - /* setup the state for the bitbang driver */ - - hw->bitbang.master = hw->master; - hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer; - hw->bitbang.chipselect = s3c24xx_spi_chipsel; - hw->bitbang.txrx_bufs = s3c24xx_spi_txrx; - hw->bitbang.master->setup = s3c24xx_spi_setup; - - dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang); - - /* find and map our resources */ - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); - err = -ENOENT; - goto err_no_iores; - } - - hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1, - pdev->name); - - if (hw->ioarea == NULL) { - dev_err(&pdev->dev, "Cannot reserve region\n"); - err = -ENXIO; - goto err_no_iores; - } - - hw->regs = ioremap(res->start, (res->end - res->start)+1); - if (hw->regs == NULL) { - dev_err(&pdev->dev, "Cannot map IO\n"); - err = -ENXIO; - goto err_no_iomap; - } - - hw->irq = platform_get_irq(pdev, 0); - if (hw->irq < 0) { - dev_err(&pdev->dev, "No IRQ specified\n"); - err = -ENOENT; - goto err_no_irq; - } - - err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); - if (err) { - dev_err(&pdev->dev, "Cannot claim IRQ\n"); - goto err_no_irq; - } - - hw->clk = clk_get(&pdev->dev, "spi"); - if (IS_ERR(hw->clk)) { - dev_err(&pdev->dev, "No clock for device\n"); - err = PTR_ERR(hw->clk); - goto err_no_clk; - } - - /* for the moment, permanently enable the clock */ - - clk_enable(hw->clk); - - /* program defaults into the registers */ - - writeb(0xff, hw->regs + S3C2410_SPPRE); - writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); - writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); - - /* setup any gpio we can */ - - if (!hw->pdata->set_cs) { - s3c2410_gpio_setpin(hw->pdata->pin_cs, 1); - s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); - } - - /* register our spi controller */ - - err = spi_bitbang_start(&hw->bitbang); - if (err) { - dev_err(&pdev->dev, "Failed to register SPI master\n"); - goto err_register; - } - - dev_dbg(hw->dev, "shutdown=%d\n", hw->bitbang.shutdown); - - /* register all the devices associated */ - - bi = &hw->pdata->board_info[0]; - for (i = 0; i < hw->pdata->board_size; i++, bi++) { - dev_info(hw->dev, "registering %s\n", bi->modalias); - - bi->controller_data = hw; - spi_new_device(master, bi); - } - - return 0; - - err_register: - clk_disable(hw->clk); - clk_put(hw->clk); - - err_no_clk: - free_irq(hw->irq, hw); - - err_no_irq: - iounmap(hw->regs); - - err_no_iomap: - release_resource(hw->ioarea); - kfree(hw->ioarea); - - err_no_iores: - err_no_pdata: - spi_master_put(hw->master);; - - err_nomem: - return err; -} - -static int s3c24xx_spi_remove(struct platform_device *dev) -{ - struct s3c24xx_spi *hw = platform_get_drvdata(dev); - - platform_set_drvdata(dev, NULL); - - spi_unregister_master(hw->master); - - clk_disable(hw->clk); - clk_put(hw->clk); - - free_irq(hw->irq, hw); - iounmap(hw->regs); - - release_resource(hw->ioarea); - kfree(hw->ioarea); - - spi_master_put(hw->master); - return 0; -} - - -#ifdef CONFIG_PM - -static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg) -{ - struct s3c24xx_spi *hw = platform_get_drvdata(dev); - - clk_disable(hw->clk); - return 0; -} - -static int s3c24xx_spi_resume(struct platform_device *pdev) -{ - struct s3c24xx_spi *hw = platform_get_drvdata(dev); - - clk_enable(hw->clk); - return 0; -} - -#else -#define s3c24xx_spi_suspend NULL -#define s3c24xx_spi_resume NULL -#endif - -static struct platform_driver s3c24xx_spidrv = { - .probe = s3c24xx_spi_probe, - .remove = s3c24xx_spi_remove, - .suspend = s3c24xx_spi_suspend, - .resume = s3c24xx_spi_resume, - .driver = { - .name = "s3c2410-spi", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c24xx_spi_init(void) -{ - return platform_driver_register(&s3c24xx_spidrv); -} - -static void __exit s3c24xx_spi_exit(void) -{ - platform_driver_unregister(&s3c24xx_spidrv); -} - -module_init(s3c24xx_spi_init); -module_exit(s3c24xx_spi_exit); - -MODULE_DESCRIPTION("S3C24XX SPI Driver"); -MODULE_AUTHOR("Ben Dooks, "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/spi_s3c24xx_gpio.c b/trunk/drivers/spi/spi_s3c24xx_gpio.c deleted file mode 100644 index aacdceb8f44b..000000000000 --- a/trunk/drivers/spi/spi_s3c24xx_gpio.c +++ /dev/null @@ -1,188 +0,0 @@ -/* linux/drivers/spi/spi_s3c24xx_gpio.c - * - * Copyright (c) 2006 Ben Dooks - * Copyright (c) 2006 Simtec Electronics - * - * S3C24XX GPIO based SPI driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -struct s3c2410_spigpio { - struct spi_bitbang bitbang; - - struct s3c2410_spigpio_info *info; - struct platform_device *dev; -}; - -static inline struct s3c2410_spigpio *spidev_to_sg(struct spi_device *spi) -{ - return spi->controller_data; -} - -static inline void setsck(struct spi_device *dev, int on) -{ - struct s3c2410_spigpio *sg = spidev_to_sg(dev); - s3c2410_gpio_setpin(sg->info->pin_clk, on ? 1 : 0); -} - -static inline void setmosi(struct spi_device *dev, int on) -{ - struct s3c2410_spigpio *sg = spidev_to_sg(dev); - s3c2410_gpio_setpin(sg->info->pin_mosi, on ? 1 : 0); -} - -static inline u32 getmiso(struct spi_device *dev) -{ - struct s3c2410_spigpio *sg = spidev_to_sg(dev); - return s3c2410_gpio_getpin(sg->info->pin_miso) ? 1 : 0; -} - -#define spidelay(x) ndelay(x) - -#define EXPAND_BITBANG_TXRX -#include - - -static u32 s3c2410_spigpio_txrx_mode0(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits) -{ - return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits); -} - -static u32 s3c2410_spigpio_txrx_mode1(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits) -{ - return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits); -} - -static void s3c2410_spigpio_chipselect(struct spi_device *dev, int value) -{ - struct s3c2410_spigpio *sg = spidev_to_sg(dev); - - if (sg->info && sg->info->chip_select) - (sg->info->chip_select)(sg->info, value); -} - -static int s3c2410_spigpio_probe(struct platform_device *dev) -{ - struct spi_master *master; - struct s3c2410_spigpio *sp; - int ret; - int i; - - master = spi_alloc_master(&dev->dev, sizeof(struct s3c2410_spigpio)); - if (master == NULL) { - dev_err(&dev->dev, "failed to allocate spi master\n"); - ret = -ENOMEM; - goto err; - } - - sp = spi_master_get_devdata(master); - - platform_set_drvdata(dev, sp); - - /* copy in the plkatform data */ - sp->info = dev->dev.platform_data; - - /* setup spi bitbang adaptor */ - sp->bitbang.master = spi_master_get(master); - sp->bitbang.chipselect = s3c2410_spigpio_chipselect; - - sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0; - sp->bitbang.txrx_word[SPI_MODE_1] = s3c2410_spigpio_txrx_mode1; - - /* set state of spi pins */ - s3c2410_gpio_setpin(sp->info->pin_clk, 0); - s3c2410_gpio_setpin(sp->info->pin_mosi, 0); - - s3c2410_gpio_cfgpin(sp->info->pin_clk, S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(sp->info->pin_mosi, S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(sp->info->pin_miso, S3C2410_GPIO_INPUT); - - ret = spi_bitbang_start(&sp->bitbang); - if (ret) - goto err_no_bitbang; - - /* register the chips to go with the board */ - - for (i = 0; i < sp->info->board_size; i++) { - dev_info(&dev->dev, "registering %p: %s\n", - &sp->info->board_info[i], - sp->info->board_info[i].modalias); - - sp->info->board_info[i].controller_data = sp; - spi_new_device(master, sp->info->board_info + i); - } - - return 0; - - err_no_bitbang: - spi_master_put(sp->bitbang.master); - err: - return ret; - -} - -static int s3c2410_spigpio_remove(struct platform_device *dev) -{ - struct s3c2410_spigpio *sp = platform_get_drvdata(dev); - - spi_bitbang_stop(&sp->bitbang); - spi_master_put(sp->bitbang.master); - - return 0; -} - -/* all gpio should be held over suspend/resume, so we should - * not need to deal with this -*/ - -#define s3c2410_spigpio_suspend NULL -#define s3c2410_spigpio_resume NULL - - -static struct platform_driver s3c2410_spigpio_drv = { - .probe = s3c2410_spigpio_probe, - .remove = s3c2410_spigpio_remove, - .suspend = s3c2410_spigpio_suspend, - .resume = s3c2410_spigpio_resume, - .driver = { - .name = "s3c24xx-spi-gpio", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c2410_spigpio_init(void) -{ - return platform_driver_register(&s3c2410_spigpio_drv); -} - -static void __exit s3c2410_spigpio_exit(void) -{ - platform_driver_unregister(&s3c2410_spigpio_drv); -} - -module_init(s3c2410_spigpio_init); -module_exit(s3c2410_spigpio_exit); - -MODULE_DESCRIPTION("S3C24XX SPI Driver"); -MODULE_AUTHOR("Ben Dooks, "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/atm/speedtch.c b/trunk/drivers/usb/atm/speedtch.c index 956b7a1e8af9..7860c8a5800d 100644 --- a/trunk/drivers/usb/atm/speedtch.c +++ b/trunk/drivers/usb/atm/speedtch.c @@ -69,7 +69,7 @@ static const char speedtch_driver_name[] = "speedtch"; #define RESUBMIT_DELAY 1000 /* milliseconds */ #define DEFAULT_BULK_ALTSETTING 1 -#define DEFAULT_ISOC_ALTSETTING 3 +#define DEFAULT_ISOC_ALTSETTING 2 #define DEFAULT_DL_512_FIRST 0 #define DEFAULT_ENABLE_ISOC 0 #define DEFAULT_SW_BUFFERING 0 diff --git a/trunk/drivers/usb/atm/usbatm.c b/trunk/drivers/usb/atm/usbatm.c index 546249843b8e..c1211fc037d9 100644 --- a/trunk/drivers/usb/atm/usbatm.c +++ b/trunk/drivers/usb/atm/usbatm.c @@ -99,11 +99,11 @@ static const char usbatm_driver_name[] = "usbatm"; #define UDSL_MAX_RCV_URBS 16 #define UDSL_MAX_SND_URBS 16 -#define UDSL_MAX_BUF_SIZE 65536 +#define UDSL_MAX_BUF_SIZE 64 * 1024 /* bytes */ #define UDSL_DEFAULT_RCV_URBS 4 #define UDSL_DEFAULT_SND_URBS 4 -#define UDSL_DEFAULT_RCV_BUF_SIZE 3392 /* 64 * ATM_CELL_SIZE */ -#define UDSL_DEFAULT_SND_BUF_SIZE 3392 /* 64 * ATM_CELL_SIZE */ +#define UDSL_DEFAULT_RCV_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ +#define UDSL_DEFAULT_SND_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ #define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD) @@ -135,7 +135,7 @@ MODULE_PARM_DESC(rcv_buf_bytes, module_param(snd_buf_bytes, uint, S_IRUGO); MODULE_PARM_DESC(snd_buf_bytes, "Size of the buffers used for transmission, in bytes (range: 1-" - __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: " + __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: " __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")"); diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index e2e00ba4e1e6..fbd938d4ea58 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -1805,12 +1805,6 @@ int usb_add_hcd(struct usb_hcd *hcd, USB_SPEED_FULL; hcd->self.root_hub = rhdev; - /* wakeup flag init defaults to "everything works" for root hubs, - * but drivers can override it in reset() if needed, along with - * recording the overall controller's system wakeup capability. - */ - device_init_wakeup(&rhdev->dev, 1); - /* "reset" is misnamed; its role is now one-time init. the controller * should already have been reset (and boot firmware kicked off etc). */ @@ -1819,6 +1813,13 @@ int usb_add_hcd(struct usb_hcd *hcd, goto err_hcd_driver_setup; } + /* wakeup flag init is in transition; for now we can't rely on PCI to + * initialize these bits properly, so we let reset() override it. + * This init should _precede_ the reset() once PCI behaves. + */ + device_init_wakeup(&rhdev->dev, + device_can_wakeup(hcd->self.controller)); + /* NOTE: root hub and controller capabilities may not be the same */ if (device_can_wakeup(hcd->self.controller) && device_can_wakeup(&hcd->self.root_hub->dev)) diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 90b8d43c6b33..0c87f73f2933 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -1168,9 +1168,19 @@ static inline const char *plural(int n) static int choose_configuration(struct usb_device *udev) { int i; + u16 devstatus; + int bus_powered; int num_configs; struct usb_host_config *c, *best; + /* If this fails, assume the device is bus-powered */ + devstatus = 0; + usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); + le16_to_cpus(&devstatus); + bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0); + dev_dbg(&udev->dev, "device is %s-powered\n", + bus_powered ? "bus" : "self"); + best = NULL; c = udev->config; num_configs = udev->descriptor.bNumConfigurations; @@ -1187,19 +1197,6 @@ static int choose_configuration(struct usb_device *udev) * similar errors in their descriptors. If the next test * were allowed to execute, such configurations would always * be rejected and the devices would not work as expected. - * In the meantime, we run the risk of selecting a config - * that requires external power at a time when that power - * isn't available. It seems to be the lesser of two evils. - * - * Bugzilla #6448 reports a device that appears to crash - * when it receives a GET_DEVICE_STATUS request! We don't - * have any other way to tell whether a device is self-powered, - * but since we don't use that information anywhere but here, - * the call has been removed. - * - * Maybe the GET_DEVICE_STATUS call and the test below can - * be reinstated when device firmwares become more reliable. - * Don't hold your breath. */ #if 0 /* Rule out self-powered configs for a bus-powered device */ diff --git a/trunk/drivers/usb/host/ohci-hcd.c b/trunk/drivers/usb/host/ohci-hcd.c index 73f5a379d9b3..544f7589912f 100644 --- a/trunk/drivers/usb/host/ohci-hcd.c +++ b/trunk/drivers/usb/host/ohci-hcd.c @@ -863,7 +863,7 @@ static int ohci_restart (struct ohci_hcd *ohci) i = ohci->num_ports; while (i--) ohci_writel (ohci, RH_PS_PSS, - &ohci->regs->roothub.portstatus [i]); + &ohci->regs->roothub.portstatus [temp]); ohci_dbg (ohci, "restart complete\n"); } return 0; diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index 435273e7c85c..f419bd82ab7f 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -1557,9 +1557,6 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_HP 0x03f0 #define USB_DEVICE_ID_HP_USBHUB_KB 0x020c -#define USB_VENDOR_ID_IBM 0x04b3 -#define USB_DEVICE_ID_IBM_USBHUB_KB 0x3005 - #define USB_VENDOR_ID_CREATIVELABS 0x062a #define USB_DEVICE_ID_CREATIVELABS_SILVERCREST 0x0201 @@ -1684,7 +1681,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVELABS_SILVERCREST, HID_QUIRK_NOGET }, { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_USBHUB_KB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET }, diff --git a/trunk/drivers/usb/input/hiddev.c b/trunk/drivers/usb/input/hiddev.c index c4670e1d4654..6dd666696178 100644 --- a/trunk/drivers/usb/input/hiddev.c +++ b/trunk/drivers/usb/input/hiddev.c @@ -317,7 +317,6 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun } schedule(); - set_current_state(TASK_INTERRUPTIBLE); } set_current_state(TASK_RUNNING); diff --git a/trunk/drivers/usb/misc/emi26.c b/trunk/drivers/usb/misc/emi26.c index 1fd9cb85f4ca..3824df33094e 100644 --- a/trunk/drivers/usb/misc/emi26.c +++ b/trunk/drivers/usb/misc/emi26.c @@ -15,7 +15,6 @@ #include #include #include -#include #define MAX_INTEL_HEX_RECORD_LENGTH 16 typedef struct _INTEL_HEX_RECORD @@ -115,7 +114,6 @@ static int emi26_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); - msleep(250); /* let device settle */ /* 2. We upload the FPGA firmware into the EMI * Note: collect up to 1023 (yes!) bytes and send them with @@ -152,7 +150,6 @@ static int emi26_load_firmware (struct usb_device *dev) goto wraperr; } } - msleep(250); /* let device settle */ /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); @@ -195,7 +192,6 @@ static int emi26_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __FUNCTION__, err); goto wraperr; } - msleep(250); /* let device settle */ /* return 1 to fail the driver inialization * and give real driver change to load */ diff --git a/trunk/drivers/usb/misc/emi62.c b/trunk/drivers/usb/misc/emi62.c index fe351371f274..52fea2e08db8 100644 --- a/trunk/drivers/usb/misc/emi62.c +++ b/trunk/drivers/usb/misc/emi62.c @@ -15,7 +15,6 @@ #include #include #include -#include #define MAX_INTEL_HEX_RECORD_LENGTH 16 typedef struct _INTEL_HEX_RECORD @@ -124,7 +123,6 @@ static int emi62_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi62_set_reset(dev,0); - msleep(250); /* let device settle */ /* 2. We upload the FPGA firmware into the EMI * Note: collect up to 1023 (yes!) bytes and send them with @@ -168,7 +166,6 @@ static int emi62_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __FUNCTION__, err); goto wraperr; } - msleep(250); /* let device settle */ /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ @@ -231,7 +228,6 @@ static int emi62_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __FUNCTION__, err); goto wraperr; } - msleep(250); /* let device settle */ kfree(buf); diff --git a/trunk/drivers/usb/net/pegasus.c b/trunk/drivers/usb/net/pegasus.c index 7683926a1b6f..2deb4c01539e 100644 --- a/trunk/drivers/usb/net/pegasus.c +++ b/trunk/drivers/usb/net/pegasus.c @@ -318,8 +318,6 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) set_register(pegasus, PhyCtrl, (indx | PHY_READ)); for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, PhyCtrl, 1, data); - if (ret == -ESHUTDOWN) - goto fail; if (data[0] & PHY_DONE) break; } @@ -328,7 +326,6 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) *regd = le16_to_cpu(regdi); return ret; } -fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); @@ -357,15 +354,12 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, PhyCtrl, 1, data); - if (ret == -ESHUTDOWN) - goto fail; if (data[0] & PHY_DONE) break; } if (i < REG_TIMEOUT) return ret; -fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); return -ETIMEDOUT; @@ -393,8 +387,6 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) ret = get_registers(pegasus, EpromCtrl, 1, &tmp); if (tmp & EPROM_DONE) break; - if (ret == -ESHUTDOWN) - goto fail; } if (i < REG_TIMEOUT) { ret = get_registers(pegasus, EpromData, 2, &retdatai); @@ -402,7 +394,6 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) return ret; } -fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); return -ETIMEDOUT; @@ -442,15 +433,12 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, EpromCtrl, 1, &tmp); - if (ret == -ESHUTDOWN) - goto fail; if (tmp & EPROM_DONE) break; } disable_eprom_write(pegasus); if (i < REG_TIMEOUT) return ret; -fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); return -ETIMEDOUT; @@ -1390,8 +1378,9 @@ static int pegasus_suspend (struct usb_interface *intf, pm_message_t message) struct pegasus *pegasus = usb_get_intfdata(intf); netif_device_detach (pegasus->net); - cancel_delayed_work(&pegasus->carrier_check); if (netif_running(pegasus->net)) { + cancel_delayed_work(&pegasus->carrier_check); + usb_kill_urb(pegasus->rx_urb); usb_kill_urb(pegasus->intr_urb); } @@ -1411,9 +1400,10 @@ static int pegasus_resume (struct usb_interface *intf) pegasus->intr_urb->status = 0; pegasus->intr_urb->actual_length = 0; intr_callback(pegasus->intr_urb, NULL); + + queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, + CARRIER_CHECK_DELAY); } - queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, - CARRIER_CHECK_DELAY); return 0; } diff --git a/trunk/drivers/usb/serial/Kconfig b/trunk/drivers/usb/serial/Kconfig index 5c60be521561..f96b73f54bf1 100644 --- a/trunk/drivers/usb/serial/Kconfig +++ b/trunk/drivers/usb/serial/Kconfig @@ -71,16 +71,6 @@ config USB_SERIAL_ANYDATA To compile this driver as a module, choose M here: the module will be called anydata. -config USB_SERIAL_ARK3116 - tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL - help - Say Y here if you want to use a ARK Micro 3116 USB to Serial - device. - - To compile this driver as a module, choose M here: the - module will be called ark3116 - config USB_SERIAL_BELKIN tristate "USB Belkin and Peracom Single Port Serial Driver" depends on USB_SERIAL diff --git a/trunk/drivers/usb/serial/Makefile b/trunk/drivers/usb/serial/Makefile index 5a0960fc9d3e..93c21245b1af 100644 --- a/trunk/drivers/usb/serial/Makefile +++ b/trunk/drivers/usb/serial/Makefile @@ -13,7 +13,6 @@ usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o obj-$(CONFIG_USB_SERIAL_ANYDATA) += anydata.o -obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o diff --git a/trunk/drivers/usb/serial/airprime.c b/trunk/drivers/usb/serial/airprime.c index 694b205f9b73..dbf1f063098c 100644 --- a/trunk/drivers/usb/serial/airprime.c +++ b/trunk/drivers/usb/serial/airprime.c @@ -18,7 +18,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0xf3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */ { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ - { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/trunk/drivers/usb/serial/ark3116.c b/trunk/drivers/usb/serial/ark3116.c deleted file mode 100644 index 8dec796222a0..000000000000 --- a/trunk/drivers/usb/serial/ark3116.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * ark3116 - * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547, - * productid=0x0232) (used in a datacable called KQ-U8A) - * - * - based on code by krisfx -> thanks !! - * (see http://www.linuxquestions.org/questions/showthread.php?p=2184457#post2184457) - * - * - based on logs created by usbsnoopy - * - * Author : Simon Schulz [ark3116_driverauctionant.de] - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include "usb-serial.h" - - -static int debug; - -static struct usb_device_id id_table [] = { - { USB_DEVICE(0x6547, 0x0232) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -struct ark3116_private { - spinlock_t lock; - u8 termios_initialized; -}; - -static inline void ARK3116_SND(struct usb_serial *serial, int seq, - __u8 request, __u8 requesttype, - __u16 value, __u16 index) -{ - int result; - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev,0), - request, requesttype, value, index, - NULL,0x00, 1000); - dbg("%03d > ok",seq); -} - -static inline void ARK3116_RCV(struct usb_serial *serial, int seq, - __u8 request, __u8 requesttype, - __u16 value, __u16 index, __u8 expected, - char *buf) -{ - int result; - result = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev,0), - request, requesttype, value, index, - buf, 0x0000001, 1000); - if (result) - dbg("%03d < %d bytes [0x%02X]",seq, result, buf[0]); - else - dbg("%03d < 0 bytes", seq); -} - - -static inline void ARK3116_RCV_QUIET(struct usb_serial *serial, - __u8 request, __u8 requesttype, - __u16 value, __u16 index, char *buf) -{ - usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev,0), - request, requesttype, value, index, - buf, 0x0000001, 1000); -} - - -static int ark3116_attach(struct usb_serial *serial) -{ - char *buf; - struct ark3116_private *priv; - int i; - - for (i = 0; i < serial->num_ports; ++i) { - priv = kmalloc (sizeof (struct ark3116_private), GFP_KERNEL); - if (!priv) - goto cleanup; - memset (priv, 0x00, sizeof (struct ark3116_private)); - spin_lock_init(&priv->lock); - - usb_set_serial_port_data(serial->port[i], priv); - } - - buf = kmalloc(1, GFP_KERNEL); - if (!buf) { - dbg("error kmalloc -> out of mem ?"); - goto cleanup; - } - - /* 3 */ - ARK3116_SND(serial, 3,0xFE,0x40,0x0008,0x0002); - ARK3116_SND(serial, 4,0xFE,0x40,0x0008,0x0001); - ARK3116_SND(serial, 5,0xFE,0x40,0x0000,0x0008); - ARK3116_SND(serial, 6,0xFE,0x40,0x0000,0x000B); - - /* <-- seq7 */ - ARK3116_RCV(serial, 7,0xFE,0xC0,0x0000,0x0003, 0x00, buf); - ARK3116_SND(serial, 8,0xFE,0x40,0x0080,0x0003); - ARK3116_SND(serial, 9,0xFE,0x40,0x001A,0x0000); - ARK3116_SND(serial,10,0xFE,0x40,0x0000,0x0001); - ARK3116_SND(serial,11,0xFE,0x40,0x0000,0x0003); - - /* <-- seq12 */ - ARK3116_RCV(serial,12,0xFE,0xC0,0x0000,0x0004, 0x00, buf); - ARK3116_SND(serial,13,0xFE,0x40,0x0000,0x0004); - - /* 14 */ - ARK3116_RCV(serial,14,0xFE,0xC0,0x0000,0x0004, 0x00, buf); - ARK3116_SND(serial,15,0xFE,0x40,0x0000,0x0004); - - /* 16 */ - ARK3116_RCV(serial,16,0xFE,0xC0,0x0000,0x0004, 0x00, buf); - /* --> seq17 */ - ARK3116_SND(serial,17,0xFE,0x40,0x0001,0x0004); - - /* <-- seq18 */ - ARK3116_RCV(serial,18,0xFE,0xC0,0x0000,0x0004, 0x01, buf); - - /* --> seq19 */ - ARK3116_SND(serial,19,0xFE,0x40,0x0003,0x0004); - - - /* <-- seq20 */ - /* seems like serial port status info (RTS, CTS,...) */ - /* returns modem control line status ?! */ - ARK3116_RCV(serial,20,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); - - /* set 9600 baud & do some init ?! */ - ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); - ARK3116_SND(serial,148,0xFE,0x40,0x0038,0x0000); - ARK3116_SND(serial,149,0xFE,0x40,0x0001,0x0001); - ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); - ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); - ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); - ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); - ARK3116_SND(serial,154,0xFE,0x40,0x0003,0x0003); - - kfree(buf); - return(0); - -cleanup: - for (--i; i>=0; --i) - usb_set_serial_port_data(serial->port[i], NULL); - return -ENOMEM; -} - -static void ark3116_set_termios(struct usb_serial_port *port, - struct termios *old_termios) -{ - struct usb_serial *serial = port->serial; - struct ark3116_private *priv = usb_get_serial_port_data(port); - unsigned int cflag = port->tty->termios->c_cflag; - unsigned long flags; - int baud; - int ark3116_baud; - char *buf; - char config; - - config = 0; - - dbg("%s - port %d", __FUNCTION__, port->number); - - if ((!port->tty) || (!port->tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); - return; - } - - spin_lock_irqsave(&priv->lock, flags); - if (!priv->termios_initialized) { - *(port->tty->termios) = tty_std_termios; - port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - priv->termios_initialized = 1; - } - spin_unlock_irqrestore(&priv->lock, flags); - - cflag = port->tty->termios->c_cflag; - - /* check that they really want us to change something: */ - if (old_termios) { - if ((cflag == old_termios->c_cflag) && - (RELEVANT_IFLAG(port->tty->termios->c_iflag) == - RELEVANT_IFLAG(old_termios->c_iflag))) { - dbg("%s - nothing to change...", __FUNCTION__); - return; - } - } - - buf = kmalloc(1, GFP_KERNEL); - if (!buf) { - dbg("error kmalloc"); - return; - } - - /* set data bit count (8/7/6/5) */ - if (cflag & CSIZE){ - switch (cflag & CSIZE){ - case CS5: - config |= 0x00; - dbg("setting CS5"); - break; - case CS6: - config |= 0x01; - dbg("setting CS6"); - break; - case CS7: - config |= 0x02; - dbg("setting CS7"); - break; - default: - err ("CSIZE was set but not CS5-CS8, using CS8!"); - case CS8: - config |= 0x03; - dbg("setting CS8"); - break; - } - } - - /* set parity (NONE,EVEN,ODD) */ - if (cflag & PARENB){ - if (cflag & PARODD) { - config |= 0x08; - dbg("setting parity to ODD"); - } else { - config |= 0x18; - dbg("setting parity to EVEN"); - } - } else { - dbg("setting parity to NONE"); - } - - /* SET STOPBIT (1/2) */ - if (cflag & CSTOPB) { - config |= 0x04; - dbg ("setting 2 stop bits"); - } else { - dbg ("setting 1 stop bit"); - } - - - /* set baudrate: */ - baud = 0; - switch (cflag & CBAUD){ - case B0: - err("can't set 0baud, using 9600 instead"); - break; - case B75: baud = 75; break; - case B150: baud = 150; break; - case B300: baud = 300; break; - case B600: baud = 600; break; - case B1200: baud = 1200; break; - case B1800: baud = 1800; break; - case B2400: baud = 2400; break; - case B4800: baud = 4800; break; - case B9600: baud = 9600; break; - case B19200: baud = 19200; break; - case B38400: baud = 38400; break; - case B57600: baud = 57600; break; - case B115200: baud = 115200; break; - case B230400: baud = 230400; break; - case B460800: baud = 460800; break; - default: - dbg("does not support the baudrate requested (fix it)"); - break; - } - - /* set 9600 as default (if given baudrate is invalid for example) */ - if (baud == 0) - baud = 9600; - - /* - * found by try'n'error, be careful, maybe there are other options - * for multiplicator etc! - */ - if (baud == 460800) - /* strange, for 460800 the formula is wrong - * (dont use round(), then 9600baud is wrong) */ - ark3116_baud = 7; - else - ark3116_baud = 3000000 / baud; - - /* ? */ - ARK3116_RCV(serial,0,0xFE,0xC0,0x0000,0x0003, 0x03, buf); - /* offset = buf[0]; */ - /* offset = 0x03; */ - /* dbg("using 0x%04X as target for 0x0003:",0x0080+offset); */ - - - /* set baudrate */ - dbg("setting baudrate to %d (->reg=%d)",baud,ark3116_baud); - ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); - ARK3116_SND(serial,148,0xFE,0x40,(ark3116_baud & 0x00FF) ,0x0000); - ARK3116_SND(serial,149,0xFE,0x40,(ark3116_baud & 0xFF00)>>8,0x0001); - ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); - - /* ? */ - ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); - ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); - - /* set data bit count, stop bit count & parity: */ - dbg("updating bit count, stop bit or parity (cfg=0x%02X)", config); - ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); - ARK3116_SND(serial,154,0xFE,0x40,config,0x0003); - - if (cflag & CRTSCTS) - dbg("CRTSCTS not supported by chipset ?!"); - - /* TEST ARK3116_SND(154,0xFE,0x40,0xFFFF, 0x0006); */ - - kfree(buf); - return; -} - -static int ark3116_open(struct usb_serial_port *port, struct file *filp) -{ - struct termios tmp_termios; - struct usb_serial *serial = port->serial; - char *buf; - int result = 0; - - dbg("%s - port %d", __FUNCTION__, port->number); - - buf = kmalloc(1, GFP_KERNEL); - if (!buf) { - dbg("error kmalloc -> out of mem ?"); - return -ENOMEM; - } - - result = usb_serial_generic_open(port, filp); - if (result) - return result; - - /* open */ - ARK3116_RCV(serial,111,0xFE,0xC0,0x0000,0x0003, 0x02, buf); - - ARK3116_SND(serial,112,0xFE,0x40,0x0082,0x0003); - ARK3116_SND(serial,113,0xFE,0x40,0x001A,0x0000); - ARK3116_SND(serial,114,0xFE,0x40,0x0000,0x0001); - ARK3116_SND(serial,115,0xFE,0x40,0x0002,0x0003); - - ARK3116_RCV(serial,116,0xFE,0xC0,0x0000,0x0004, 0x03, buf); - ARK3116_SND(serial,117,0xFE,0x40,0x0002,0x0004); - - ARK3116_RCV(serial,118,0xFE,0xC0,0x0000,0x0004, 0x02, buf); - ARK3116_SND(serial,119,0xFE,0x40,0x0000,0x0004); - - ARK3116_RCV(serial,120,0xFE,0xC0,0x0000,0x0004, 0x00, buf); - - ARK3116_SND(serial,121,0xFE,0x40,0x0001,0x0004); - - ARK3116_RCV(serial,122,0xFE,0xC0,0x0000,0x0004, 0x01, buf); - - ARK3116_SND(serial,123,0xFE,0x40,0x0003,0x0004); - - /* returns different values (control lines ?!) */ - ARK3116_RCV(serial,124,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); - - /* initialise termios: */ - if (port->tty) - ark3116_set_termios(port, &tmp_termios); - - kfree(buf); - - return result; - -} - -static int ark3116_ioctl(struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg) -{ - dbg("ioctl not supported yet..."); - return -ENOIOCTLCMD; -} - -static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file) -{ - struct usb_serial *serial = port->serial; - char *buf; - char temp; - - /* seems like serial port status info (RTS, CTS,...) is stored - * in reg(?) 0x0006 - * pcb connection point 11 = GND -> sets bit4 of response - * pcb connection point 7 = GND -> sets bit6 of response - */ - - buf = kmalloc(1, GFP_KERNEL); - if (!buf) { - dbg("error kmalloc"); - return -ENOMEM; - } - - /* read register: */ - ARK3116_RCV_QUIET(serial,0xFE,0xC0,0x0000,0x0006,buf); - temp = buf[0]; - kfree(buf); - - /* i do not really know if bit4=CTS and bit6=DSR... was just a - * quick guess !! - */ - return (temp & (1<<4) ? TIOCM_CTS : 0) | - (temp & (1<<6) ? TIOCM_DSR : 0); -} - -static struct usb_driver ark3116_driver = { - .name = "ark3116", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver ark3116_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ark3116", - }, - .id_table = id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, - .num_ports = 1, - .attach = ark3116_attach, - .set_termios = ark3116_set_termios, - .ioctl = ark3116_ioctl, - .tiocmget = ark3116_tiocmget, - .open = ark3116_open, -}; - -static int __init ark3116_init(void) -{ - int retval; - - retval = usb_serial_register(&ark3116_device); - if (retval) - return retval; - retval = usb_register(&ark3116_driver); - if (retval) - usb_serial_deregister(&ark3116_device); - return retval; -} - -static void __exit ark3116_exit(void) -{ - usb_deregister(&ark3116_driver); - usb_serial_deregister(&ark3116_device); -} - -module_init(ark3116_init); -module_exit(ark3116_exit); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 986d7622273d..82151207d814 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -307,7 +307,6 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { static struct usb_device_id id_table_combined [] = { - { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, @@ -499,7 +498,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index d69a917e768f..2c55a5ea9c99 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -32,10 +32,6 @@ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ -/* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ -#define FTDI_ACTZWAVE_PID 0xF2D0 - - /* www.irtrans.de device */ #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ @@ -430,11 +426,6 @@ #define PAPOUCH_VID 0x5050 /* Vendor ID */ #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ -/* - * ACG Identification Technologies GmbH products (http://www.acg.de/). - * Submitted by anton -at- goto10 -dot- org. - */ -#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ diff --git a/trunk/drivers/usb/serial/generic.c b/trunk/drivers/usb/serial/generic.c index c62cc2876519..476cda107f4f 100644 --- a/trunk/drivers/usb/serial/generic.c +++ b/trunk/drivers/usb/serial/generic.c @@ -138,7 +138,6 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) return result; } -EXPORT_SYMBOL_GPL(usb_serial_generic_open); static void generic_cleanup (struct usb_serial_port *port) { diff --git a/trunk/drivers/usb/serial/omninet.c b/trunk/drivers/usb/serial/omninet.c index 238033a87092..4d40704dea2c 100644 --- a/trunk/drivers/usb/serial/omninet.c +++ b/trunk/drivers/usb/serial/omninet.c @@ -257,14 +257,14 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf return (0); } - spin_lock(&wport->lock); - if (wport->write_urb_busy) { - spin_unlock(&wport->lock); + spin_lock(&port->lock); + if (port->write_urb_busy) { + spin_unlock(&port->lock); dbg("%s - already writing", __FUNCTION__); return 0; } - wport->write_urb_busy = 1; - spin_unlock(&wport->lock); + port->write_urb_busy = 1; + spin_unlock(&port->lock); count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; @@ -283,7 +283,7 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf wport->write_urb->dev = serial->dev; result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); if (result) { - wport->write_urb_busy = 0; + port->write_urb_busy = 0; err("%s - failed submitting write urb, error %d", __FUNCTION__, result); } else result = count; diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 9c36f0ece20f..071f86a59c08 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -189,15 +189,11 @@ static int serial_open (struct tty_struct *tty, struct file * filp) portNumber = tty->index - serial->minor; port = serial->port[portNumber]; - if (!port) { - retval = -ENODEV; - goto bailout_kref_put; - } + if (!port) + return -ENODEV; - if (mutex_lock_interruptible(&port->mutex)) { - retval = -ERESTARTSYS; - goto bailout_kref_put; - } + if (mutex_lock_interruptible(&port->mutex)) + return -ERESTARTSYS; ++port->open_count; @@ -213,7 +209,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) * safe because we are called with BKL held */ if (!try_module_get(serial->type->driver.owner)) { retval = -ENODEV; - goto bailout_mutex_unlock; + goto bailout_kref_put; } /* only call the device specific open if this @@ -228,11 +224,10 @@ static int serial_open (struct tty_struct *tty, struct file * filp) bailout_module_put: module_put(serial->type->driver.owner); -bailout_mutex_unlock: - port->open_count = 0; - mutex_unlock(&port->mutex); bailout_kref_put: kref_put(&serial->kref, destroy_serial); + port->open_count = 0; + mutex_unlock(&port->mutex); return retval; } diff --git a/trunk/drivers/video/backlight/backlight.c b/trunk/drivers/video/backlight/backlight.c index 27597c576eff..334b1db1bd7c 100644 --- a/trunk/drivers/video/backlight/backlight.c +++ b/trunk/drivers/video/backlight/backlight.c @@ -29,15 +29,12 @@ static ssize_t backlight_show_power(struct class_device *cdev, char *buf) static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count) { - int rc = -ENXIO; + int rc = -ENXIO, power; char *endp; struct backlight_device *bd = to_backlight_device(cdev); - int power = simple_strtoul(buf, &endp, 0); - size_t size = endp - buf; - if (*endp && isspace(*endp)) - size++; - if (size != count) + power = simple_strtoul(buf, &endp, 0); + if (*endp && !isspace(*endp)) return -EINVAL; down(&bd->sem); @@ -68,15 +65,12 @@ static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count) { - int rc = -ENXIO; + int rc = -ENXIO, brightness; char *endp; struct backlight_device *bd = to_backlight_device(cdev); - int brightness = simple_strtoul(buf, &endp, 0); - size_t size = endp - buf; - if (*endp && isspace(*endp)) - size++; - if (size != count) + brightness = simple_strtoul(buf, &endp, 0); + if (*endp && !isspace(*endp)) return -EINVAL; down(&bd->sem); diff --git a/trunk/drivers/video/backlight/lcd.c b/trunk/drivers/video/backlight/lcd.c index bc8ab005a3fb..86908a60c630 100644 --- a/trunk/drivers/video/backlight/lcd.c +++ b/trunk/drivers/video/backlight/lcd.c @@ -31,15 +31,12 @@ static ssize_t lcd_show_power(struct class_device *cdev, char *buf) static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_t count) { - int rc = -ENXIO; + int rc, power; char *endp; struct lcd_device *ld = to_lcd_device(cdev); - int power = simple_strtoul(buf, &endp, 0); - size_t size = endp - buf; - if (*endp && isspace(*endp)) - size++; - if (size != count) + power = simple_strtoul(buf, &endp, 0); + if (*endp && !isspace(*endp)) return -EINVAL; down(&ld->sem); @@ -47,7 +44,8 @@ static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_ pr_debug("lcd: set power to %d\n", power); ld->props->set_power(ld, power); rc = count; - } + } else + rc = -ENXIO; up(&ld->sem); return rc; @@ -55,12 +53,14 @@ static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_ static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf) { - int rc = -ENXIO; + int rc; struct lcd_device *ld = to_lcd_device(cdev); down(&ld->sem); if (likely(ld->props && ld->props->get_contrast)) rc = sprintf(buf, "%d\n", ld->props->get_contrast(ld)); + else + rc = -ENXIO; up(&ld->sem); return rc; @@ -68,15 +68,12 @@ static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf) static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, size_t count) { - int rc = -ENXIO; + int rc, contrast; char *endp; struct lcd_device *ld = to_lcd_device(cdev); - int contrast = simple_strtoul(buf, &endp, 0); - size_t size = endp - buf; - if (*endp && isspace(*endp)) - size++; - if (size != count) + contrast = simple_strtoul(buf, &endp, 0); + if (*endp && !isspace(*endp)) return -EINVAL; down(&ld->sem); @@ -84,7 +81,8 @@ static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, si pr_debug("lcd: set contrast to %d\n", contrast); ld->props->set_contrast(ld, contrast); rc = count; - } + } else + rc = -ENXIO; up(&ld->sem); return rc; @@ -92,12 +90,14 @@ static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, si static ssize_t lcd_show_max_contrast(struct class_device *cdev, char *buf) { - int rc = -ENXIO; + int rc; struct lcd_device *ld = to_lcd_device(cdev); down(&ld->sem); if (likely(ld->props)) rc = sprintf(buf, "%d\n", ld->props->max_contrast); + else + rc = -ENXIO; up(&ld->sem); return rc; diff --git a/trunk/drivers/video/i810/i810_main.c b/trunk/drivers/video/i810/i810_main.c index 44aa2ffff973..788297e9d59e 100644 --- a/trunk/drivers/video/i810/i810_main.c +++ b/trunk/drivers/video/i810/i810_main.c @@ -76,8 +76,8 @@ * * Experiment with v_offset to find out which works best for you. */ -static u32 v_offset_default __devinitdata; /* For 32 MiB Aper size, 8 should be the default */ -static u32 voffset __devinitdata; +static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */ +static u32 voffset __initdata = 0; static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor); static int __devinit i810fb_init_pci (struct pci_dev *dev, diff --git a/trunk/drivers/video/logo/Makefile b/trunk/drivers/video/logo/Makefile index b985dfad6c63..4ef5cd19609d 100644 --- a/trunk/drivers/video/logo/Makefile +++ b/trunk/drivers/video/logo/Makefile @@ -34,7 +34,7 @@ extra-y += $(call logo-cfiles,_clut224,ppm) extra-y += $(call logo-cfiles,_gray256,pgm) # Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..." -quiet_cmd_logo = LOGO $@ +quiet_cmd_logo = LOGO $@ cmd_logo = scripts/pnmtologo \ -t $(patsubst $*_%,%,$(notdir $(basename $<))) \ -n $(notdir $(basename $<)) -o $@ $< diff --git a/trunk/drivers/video/matrox/g450_pll.c b/trunk/drivers/video/matrox/g450_pll.c index 440272ad10e7..8073a73f6f35 100644 --- a/trunk/drivers/video/matrox/g450_pll.c +++ b/trunk/drivers/video/matrox/g450_pll.c @@ -316,24 +316,14 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, case M_PIXEL_PLL_B: case M_PIXEL_PLL_C: { - u_int8_t tmp, xpwrctrl; + u_int8_t tmp; unsigned long flags; matroxfb_DAC_lock_irqsave(flags); - - xpwrctrl = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL); - matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN); - mga_outb(M_SEQ_INDEX, M_SEQ1); - mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF); tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL); - tmp |= M1064_XPIXCLKCTRL_DIS; if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) { - tmp |= M1064_XPIXCLKCTRL_PLL_UP; + matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp | M1064_XPIXCLKCTRL_PLL_UP); } - matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp); - matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0); - matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl); - matroxfb_DAC_unlock_irqrestore(flags); } { @@ -428,15 +418,6 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, frequency to higher - with <= lowest wins, while with < highest one wins */ if (delta <= deltaarray[idx-1]) { - /* all else being equal except VCO, - * choose VCO not near (within 1/16th or so) VCOmin - * (freqs near VCOmin aren't as stable) - */ - if (delta == deltaarray[idx-1] - && vco != g450_mnp2vco(PMINFO mnparray[idx-1]) - && vco < (pi->vcomin * 17 / 16)) { - break; - } mnparray[idx] = mnparray[idx-1]; deltaarray[idx] = deltaarray[idx-1]; } else { diff --git a/trunk/drivers/video/matrox/matroxfb_DAC1064.h b/trunk/drivers/video/matrox/matroxfb_DAC1064.h index 56513a5d220b..2e7238aa2432 100644 --- a/trunk/drivers/video/matrox/matroxfb_DAC1064.h +++ b/trunk/drivers/video/matrox/matroxfb_DAC1064.h @@ -40,7 +40,6 @@ void DAC1064_global_restore(WPMINFO2); #define M1064_XCURCOL1RED 0x0C #define M1064_XCURCOL1GREEN 0x0D #define M1064_XCURCOL1BLUE 0x0E -#define M1064_XDVICLKCTRL 0x0F #define M1064_XCURCOL2RED 0x10 #define M1064_XCURCOL2GREEN 0x11 #define M1064_XCURCOL2BLUE 0x12 @@ -145,7 +144,6 @@ void DAC1064_global_restore(WPMINFO2); #define M1064_XVIDPLLN 0x8F #define M1064_XPWRCTRL 0xA0 -#define M1064_XPWRCTRL_PANELPDN 0x04 #define M1064_XPANMODE 0xA2 diff --git a/trunk/drivers/video/matrox/matroxfb_base.h b/trunk/drivers/video/matrox/matroxfb_base.h index b71737178d0d..3a3e1804c56a 100644 --- a/trunk/drivers/video/matrox/matroxfb_base.h +++ b/trunk/drivers/video/matrox/matroxfb_base.h @@ -672,8 +672,6 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv); #define M_SEQ_INDEX 0x1FC4 #define M_SEQ_DATA 0x1FC5 -#define M_SEQ1 0x01 -#define M_SEQ1_SCROFF 0x20 #define M_MISC_REG_READ 0x1FCC diff --git a/trunk/fs/9p/fcall.c b/trunk/fs/9p/fcall.c index 6f2617820a4e..71742ba150c4 100644 --- a/trunk/fs/9p/fcall.c +++ b/trunk/fs/9p/fcall.c @@ -98,20 +98,23 @@ v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err) { - int fid, id; + int fid; struct v9fs_session_info *v9ses; - id = 0; - fid = tc->params.tclunk.fid; - if (rc) - id = rc->id; + if (err) + return; + fid = tc->params.tclunk.fid; kfree(tc); - kfree(rc); - if (id == RCLUNK) { - v9ses = a; + + if (!rc) + return; + + v9ses = a; + if (rc->id == RCLUNK) v9fs_put_idpool(fid, &v9ses->fidpool); - } + + kfree(rc); } /** diff --git a/trunk/fs/9p/mux.c b/trunk/fs/9p/mux.c index f4407eb276c7..3e5b124a7212 100644 --- a/trunk/fs/9p/mux.c +++ b/trunk/fs/9p/mux.c @@ -50,23 +50,15 @@ enum { Wpending = 8, /* can write */ }; -enum { - None, - Flushing, - Flushed, -}; - struct v9fs_mux_poll_task; struct v9fs_req { - spinlock_t lock; int tag; struct v9fs_fcall *tcall; struct v9fs_fcall *rcall; int err; v9fs_mux_req_callback cb; void *cba; - int flush; struct list_head req_list; }; @@ -104,8 +96,8 @@ struct v9fs_mux_poll_task { struct v9fs_mux_rpc { struct v9fs_mux_data *m; + struct v9fs_req *req; int err; - struct v9fs_fcall *tcall; struct v9fs_fcall *rcall; wait_queue_head_t wqueue; }; @@ -532,9 +524,10 @@ static void v9fs_write_work(void *a) static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) { - int ecode; + int ecode, tag; struct v9fs_str *ename; + tag = req->tag; if (!req->err && req->rcall->id == RERROR) { ecode = req->rcall->params.rerror.errno; ename = &req->rcall->params.rerror.error; @@ -560,6 +553,23 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) if (!req->err) req->err = -EIO; } + + if (req->err == ERREQFLUSH) + return; + + if (req->cb) { + dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n", + req->tcall, req->rcall); + + (*req->cb) (req->cba, req->tcall, req->rcall, req->err); + req->cb = NULL; + } else + kfree(req->rcall); + + v9fs_mux_put_tag(m, tag); + + wake_up(&m->equeue); + kfree(req); } /** @@ -659,26 +669,17 @@ static void v9fs_read_work(void *a) list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) { if (rreq->tag == rcall->tag) { req = rreq; - if (req->flush != Flushing) - list_del(&req->req_list); + req->rcall = rcall; + list_del(&req->req_list); + spin_unlock(&m->lock); + process_request(m, req); break; } - } - spin_unlock(&m->lock); - - if (req) { - req->rcall = rcall; - process_request(m, req); - if (req->flush != Flushing) { - if (req->cb) - (*req->cb) (req, req->cba); - else - kfree(req->rcall); + } - wake_up(&m->equeue); - } - } else { + if (!req) { + spin_unlock(&m->lock); if (err >= 0 && rcall->id != RFLUSH) dprintk(DEBUG_ERROR, "unexpected response mux %p id %d tag %d\n", @@ -745,6 +746,7 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m, return ERR_PTR(-ENOMEM); v9fs_set_tag(tc, n); + if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { char buf[150]; @@ -752,14 +754,12 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m, printk(KERN_NOTICE "<<< %p %s\n", m, buf); } - spin_lock_init(&req->lock); req->tag = n; req->tcall = tc; req->rcall = NULL; req->err = 0; req->cb = cb; req->cba = cba; - req->flush = None; spin_lock(&m->lock); list_add_tail(&req->req_list, &m->unsent_req_list); @@ -776,108 +776,72 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m, return req; } -static void v9fs_mux_free_request(struct v9fs_mux_data *m, struct v9fs_req *req) -{ - v9fs_mux_put_tag(m, req->tag); - kfree(req); -} - -static void v9fs_mux_flush_cb(struct v9fs_req *freq, void *a) +static void v9fs_mux_flush_cb(void *a, struct v9fs_fcall *tc, + struct v9fs_fcall *rc, int err) { v9fs_mux_req_callback cb; int tag; struct v9fs_mux_data *m; - struct v9fs_req *req, *rreq, *rptr; + struct v9fs_req *req, *rptr; m = a; - dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, - freq->tcall, freq->rcall, freq->err, - freq->tcall->params.tflush.oldtag); + dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, tc, + rc, err, tc->params.tflush.oldtag); spin_lock(&m->lock); cb = NULL; - tag = freq->tcall->params.tflush.oldtag; - req = NULL; - list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) { - if (rreq->tag == tag) { - req = rreq; + tag = tc->params.tflush.oldtag; + list_for_each_entry_safe(req, rptr, &m->req_list, req_list) { + if (req->tag == tag) { list_del(&req->req_list); + if (req->cb) { + cb = req->cb; + req->cb = NULL; + spin_unlock(&m->lock); + (*cb) (req->cba, req->tcall, req->rcall, + req->err); + } + kfree(req); + wake_up(&m->equeue); break; } } - spin_unlock(&m->lock); - - if (req) { - spin_lock(&req->lock); - req->flush = Flushed; - spin_unlock(&req->lock); - if (req->cb) - (*req->cb) (req, req->cba); - else - kfree(req->rcall); - - wake_up(&m->equeue); - } + if (!cb) + spin_unlock(&m->lock); - kfree(freq->tcall); - kfree(freq->rcall); - v9fs_mux_free_request(m, freq); + v9fs_mux_put_tag(m, tag); + kfree(tc); + kfree(rc); } -static int +static void v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req) { struct v9fs_fcall *fc; - struct v9fs_req *rreq, *rptr; dprintk(DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag); - /* if a response was received for a request, do nothing */ - spin_lock(&req->lock); - if (req->rcall || req->err) { - spin_unlock(&req->lock); - dprintk(DEBUG_MUX, "mux %p req %p response already received\n", m, req); - return 0; - } - - req->flush = Flushing; - spin_unlock(&req->lock); - - spin_lock(&m->lock); - /* if the request is not sent yet, just remove it from the list */ - list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) { - if (rreq->tag == req->tag) { - dprintk(DEBUG_MUX, "mux %p req %p request is not sent yet\n", m, req); - list_del(&rreq->req_list); - req->flush = Flushed; - spin_unlock(&m->lock); - if (req->cb) - (*req->cb) (req, req->cba); - return 0; - } - } - spin_unlock(&m->lock); - - clear_thread_flag(TIF_SIGPENDING); fc = v9fs_create_tflush(req->tag); v9fs_send_request(m, fc, v9fs_mux_flush_cb, m); - return 1; } static void -v9fs_mux_rpc_cb(struct v9fs_req *req, void *a) +v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err) { struct v9fs_mux_rpc *r; - dprintk(DEBUG_MUX, "req %p r %p\n", req, a); - r = a; - r->rcall = req->rcall; - r->err = req->err; - - if (req->flush!=None && !req->err) - r->err = -ERESTARTSYS; + if (err == ERREQFLUSH) { + kfree(rc); + dprintk(DEBUG_MUX, "err req flush\n"); + return; + } + r = a; + dprintk(DEBUG_MUX, "mux %p req %p tc %p rc %p err %d\n", r->m, r->req, + tc, rc, err); + r->rcall = rc; + r->err = err; wake_up(&r->wqueue); } @@ -892,13 +856,12 @@ int v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, struct v9fs_fcall **rc) { - int err, sigpending; + int err; unsigned long flags; struct v9fs_req *req; struct v9fs_mux_rpc r; r.err = 0; - r.tcall = tc; r.rcall = NULL; r.m = m; init_waitqueue_head(&r.wqueue); @@ -906,50 +869,48 @@ v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, if (rc) *rc = NULL; - sigpending = 0; - if (signal_pending(current)) { - sigpending = 1; - clear_thread_flag(TIF_SIGPENDING); - } - req = v9fs_send_request(m, tc, v9fs_mux_rpc_cb, &r); if (IS_ERR(req)) { err = PTR_ERR(req); dprintk(DEBUG_MUX, "error %d\n", err); - return err; + return PTR_ERR(req); } + r.req = req; + dprintk(DEBUG_MUX, "mux %p tc %p tag %d rpc %p req %p\n", m, tc, + req->tag, &r, req); err = wait_event_interruptible(r.wqueue, r.rcall != NULL || r.err < 0); if (r.err < 0) err = r.err; if (err == -ERESTARTSYS && m->trans->status == Connected && m->err == 0) { - if (v9fs_mux_flush_request(m, req)) { - /* wait until we get response of the flush message */ - do { - clear_thread_flag(TIF_SIGPENDING); - err = wait_event_interruptible(r.wqueue, - r.rcall || r.err); - } while (!r.rcall && !r.err && err==-ERESTARTSYS && - m->trans->status==Connected && !m->err); - } - sigpending = 1; - } + spin_lock(&m->lock); + req->tcall = NULL; + req->err = ERREQFLUSH; + spin_unlock(&m->lock); - if (sigpending) { + clear_thread_flag(TIF_SIGPENDING); + v9fs_mux_flush_request(m, req); spin_lock_irqsave(¤t->sighand->siglock, flags); recalc_sigpending(); spin_unlock_irqrestore(¤t->sighand->siglock, flags); } - if (rc) - *rc = r.rcall; - else - kfree(r.rcall); + if (!err) { + if (r.rcall) + dprintk(DEBUG_MUX, "got response id %d tag %d\n", + r.rcall->id, r.rcall->tag); - v9fs_mux_free_request(m, req); - if (err > 0) - err = -EIO; + if (rc) + *rc = r.rcall; + else + kfree(r.rcall); + } else { + kfree(r.rcall); + dprintk(DEBUG_MUX, "got error %d\n", err); + if (err > 0) + err = -EIO; + } return err; } @@ -990,15 +951,12 @@ void v9fs_mux_cancel(struct v9fs_mux_data *m, int err) struct v9fs_req *req, *rtmp; LIST_HEAD(cancel_list); - dprintk(DEBUG_ERROR, "mux %p err %d\n", m, err); + dprintk(DEBUG_MUX, "mux %p err %d\n", m, err); m->err = err; spin_lock(&m->lock); list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { list_move(&req->req_list, &cancel_list); } - list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) { - list_move(&req->req_list, &cancel_list); - } spin_unlock(&m->lock); list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { @@ -1007,9 +965,11 @@ void v9fs_mux_cancel(struct v9fs_mux_data *m, int err) req->err = err; if (req->cb) - (*req->cb) (req, req->cba); + (*req->cb) (req->cba, req->tcall, req->rcall, req->err); else kfree(req->rcall); + + kfree(req); } wake_up(&m->equeue); diff --git a/trunk/fs/9p/mux.h b/trunk/fs/9p/mux.h index fb10c50186a1..e90bfd32ea42 100644 --- a/trunk/fs/9p/mux.h +++ b/trunk/fs/9p/mux.h @@ -24,7 +24,6 @@ */ struct v9fs_mux_data; -struct v9fs_req; /** * v9fs_mux_req_callback - callback function that is called when the @@ -37,7 +36,8 @@ struct v9fs_req; * @rc - response call * @err - error code (non-zero if error occured) */ -typedef void (*v9fs_mux_req_callback)(struct v9fs_req *req, void *a); +typedef void (*v9fs_mux_req_callback)(void *a, struct v9fs_fcall *tc, + struct v9fs_fcall *rc, int err); int v9fs_mux_global_init(void); void v9fs_mux_global_exit(void); diff --git a/trunk/fs/9p/vfs_file.c b/trunk/fs/9p/vfs_file.c index 1a8e46084f0e..083dcfcd158e 100644 --- a/trunk/fs/9p/vfs_file.c +++ b/trunk/fs/9p/vfs_file.c @@ -72,17 +72,11 @@ int v9fs_file_open(struct inode *inode, struct file *file) return -ENOSPC; } - err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, &fcall); + err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); if (err < 0) { dprintk(DEBUG_ERROR, "rewalk didn't work\n"); - if (fcall && fcall->id == RWALK) - goto clunk_fid; - else { - v9fs_put_idpool(fid, &v9ses->fidpool); - goto free_fcall; - } + goto put_fid; } - kfree(fcall); /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ /* translate open mode appropriately */ @@ -115,7 +109,8 @@ int v9fs_file_open(struct inode *inode, struct file *file) clunk_fid: v9fs_t_clunk(v9ses, fid); -free_fcall: +put_fid: + v9fs_put_idpool(fid, &v9ses->fidpool); kfree(fcall); return err; diff --git a/trunk/fs/9p/vfs_inode.c b/trunk/fs/9p/vfs_inode.c index 2cb87ba4b1c1..133db366d306 100644 --- a/trunk/fs/9p/vfs_inode.c +++ b/trunk/fs/9p/vfs_inode.c @@ -270,10 +270,7 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); if (err < 0) { PRINT_FCALL_ERROR("clone error", fcall); - if (fcall && fcall->id == RWALK) - goto clunk_fid; - else - goto put_fid; + goto put_fid; } kfree(fcall); @@ -325,9 +322,6 @@ v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) &fcall); if (err < 0) { - if (fcall && fcall->id == RWALK) - goto clunk_fid; - PRINT_FCALL_ERROR("walk error", fcall); v9fs_put_idpool(nfid, &v9ses->fidpool); goto error; @@ -646,26 +640,19 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, } result = v9fs_t_walk(v9ses, dirfidnum, newfid, - (char *)dentry->d_name.name, &fcall); - + (char *)dentry->d_name.name, NULL); if (result < 0) { - if (fcall && fcall->id == RWALK) - v9fs_t_clunk(v9ses, newfid); - else - v9fs_put_idpool(newfid, &v9ses->fidpool); - + v9fs_put_idpool(newfid, &v9ses->fidpool); if (result == -ENOENT) { d_add(dentry, NULL); dprintk(DEBUG_VFS, "Return negative dentry %p count %d\n", dentry, atomic_read(&dentry->d_count)); - kfree(fcall); return NULL; } dprintk(DEBUG_ERROR, "walk error:%d\n", result); goto FreeFcall; } - kfree(fcall); result = v9fs_t_stat(v9ses, newfid, &fcall); if (result < 0) { diff --git a/trunk/fs/Makefile b/trunk/fs/Makefile index 078d3d1191a5..83bf478e786b 100644 --- a/trunk/fs/Makefile +++ b/trunk/fs/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_DNOTIFY) += dnotify.o obj-$(CONFIG_PROC_FS) += proc/ obj-y += partitions/ obj-$(CONFIG_SYSFS) += sysfs/ -obj-$(CONFIG_CONFIGFS_FS) += configfs/ obj-y += devpts/ obj-$(CONFIG_PROFILING) += dcookies.o @@ -101,4 +100,5 @@ obj-$(CONFIG_BEFS_FS) += befs/ obj-$(CONFIG_HOSTFS) += hostfs/ obj-$(CONFIG_HPPFS) += hppfs/ obj-$(CONFIG_DEBUG_FS) += debugfs/ +obj-$(CONFIG_CONFIGFS_FS) += configfs/ obj-$(CONFIG_OCFS2_FS) += ocfs2/ diff --git a/trunk/fs/autofs4/autofs_i.h b/trunk/fs/autofs4/autofs_i.h index d6603d02304c..57c4903614e5 100644 --- a/trunk/fs/autofs4/autofs_i.h +++ b/trunk/fs/autofs4/autofs_i.h @@ -74,8 +74,8 @@ struct autofs_wait_queue { struct autofs_wait_queue *next; autofs_wqt_t wait_queue_token; /* We use the following to see what we are waiting for */ - unsigned int hash; - unsigned int len; + int hash; + int len; char *name; u32 dev; u64 ino; @@ -85,6 +85,7 @@ struct autofs_wait_queue { pid_t tgid; /* This is for status reporting upon return */ int status; + atomic_t notify; atomic_t wait_ctr; }; diff --git a/trunk/fs/autofs4/root.c b/trunk/fs/autofs4/root.c index 5100f984783f..84e030c8ddd0 100644 --- a/trunk/fs/autofs4/root.c +++ b/trunk/fs/autofs4/root.c @@ -327,7 +327,6 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags) static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) { struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); - struct autofs_info *ino = autofs4_dentry_ino(dentry); int oz_mode = autofs4_oz_mode(sbi); unsigned int lookup_type; int status; @@ -341,8 +340,13 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) if (oz_mode || !lookup_type) goto done; - /* If an expire request is pending wait for it. */ - if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) { + /* + * If a request is pending wait for it. + * If it's a mount then it won't be expired till at least + * a liitle later and if it's an expire then we might need + * to mount it again. + */ + if (autofs4_ispending(dentry)) { DPRINTK("waiting for active request %p name=%.*s", dentry, dentry->d_name.len, dentry->d_name.name); diff --git a/trunk/fs/autofs4/waitq.c b/trunk/fs/autofs4/waitq.c index ce103e7b0bc3..142ab6aa2aa1 100644 --- a/trunk/fs/autofs4/waitq.c +++ b/trunk/fs/autofs4/waitq.c @@ -189,30 +189,14 @@ static int autofs4_getpath(struct autofs_sb_info *sbi, return len; } -static struct autofs_wait_queue * -autofs4_find_wait(struct autofs_sb_info *sbi, - char *name, unsigned int hash, unsigned int len) -{ - struct autofs_wait_queue *wq; - - for (wq = sbi->queues; wq; wq = wq->next) { - if (wq->hash == hash && - wq->len == len && - wq->name && !memcmp(wq->name, name, len)) - break; - } - return wq; -} - int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, enum autofs_notify notify) { - struct autofs_info *ino; struct autofs_wait_queue *wq; char *name; unsigned int len = 0; unsigned int hash = 0; - int status, type; + int status; /* In catatonic mode, we don't wait for nobody */ if (sbi->catatonic) @@ -239,41 +223,21 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, return -EINTR; } - wq = autofs4_find_wait(sbi, name, hash, len); - ino = autofs4_dentry_ino(dentry); - if (!wq && ino && notify == NFY_NONE) { - /* - * Either we've betean the pending expire to post it's - * wait or it finished while we waited on the mutex. - * So we need to wait till either, the wait appears - * or the expire finishes. - */ - - while (ino->flags & AUTOFS_INF_EXPIRING) { - mutex_unlock(&sbi->wq_mutex); - schedule_timeout_interruptible(HZ/10); - if (mutex_lock_interruptible(&sbi->wq_mutex)) { - kfree(name); - return -EINTR; - } - wq = autofs4_find_wait(sbi, name, hash, len); - if (wq) - break; - } + for (wq = sbi->queues ; wq ; wq = wq->next) { + if (wq->hash == dentry->d_name.hash && + wq->len == len && + wq->name && !memcmp(wq->name, name, len)) + break; + } - /* - * Not ideal but the status has already gone. Of the two - * cases where we wait on NFY_NONE neither depend on the - * return status of the wait. - */ - if (!wq) { + if (!wq) { + /* Can't wait for an expire if there's no mount */ + if (notify == NFY_NONE && !d_mountpoint(dentry)) { kfree(name); mutex_unlock(&sbi->wq_mutex); - return 0; + return -ENOENT; } - } - if (!wq) { /* Create a new wait queue */ wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); if (!wq) { @@ -299,7 +263,20 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, wq->tgid = current->tgid; wq->status = -EINTR; /* Status return if interrupted */ atomic_set(&wq->wait_ctr, 2); + atomic_set(&wq->notify, 1); + mutex_unlock(&sbi->wq_mutex); + } else { + atomic_inc(&wq->wait_ctr); mutex_unlock(&sbi->wq_mutex); + kfree(name); + DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d", + (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); + } + + if (notify != NFY_NONE && atomic_read(&wq->notify)) { + int type; + + atomic_dec(&wq->notify); if (sbi->version < 5) { if (notify == NFY_MOUNT) @@ -322,12 +299,6 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, /* autofs4_notify_daemon() may block */ autofs4_notify_daemon(sbi, wq, type); - } else { - atomic_inc(&wq->wait_ctr); - mutex_unlock(&sbi->wq_mutex); - kfree(name); - DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d", - (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); } /* wq->name is NULL if and only if the lock is already released */ diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index b1c902e319c1..69f44dcdb0b4 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -428,6 +428,7 @@ static int load_flat_file(struct linux_binprm * bprm, loff_t fpos; unsigned long start_code, end_code; int ret; + int exec_fileno; hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ inode = bprm->file->f_dentry->d_inode; @@ -501,12 +502,21 @@ static int load_flat_file(struct linux_binprm * bprm, goto err; } + /* check file descriptor */ + exec_fileno = get_unused_fd(); + if (exec_fileno < 0) { + ret = -EMFILE; + goto err; + } + get_file(bprm->file); + fd_install(exec_fileno, bprm->file); + /* Flush all traces of the currently running executable */ if (id == 0) { result = flush_old_exec(bprm); if (result) { ret = result; - goto err; + goto err_close; } /* OK, This is the point of no return */ @@ -538,7 +548,7 @@ static int load_flat_file(struct linux_binprm * bprm, textpos = (unsigned long) -ENOMEM; printk("Unable to mmap process text, errno %d\n", (int)-textpos); ret = textpos; - goto err; + goto err_close; } down_write(¤t->mm->mmap_sem); @@ -554,7 +564,7 @@ static int load_flat_file(struct linux_binprm * bprm, (int)-datapos); do_munmap(current->mm, textpos, text_len); ret = realdatastart; - goto err; + goto err_close; } datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); @@ -577,7 +587,7 @@ static int load_flat_file(struct linux_binprm * bprm, do_munmap(current->mm, textpos, text_len); do_munmap(current->mm, realdatastart, data_len + extra); ret = result; - goto err; + goto err_close; } reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len)); @@ -596,7 +606,7 @@ static int load_flat_file(struct linux_binprm * bprm, printk("Unable to allocate RAM for process text/data, errno %d\n", (int)-textpos); ret = textpos; - goto err; + goto err_close; } realdatastart = textpos + ntohl(hdr->data_start); @@ -642,7 +652,7 @@ static int load_flat_file(struct linux_binprm * bprm, do_munmap(current->mm, textpos, text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long)); ret = result; - goto err; + goto err_close; } } @@ -707,7 +717,7 @@ static int load_flat_file(struct linux_binprm * bprm, addr = calc_reloc(*rp, libinfo, id, 0); if (addr == RELOC_FAILED) { ret = -ENOEXEC; - goto err; + goto err_close; } *rp = addr; } @@ -737,7 +747,7 @@ static int load_flat_file(struct linux_binprm * bprm, rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1); if (rp == (unsigned long *)RELOC_FAILED) { ret = -ENOEXEC; - goto err; + goto err_close; } /* Get the pointer's value. */ @@ -752,7 +762,7 @@ static int load_flat_file(struct linux_binprm * bprm, addr = calc_reloc(addr, libinfo, id, 0); if (addr == RELOC_FAILED) { ret = -ENOEXEC; - goto err; + goto err_close; } /* Write back the relocated pointer. */ @@ -773,6 +783,8 @@ static int load_flat_file(struct linux_binprm * bprm, stack_len); return 0; +err_close: + sys_close(exec_fileno); err: return ret; } diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 098c12b2d60a..eb8fbc53f2cd 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -1116,9 +1116,6 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors) bp->bio1.bi_io_vec = &bp->bv1; bp->bio2.bi_io_vec = &bp->bv2; - bp->bio1.bi_max_vecs = 1; - bp->bio2.bi_max_vecs = 1; - bp->bio1.bi_end_io = bio_pair_end_1; bp->bio2.bi_end_io = bio_pair_end_2; diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index b1f64786a613..970888aad843 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -1913,7 +1913,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, } if (sigmask) { - if (sigsetsize != sizeof(compat_sigset_t)) + if (sigsetsize |= sizeof(compat_sigset_t)) return -EINVAL; if (copy_from_user(&ss32, sigmask, sizeof(ss32))) return -EFAULT; @@ -2030,115 +2030,109 @@ union compat_nfsctl_res { struct knfsd_fh cr32_getfs; }; -static int compat_nfs_svc_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) +static int compat_nfs_svc_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) { - if (!access_ok(VERIFY_READ, &arg->ca32_svc, sizeof(arg->ca32_svc)) || - get_user(karg->ca_version, &arg->ca32_version) || - __get_user(karg->ca_svc.svc_port, &arg->ca32_svc.svc32_port) || - __get_user(karg->ca_svc.svc_nthreads, - &arg->ca32_svc.svc32_nthreads)) - return -EFAULT; - return 0; + int err; + + err = access_ok(VERIFY_READ, &arg->ca32_svc, sizeof(arg->ca32_svc)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __get_user(karg->ca_svc.svc_port, &arg->ca32_svc.svc32_port); + err |= __get_user(karg->ca_svc.svc_nthreads, &arg->ca32_svc.svc32_nthreads); + return (err) ? -EFAULT : 0; } -static int compat_nfs_clnt_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) -{ - if (!access_ok(VERIFY_READ, &arg->ca32_client, - sizeof(arg->ca32_client)) || - get_user(karg->ca_version, &arg->ca32_version) || - __copy_from_user(&karg->ca_client.cl_ident[0], - &arg->ca32_client.cl32_ident[0], - NFSCLNT_IDMAX) || - __get_user(karg->ca_client.cl_naddr, - &arg->ca32_client.cl32_naddr) || - __copy_from_user(&karg->ca_client.cl_addrlist[0], - &arg->ca32_client.cl32_addrlist[0], - (sizeof(struct in_addr) * NFSCLNT_ADDRMAX)) || - __get_user(karg->ca_client.cl_fhkeytype, - &arg->ca32_client.cl32_fhkeytype) || - __get_user(karg->ca_client.cl_fhkeylen, - &arg->ca32_client.cl32_fhkeylen) || - __copy_from_user(&karg->ca_client.cl_fhkey[0], - &arg->ca32_client.cl32_fhkey[0], - NFSCLNT_KEYMAX)) - return -EFAULT; +static int compat_nfs_clnt_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) +{ + int err; - return 0; + err = access_ok(VERIFY_READ, &arg->ca32_client, sizeof(arg->ca32_client)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __copy_from_user(&karg->ca_client.cl_ident[0], + &arg->ca32_client.cl32_ident[0], + NFSCLNT_IDMAX); + err |= __get_user(karg->ca_client.cl_naddr, &arg->ca32_client.cl32_naddr); + err |= __copy_from_user(&karg->ca_client.cl_addrlist[0], + &arg->ca32_client.cl32_addrlist[0], + (sizeof(struct in_addr) * NFSCLNT_ADDRMAX)); + err |= __get_user(karg->ca_client.cl_fhkeytype, + &arg->ca32_client.cl32_fhkeytype); + err |= __get_user(karg->ca_client.cl_fhkeylen, + &arg->ca32_client.cl32_fhkeylen); + err |= __copy_from_user(&karg->ca_client.cl_fhkey[0], + &arg->ca32_client.cl32_fhkey[0], + NFSCLNT_KEYMAX); + + return (err) ? -EFAULT : 0; } -static int compat_nfs_exp_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) -{ - if (!access_ok(VERIFY_READ, &arg->ca32_export, - sizeof(arg->ca32_export)) || - get_user(karg->ca_version, &arg->ca32_version) || - __copy_from_user(&karg->ca_export.ex_client[0], - &arg->ca32_export.ex32_client[0], - NFSCLNT_IDMAX) || - __copy_from_user(&karg->ca_export.ex_path[0], - &arg->ca32_export.ex32_path[0], - NFS_MAXPATHLEN) || - __get_user(karg->ca_export.ex_dev, - &arg->ca32_export.ex32_dev) || - __get_user(karg->ca_export.ex_ino, - &arg->ca32_export.ex32_ino) || - __get_user(karg->ca_export.ex_flags, - &arg->ca32_export.ex32_flags) || - __get_user(karg->ca_export.ex_anon_uid, - &arg->ca32_export.ex32_anon_uid) || - __get_user(karg->ca_export.ex_anon_gid, - &arg->ca32_export.ex32_anon_gid)) - return -EFAULT; +static int compat_nfs_exp_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) +{ + int err; + + err = access_ok(VERIFY_READ, &arg->ca32_export, sizeof(arg->ca32_export)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __copy_from_user(&karg->ca_export.ex_client[0], + &arg->ca32_export.ex32_client[0], + NFSCLNT_IDMAX); + err |= __copy_from_user(&karg->ca_export.ex_path[0], + &arg->ca32_export.ex32_path[0], + NFS_MAXPATHLEN); + err |= __get_user(karg->ca_export.ex_dev, + &arg->ca32_export.ex32_dev); + err |= __get_user(karg->ca_export.ex_ino, + &arg->ca32_export.ex32_ino); + err |= __get_user(karg->ca_export.ex_flags, + &arg->ca32_export.ex32_flags); + err |= __get_user(karg->ca_export.ex_anon_uid, + &arg->ca32_export.ex32_anon_uid); + err |= __get_user(karg->ca_export.ex_anon_gid, + &arg->ca32_export.ex32_anon_gid); SET_UID(karg->ca_export.ex_anon_uid, karg->ca_export.ex_anon_uid); SET_GID(karg->ca_export.ex_anon_gid, karg->ca_export.ex_anon_gid); - return 0; + return (err) ? -EFAULT : 0; } -static int compat_nfs_getfd_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) -{ - if (!access_ok(VERIFY_READ, &arg->ca32_getfd, - sizeof(arg->ca32_getfd)) || - get_user(karg->ca_version, &arg->ca32_version) || - __copy_from_user(&karg->ca_getfd.gd_addr, - &arg->ca32_getfd.gd32_addr, - (sizeof(struct sockaddr))) || - __copy_from_user(&karg->ca_getfd.gd_path, - &arg->ca32_getfd.gd32_path, - (NFS_MAXPATHLEN+1)) || - __get_user(karg->ca_getfd.gd_version, - &arg->ca32_getfd.gd32_version)) - return -EFAULT; +static int compat_nfs_getfd_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) +{ + int err; - return 0; + err = access_ok(VERIFY_READ, &arg->ca32_getfd, sizeof(arg->ca32_getfd)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __copy_from_user(&karg->ca_getfd.gd_addr, + &arg->ca32_getfd.gd32_addr, + (sizeof(struct sockaddr))); + err |= __copy_from_user(&karg->ca_getfd.gd_path, + &arg->ca32_getfd.gd32_path, + (NFS_MAXPATHLEN+1)); + err |= __get_user(karg->ca_getfd.gd_version, + &arg->ca32_getfd.gd32_version); + + return (err) ? -EFAULT : 0; } -static int compat_nfs_getfs_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) +static int compat_nfs_getfs_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) { - if (!access_ok(VERIFY_READ,&arg->ca32_getfs,sizeof(arg->ca32_getfs)) || - get_user(karg->ca_version, &arg->ca32_version) || - __copy_from_user(&karg->ca_getfs.gd_addr, - &arg->ca32_getfs.gd32_addr, - (sizeof(struct sockaddr))) || - __copy_from_user(&karg->ca_getfs.gd_path, - &arg->ca32_getfs.gd32_path, - (NFS_MAXPATHLEN+1)) || - __get_user(karg->ca_getfs.gd_maxlen, - &arg->ca32_getfs.gd32_maxlen)) - return -EFAULT; + int err; - return 0; + err = access_ok(VERIFY_READ, &arg->ca32_getfs, sizeof(arg->ca32_getfs)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __copy_from_user(&karg->ca_getfs.gd_addr, + &arg->ca32_getfs.gd32_addr, + (sizeof(struct sockaddr))); + err |= __copy_from_user(&karg->ca_getfs.gd_path, + &arg->ca32_getfs.gd32_path, + (NFS_MAXPATHLEN+1)); + err |= __get_user(karg->ca_getfs.gd_maxlen, + &arg->ca32_getfs.gd32_maxlen); + + return (err) ? -EFAULT : 0; } /* This really doesn't need translations, we are only passing * back a union which contains opaque nfs file handle data. */ -static int compat_nfs_getfh_res_trans(union nfsctl_res *kres, - union compat_nfsctl_res __user *res) +static int compat_nfs_getfh_res_trans(union nfsctl_res *kres, union compat_nfsctl_res __user *res) { int err; @@ -2147,9 +2141,8 @@ static int compat_nfs_getfh_res_trans(union nfsctl_res *kres, return (err) ? -EFAULT : 0; } -asmlinkage long compat_sys_nfsservctl(int cmd, - struct compat_nfsctl_arg __user *arg, - union compat_nfsctl_res __user *res) +asmlinkage long compat_sys_nfsservctl(int cmd, struct compat_nfsctl_arg __user *arg, + union compat_nfsctl_res __user *res) { struct nfsctl_arg *karg; union nfsctl_res *kres; diff --git a/trunk/fs/configfs/dir.c b/trunk/fs/configfs/dir.c index 5f952187fc53..5638c8f9362f 100644 --- a/trunk/fs/configfs/dir.c +++ b/trunk/fs/configfs/dir.c @@ -505,15 +505,13 @@ static int populate_groups(struct config_group *group) int i; if (group->default_groups) { - /* - * FYI, we're faking mkdir here + /* FYI, we're faking mkdir here * I'm not sure we need this semaphore, as we're called * from our parent's mkdir. That holds our parent's * i_mutex, so afaik lookup cannot continue through our * parent to find us, let alone mess with our tree. * That said, taking our i_mutex is closer to mkdir - * emulation, and shouldn't hurt. - */ + * emulation, and shouldn't hurt. */ mutex_lock(&dentry->d_inode->i_mutex); for (i = 0; group->default_groups[i]; i++) { @@ -548,34 +546,20 @@ static void unlink_obj(struct config_item *item) item->ci_group = NULL; item->ci_parent = NULL; - - /* Drop the reference for ci_entry */ config_item_put(item); - /* Drop the reference for ci_parent */ config_group_put(group); } } static void link_obj(struct config_item *parent_item, struct config_item *item) { - /* - * Parent seems redundant with group, but it makes certain - * traversals much nicer. - */ + /* Parent seems redundant with group, but it makes certain + * traversals much nicer. */ item->ci_parent = parent_item; - - /* - * We hold a reference on the parent for the child's ci_parent - * link. - */ item->ci_group = config_group_get(to_config_group(parent_item)); list_add_tail(&item->ci_entry, &item->ci_group->cg_children); - /* - * We hold a reference on the child for ci_entry on the parent's - * cg_children - */ config_item_get(item); } @@ -700,10 +684,6 @@ static void client_drop_item(struct config_item *parent_item, type = parent_item->ci_type; BUG_ON(!type); - /* - * If ->drop_item() exists, it is responsible for the - * config_item_put(). - */ if (type->ct_group_ops && type->ct_group_ops->drop_item) type->ct_group_ops->drop_item(to_config_group(parent_item), item); @@ -714,28 +694,23 @@ static void client_drop_item(struct config_item *parent_item, static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { - int ret, module_got = 0; + int ret; struct config_group *group; struct config_item *item; struct config_item *parent_item; struct configfs_subsystem *subsys; struct configfs_dirent *sd; struct config_item_type *type; - struct module *owner = NULL; + struct module *owner; char *name; - if (dentry->d_parent == configfs_sb->s_root) { - ret = -EPERM; - goto out; - } + if (dentry->d_parent == configfs_sb->s_root) + return -EPERM; sd = dentry->d_parent->d_fsdata; - if (!(sd->s_type & CONFIGFS_USET_DIR)) { - ret = -EPERM; - goto out; - } + if (!(sd->s_type & CONFIGFS_USET_DIR)) + return -EPERM; - /* Get a working ref for the duration of this function */ parent_item = configfs_get_config_item(dentry->d_parent); type = parent_item->ci_type; subsys = to_config_group(parent_item)->cg_subsys; @@ -744,16 +719,15 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (!type || !type->ct_group_ops || (!type->ct_group_ops->make_group && !type->ct_group_ops->make_item)) { - ret = -EPERM; /* Lack-of-mkdir returns -EPERM */ - goto out_put; + config_item_put(parent_item); + return -EPERM; /* What lack-of-mkdir returns */ } name = kmalloc(dentry->d_name.len + 1, GFP_KERNEL); if (!name) { - ret = -ENOMEM; - goto out_put; + config_item_put(parent_item); + return -ENOMEM; } - snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name); down(&subsys->su_sem); @@ -774,67 +748,40 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) kfree(name); if (!item) { - /* - * If item == NULL, then link_obj() was never called. - * There are no extra references to clean up. - */ - ret = -ENOMEM; - goto out_put; + config_item_put(parent_item); + return -ENOMEM; } - /* - * link_obj() has been called (via link_group() for groups). - * From here on out, errors must clean that up. - */ - + ret = -EINVAL; type = item->ci_type; - if (!type) { - ret = -EINVAL; - goto out_unlink; - } - - owner = type->ct_owner; - if (!try_module_get(owner)) { - ret = -EINVAL; - goto out_unlink; - } - - /* - * I hate doing it this way, but if there is - * an error, module_put() probably should - * happen after any cleanup. - */ - module_got = 1; + if (type) { + owner = type->ct_owner; + if (try_module_get(owner)) { + if (group) { + ret = configfs_attach_group(parent_item, + item, + dentry); + } else { + ret = configfs_attach_item(parent_item, + item, + dentry); + } - if (group) - ret = configfs_attach_group(parent_item, item, dentry); - else - ret = configfs_attach_item(parent_item, item, dentry); + if (ret) { + down(&subsys->su_sem); + if (group) + unlink_group(group); + else + unlink_obj(item); + client_drop_item(parent_item, item); + up(&subsys->su_sem); -out_unlink: - if (ret) { - /* Tear down everything we built up */ - down(&subsys->su_sem); - if (group) - unlink_group(group); - else - unlink_obj(item); - client_drop_item(parent_item, item); - up(&subsys->su_sem); - - if (module_got) - module_put(owner); + config_item_put(parent_item); + module_put(owner); + } + } } -out_put: - /* - * link_obj()/link_group() took a reference from child->parent, - * so the parent is safely pinned. We can drop our working - * reference. - */ - config_item_put(parent_item); - -out: return ret; } @@ -854,7 +801,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) if (sd->s_type & CONFIGFS_USET_DEFAULT) return -EPERM; - /* Get a working ref until we have the child */ parent_item = configfs_get_config_item(dentry->d_parent); subsys = to_config_group(parent_item)->cg_subsys; BUG_ON(!subsys); @@ -871,7 +817,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) return ret; } - /* Get a working ref for the duration of this function */ item = configfs_get_config_item(dentry); /* Drop reference from above, item already holds one. */ diff --git a/trunk/fs/exportfs/expfs.c b/trunk/fs/exportfs/expfs.c index 4c39009350f3..b06b54f1bbbb 100644 --- a/trunk/fs/exportfs/expfs.c +++ b/trunk/fs/exportfs/expfs.c @@ -102,7 +102,7 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, if (acceptable(context, result)) return result; if (S_ISDIR(result->d_inode->i_mode)) { - err = -EACCES; + /* there is no other dentry, so fail */ goto err_result; } diff --git a/trunk/fs/inotify.c b/trunk/fs/inotify.c index 732ec4bd5774..1f50302849c5 100644 --- a/trunk/fs/inotify.c +++ b/trunk/fs/inotify.c @@ -848,11 +848,7 @@ static int inotify_release(struct inode *ignored, struct file *file) inode = watch->inode; mutex_lock(&inode->inotify_mutex); mutex_lock(&dev->mutex); - - /* make sure we didn't race with another list removal */ - if (likely(idr_find(&dev->idr, watch->wd))) - remove_watch_no_event(watch, dev); - + remove_watch_no_event(watch, dev); mutex_unlock(&dev->mutex); mutex_unlock(&inode->inotify_mutex); put_inotify_watch(watch); @@ -894,7 +890,8 @@ static int inotify_ignore(struct inotify_device *dev, s32 wd) mutex_lock(&dev->mutex); /* make sure that we did not race */ - if (likely(idr_find(&dev->idr, wd) == watch)) + watch = idr_find(&dev->idr, wd); + if (likely(watch)) remove_watch(watch, dev); mutex_unlock(&dev->mutex); diff --git a/trunk/fs/jffs2/nodelist.c b/trunk/fs/jffs2/nodelist.c index 1d46677afd17..d4d0c41490cd 100644 --- a/trunk/fs/jffs2/nodelist.c +++ b/trunk/fs/jffs2/nodelist.c @@ -438,8 +438,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info if (c->mtd->point) { err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer); if (!err && retlen < tn->csize) { - JFFS2_WARNING("MTD point returned len too short: %zu " - "instead of %u.\n", retlen, tn->csize); + JFFS2_WARNING("MTD point returned len too short: %u instead of %u.\n", retlen, tn->csize); c->mtd->unpoint(c->mtd, buffer, ofs, len); } else if (err) JFFS2_WARNING("MTD point failed: error code %d.\n", err); @@ -462,8 +461,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info } if (retlen != len) { - JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", - ofs, retlen, len); + JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ofs, retlen, len); err = -EIO; goto free_out; } diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index 6f99c0a6f836..efad798824dc 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -446,14 +446,15 @@ static struct lock_manager_operations lease_manager_ops = { */ static int lease_init(struct file *filp, int type, struct file_lock *fl) { - if (assign_type(fl, type) != 0) - return -EINVAL; - fl->fl_owner = current->files; fl->fl_pid = current->tgid; fl->fl_file = filp; fl->fl_flags = FL_LEASE; + if (assign_type(fl, type) != 0) { + locks_free_lock(fl); + return -EINVAL; + } fl->fl_start = 0; fl->fl_end = OFFSET_MAX; fl->fl_ops = NULL; @@ -465,19 +466,16 @@ static int lease_init(struct file *filp, int type, struct file_lock *fl) static int lease_alloc(struct file *filp, int type, struct file_lock **flp) { struct file_lock *fl = locks_alloc_lock(); - int error = -ENOMEM; + int error; if (fl == NULL) - goto out; + return -ENOMEM; error = lease_init(filp, type, fl); - if (error) { - locks_free_lock(fl); - fl = NULL; - } -out: + if (error) + return error; *flp = fl; - return error; + return 0; } /* Check if two locks overlap each other. @@ -1374,7 +1372,6 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp) goto out; if (my_before != NULL) { - *flp = *my_before; error = lease->fl_lmops->fl_change(my_before, arg); goto out; } diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index bf478addb852..2c5f1f80bdc2 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -899,11 +899,13 @@ static int do_change_type(struct nameidata *nd, int flag) /* * do loopback mount. */ -static int do_loopback(struct nameidata *nd, char *old_name, int recurse) +static int do_loopback(struct nameidata *nd, char *old_name, unsigned long flags, int mnt_flags) { struct nameidata old_nd; struct vfsmount *mnt = NULL; + int recurse = flags & MS_REC; int err = mount_is_safe(nd); + if (err) return err; if (!old_name || !*old_name) @@ -937,6 +939,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse) spin_unlock(&vfsmount_lock); release_mounts(&umount_list); } + mnt->mnt_flags = mnt_flags; out: up_write(&namespace_sem); @@ -1350,7 +1353,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, data_page); else if (flags & MS_BIND) - retval = do_loopback(&nd, dev_name, flags & MS_REC); + retval = do_loopback(&nd, dev_name, flags, mnt_flags); else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) retval = do_change_type(&nd, flags); else if (flags & MS_MOVE) diff --git a/trunk/fs/nfsd/export.c b/trunk/fs/nfsd/export.c index 3eec30000f3f..4e0578121d9a 100644 --- a/trunk/fs/nfsd/export.c +++ b/trunk/fs/nfsd/export.c @@ -1066,11 +1066,9 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp, rv = nfserr_perm; else if (IS_ERR(exp)) rv = nfserrno(PTR_ERR(exp)); - else { + else rv = fh_compose(fhp, exp, fsid_key->ek_dentry, NULL); - exp_put(exp); - } cache_put(&fsid_key->h, &svc_expkey_cache); return rv; } diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 1d65f13f458c..6aa92d0e6876 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -1922,10 +1922,11 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) value = kmalloc(size, GFP_KERNEL); if (!value) return -ENOMEM; - error = posix_acl_to_xattr(acl, value, size); - if (error < 0) + size = posix_acl_to_xattr(acl, value, size); + if (size < 0) { + error = size; goto getout; - size = error; + } } else size = 0; diff --git a/trunk/fs/ocfs2/aops.c b/trunk/fs/ocfs2/aops.c index 47152bf9a7f2..0d858d0b25be 100644 --- a/trunk/fs/ocfs2/aops.c +++ b/trunk/fs/ocfs2/aops.c @@ -276,29 +276,13 @@ static int ocfs2_writepage(struct page *page, struct writeback_control *wbc) return ret; } -/* This can also be called from ocfs2_write_zero_page() which has done - * it's own cluster locking. */ -int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page, - unsigned from, unsigned to) -{ - int ret; - - down_read(&OCFS2_I(inode)->ip_alloc_sem); - - ret = block_prepare_write(page, from, to, ocfs2_get_block); - - up_read(&OCFS2_I(inode)->ip_alloc_sem); - - return ret; -} - /* * ocfs2_prepare_write() can be an outer-most ocfs2 call when it is called * from loopback. It must be able to perform its own locking around * ocfs2_get_block(). */ -static int ocfs2_prepare_write(struct file *file, struct page *page, - unsigned from, unsigned to) +int ocfs2_prepare_write(struct file *file, struct page *page, + unsigned from, unsigned to) { struct inode *inode = page->mapping->host; int ret; @@ -311,7 +295,11 @@ static int ocfs2_prepare_write(struct file *file, struct page *page, goto out; } - ret = ocfs2_prepare_write_nolock(inode, page, from, to); + down_read(&OCFS2_I(inode)->ip_alloc_sem); + + ret = block_prepare_write(page, from, to, ocfs2_get_block); + + up_read(&OCFS2_I(inode)->ip_alloc_sem); ocfs2_meta_unlock(inode, 0); out: @@ -637,31 +625,11 @@ static ssize_t ocfs2_direct_IO(int rw, int ret; mlog_entry_void(); - - /* - * We get PR data locks even for O_DIRECT. This allows - * concurrent O_DIRECT I/O but doesn't let O_DIRECT with - * extending and buffered zeroing writes race. If they did - * race then the buffered zeroing could be written back after - * the O_DIRECT I/O. It's one thing to tell people not to mix - * buffered and O_DIRECT writes, but expecting them to - * understand that file extension is also an implicit buffered - * write is too much. By getting the PR we force writeback of - * the buffered zeroing before proceeding. - */ - ret = ocfs2_data_lock(inode, 0); - if (ret < 0) { - mlog_errno(ret); - goto out; - } - ocfs2_data_unlock(inode, 0); - ret = blockdev_direct_IO_no_locking(rw, iocb, inode, inode->i_sb->s_bdev, iov, offset, nr_segs, ocfs2_direct_IO_get_blocks, ocfs2_dio_end_io); -out: mlog_exit(ret); return ret; } diff --git a/trunk/fs/ocfs2/aops.h b/trunk/fs/ocfs2/aops.h index e88c3f0b8fa9..d40456d509a0 100644 --- a/trunk/fs/ocfs2/aops.h +++ b/trunk/fs/ocfs2/aops.h @@ -22,8 +22,8 @@ #ifndef OCFS2_AOPS_H #define OCFS2_AOPS_H -int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page, - unsigned from, unsigned to); +int ocfs2_prepare_write(struct file *file, struct page *page, + unsigned from, unsigned to); struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, struct page *page, diff --git a/trunk/fs/ocfs2/extent_map.c b/trunk/fs/ocfs2/extent_map.c index 1a5c69071df6..4601fc256f11 100644 --- a/trunk/fs/ocfs2/extent_map.c +++ b/trunk/fs/ocfs2/extent_map.c @@ -569,7 +569,7 @@ static int ocfs2_extent_map_insert(struct inode *inode, ret = -ENOMEM; ctxt.new_ent = kmem_cache_alloc(ocfs2_em_ent_cachep, - GFP_NOFS); + GFP_KERNEL); if (!ctxt.new_ent) { mlog_errno(ret); return ret; @@ -583,14 +583,14 @@ static int ocfs2_extent_map_insert(struct inode *inode, if (ctxt.need_left && !ctxt.left_ent) { ctxt.left_ent = kmem_cache_alloc(ocfs2_em_ent_cachep, - GFP_NOFS); + GFP_KERNEL); if (!ctxt.left_ent) break; } if (ctxt.need_right && !ctxt.right_ent) { ctxt.right_ent = kmem_cache_alloc(ocfs2_em_ent_cachep, - GFP_NOFS); + GFP_KERNEL); if (!ctxt.right_ent) break; } diff --git a/trunk/fs/ocfs2/file.c b/trunk/fs/ocfs2/file.c index a9559c874530..581eb451a41a 100644 --- a/trunk/fs/ocfs2/file.c +++ b/trunk/fs/ocfs2/file.c @@ -613,8 +613,7 @@ static int ocfs2_extend_allocation(struct inode *inode, /* Some parts of this taken from generic_cont_expand, which turned out * to be too fragile to do exactly what we need without us having to - * worry about recursive locking in ->prepare_write() and - * ->commit_write(). */ + * worry about recursive locking in ->commit_write(). */ static int ocfs2_write_zero_page(struct inode *inode, u64 size) { @@ -642,7 +641,7 @@ static int ocfs2_write_zero_page(struct inode *inode, goto out; } - ret = ocfs2_prepare_write_nolock(inode, page, offset, offset); + ret = ocfs2_prepare_write(NULL, page, offset, offset); if (ret < 0) { mlog_errno(ret); goto out_unlock; @@ -696,26 +695,13 @@ static int ocfs2_zero_extend(struct inode *inode, return ret; } -/* - * A tail_to_skip value > 0 indicates that we're being called from - * ocfs2_file_aio_write(). This has the following implications: - * - * - we don't want to update i_size - * - di_bh will be NULL, which is fine because it's only used in the - * case where we want to update i_size. - * - ocfs2_zero_extend() will then only be filling the hole created - * between i_size and the start of the write. - */ static int ocfs2_extend_file(struct inode *inode, struct buffer_head *di_bh, - u64 new_i_size, - size_t tail_to_skip) + u64 new_i_size) { int ret = 0; u32 clusters_to_add; - BUG_ON(!tail_to_skip && !di_bh); - /* setattr sometimes calls us like this. */ if (new_i_size == 0) goto out; @@ -728,44 +714,27 @@ static int ocfs2_extend_file(struct inode *inode, OCFS2_I(inode)->ip_clusters; if (clusters_to_add) { - /* - * protect the pages that ocfs2_zero_extend is going to - * be pulling into the page cache.. we do this before the - * metadata extend so that we don't get into the situation - * where we've extended the metadata but can't get the data - * lock to zero. - */ - ret = ocfs2_data_lock(inode, 1); - if (ret < 0) { - mlog_errno(ret); - goto out; - } - ret = ocfs2_extend_allocation(inode, clusters_to_add); if (ret < 0) { mlog_errno(ret); - goto out_unlock; + goto out; } - ret = ocfs2_zero_extend(inode, (u64)new_i_size - tail_to_skip); + ret = ocfs2_zero_extend(inode, new_i_size); if (ret < 0) { mlog_errno(ret); - goto out_unlock; + goto out; } - } + } - if (!tail_to_skip) { - /* We're being called from ocfs2_setattr() which wants - * us to update i_size */ - ret = ocfs2_simple_size_update(inode, di_bh, new_i_size); - if (ret < 0) - mlog_errno(ret); + /* No allocation required, we just use this helper to + * do a trivial update of i_size. */ + ret = ocfs2_simple_size_update(inode, di_bh, new_i_size); + if (ret < 0) { + mlog_errno(ret); + goto out; } -out_unlock: - if (clusters_to_add) /* this is the only case in which we lock */ - ocfs2_data_unlock(inode, 1); - out: return ret; } @@ -824,7 +793,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) if (i_size_read(inode) > attr->ia_size) status = ocfs2_truncate_file(inode, bh, attr->ia_size); else - status = ocfs2_extend_file(inode, bh, attr->ia_size, 0); + status = ocfs2_extend_file(inode, bh, attr->ia_size); if (status < 0) { if (status != -ENOSPC) mlog_errno(status); @@ -1080,12 +1049,21 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, if (!clusters) break; - ret = ocfs2_extend_file(inode, NULL, newsize, count); + ret = ocfs2_extend_allocation(inode, clusters); if (ret < 0) { if (ret != -ENOSPC) mlog_errno(ret); goto out; } + + /* Fill any holes which would've been created by this + * write. If we're O_APPEND, this will wind up + * (correctly) being a noop. */ + ret = ocfs2_zero_extend(inode, (u64) newsize - count); + if (ret < 0) { + mlog_errno(ret); + goto out; + } break; } @@ -1168,22 +1146,6 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, ocfs2_iocb_set_rw_locked(iocb); } - /* - * We're fine letting folks race truncates and extending - * writes with read across the cluster, just like they can - * locally. Hence no rw_lock during read. - * - * Take and drop the meta data lock to update inode fields - * like i_size. This allows the checks down below - * generic_file_aio_read() a chance of actually working. - */ - ret = ocfs2_meta_lock(inode, NULL, NULL, 0); - if (ret < 0) { - mlog_errno(ret); - goto bail; - } - ocfs2_meta_unlock(inode, 0); - ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos); if (ret == -EINVAL) mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); diff --git a/trunk/fs/ocfs2/journal.c b/trunk/fs/ocfs2/journal.c index eebc3cfa6be8..6a610ae53583 100644 --- a/trunk/fs/ocfs2/journal.c +++ b/trunk/fs/ocfs2/journal.c @@ -117,7 +117,7 @@ struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb) { struct ocfs2_journal_handle *retval = NULL; - retval = kcalloc(1, sizeof(*retval), GFP_NOFS); + retval = kcalloc(1, sizeof(*retval), GFP_KERNEL); if (!retval) { mlog(ML_ERROR, "Failed to allocate memory for journal " "handle!\n"); @@ -870,11 +870,9 @@ static int ocfs2_force_read_journal(struct inode *inode) if (p_blocks > CONCURRENT_JOURNAL_FILL) p_blocks = CONCURRENT_JOURNAL_FILL; - /* We are reading journal data which should not - * be put in the uptodate cache */ status = ocfs2_read_blocks(OCFS2_SB(inode->i_sb), p_blkno, p_blocks, bhs, 0, - NULL); + inode); if (status < 0) { mlog_errno(status); goto bail; @@ -984,7 +982,7 @@ static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal, { struct ocfs2_la_recovery_item *item; - item = kmalloc(sizeof(struct ocfs2_la_recovery_item), GFP_NOFS); + item = kmalloc(sizeof(struct ocfs2_la_recovery_item), GFP_KERNEL); if (!item) { /* Though we wish to avoid it, we are in fact safe in * skipping local alloc cleanup as fsck.ocfs2 is more diff --git a/trunk/fs/ocfs2/uptodate.c b/trunk/fs/ocfs2/uptodate.c index b8a00a793326..04a684dfdd96 100644 --- a/trunk/fs/ocfs2/uptodate.c +++ b/trunk/fs/ocfs2/uptodate.c @@ -337,7 +337,7 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_inode_info *oi, (unsigned long long)oi->ip_blkno, (unsigned long long)block, expand_tree); - new = kmem_cache_alloc(ocfs2_uptodate_cachep, GFP_NOFS); + new = kmem_cache_alloc(ocfs2_uptodate_cachep, GFP_KERNEL); if (!new) { mlog_errno(-ENOMEM); return; @@ -349,7 +349,7 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_inode_info *oi, * has no way of tracking that. */ for(i = 0; i < OCFS2_INODE_MAX_CACHE_ARRAY; i++) { tree[i] = kmem_cache_alloc(ocfs2_uptodate_cachep, - GFP_NOFS); + GFP_KERNEL); if (!tree[i]) { mlog_errno(-ENOMEM); goto out_free; diff --git a/trunk/fs/ocfs2/vote.c b/trunk/fs/ocfs2/vote.c index ee42765a8553..53049a204197 100644 --- a/trunk/fs/ocfs2/vote.c +++ b/trunk/fs/ocfs2/vote.c @@ -586,7 +586,7 @@ static struct ocfs2_net_wait_ctxt *ocfs2_new_net_wait_ctxt(unsigned int response { struct ocfs2_net_wait_ctxt *w; - w = kcalloc(1, sizeof(*w), GFP_NOFS); + w = kcalloc(1, sizeof(*w), GFP_KERNEL); if (!w) { mlog_errno(-ENOMEM); goto bail; @@ -749,7 +749,7 @@ static struct ocfs2_vote_msg * ocfs2_new_vote_request(struct ocfs2_super *osb, BUG_ON(!ocfs2_is_valid_vote_request(type)); - request = kcalloc(1, sizeof(*request), GFP_NOFS); + request = kcalloc(1, sizeof(*request), GFP_KERNEL); if (!request) { mlog_errno(-ENOMEM); } else { @@ -1129,7 +1129,7 @@ static int ocfs2_handle_vote_message(struct o2net_msg *msg, struct ocfs2_super *osb = data; struct ocfs2_vote_work *work; - work = kmalloc(sizeof(struct ocfs2_vote_work), GFP_NOFS); + work = kmalloc(sizeof(struct ocfs2_vote_work), GFP_KERNEL); if (!work) { status = -ENOMEM; mlog_errno(status); diff --git a/trunk/fs/open.c b/trunk/fs/open.c index 317b7c7f38a7..53ec28c36777 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -1124,6 +1124,7 @@ asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, prevent_tail_call(ret); return ret; } +EXPORT_SYMBOL_GPL(sys_openat); #ifndef __alpha__ diff --git a/trunk/fs/partitions/check.c b/trunk/fs/partitions/check.c index 7ef1f094de91..45ae7dd3c650 100644 --- a/trunk/fs/partitions/check.c +++ b/trunk/fs/partitions/check.c @@ -533,7 +533,6 @@ void del_gendisk(struct gendisk *disk) devfs_remove_disk(disk); - kobject_uevent(&disk->kobj, KOBJ_REMOVE); if (disk->holder_dir) kobject_unregister(disk->holder_dir); if (disk->slave_dir) @@ -546,7 +545,7 @@ void del_gendisk(struct gendisk *disk) kfree(disk_name); } put_device(disk->driverfs_dev); - disk->driverfs_dev = NULL; } + kobject_uevent(&disk->kobj, KOBJ_REMOVE); kobject_del(&disk->kobj); } diff --git a/trunk/fs/smbfs/dir.c b/trunk/fs/smbfs/dir.c index 70d9c5a37f5a..34c7a11d91f0 100644 --- a/trunk/fs/smbfs/dir.c +++ b/trunk/fs/smbfs/dir.c @@ -434,11 +434,6 @@ smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) if (dentry->d_name.len > SMB_MAXNAMELEN) goto out; - /* Do not allow lookup of names with backslashes in */ - error = -EINVAL; - if (memchr(dentry->d_name.name, '\\', dentry->d_name.len)) - goto out; - lock_kernel(); error = smb_proc_getattr(dentry, &finfo); #ifdef SMBFS_PARANOIA diff --git a/trunk/fs/smbfs/request.c b/trunk/fs/smbfs/request.c index c71dd2760d32..c71c375863cc 100644 --- a/trunk/fs/smbfs/request.c +++ b/trunk/fs/smbfs/request.c @@ -339,11 +339,9 @@ int smb_add_request(struct smb_request *req) /* * On timeout or on interrupt we want to try and remove the * request from the recvq/xmitq. - * First check if the request is still part of a queue. (May - * have been removed by some error condition) */ smb_lock_server(server); - if (!list_empty(&req->rq_queue)) { + if (!(req->rq_flags & SMB_REQ_RECEIVED)) { list_del_init(&req->rq_queue); smb_rput(req); } diff --git a/trunk/fs/xfs/xfs_alloc.c b/trunk/fs/xfs/xfs_alloc.c index 8558226281c4..64ee07db0d5e 100644 --- a/trunk/fs/xfs/xfs_alloc.c +++ b/trunk/fs/xfs/xfs_alloc.c @@ -1942,10 +1942,8 @@ xfs_alloc_fix_freelist( /* * Allocate as many blocks as possible at once. */ - if ((error = xfs_alloc_ag_vextent(&targs))) { - xfs_trans_brelse(tp, agflbp); + if ((error = xfs_alloc_ag_vextent(&targs))) return error; - } /* * Stop if we run out. Won't happen if callers are obeying * the restrictions correctly. Can happen for free calls @@ -1962,7 +1960,6 @@ xfs_alloc_fix_freelist( return error; } } - xfs_trans_brelse(tp, agflbp); args->agbp = agbp; return 0; } diff --git a/trunk/fs/xfs/xfs_rename.c b/trunk/fs/xfs/xfs_rename.c index 1f148762eb28..81a05cfd77d2 100644 --- a/trunk/fs/xfs/xfs_rename.c +++ b/trunk/fs/xfs/xfs_rename.c @@ -316,18 +316,6 @@ xfs_rename( } } - /* - * If we are using project inheritance, we only allow renames - * into our tree when the project IDs are the same; else the - * tree quota mechanism would be circumvented. - */ - if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && - (target_dp->i_d.di_projid != src_ip->i_d.di_projid))) { - error = XFS_ERROR(EXDEV); - xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); - goto rele_return; - } - new_parent = (src_dp != target_dp); src_is_directory = ((src_ip->i_d.di_mode & S_IFMT) == S_IFDIR); diff --git a/trunk/fs/xfs/xfs_vfsops.c b/trunk/fs/xfs/xfs_vfsops.c index 36ea1b2094f2..f0e09ca14139 100644 --- a/trunk/fs/xfs/xfs_vfsops.c +++ b/trunk/fs/xfs/xfs_vfsops.c @@ -669,22 +669,31 @@ xfs_mntupdate( xfs_mount_t *mp = XFS_BHVTOM(bdp); int error; - if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ - if (vfsp->vfs_flag & VFS_RDONLY) - vfsp->vfs_flag &= ~VFS_RDONLY; - if (args->flags & XFSMNT_BARRIER) { - mp->m_flags |= XFS_MOUNT_BARRIER; + if (args->flags & XFSMNT_BARRIER) + mp->m_flags |= XFS_MOUNT_BARRIER; + else + mp->m_flags &= ~XFS_MOUNT_BARRIER; + + if ((vfsp->vfs_flag & VFS_RDONLY) && + !(*flags & MS_RDONLY)) { + vfsp->vfs_flag &= ~VFS_RDONLY; + + if (args->flags & XFSMNT_BARRIER) xfs_mountfs_check_barriers(mp); - } else { - mp->m_flags &= ~XFS_MOUNT_BARRIER; - } - } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ + } + + if (!(vfsp->vfs_flag & VFS_RDONLY) && + (*flags & MS_RDONLY)) { VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error); + xfs_quiesce_fs(mp); + + /* Ok now write out an unmount record */ xfs_log_unmount_write(mp); xfs_unmountfs_writesb(mp); vfsp->vfs_flag |= VFS_RDONLY; } + return 0; } diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index 7027ae68ee38..fa71b305ba5c 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -2663,7 +2663,7 @@ xfs_link( */ if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && (tdp->i_d.di_projid != sip->i_d.di_projid))) { - error = XFS_ERROR(EXDEV); + error = XFS_ERROR(EPERM); goto error_return; } diff --git a/trunk/include/asm-arm/arch-aaec2000/debug-macro.S b/trunk/include/asm-arm/arch-aaec2000/debug-macro.S index 7b1fce021d8a..e4f1fa539a74 100644 --- a/trunk/include/asm-arm/arch-aaec2000/debug-macro.S +++ b/trunk/include/asm-arm/arch-aaec2000/debug-macro.S @@ -9,7 +9,6 @@ * published by the Free Software Foundation. */ -#include "hardware.h" .macro addruart,rx mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? diff --git a/trunk/include/asm-arm/arch-aaec2000/entry-macro.S b/trunk/include/asm-arm/arch-aaec2000/entry-macro.S index 1eb3503bd16e..df31313ab07e 100644 --- a/trunk/include/asm-arm/arch-aaec2000/entry-macro.S +++ b/trunk/include/asm-arm/arch-aaec2000/entry-macro.S @@ -10,7 +10,6 @@ * published by the Free Software Foundation. * */ -#include .macro disable_fiq .endm diff --git a/trunk/include/asm-arm/arch-imx/debug-macro.S b/trunk/include/asm-arm/arch-imx/debug-macro.S index c611871643a2..83f552f7bcc1 100644 --- a/trunk/include/asm-arm/arch-imx/debug-macro.S +++ b/trunk/include/asm-arm/arch-imx/debug-macro.S @@ -16,7 +16,7 @@ tst \rx, #1 @ MMU enabled? moveq \rx, #0x00000000 @ physical movne \rx, #0xe0000000 @ virtual - orreq \rx, \rx, #0x00200000 @ physical + orr \rx, \rx, #0x00200000 orr \rx, \rx, #0x00006000 @ UART1 offset .endm diff --git a/trunk/include/asm-arm/arch-pxa/dma.h b/trunk/include/asm-arm/arch-pxa/dma.h index a008150abc59..3e88a2a02a0f 100644 --- a/trunk/include/asm-arm/arch-pxa/dma.h +++ b/trunk/include/asm-arm/arch-pxa/dma.h @@ -24,29 +24,27 @@ typedef struct pxa_dma_desc { volatile u32 dcmd; /* DCMD value for the current transfer */ } pxa_dma_desc; -typedef enum { - DMA_PRIO_HIGH = 0, - DMA_PRIO_MEDIUM = 1, - DMA_PRIO_LOW = 2 -} pxa_dma_prio; - #if defined(CONFIG_PXA27x) #define PXA_DMA_CHANNELS 32 +#define PXA_DMA_NBCH(prio) ((prio == DMA_PRIO_LOW) ? 16 : 8) -#define pxa_for_each_dma_prio(ch, prio) \ -for ( \ - ch = prio * 4; \ - ch != (4 << prio) + 16; \ - ch = (ch + 1 == (4 << prio)) ? (prio * 4 + 16) : (ch + 1) \ -) +typedef enum { + DMA_PRIO_HIGH = 0, + DMA_PRIO_MEDIUM = 8, + DMA_PRIO_LOW = 16 +} pxa_dma_prio; #elif defined(CONFIG_PXA25x) #define PXA_DMA_CHANNELS 16 +#define PXA_DMA_NBCH(prio) ((prio == DMA_PRIO_LOW) ? 8 : 4) -#define pxa_for_each_dma_prio(ch, prio) \ - for (ch = prio * 4; ch != (4 << prio); ch++) +typedef enum { + DMA_PRIO_HIGH = 0, + DMA_PRIO_MEDIUM = 4, + DMA_PRIO_LOW = 8 +} pxa_dma_prio; #endif diff --git a/trunk/include/asm-arm/arch-pxa/pxa2xx_spi.h b/trunk/include/asm-arm/arch-pxa/pxa2xx_spi.h deleted file mode 100644 index 915590c391c8..000000000000 --- a/trunk/include/asm-arm/arch-pxa/pxa2xx_spi.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef PXA2XX_SPI_H_ -#define PXA2XX_SPI_H_ - -#define PXA2XX_CS_ASSERT (0x01) -#define PXA2XX_CS_DEASSERT (0x02) - -#if defined(CONFIG_PXA25x) -#define CLOCK_SPEED_HZ 3686400 -#define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/2/(x+1))<<8)&0x0000ff00) -#define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00) -#define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00) -#define SSP_TIMEOUT_SCALE (2712) -#elif defined(CONFIG_PXA27x) -#define CLOCK_SPEED_HZ 13000000 -#define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00) -#define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00) -#define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00) -#define SSP_TIMEOUT_SCALE (769) -#endif - -#define SSP_TIMEOUT(x) ((x*10000)/SSP_TIMEOUT_SCALE) -#define SSP1_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(1))))) -#define SSP2_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(2))))) -#define SSP3_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(3))))) - -enum pxa_ssp_type { - SSP_UNDEFINED = 0, - PXA25x_SSP, /* pxa 210, 250, 255, 26x */ - PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ - PXA27x_SSP, -}; - -/* device.platform_data for SSP controller devices */ -struct pxa2xx_spi_master { - enum pxa_ssp_type ssp_type; - u32 clock_enable; - u16 num_chipselect; - u8 enable_dma; -}; - -/* spi_board_info.controller_data for SPI slave devices, - * copied to spi_device.platform_data ... mostly for dma tuning - */ -struct pxa2xx_spi_chip { - u8 tx_threshold; - u8 rx_threshold; - u8 dma_burst_size; - u32 timeout_microsecs; - u8 enable_loopback; - void (*cs_control)(u32 command); -}; - -#endif /*PXA2XX_SPI_H_*/ diff --git a/trunk/include/asm-arm/arch-s3c2410/spi-gpio.h b/trunk/include/asm-arm/arch-s3c2410/spi-gpio.h deleted file mode 100644 index 258c00bca270..000000000000 --- a/trunk/include/asm-arm/arch-s3c2410/spi-gpio.h +++ /dev/null @@ -1,31 +0,0 @@ -/* linux/include/asm-arm/arch-s3c2410/spi.h - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * S3C2410 - SPI Controller platfrom_device info - * - * 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. -*/ - -#ifndef __ASM_ARCH_SPIGPIO_H -#define __ASM_ARCH_SPIGPIO_H __FILE__ - -struct s3c2410_spigpio_info; -struct spi_board_info; - -struct s3c2410_spigpio_info { - unsigned long pin_clk; - unsigned long pin_mosi; - unsigned long pin_miso; - - unsigned long board_size; - struct spi_board_info *board_info; - - void (*chip_select)(struct s3c2410_spigpio_info *spi, int cs); -}; - - -#endif /* __ASM_ARCH_SPIGPIO_H */ diff --git a/trunk/include/asm-arm/arch-s3c2410/spi.h b/trunk/include/asm-arm/arch-s3c2410/spi.h deleted file mode 100644 index 4029a1a1ab40..000000000000 --- a/trunk/include/asm-arm/arch-s3c2410/spi.h +++ /dev/null @@ -1,29 +0,0 @@ -/* linux/include/asm-arm/arch-s3c2410/spi.h - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * S3C2410 - SPI Controller platform_device info - * - * 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. -*/ - -#ifndef __ASM_ARCH_SPI_H -#define __ASM_ARCH_SPI_H __FILE__ - -struct s3c2410_spi_info; -struct spi_board_info; - -struct s3c2410_spi_info { - unsigned long pin_cs; /* simple gpio cs */ - - unsigned long board_size; - struct spi_board_info *board_info; - - void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); -}; - - -#endif /* __ASM_ARCH_SPI_H */ diff --git a/trunk/include/asm-arm/bug.h b/trunk/include/asm-arm/bug.h index 5ab8216f5204..7fb02138f585 100644 --- a/trunk/include/asm-arm/bug.h +++ b/trunk/include/asm-arm/bug.h @@ -2,7 +2,6 @@ #define _ASMARM_BUG_H #include -#include #ifdef CONFIG_BUG #ifdef CONFIG_DEBUG_BUGVERBOSE diff --git a/trunk/include/asm-arm/procinfo.h b/trunk/include/asm-arm/procinfo.h index 842526055225..a9c75b2c314f 100644 --- a/trunk/include/asm-arm/procinfo.h +++ b/trunk/include/asm-arm/procinfo.h @@ -45,6 +45,8 @@ extern unsigned int elf_hwcap; #endif /* __ASSEMBLY__ */ +#define PROC_INFO_SZ 48 + #define HWCAP_SWP 1 #define HWCAP_HALF 2 #define HWCAP_THUMB 4 diff --git a/trunk/include/asm-arm/spinlock.h b/trunk/include/asm-arm/spinlock.h index 406ca97a8ab2..43ad4e55878c 100644 --- a/trunk/include/asm-arm/spinlock.h +++ b/trunk/include/asm-arm/spinlock.h @@ -142,9 +142,6 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) : "cc"); } -/* write_can_lock - would write_trylock() succeed? */ -#define __raw_write_can_lock(x) ((x)->lock == 0x80000000) - /* * Read locks are a bit more hairy: * - Exclusively load the lock value. @@ -201,7 +198,4 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) #define __raw_read_trylock(lock) generic__raw_read_trylock(lock) -/* read_can_lock - would read_trylock() succeed? */ -#define __raw_read_can_lock(x) ((x)->lock < 0x80000000) - #endif /* __ASM_SPINLOCK_H */ diff --git a/trunk/include/asm-arm/unistd.h b/trunk/include/asm-arm/unistd.h index cbf39a56dbe7..26f2f4828e03 100644 --- a/trunk/include/asm-arm/unistd.h +++ b/trunk/include/asm-arm/unistd.h @@ -363,7 +363,7 @@ /* * The following syscalls are obsolete and no longer available for EABI. */ -#if defined(__ARM_EABI__) && !defined(__KERNEL__) +#if defined(__ARM_EABI__) #undef __NR_time #undef __NR_umount #undef __NR_stime diff --git a/trunk/include/asm-i386/io_apic.h b/trunk/include/asm-i386/io_apic.h index d92e253f7f6f..51c4e5fe6062 100644 --- a/trunk/include/asm-i386/io_apic.h +++ b/trunk/include/asm-i386/io_apic.h @@ -200,7 +200,6 @@ extern int io_apic_get_unique_id (int ioapic, int apic_id); extern int io_apic_get_version (int ioapic); extern int io_apic_get_redir_entries (int ioapic); extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low); -extern int timer_uses_ioapic_pin_0; #endif /* CONFIG_ACPI */ extern int (*ioapic_renumber_irq)(int ioapic, int irq); diff --git a/trunk/include/asm-ia64/bitops.h b/trunk/include/asm-ia64/bitops.h index 6cc517e212a9..90921e162793 100644 --- a/trunk/include/asm-ia64/bitops.h +++ b/trunk/include/asm-ia64/bitops.h @@ -11,6 +11,7 @@ #include #include +#include #include /** diff --git a/trunk/include/asm-powerpc/unistd.h b/trunk/include/asm-powerpc/unistd.h index edde2462bf52..908acb44cb8a 100644 --- a/trunk/include/asm-powerpc/unistd.h +++ b/trunk/include/asm-powerpc/unistd.h @@ -321,10 +321,8 @@ #define __NR_readlinkat 296 #define __NR_fchmodat 297 #define __NR_faccessat 298 -#define __NR_get_robust_list 299 -#define __NR_set_robust_list 300 -#define __NR_syscalls 301 +#define __NR_syscalls 299 #ifdef __KERNEL__ #define __NR__exit __NR_exit diff --git a/trunk/include/asm-ppc/page.h b/trunk/include/asm-ppc/page.h index 0fb68a0b0181..a70ba2ee552d 100644 --- a/trunk/include/asm-ppc/page.h +++ b/trunk/include/asm-ppc/page.h @@ -20,7 +20,6 @@ /* This must match what is in arch/ppc/Makefile */ #define PAGE_OFFSET CONFIG_KERNEL_START #define KERNELBASE PAGE_OFFSET -#define is_kernel_addr(x) ((x) >= PAGE_OFFSET) #ifndef __ASSEMBLY__ diff --git a/trunk/include/asm-s390/unistd.h b/trunk/include/asm-s390/unistd.h index 41c2792ff6b0..657d582e8149 100644 --- a/trunk/include/asm-s390/unistd.h +++ b/trunk/include/asm-s390/unistd.h @@ -296,14 +296,8 @@ #define __NR_pselect6 301 #define __NR_ppoll 302 #define __NR_unshare 303 -#define __NR_set_robust_list 304 -#define __NR_get_robust_list 305 -#define __NR_splice 306 -#define __NR_sync_file_range 307 -#define __NR_tee 308 -#define __NR_vmsplice 309 -#define NR_syscalls 310 +#define NR_syscalls 304 /* * There are some system calls that are not present on 64 bit, some diff --git a/trunk/include/asm-sparc/unistd.h b/trunk/include/asm-sparc/unistd.h index 45a576507785..f5611a721fbd 100644 --- a/trunk/include/asm-sparc/unistd.h +++ b/trunk/include/asm-sparc/unistd.h @@ -316,13 +316,11 @@ #define __NR_pselect6 297 #define __NR_ppoll 298 #define __NR_unshare 299 -#define __NR_set_robust_list 300 -#define __NR_get_robust_list 301 -/* WARNING: You MAY NOT add syscall numbers larger than 301, since +/* WARNING: You MAY NOT add syscall numbers larger than 299, since * all of the syscall tables in the Sparc kernel are - * sized to have 301 entries (starting at zero). Therefore - * find a free slot in the 0-301 range. + * sized to have 299 entries (starting at zero). Therefore + * find a free slot in the 0-299 range. */ #define _syscall0(type,name) \ diff --git a/trunk/include/asm-sparc64/dma-mapping.h b/trunk/include/asm-sparc64/dma-mapping.h index a8d39f23d43b..c7d5804ba76d 100644 --- a/trunk/include/asm-sparc64/dma-mapping.h +++ b/trunk/include/asm-sparc64/dma-mapping.h @@ -4,146 +4,7 @@ #include #ifdef CONFIG_PCI - -/* we implement the API below in terms of the existing PCI one, - * so include it */ -#include -/* need struct page definitions */ -#include - -static inline int -dma_supported(struct device *dev, u64 mask) -{ - BUG_ON(dev->bus != &pci_bus_type); - - return pci_dma_supported(to_pci_dev(dev), mask); -} - -static inline int -dma_set_mask(struct device *dev, u64 dma_mask) -{ - BUG_ON(dev->bus != &pci_bus_type); - - return pci_set_dma_mask(to_pci_dev(dev), dma_mask); -} - -static inline void * -dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, - gfp_t flag) -{ - BUG_ON(dev->bus != &pci_bus_type); - - return pci_iommu_ops->alloc_consistent(to_pci_dev(dev), size, dma_handle, flag); -} - -static inline void -dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle) -{ - BUG_ON(dev->bus != &pci_bus_type); - - pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle); -} - -static inline dma_addr_t -dma_map_single(struct device *dev, void *cpu_addr, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction); -} - -static inline void -dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction); -} - -static inline dma_addr_t -dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - return pci_map_page(to_pci_dev(dev), page, offset, size, (int)direction); -} - -static inline void -dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - pci_unmap_page(to_pci_dev(dev), dma_address, size, (int)direction); -} - -static inline int -dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction); -} - -static inline void -dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction); -} - -static inline void -dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle, - size, (int)direction); -} - -static inline void -dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle, - size, (int)direction); -} - -static inline void -dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg, nelems, (int)direction); -} - -static inline void -dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, - enum dma_data_direction direction) -{ - BUG_ON(dev->bus != &pci_bus_type); - - pci_dma_sync_sg_for_device(to_pci_dev(dev), sg, nelems, (int)direction); -} - -static inline int -dma_mapping_error(dma_addr_t dma_addr) -{ - return pci_dma_mapping_error(dma_addr); -} - +#include #else struct device; diff --git a/trunk/include/asm-sparc64/pci.h b/trunk/include/asm-sparc64/pci.h index e1ea67bc32f2..7c5a589ea437 100644 --- a/trunk/include/asm-sparc64/pci.h +++ b/trunk/include/asm-sparc64/pci.h @@ -42,7 +42,7 @@ static inline void pcibios_penalize_isa_irq(int irq, int active) struct pci_dev; struct pci_iommu_ops { - void *(*alloc_consistent)(struct pci_dev *, size_t, dma_addr_t *, gfp_t); + void *(*alloc_consistent)(struct pci_dev *, size_t, dma_addr_t *); void (*free_consistent)(struct pci_dev *, size_t, void *, dma_addr_t); dma_addr_t (*map_single)(struct pci_dev *, void *, size_t, int); void (*unmap_single)(struct pci_dev *, dma_addr_t, size_t, int); @@ -59,7 +59,7 @@ extern struct pci_iommu_ops *pci_iommu_ops; */ static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) { - return pci_iommu_ops->alloc_consistent(hwdev, size, dma_handle, GFP_ATOMIC); + return pci_iommu_ops->alloc_consistent(hwdev, size, dma_handle); } /* Free and unmap a consistent DMA buffer. diff --git a/trunk/include/asm-sparc64/unistd.h b/trunk/include/asm-sparc64/unistd.h index 998ef4ab0e06..68705748bec0 100644 --- a/trunk/include/asm-sparc64/unistd.h +++ b/trunk/include/asm-sparc64/unistd.h @@ -318,13 +318,11 @@ #define __NR_pselect6 297 #define __NR_ppoll 298 #define __NR_unshare 299 -#define __NR_set_robust_list 300 -#define __NR_get_robust_list 301 -/* WARNING: You MAY NOT add syscall numbers larger than 301, since +/* WARNING: You MAY NOT add syscall numbers larger than 299, since * all of the syscall tables in the Sparc kernel are - * sized to have 301 entries (starting at zero). Therefore - * find a free slot in the 0-301 range. + * sized to have 299 entries (starting at zero). Therefore + * find a free slot in the 0-299 range. */ #define _syscall0(type,name) \ diff --git a/trunk/include/asm-x86_64/e820.h b/trunk/include/asm-x86_64/e820.h index 670a3388e70a..93b51df51687 100644 --- a/trunk/include/asm-x86_64/e820.h +++ b/trunk/include/asm-x86_64/e820.h @@ -59,8 +59,6 @@ extern void __init parse_memopt(char *p, char **end); extern void __init parse_memmapopt(char *p, char **end); extern struct e820map e820; - -extern unsigned ebda_addr, ebda_size; #endif/*!__ASSEMBLY__*/ #endif/*__E820_HEADER*/ diff --git a/trunk/include/asm-x86_64/io_apic.h b/trunk/include/asm-x86_64/io_apic.h index 52484e82c641..ee1bc69aec9c 100644 --- a/trunk/include/asm-x86_64/io_apic.h +++ b/trunk/include/asm-x86_64/io_apic.h @@ -205,7 +205,6 @@ extern int skip_ioapic_setup; extern int io_apic_get_version (int ioapic); extern int io_apic_get_redir_entries (int ioapic); extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int); -extern int timer_uses_ioapic_pin_0; #endif extern int sis_apic_bug; /* dummy */ diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index e8e53b9accc6..f6e72a65a3f2 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -200,7 +200,6 @@ extern int class_device_create_file(struct class_device *, * @node: for internal use by the driver core only. * @kobj: for internal use by the driver core only. * @devt_attr: for internal use by the driver core only. - * @groups: optional additional groups to be created * @dev: if set, a symlink to the struct device is created in the sysfs * directory for this struct class device. * @class_data: pointer to whatever you want to store here for this struct @@ -229,7 +228,6 @@ struct class_device { struct device * dev; /* not necessary, but nice to have */ void * class_data; /* class-specific data */ struct class_device *parent; /* parent of this child device, if there is one */ - struct attribute_group ** groups; /* optional groups */ void (*release)(struct class_device *dev); int (*uevent)(struct class_device *dev, char **envp, diff --git a/trunk/include/linux/dma-mapping.h b/trunk/include/linux/dma-mapping.h index 635690cf3e3d..ff61817082fa 100644 --- a/trunk/include/linux/dma-mapping.h +++ b/trunk/include/linux/dma-mapping.h @@ -14,7 +14,6 @@ enum dma_data_direction { }; #define DMA_64BIT_MASK 0xffffffffffffffffULL -#define DMA_48BIT_MASK 0x0000ffffffffffffULL #define DMA_40BIT_MASK 0x000000ffffffffffULL #define DMA_39BIT_MASK 0x0000007fffffffffULL #define DMA_32BIT_MASK 0x00000000ffffffffULL diff --git a/trunk/include/linux/firmware.h b/trunk/include/linux/firmware.h index 33d8f2087b6e..2d716080be4a 100644 --- a/trunk/include/linux/firmware.h +++ b/trunk/include/linux/firmware.h @@ -19,4 +19,5 @@ int request_firmware_nowait( void (*cont)(const struct firmware *fw, void *context)); void release_firmware(const struct firmware *fw); +void register_firmware(const char *name, const u8 *data, size_t size); #endif diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index f813bc8266aa..3de2bfb2410f 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -213,10 +213,6 @@ extern int dir_notify_enable; #define FIBMAP _IO(0x00,1) /* bmap access */ #define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */ -#define SYNC_FILE_RANGE_WAIT_BEFORE 1 -#define SYNC_FILE_RANGE_WRITE 2 -#define SYNC_FILE_RANGE_WAIT_AFTER 4 - #ifdef __KERNEL__ #include @@ -762,6 +758,9 @@ extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); extern int fcntl_getlease(struct file *filp); /* fs/sync.c */ +#define SYNC_FILE_RANGE_WAIT_BEFORE 1 +#define SYNC_FILE_RANGE_WRITE 2 +#define SYNC_FILE_RANGE_WAIT_AFTER 4 extern int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte, unsigned int flags); diff --git a/trunk/include/linux/fsl_devices.h b/trunk/include/linux/fsl_devices.h index 16fbe59edeb1..a3a0e078f79d 100644 --- a/trunk/include/linux/fsl_devices.h +++ b/trunk/include/linux/fsl_devices.h @@ -110,16 +110,5 @@ struct fsl_usb2_platform_data { #define FSL_USB2_PORT0_ENABLED 0x00000001 #define FSL_USB2_PORT1_ENABLED 0x00000002 -struct fsl_spi_platform_data { - u32 initial_spmode; /* initial SPMODE value */ - u16 bus_num; - - /* board specific information */ - u16 max_chipselect; - void (*activate_cs)(u8 cs, u8 polarity); - void (*deactivate_cs)(u8 cs, u8 polarity); - u32 sysclk; -}; - #endif /* _FSL_DEVICE_H_ */ #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index f4fc576ed4c4..e1bd0842f6a1 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -124,7 +124,6 @@ extern int get_option(char **str, int *pint); extern char *get_options(const char *str, int nints, int *ints); extern unsigned long long memparse(char *ptr, char **retptr); -extern int core_kernel_text(unsigned long addr); extern int __kernel_text_address(unsigned long addr); extern int kernel_text_address(unsigned long addr); extern int session_of_pgrp(int pgrp); diff --git a/trunk/include/linux/mmc/mmc.h b/trunk/include/linux/mmc/mmc.h index 03a14a30c46a..bdc556d88498 100644 --- a/trunk/include/linux/mmc/mmc.h +++ b/trunk/include/linux/mmc/mmc.h @@ -69,7 +69,6 @@ struct mmc_data { unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ unsigned int timeout_clks; /* data timeout (in clocks) */ unsigned int blksz_bits; /* data block size */ - unsigned int blksz; /* data block size */ unsigned int blocks; /* number of blocks */ unsigned int error; /* data error */ unsigned int flags; diff --git a/trunk/include/linux/mmzone.h b/trunk/include/linux/mmzone.h index 36740354d4db..b5c21122c299 100644 --- a/trunk/include/linux/mmzone.h +++ b/trunk/include/linux/mmzone.h @@ -22,7 +22,6 @@ #else #define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER #endif -#define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1)) struct free_area { struct list_head free_list; diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index f4169bbb60eb..01db7b88a2b1 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -433,7 +433,8 @@ struct net_device /* register/unregister state machine */ enum { NETREG_UNINITIALIZED=0, - NETREG_REGISTERED, /* completed register_netdevice */ + NETREG_REGISTERING, /* called register_netdevice */ + NETREG_REGISTERED, /* completed register todo */ NETREG_UNREGISTERING, /* called unregister_netdevice */ NETREG_UNREGISTERED, /* completed unregister todo */ NETREG_RELEASED, /* called free_netdev */ @@ -505,8 +506,6 @@ struct net_device /* class/net/name entry */ struct class_device class_dev; - /* space for optional statistics and wireless sysfs groups */ - struct attribute_group *sysfs_groups[3]; }; #define NETDEV_ALIGN 32 @@ -830,19 +829,21 @@ static inline void netif_rx_schedule(struct net_device *dev) __netif_rx_schedule(dev); } -/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). - * Do not inline this? - */ + +static inline void __netif_rx_reschedule(struct net_device *dev, int undo) +{ + dev->quota += undo; + list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); + __raise_softirq_irqoff(NET_RX_SOFTIRQ); +} + +/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). */ static inline int netif_rx_reschedule(struct net_device *dev, int undo) { if (netif_rx_schedule_prep(dev)) { unsigned long flags; - - dev->quota += undo; - local_irq_save(flags); - list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); - __raise_softirq_irqoff(NET_RX_SOFTIRQ); + __netif_rx_reschedule(dev, undo); local_irq_restore(flags); return 1; } diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 6fd36cb09160..3a6a4e37a482 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -442,7 +442,6 @@ struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int devic 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); -int pci_find_ext_capability (struct pci_dev *dev, int cap); struct pci_bus * pci_find_next_bus(const struct pci_bus *from); struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); @@ -663,7 +662,6 @@ static inline int pci_register_driver(struct pci_driver *drv) { return 0;} static inline void pci_unregister_driver(struct pci_driver *drv) { } static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; } -static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; } static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; } /* Power management related routines */ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 151549a69ee0..d6fe048376ab 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -935,7 +935,6 @@ #define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151 #define PCI_DEVICE_ID_PLX_R753 0x1152 #define PCI_DEVICE_ID_PLX_OLITEC 0x1187 -#define PCI_DEVICE_ID_PLX_PCI200SYN 0x3196 #define PCI_DEVICE_ID_PLX_9050 0x9050 #define PCI_DEVICE_ID_PLX_9080 0x9080 #define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001 @@ -1827,7 +1826,6 @@ #define PCI_VENDOR_ID_SAMSUNG 0x144d -#define PCI_VENDOR_ID_MYRICOM 0x14c1 #define PCI_VENDOR_ID_TITAN 0x14D2 #define PCI_DEVICE_ID_TITAN_010L 0x8001 diff --git a/trunk/include/linux/rcupdate.h b/trunk/include/linux/rcupdate.h index 970284f571a6..5673008b61e1 100644 --- a/trunk/include/linux/rcupdate.h +++ b/trunk/include/linux/rcupdate.h @@ -132,7 +132,6 @@ static inline void rcu_bh_qsctr_inc(int cpu) } extern int rcu_pending(int cpu); -extern int rcu_needs_cpu(int cpu); /** * rcu_read_lock - mark the beginning of an RCU read-side critical section. diff --git a/trunk/include/linux/serial_core.h b/trunk/include/linux/serial_core.h index bd14858121ea..c32e60e79dea 100644 --- a/trunk/include/linux/serial_core.h +++ b/trunk/include/linux/serial_core.h @@ -254,7 +254,6 @@ struct uart_port { #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) -#define UPF_DEAD ((__force upf_t) (1 << 30)) #define UPF_IOREMAP ((__force upf_t) (1 << 31)) #define UPF_CHANGE_MASK ((__force upf_t) (0x17fff)) diff --git a/trunk/include/linux/slab.h b/trunk/include/linux/slab.h index 2d985d59c7b8..3af03b19c983 100644 --- a/trunk/include/linux/slab.h +++ b/trunk/include/linux/slab.h @@ -150,7 +150,6 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags) extern void kfree(const void *); extern unsigned int ksize(const void *); -extern int slab_is_available(void); #ifdef CONFIG_NUMA extern void *kmem_cache_alloc_node(kmem_cache_t *, gfp_t flags, int node); diff --git a/trunk/include/linux/spi/spi.h b/trunk/include/linux/spi/spi.h index e928c0dcc297..b05f1463a267 100644 --- a/trunk/include/linux/spi/spi.h +++ b/trunk/include/linux/spi/spi.h @@ -31,23 +31,18 @@ extern struct bus_type spi_bus_type; * @master: SPI controller used with the device. * @max_speed_hz: Maximum clock rate to be used with this chip * (on this board); may be changed by the device's driver. - * The spi_transfer.speed_hz can override this for each transfer. * @chip-select: Chipselect, distinguishing chips handled by "master". * @mode: The spi mode defines how data is clocked out and in. * This may be changed by the device's driver. - * The "active low" default for chipselect mode can be overridden, - * as can the "MSB first" default for each word in a transfer. * @bits_per_word: Data transfers involve one or more words; word sizes - * like eight or 12 bits are common. In-memory wordsizes are + * like eight or 12 bits are common. In-memory wordsizes are * powers of two bytes (e.g. 20 bit samples use 32 bits). - * This may be changed by the device's driver, or left at the - * default (0) indicating protocol words are eight bit bytes. - * The spi_transfer.bits_per_word can override this for each transfer. + * This may be changed by the device's driver. * @irq: Negative, or the number passed to request_irq() to receive - * interrupts from this device. + * interrupts from this device. * @controller_state: Controller's runtime state * @controller_data: Board-specific definitions for controller, such as - * FIFO initialization parameters; from board_info.controller_data + * FIFO initialization parameters; from board_info.controller_data * * An spi_device is used to interchange data between an SPI slave * (usually a discrete chip) and CPU memory. @@ -70,7 +65,6 @@ struct spi_device { #define SPI_MODE_2 (SPI_CPOL|0) #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) #define SPI_CS_HIGH 0x04 /* chipselect active high? */ -#define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ u8 bits_per_word; int irq; void *controller_state; @@ -79,6 +73,7 @@ struct spi_device { // likely need more hooks for more protocol options affecting how // the controller talks to each chip, like: + // - bit order (default is wordwise msb-first) // - memory packing (12 bit samples into low bits, others zeroed) // - priority // - drop chipselect after each word @@ -148,13 +143,13 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * struct spi_master - interface to SPI master controller * @cdev: class interface to this driver * @bus_num: board-specific (and often SOC-specific) identifier for a - * given SPI controller. + * given SPI controller. * @num_chipselect: chipselects are used to distinguish individual - * SPI slaves, and are numbered from zero to num_chipselects. - * each slave has a chipselect signal, but it's common that not - * every chipselect is connected to a slave. + * SPI slaves, and are numbered from zero to num_chipselects. + * each slave has a chipselect signal, but it's common that not + * every chipselect is connected to a slave. * @setup: updates the device mode and clocking records used by a - * device's SPI controller; protocol code may call this. + * device's SPI controller; protocol code may call this. * @transfer: adds a message to the controller's transfer queue. * @cleanup: frees controller-specific state * @@ -172,13 +167,13 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) struct spi_master { struct class_device cdev; - /* other than negative (== assign one dynamically), bus_num is fully + /* other than zero (== assign one dynamically), bus_num is fully * board-specific. usually that simplifies to being SOC-specific. - * example: one SOC has three SPI controllers, numbered 0..2, + * example: one SOC has three SPI controllers, numbered 1..3, * and one board's schematics might show it using SPI-2. software * would normally use bus_num=2 for that controller. */ - s16 bus_num; + u16 bus_num; /* chipselects will be integral to many controllers; some others * might use board-specific GPIOs. @@ -273,14 +268,10 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); * @tx_dma: DMA address of tx_buf, if spi_message.is_dma_mapped * @rx_dma: DMA address of rx_buf, if spi_message.is_dma_mapped * @len: size of rx and tx buffers (in bytes) - * @speed_hz: Select a speed other then the device default for this - * transfer. If 0 the default (from spi_device) is used. - * @bits_per_word: select a bits_per_word other then the device default - * for this transfer. If 0 the default (from spi_device) is used. * @cs_change: affects chipselect after this transfer completes * @delay_usecs: microseconds to delay after this transfer before - * (optionally) changing the chipselect status, then starting - * the next transfer or completing this spi_message. + * (optionally) changing the chipselect status, then starting + * the next transfer or completing this spi_message. * @transfer_list: transfers are sequenced through spi_message.transfers * * SPI transfers always write the same number of bytes as they read. @@ -331,9 +322,7 @@ struct spi_transfer { dma_addr_t rx_dma; unsigned cs_change:1; - u8 bits_per_word; u16 delay_usecs; - u32 speed_hz; struct list_head transfer_list; }; @@ -367,7 +356,7 @@ struct spi_transfer { * and its transfers, ignore them until its completion callback. */ struct spi_message { - struct list_head transfers; + struct list_head transfers; struct spi_device *spi; @@ -385,7 +374,7 @@ struct spi_message { */ /* completion is reported through a callback */ - void (*complete)(void *context); + void (*complete)(void *context); void *context; unsigned actual_length; int status; diff --git a/trunk/include/linux/spi/spi_bitbang.h b/trunk/include/linux/spi/spi_bitbang.h index 16ce178f54d7..c961fe9bf3eb 100644 --- a/trunk/include/linux/spi/spi_bitbang.h +++ b/trunk/include/linux/spi/spi_bitbang.h @@ -30,12 +30,6 @@ struct spi_bitbang { struct spi_master *master; - /* setup_transfer() changes clock and/or wordsize to match settings - * for this transfer; zeroes restore defaults from spi_device. - */ - int (*setup_transfer)(struct spi_device *spi, - struct spi_transfer *t); - void (*chipselect)(struct spi_device *spi, int is_on); #define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */ #define BITBANG_CS_INACTIVE 0 @@ -57,8 +51,6 @@ struct spi_bitbang { extern int spi_bitbang_setup(struct spi_device *spi); extern void spi_bitbang_cleanup(const struct spi_device *spi); extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m); -extern int spi_bitbang_setup_transfer(struct spi_device *spi, - struct spi_transfer *t); /* start or stop queue processing */ extern int spi_bitbang_start(struct spi_bitbang *spi); diff --git a/trunk/include/linux/swap.h b/trunk/include/linux/swap.h index f03c24719302..5b1fdf1cff4f 100644 --- a/trunk/include/linux/swap.h +++ b/trunk/include/linux/swap.h @@ -296,7 +296,7 @@ static inline void disable_swap_token(void) #define read_swap_cache_async(swp,vma,addr) NULL #define lookup_swap_cache(swp) NULL #define valid_swaphandles(swp, off) 0 -#define can_share_swap_page(p) (page_mapcount(p) == 1) +#define can_share_swap_page(p) 0 #define move_to_swap_cache(p, swp) 1 #define move_from_swap_cache(p, i, m) 1 #define __delete_from_swap_cache(p) /*NOTHING*/ diff --git a/trunk/include/linux/syscalls.h b/trunk/include/linux/syscalls.h index 60d49e5456e7..3996960fc565 100644 --- a/trunk/include/linux/syscalls.h +++ b/trunk/include/linux/syscalls.h @@ -52,7 +52,6 @@ struct utimbuf; struct mq_attr; struct compat_stat; struct compat_timeval; -struct robust_list_head; #include #include @@ -582,10 +581,5 @@ asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, unsigned int flags); -asmlinkage long sys_get_robust_list(int pid, - struct robust_list_head __user **head_ptr, - size_t __user *len_ptr); -asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, - size_t len); #endif diff --git a/trunk/include/linux/videodev2.h b/trunk/include/linux/videodev2.h index ad7fa9c86c10..d7670ec1ec1e 100644 --- a/trunk/include/linux/videodev2.h +++ b/trunk/include/linux/videodev2.h @@ -1141,13 +1141,8 @@ extern char *v4l2_type_names[]; /* Compatibility layer interface -- v4l1-compat module */ typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file, unsigned int cmd, void *arg); - -#ifdef CONFIG_VIDEO_V4L1_COMPAT int v4l_compat_translate_ioctl(struct inode *inode, struct file *file, int cmd, void *arg, v4l2_kioctl driver_ioctl); -#else -#define v4l_compat_translate_ioctl(inode,file,cmd,arg,ioctl) -EINVAL -#endif /* 32 Bits compatibility layer for 64 bits processors */ extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd, diff --git a/trunk/include/net/ieee80211.h b/trunk/include/net/ieee80211.h index 293e920ca59d..4087dfc47094 100644 --- a/trunk/include/net/ieee80211.h +++ b/trunk/include/net/ieee80211.h @@ -958,13 +958,11 @@ enum ieee80211_state { #define IEEE80211_24GHZ_MIN_CHANNEL 1 #define IEEE80211_24GHZ_MAX_CHANNEL 14 -#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \ - IEEE80211_24GHZ_MIN_CHANNEL + 1) +#define IEEE80211_24GHZ_CHANNELS 14 #define IEEE80211_52GHZ_MIN_CHANNEL 34 #define IEEE80211_52GHZ_MAX_CHANNEL 165 -#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \ - IEEE80211_52GHZ_MIN_CHANNEL + 1) +#define IEEE80211_52GHZ_CHANNELS 131 enum { IEEE80211_CH_PASSIVE_ONLY = (1 << 0), diff --git a/trunk/include/net/ieee80211softmac.h b/trunk/include/net/ieee80211softmac.h index 052ed596a4e4..b1ebfbae397f 100644 --- a/trunk/include/net/ieee80211softmac.h +++ b/trunk/include/net/ieee80211softmac.h @@ -204,8 +204,7 @@ struct ieee80211softmac_device { /* couple of flags */ u8 scanning:1, /* protects scanning from being done multiple times at once */ - associated:1, - running:1; + associated:1; struct ieee80211softmac_scaninfo *scaninfo; struct ieee80211softmac_assoc_info associnfo; diff --git a/trunk/include/net/irda/irlmp.h b/trunk/include/net/irda/irlmp.h index c0c895d379ba..86aefb1fda5e 100644 --- a/trunk/include/net/irda/irlmp.h +++ b/trunk/include/net/irda/irlmp.h @@ -112,7 +112,7 @@ struct lsap_cb { struct timer_list watchdog_timer; - LSAP_STATE lsap_state; /* Connection state */ + IRLMP_STATE lsap_state; /* Connection state */ notify_t notify; /* Indication/Confirm entry points */ struct qos_info qos; /* QoS for this connection */ diff --git a/trunk/include/net/neighbour.h b/trunk/include/net/neighbour.h index 4901ee446879..b0666d66293f 100644 --- a/trunk/include/net/neighbour.h +++ b/trunk/include/net/neighbour.h @@ -211,7 +211,6 @@ struct neigh_table #define NEIGH_UPDATE_F_ADMIN 0x80000000 extern void neigh_table_init(struct neigh_table *tbl); -extern void neigh_table_init_no_netlink(struct neigh_table *tbl); extern int neigh_table_clear(struct neigh_table *tbl); extern struct neighbour * neigh_lookup(struct neigh_table *tbl, const void *pkey, diff --git a/trunk/include/net/sctp/command.h b/trunk/include/net/sctp/command.h index 807d6f1ef4b5..34a1a09e5aef 100644 --- a/trunk/include/net/sctp/command.h +++ b/trunk/include/net/sctp/command.h @@ -99,7 +99,6 @@ typedef enum { SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */ SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */ SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */ - SCTP_CMD_SET_SK_ERR, /* Set sk_err */ SCTP_CMD_LAST } sctp_verb_t; diff --git a/trunk/include/net/sctp/sctp.h b/trunk/include/net/sctp/sctp.h index aa6033ca7cd8..e673b2c984e9 100644 --- a/trunk/include/net/sctp/sctp.h +++ b/trunk/include/net/sctp/sctp.h @@ -461,12 +461,12 @@ static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu) * there is room for a param header too. */ #define sctp_walk_params(pos, chunk, member)\ -_sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member) +_sctp_walk_params((pos), (chunk), WORD_ROUND(ntohs((chunk)->chunk_hdr.length)), member) #define _sctp_walk_params(pos, chunk, end, member)\ for (pos.v = chunk->member;\ pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\ - pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\ + pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\ ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\ pos.v += WORD_ROUND(ntohs(pos.p->length))) @@ -477,7 +477,7 @@ _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length)) for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \ sizeof(sctp_chunkhdr_t));\ (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\ - (void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\ + (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\ ntohs(err->length) >= sizeof(sctp_errhdr_t); \ err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length)))) diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h index 7f4fea173fb1..eba99f375517 100644 --- a/trunk/include/net/sctp/structs.h +++ b/trunk/include/net/sctp/structs.h @@ -712,7 +712,6 @@ struct sctp_chunk { __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ __u8 tsn_missing_report; /* Data chunk missing counter. */ - __u8 data_accepted; /* At least 1 chunk in this packet accepted */ }; void sctp_chunk_hold(struct sctp_chunk *); diff --git a/trunk/include/scsi/srp.h b/trunk/include/scsi/srp.h index 637f77eccf0c..6c2681dc5b46 100644 --- a/trunk/include/scsi/srp.h +++ b/trunk/include/scsi/srp.h @@ -95,15 +95,14 @@ struct srp_direct_buf { /* * We need the packed attribute because the SRP spec puts the list of - * descriptors at an offset of 20, which is not aligned to the size of - * struct srp_direct_buf. The whole structure must be packed to avoid - * having the 20-byte structure padded to 24 bytes on 64-bit architectures. + * descriptors at an offset of 20, which is not aligned to the size + * of struct srp_direct_buf. */ struct srp_indirect_buf { struct srp_direct_buf table_desc; __be32 len; - struct srp_direct_buf desc_list[0]; -} __attribute__((packed)); + struct srp_direct_buf desc_list[0] __attribute__((packed)); +}; enum { SRP_MULTICHAN_SINGLE = 0, @@ -123,11 +122,6 @@ struct srp_login_req { u8 target_port_id[16]; }; -/* - * The SRP spec defines the size of the LOGIN_RSP structure to be 52 - * bytes, so it needs to be packed to avoid having it padded to 56 - * bytes on 64-bit architectures. - */ struct srp_login_rsp { u8 opcode; u8 reserved1[3]; @@ -138,7 +132,7 @@ struct srp_login_rsp { __be16 buf_fmt; u8 rsp_flags; u8 reserved2[25]; -} __attribute__((packed)); +}; struct srp_login_rej { u8 opcode; @@ -213,11 +207,6 @@ enum { SRP_RSP_FLAG_DIUNDER = 1 << 5 }; -/* - * The SRP spec defines the size of the RSP structure to be 36 bytes, - * so it needs to be packed to avoid having it padded to 40 bytes on - * 64-bit architectures. - */ struct srp_rsp { u8 opcode; u8 sol_not; @@ -232,6 +221,6 @@ struct srp_rsp { __be32 sense_data_len; __be32 resp_data_len; u8 data[0]; -} __attribute__((packed)); +}; #endif /* SCSI_SRP_H */ diff --git a/trunk/init/do_mounts.c b/trunk/init/do_mounts.c index f4b7b9d278cd..adb7cad3e6ee 100644 --- a/trunk/init/do_mounts.c +++ b/trunk/init/do_mounts.c @@ -310,11 +310,6 @@ void __init mount_block_root(char *name, int flags) panic("VFS: Unable to mount root fs on %s", b); } - - printk("No filesystem could mount root, tried: "); - for (p = fs_names; *p; p += strlen(p)+1) - printk(" %s", p); - printk("\n"); panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b)); out: putname(fs_names); diff --git a/trunk/init/initramfs.c b/trunk/init/initramfs.c index f81cfa40a719..679d870d991b 100644 --- a/trunk/init/initramfs.c +++ b/trunk/init/initramfs.c @@ -26,12 +26,10 @@ static void __init free(void *where) /* link hash */ -#define N_ALIGN(len) ((((len) + 1) & ~3) + 2) - static __initdata struct hash { int ino, minor, major; struct hash *next; - char name[N_ALIGN(PATH_MAX)]; + char *name; } *head[32]; static inline int hash(int major, int minor, int ino) @@ -59,7 +57,7 @@ static char __init *find_link(int major, int minor, int ino, char *name) q->ino = ino; q->minor = minor; q->major = major; - strcpy(q->name, name); + q->name = name; q->next = NULL; *p = q; return NULL; @@ -135,6 +133,8 @@ static inline void eat(unsigned n) count -= n; } +#define N_ALIGN(len) ((((len) + 1) & ~3) + 2) + static __initdata char *collected; static __initdata int remains; static __initdata char *collect; diff --git a/trunk/kernel/cpuset.c b/trunk/kernel/cpuset.c index ab81fdd4572b..72248d1b9e3f 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -2231,25 +2231,19 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs) * So only GFP_KERNEL allocations, if all nodes in the cpuset are * short of memory, might require taking the callback_mutex mutex. * - * The first call here from mm/page_alloc:get_page_from_freelist() - * has __GFP_HARDWALL set in gfp_mask, enforcing hardwall cpusets, so - * no allocation on a node outside the cpuset is allowed (unless in - * interrupt, of course). - * - * The second pass through get_page_from_freelist() doesn't even call - * here for GFP_ATOMIC calls. For those calls, the __alloc_pages() - * variable 'wait' is not set, and the bit ALLOC_CPUSET is not set - * in alloc_flags. That logic and the checks below have the combined - * affect that: + * The first loop over the zonelist in mm/page_alloc.c:__alloc_pages() + * calls here with __GFP_HARDWALL always set in gfp_mask, enforcing + * hardwall cpusets - no allocation on a node outside the cpuset is + * allowed (unless in interrupt, of course). + * + * The second loop doesn't even call here for GFP_ATOMIC requests + * (if the __alloc_pages() local variable 'wait' is set). That check + * and the checks below have the combined affect in the second loop of + * the __alloc_pages() routine that: * in_interrupt - any node ok (current task context irrelevant) * GFP_ATOMIC - any node ok * GFP_KERNEL - any node in enclosing mem_exclusive cpuset ok * GFP_USER - only nodes in current tasks mems allowed ok. - * - * Rule: - * Don't call cpuset_zone_allowed() if you can't sleep, unless you - * pass in the __GFP_HARDWALL flag set in gfp_flag, which disables - * the code that might scan up ancestor cpusets and sleep. **/ int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask) @@ -2261,7 +2255,6 @@ int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask) if (in_interrupt()) return 1; node = z->zone_pgdat->node_id; - might_sleep_if(!(gfp_mask & __GFP_HARDWALL)); if (node_isset(node, current->mems_allowed)) return 1; if (gfp_mask & __GFP_HARDWALL) /* If hardwall request, stop here */ diff --git a/trunk/kernel/extable.c b/trunk/kernel/extable.c index 7fe262855317..7501b531ceed 100644 --- a/trunk/kernel/extable.c +++ b/trunk/kernel/extable.c @@ -40,7 +40,7 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr) return e; } -int core_kernel_text(unsigned long addr) +static int core_kernel_text(unsigned long addr) { if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index bbe04862e1b0..d24deb0dbbc9 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -705,14 +705,14 @@ EXPORT_SYMBOL(__symbol_put); void symbol_put_addr(void *addr) { - struct module *modaddr; - - if (core_kernel_text((unsigned long)addr)) - return; + unsigned long flags; - if (!(modaddr = module_text_address((unsigned long)addr))) + spin_lock_irqsave(&modlist_lock, flags); + if (!kernel_text_address((unsigned long)addr)) BUG(); - module_put(modaddr); + + module_put(module_text_address((unsigned long)addr)); + spin_unlock_irqrestore(&modlist_lock, flags); } EXPORT_SYMBOL_GPL(symbol_put_addr); diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index 921c22ad16e4..4e0f0ec003f7 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -148,34 +148,12 @@ int ptrace_may_attach(struct task_struct *task) int ptrace_attach(struct task_struct *task) { int retval; - + task_lock(task); retval = -EPERM; if (task->pid <= 1) - goto out; + goto bad; if (task->tgid == current->tgid) - goto out; - -repeat: - /* - * Nasty, nasty. - * - * We want to hold both the task-lock and the - * tasklist_lock for writing at the same time. - * But that's against the rules (tasklist_lock - * is taken for reading by interrupts on other - * cpu's that may have task_lock). - */ - task_lock(task); - local_irq_disable(); - if (!write_trylock(&tasklist_lock)) { - local_irq_enable(); - task_unlock(task); - do { - cpu_relax(); - } while (!write_can_lock(&tasklist_lock)); - goto repeat; - } - + goto bad; /* the same process cannot be attached many times */ if (task->ptrace & PT_PTRACED) goto bad; @@ -188,15 +166,17 @@ int ptrace_attach(struct task_struct *task) ? PT_ATTACHED : 0); if (capable(CAP_SYS_PTRACE)) task->ptrace |= PT_PTRACE_CAP; + task_unlock(task); + write_lock_irq(&tasklist_lock); __ptrace_link(task, current); + write_unlock_irq(&tasklist_lock); force_sig_specific(SIGSTOP, task); + return 0; bad: - write_unlock_irq(&tasklist_lock); task_unlock(task); -out: return retval; } @@ -437,22 +417,21 @@ int ptrace_request(struct task_struct *child, long request, */ int ptrace_traceme(void) { - int ret = -EPERM; + int ret; /* * Are we already being traced? */ - task_lock(current); - if (!(current->ptrace & PT_PTRACED)) { - ret = security_ptrace(current->parent, current); - /* - * Set the ptrace bit in the process ptrace flags. - */ - if (!ret) - current->ptrace |= PT_PTRACED; - } - task_unlock(current); - return ret; + if (current->ptrace & PT_PTRACED) + return -EPERM; + ret = security_ptrace(current->parent, current); + if (ret) + return -EPERM; + /* + * Set the ptrace bit in the process ptrace flags. + */ + current->ptrace |= PT_PTRACED; + return 0; } /** diff --git a/trunk/kernel/rcupdate.c b/trunk/kernel/rcupdate.c index 2058f88c7bbb..6d32ff26f948 100644 --- a/trunk/kernel/rcupdate.c +++ b/trunk/kernel/rcupdate.c @@ -479,31 +479,12 @@ static int __rcu_pending(struct rcu_ctrlblk *rcp, struct rcu_data *rdp) return 0; } -/* - * Check to see if there is any immediate RCU-related work to be done - * by the current CPU, returning 1 if so. This function is part of the - * RCU implementation; it is -not- an exported member of the RCU API. - */ int rcu_pending(int cpu) { return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) || __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu)); } -/* - * Check to see if any future RCU-related work will need to be done - * by the current CPU, even if none need be done immediately, returning - * 1 if so. This function is part of the RCU implementation; it is -not- - * an exported member of the RCU API. - */ -int rcu_needs_cpu(int cpu) -{ - struct rcu_data *rdp = &per_cpu(rcu_data, cpu); - struct rcu_data *rdp_bh = &per_cpu(rcu_bh_data, cpu); - - return (!!rdp->curlist || !!rdp_bh->curlist || rcu_pending(cpu)); -} - void rcu_check_callbacks(int cpu, int user) { if (user || diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index c13f1bd2df7d..4c64f85698ae 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -664,6 +664,48 @@ static int effective_prio(task_t *p) return prio; } +/* + * We place interactive tasks back into the active array, if possible. + * + * To guarantee that this does not starve expired tasks we ignore the + * interactivity of a task if the first expired task had to wait more + * than a 'reasonable' amount of time. This deadline timeout is + * load-dependent, as the frequency of array switched decreases with + * increasing number of running tasks. We also ignore the interactivity + * if a better static_prio task has expired, and switch periodically + * regardless, to ensure that highly interactive tasks do not starve + * the less fortunate for unreasonably long periods. + */ +static inline int expired_starving(runqueue_t *rq) +{ + int limit; + + /* + * Arrays were recently switched, all is well + */ + if (!rq->expired_timestamp) + return 0; + + limit = STARVATION_LIMIT * rq->nr_running; + + /* + * It's time to switch arrays + */ + if (jiffies - rq->expired_timestamp >= limit) + return 1; + + /* + * There's a better selection in the expired array + */ + if (rq->curr->static_prio > rq->best_expired_prio) + return 1; + + /* + * All is well + */ + return 0; +} + /* * __activate_task - move a task to the runqueue. */ @@ -671,7 +713,7 @@ static void __activate_task(task_t *p, runqueue_t *rq) { prio_array_t *target = rq->active; - if (batch_task(p)) + if (unlikely(batch_task(p) || (expired_starving(rq) && !rt_task(p)))) target = rq->expired; enqueue_task(p, target); rq->nr_running++; @@ -2489,22 +2531,6 @@ unsigned long long current_sched_time(const task_t *tsk) return ns; } -/* - * We place interactive tasks back into the active array, if possible. - * - * To guarantee that this does not starve expired tasks we ignore the - * interactivity of a task if the first expired task had to wait more - * than a 'reasonable' amount of time. This deadline timeout is - * load-dependent, as the frequency of array switched decreases with - * increasing number of running tasks. We also ignore the interactivity - * if a better static_prio task has expired: - */ -#define EXPIRED_STARVING(rq) \ - ((STARVATION_LIMIT && ((rq)->expired_timestamp && \ - (jiffies - (rq)->expired_timestamp >= \ - STARVATION_LIMIT * ((rq)->nr_running) + 1))) || \ - ((rq)->curr->static_prio > (rq)->best_expired_prio)) - /* * Account user cpu time to a process. * @p: the process that the cpu time gets accounted to @@ -2640,7 +2666,7 @@ void scheduler_tick(void) if (!rq->expired_timestamp) rq->expired_timestamp = jiffies; - if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) { + if (!TASK_INTERACTIVE(p) || expired_starving(rq)) { enqueue_task(p, rq->expired); if (p->static_prio < rq->best_expired_prio) rq->best_expired_prio = p->static_prio; diff --git a/trunk/kernel/timer.c b/trunk/kernel/timer.c index 9e49deed468c..67eaf0f54096 100644 --- a/trunk/kernel/timer.c +++ b/trunk/kernel/timer.c @@ -541,22 +541,6 @@ unsigned long next_timer_interrupt(void) } spin_unlock(&base->lock); - /* - * It can happen that other CPUs service timer IRQs and increment - * jiffies, but we have not yet got a local timer tick to process - * the timer wheels. In that case, the expiry time can be before - * jiffies, but since the high-resolution timer here is relative to - * jiffies, the default expression when high-resolution timers are - * not active, - * - * time_before(MAX_JIFFY_OFFSET + jiffies, expires) - * - * would falsely evaluate to true. If that is the case, just - * return jiffies so that we can immediately fire the local timer - */ - if (time_before(expires, jiffies)) - return jiffies; - if (time_before(hr_expires, expires)) return hr_expires; diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index ccb0c1fdf1b5..6ecc180beb71 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -189,7 +189,7 @@ config FRAME_POINTER config UNWIND_INFO bool "Compile the kernel with frame unwind information" depends on !IA64 - depends on !MODULES || !(MIPS || PARISC || PPC || SUPERH || V850) + depends on !MODULES || !(MIPS || PARISC || PPC || SUPERH || SPARC64 || V850) help If you say Y here the resulting kernel image will be slightly larger but not slower, and it will give very useful debugging information. diff --git a/trunk/lib/kobject.c b/trunk/lib/kobject.c index 687ab418d292..b46350c27837 100644 --- a/trunk/lib/kobject.c +++ b/trunk/lib/kobject.c @@ -198,14 +198,14 @@ int kobject_add(struct kobject * kobj) /* be noisy on error issues */ if (error == -EEXIST) - pr_debug("kobject_add failed for %s with -EEXIST, " + printk("kobject_add failed for %s with -EEXIST, " "don't try to register things with the " "same name in the same directory.\n", kobject_name(kobj)); else - pr_debug("kobject_add failed for %s (%d)\n", + printk("kobject_add failed for %s (%d)\n", kobject_name(kobj), error); - /* dump_stack(); */ + dump_stack(); } return error; diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 253a450c400d..ea77c999047e 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -39,7 +39,6 @@ #include #include -#include #include "internal.h" /* @@ -951,7 +950,7 @@ __alloc_pages(gfp_t gfp_mask, unsigned int order, goto got_pg; do { - if (cpuset_zone_allowed(*z, gfp_mask|__GFP_HARDWALL)) + if (cpuset_zone_allowed(*z, gfp_mask)) wakeup_kswapd(*z, order); } while (*(++z)); @@ -970,8 +969,7 @@ __alloc_pages(gfp_t gfp_mask, unsigned int order, alloc_flags |= ALLOC_HARDER; if (gfp_mask & __GFP_HIGH) alloc_flags |= ALLOC_HIGH; - if (wait) - alloc_flags |= ALLOC_CPUSET; + alloc_flags |= ALLOC_CPUSET; /* * Go through the zonelist again. Let __GFP_HIGH and allocations @@ -2125,22 +2123,14 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat) #ifdef CONFIG_FLAT_NODE_MEM_MAP /* ia64 gets its own node_mem_map, before this, without bootmem */ if (!pgdat->node_mem_map) { - unsigned long size, start, end; + unsigned long size; struct page *map; - /* - * The zone's endpoints aren't required to be MAX_ORDER - * aligned but the node_mem_map endpoints must be in order - * for the buddy allocator to function correctly. - */ - start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1); - end = pgdat->node_start_pfn + pgdat->node_spanned_pages; - end = ALIGN(end, MAX_ORDER_NR_PAGES); - size = (end - start) * sizeof(struct page); + size = (pgdat->node_spanned_pages + 1) * sizeof(struct page); map = alloc_remap(pgdat->node_id, size); if (!map) map = alloc_bootmem_node(pgdat, size); - pgdat->node_mem_map = map + (pgdat->node_start_pfn - start); + pgdat->node_mem_map = map; } #ifdef CONFIG_FLATMEM /* @@ -2576,11 +2566,9 @@ void setup_per_zone_pages_min(void) } for_each_zone(zone) { - u64 tmp; - + unsigned long tmp; spin_lock_irqsave(&zone->lru_lock, flags); - tmp = (u64)pages_min * zone->present_pages; - do_div(tmp, lowmem_pages); + tmp = (pages_min * zone->present_pages) / lowmem_pages; if (is_highmem(zone)) { /* * __GFP_HIGH and PF_MEMALLOC allocations usually don't @@ -2607,8 +2595,8 @@ void setup_per_zone_pages_min(void) zone->pages_min = tmp; } - zone->pages_low = zone->pages_min + (tmp >> 2); - zone->pages_high = zone->pages_min + (tmp >> 1); + zone->pages_low = zone->pages_min + tmp / 4; + zone->pages_high = zone->pages_min + tmp / 2; spin_unlock_irqrestore(&zone->lru_lock, flags); } diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index d31a06bfbea5..c32af7e7581e 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -700,14 +700,6 @@ static enum { FULL } g_cpucache_up; -/* - * used by boot code to determine if it can use slab based allocator - */ -int slab_is_available(void) -{ - return g_cpucache_up == FULL; -} - static DEFINE_PER_CPU(struct work_struct, reap_work); static void free_block(struct kmem_cache *cachep, void **objpp, int len, @@ -2200,14 +2192,11 @@ static void drain_cpu_caches(struct kmem_cache *cachep) check_irq_on(); for_each_online_node(node) { l3 = cachep->nodelists[node]; - if (l3 && l3->alien) - drain_alien_cache(cachep, l3->alien); - } - - for_each_online_node(node) { - l3 = cachep->nodelists[node]; - if (l3) + if (l3) { drain_array(cachep, l3, l3->shared, 1, node); + if (l3->alien) + drain_alien_cache(cachep, l3->alien); + } } } diff --git a/trunk/mm/sparse.c b/trunk/mm/sparse.c index 100040c0dfb6..d7c32de99ee8 100644 --- a/trunk/mm/sparse.c +++ b/trunk/mm/sparse.c @@ -32,7 +32,7 @@ static struct mem_section *sparse_index_alloc(int nid) unsigned long array_size = SECTIONS_PER_ROOT * sizeof(struct mem_section); - if (slab_is_available()) + if (system_state == SYSTEM_RUNNING) section = kmalloc_node(array_size, GFP_KERNEL, nid); else section = alloc_bootmem_node(NODE_DATA(nid), array_size); @@ -87,8 +87,11 @@ int __section_nr(struct mem_section* ms) unsigned long root_nr; struct mem_section* root; - for (root_nr = 0; root_nr < NR_SECTION_ROOTS; root_nr++) { - root = __nr_to_section(root_nr * SECTIONS_PER_ROOT); + for (root_nr = 0; + root_nr < NR_MEM_SECTIONS; + root_nr += SECTIONS_PER_ROOT) { + root = __nr_to_section(root_nr); + if (!root) continue; diff --git a/trunk/net/802/tr.c b/trunk/net/802/tr.c index e9dc803f2fe0..afd8385c0c9c 100644 --- a/trunk/net/802/tr.c +++ b/trunk/net/802/tr.c @@ -643,5 +643,6 @@ static int __init rif_init(void) module_init(rif_init); +EXPORT_SYMBOL(tr_source_route); EXPORT_SYMBOL(tr_type_trans); EXPORT_SYMBOL(alloc_trdev); diff --git a/trunk/net/atm/clip.c b/trunk/net/atm/clip.c index 72d852982664..1a786bfaa416 100644 --- a/trunk/net/atm/clip.c +++ b/trunk/net/atm/clip.c @@ -963,7 +963,7 @@ static struct file_operations arp_seq_fops = { static int __init atm_clip_init(void) { struct proc_dir_entry *p; - neigh_table_init_no_netlink(&clip_tbl); + neigh_table_init(&clip_tbl); clip_tbl_hook = &clip_tbl; register_atm_ioctl(&clip_ioctl_ops); diff --git a/trunk/net/bridge/br.c b/trunk/net/bridge/br.c index 12da21afb9ca..22d806cf40ca 100644 --- a/trunk/net/bridge/br.c +++ b/trunk/net/bridge/br.c @@ -55,7 +55,7 @@ static int __init br_init(void) static void __exit br_deinit(void) { - rcu_assign_pointer(br_stp_sap->rcv_func, NULL); + llc_sap_close(br_stp_sap); #ifdef CONFIG_BRIDGE_NETFILTER br_netfilter_fini(); @@ -67,7 +67,6 @@ static void __exit br_deinit(void) synchronize_net(); - llc_sap_put(br_stp_sap); br_fdb_get_hook = NULL; br_fdb_put_hook = NULL; diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index ad1c7af65ec8..59eef42d4a42 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -308,19 +308,26 @@ int br_add_bridge(const char *name) if (ret) goto err2; - ret = br_sysfs_addbr(dev); - if (ret) - goto err3; + /* network device kobject is not setup until + * after rtnl_unlock does it's hotplug magic. + * so hold reference to avoid race. + */ + dev_hold(dev); rtnl_unlock(); - return 0; - err3: - unregister_netdev(dev); + ret = br_sysfs_addbr(dev); + dev_put(dev); + + if (ret) + unregister_netdev(dev); + out: + return ret; + err2: free_netdev(dev); err1: rtnl_unlock(); - return ret; + goto out; } int br_del_bridge(const char *name) diff --git a/trunk/net/bridge/br_input.c b/trunk/net/bridge/br_input.c index bfa4d8c333f7..b0b7f55c1edd 100644 --- a/trunk/net/bridge/br_input.c +++ b/trunk/net/bridge/br_input.c @@ -66,7 +66,6 @@ int br_handle_frame_finish(struct sk_buff *skb) } if (is_multicast_ether_addr(dest)) { - br->statistics.multicast++; br_flood_forward(br, skb, !passedup); if (!passedup) br_pass_frame_up(br, skb); diff --git a/trunk/net/bridge/netfilter/ebt_log.c b/trunk/net/bridge/netfilter/ebt_log.c index 466ed3440b74..d159c92cca84 100644 --- a/trunk/net/bridge/netfilter/ebt_log.c +++ b/trunk/net/bridge/netfilter/ebt_log.c @@ -168,7 +168,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, if (info->bitmask & EBT_LOG_NFLOG) nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, - "%s", info->prefix); + info->prefix); else ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix); diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 2dce673a039b..3bad1afc89fa 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -193,7 +193,7 @@ static inline struct hlist_head *dev_index_hash(int ifindex) * Our notifier list */ -static RAW_NOTIFIER_HEAD(netdev_chain); +static BLOCKING_NOTIFIER_HEAD(netdev_chain); /* * Device drivers call our routines to queue packets here. We empty the @@ -736,7 +736,7 @@ int dev_change_name(struct net_device *dev, char *newname) if (!err) { hlist_del(&dev->name_hlist); hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); - raw_notifier_call_chain(&netdev_chain, + blocking_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); } @@ -751,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname) */ void netdev_features_change(struct net_device *dev) { - raw_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); } EXPORT_SYMBOL(netdev_features_change); @@ -766,7 +766,7 @@ EXPORT_SYMBOL(netdev_features_change); void netdev_state_change(struct net_device *dev) { if (dev->flags & IFF_UP) { - raw_notifier_call_chain(&netdev_chain, + blocking_notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); rtmsg_ifinfo(RTM_NEWLINK, dev, 0); } @@ -864,7 +864,7 @@ int dev_open(struct net_device *dev) /* * ... and announce new interface. */ - raw_notifier_call_chain(&netdev_chain, NETDEV_UP, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_UP, dev); } return ret; } @@ -887,7 +887,7 @@ int dev_close(struct net_device *dev) * Tell people we are going down, so that they can * prepare to death, when device is still operating. */ - raw_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); dev_deactivate(dev); @@ -924,7 +924,7 @@ int dev_close(struct net_device *dev) /* * Tell people we are down */ - raw_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); return 0; } @@ -955,7 +955,7 @@ int register_netdevice_notifier(struct notifier_block *nb) int err; rtnl_lock(); - err = raw_notifier_chain_register(&netdev_chain, nb); + err = blocking_notifier_chain_register(&netdev_chain, nb); if (!err) { for (dev = dev_base; dev; dev = dev->next) { nb->notifier_call(nb, NETDEV_REGISTER, dev); @@ -983,7 +983,7 @@ int unregister_netdevice_notifier(struct notifier_block *nb) int err; rtnl_lock(); - err = raw_notifier_chain_unregister(&netdev_chain, nb); + err = blocking_notifier_chain_unregister(&netdev_chain, nb); rtnl_unlock(); return err; } @@ -994,12 +994,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb) * @v: pointer passed unmodified to notifier function * * Call all network notifier blocks. Parameters and return value - * are as for raw_notifier_call_chain(). + * are as for blocking_notifier_call_chain(). */ int call_netdevice_notifiers(unsigned long val, void *v) { - return raw_notifier_call_chain(&netdev_chain, val, v); + return blocking_notifier_call_chain(&netdev_chain, val, v); } /* When > 0 there are consumers of rx skb time stamps */ @@ -2308,7 +2308,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags) if (dev->flags & IFF_UP && ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE))) - raw_notifier_call_chain(&netdev_chain, + blocking_notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); if ((flags ^ dev->gflags) & IFF_PROMISC) { @@ -2353,7 +2353,7 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) else dev->mtu = new_mtu; if (!err && dev->flags & IFF_UP) - raw_notifier_call_chain(&netdev_chain, + blocking_notifier_call_chain(&netdev_chain, NETDEV_CHANGEMTU, dev); return err; } @@ -2370,7 +2370,7 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) return -ENODEV; err = dev->set_mac_address(dev, sa); if (!err) - raw_notifier_call_chain(&netdev_chain, + blocking_notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev); return err; } @@ -2427,7 +2427,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) return -EINVAL; memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); - raw_notifier_call_chain(&netdev_chain, + blocking_notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev); return 0; @@ -2777,8 +2777,6 @@ int register_netdevice(struct net_device *dev) BUG_ON(dev_boot_phase); ASSERT_RTNL(); - might_sleep(); - /* When net_device's are persistent, this will be fatal. */ BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); @@ -2865,11 +2863,6 @@ int register_netdevice(struct net_device *dev) if (!dev->rebuild_header) dev->rebuild_header = default_rebuild_header; - ret = netdev_register_sysfs(dev); - if (ret) - goto out_err; - dev->reg_state = NETREG_REGISTERED; - /* * Default initial state at registry is that the * device is present. @@ -2885,11 +2878,14 @@ int register_netdevice(struct net_device *dev) hlist_add_head(&dev->name_hlist, head); hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex)); dev_hold(dev); + dev->reg_state = NETREG_REGISTERING; write_unlock_bh(&dev_base_lock); /* Notify protocols, that a new device appeared. */ - raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); + /* Finish registration after unlock */ + net_set_todo(dev); ret = 0; out: @@ -2965,7 +2961,7 @@ static void netdev_wait_allrefs(struct net_device *dev) rtnl_lock(); /* Rebroadcast unregister notification */ - raw_notifier_call_chain(&netdev_chain, + blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); if (test_bit(__LINK_STATE_LINKWATCH_PENDING, @@ -3012,7 +3008,7 @@ static void netdev_wait_allrefs(struct net_device *dev) * * We are invoked by rtnl_unlock() after it drops the semaphore. * This allows us to deal with problems: - * 1) We can delete sysfs objects which invoke hotplug + * 1) We can create/delete sysfs objects which invoke hotplug * without deadlocking with linkwatch via keventd. * 2) Since we run with the RTNL semaphore not held, we can sleep * safely in order to wait for the netdev refcnt to drop to zero. @@ -3021,6 +3017,8 @@ static DEFINE_MUTEX(net_todo_run_mutex); void netdev_run_todo(void) { struct list_head list = LIST_HEAD_INIT(list); + int err; + /* Need to guard against multiple cpu's getting out of order. */ mutex_lock(&net_todo_run_mutex); @@ -3043,29 +3041,40 @@ void netdev_run_todo(void) = list_entry(list.next, struct net_device, todo_list); list_del(&dev->todo_list); - if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) { - printk(KERN_ERR "network todo '%s' but state %d\n", - dev->name, dev->reg_state); - dump_stack(); - continue; - } + switch(dev->reg_state) { + case NETREG_REGISTERING: + dev->reg_state = NETREG_REGISTERED; + err = netdev_register_sysfs(dev); + if (err) + printk(KERN_ERR "%s: failed sysfs registration (%d)\n", + dev->name, err); + break; - netdev_unregister_sysfs(dev); - dev->reg_state = NETREG_UNREGISTERED; + case NETREG_UNREGISTERING: + netdev_unregister_sysfs(dev); + dev->reg_state = NETREG_UNREGISTERED; - netdev_wait_allrefs(dev); + netdev_wait_allrefs(dev); - /* paranoia */ - BUG_ON(atomic_read(&dev->refcnt)); - BUG_TRAP(!dev->ip_ptr); - BUG_TRAP(!dev->ip6_ptr); - BUG_TRAP(!dev->dn_ptr); + /* paranoia */ + BUG_ON(atomic_read(&dev->refcnt)); + BUG_TRAP(!dev->ip_ptr); + BUG_TRAP(!dev->ip6_ptr); + BUG_TRAP(!dev->dn_ptr); - /* It must be the very last action, - * after this 'dev' may point to freed up memory. - */ - if (dev->destructor) - dev->destructor(dev); + + /* It must be the very last action, + * after this 'dev' may point to freed up memory. + */ + if (dev->destructor) + dev->destructor(dev); + break; + + default: + printk(KERN_ERR "network todo '%s' but state %d\n", + dev->name, dev->reg_state); + break; + } } out: @@ -3207,7 +3216,7 @@ int unregister_netdevice(struct net_device *dev) /* Notify protocols, that we are about to destroy this device. They should clean all the things. */ - raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); /* * Flush the multicast chain diff --git a/trunk/net/core/link_watch.c b/trunk/net/core/link_watch.c index 646937cc2d84..341de44c7ed1 100644 --- a/trunk/net/core/link_watch.c +++ b/trunk/net/core/link_watch.c @@ -170,13 +170,13 @@ void linkwatch_fire_event(struct net_device *dev) spin_unlock_irqrestore(&lweventlist_lock, flags); if (!test_and_set_bit(LW_RUNNING, &linkwatch_flags)) { - unsigned long delay = linkwatch_nextevent - jiffies; + unsigned long thisevent = jiffies; - /* If we wrap around we'll delay it by at most HZ. */ - if (!delay || delay > HZ) + if (thisevent >= linkwatch_nextevent) { schedule_work(&linkwatch_work); - else - schedule_delayed_work(&linkwatch_work, delay); + } else { + schedule_delayed_work(&linkwatch_work, linkwatch_nextevent - thisevent); + } } } } diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index 50a8c73caf97..4cf878efdb49 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -1326,7 +1326,8 @@ void neigh_parms_destroy(struct neigh_parms *parms) kfree(parms); } -void neigh_table_init_no_netlink(struct neigh_table *tbl) + +void neigh_table_init(struct neigh_table *tbl) { unsigned long now = jiffies; unsigned long phsize; @@ -1382,27 +1383,10 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) tbl->last_flush = now; tbl->last_rand = now + tbl->parms.reachable_time * 20; -} - -void neigh_table_init(struct neigh_table *tbl) -{ - struct neigh_table *tmp; - - neigh_table_init_no_netlink(tbl); write_lock(&neigh_tbl_lock); - for (tmp = neigh_tables; tmp; tmp = tmp->next) { - if (tmp->family == tbl->family) - break; - } tbl->next = neigh_tables; neigh_tables = tbl; write_unlock(&neigh_tbl_lock); - - if (unlikely(tmp)) { - printk(KERN_ERR "NEIGH: Registering multiple tables for " - "family %d\n", tbl->family); - dump_stack(); - } } int neigh_table_clear(struct neigh_table *tbl) @@ -2673,7 +2657,6 @@ EXPORT_SYMBOL(neigh_rand_reach_time); EXPORT_SYMBOL(neigh_resolve_output); EXPORT_SYMBOL(neigh_table_clear); EXPORT_SYMBOL(neigh_table_init); -EXPORT_SYMBOL(neigh_table_init_no_netlink); EXPORT_SYMBOL(neigh_update); EXPORT_SYMBOL(neigh_update_hhs); EXPORT_SYMBOL(pneigh_enqueue); diff --git a/trunk/net/core/net-sysfs.c b/trunk/net/core/net-sysfs.c index 47a6fceb6771..c12990c9c603 100644 --- a/trunk/net/core/net-sysfs.c +++ b/trunk/net/core/net-sysfs.c @@ -29,7 +29,7 @@ static const char fmt_ulong[] = "%lu\n"; static inline int dev_isalive(const struct net_device *dev) { - return dev->reg_state <= NETREG_REGISTERED; + return dev->reg_state == NETREG_REGISTERED; } /* use same locking rules as GIF* ioctl's */ @@ -445,33 +445,58 @@ static struct class net_class = { void netdev_unregister_sysfs(struct net_device * net) { - class_device_del(&(net->class_dev)); + struct class_device * class_dev = &(net->class_dev); + + if (net->get_stats) + sysfs_remove_group(&class_dev->kobj, &netstat_group); + +#ifdef WIRELESS_EXT + if (net->get_wireless_stats || (net->wireless_handlers && + net->wireless_handlers->get_wireless_stats)) + sysfs_remove_group(&class_dev->kobj, &wireless_group); +#endif + class_device_del(class_dev); + } /* Create sysfs entries for network device. */ int netdev_register_sysfs(struct net_device *net) { struct class_device *class_dev = &(net->class_dev); - struct attribute_group **groups = net->sysfs_groups; + int ret; - 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(class_dev->class_id, net->name, BUS_ID_SIZE); + if ((ret = class_device_register(class_dev))) + goto out; - if (net->get_stats) - *groups++ = &netstat_group; + if (net->get_stats && + (ret = sysfs_create_group(&class_dev->kobj, &netstat_group))) + goto out_unreg; #ifdef WIRELESS_EXT - if (net->get_wireless_stats - || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)) - *groups++ = &wireless_group; + if (net->get_wireless_stats || (net->wireless_handlers && + net->wireless_handlers->get_wireless_stats)) { + ret = sysfs_create_group(&class_dev->kobj, &wireless_group); + if (ret) + goto out_cleanup; + } + return 0; +out_cleanup: + if (net->get_stats) + sysfs_remove_group(&class_dev->kobj, &netstat_group); +#else + return 0; #endif - return class_device_add(class_dev); +out_unreg: + printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n", + net->name, ret); + class_device_unregister(class_dev); +out: + return ret; } int netdev_sysfs_init(void) diff --git a/trunk/net/dccp/proto.c b/trunk/net/dccp/proto.c index 2e0ee8355c41..1ff7328b0e17 100644 --- a/trunk/net/dccp/proto.c +++ b/trunk/net/dccp/proto.c @@ -848,7 +848,6 @@ static int dccp_close_state(struct sock *sk) void dccp_close(struct sock *sk, long timeout) { struct sk_buff *skb; - int state; lock_sock(sk); @@ -883,11 +882,6 @@ void dccp_close(struct sock *sk, long timeout) sk_stream_wait_close(sk, timeout); adjudge_to_death: - state = sk->sk_state; - sock_hold(sk); - sock_orphan(sk); - atomic_inc(sk->sk_prot->orphan_count); - /* * It is the last release_sock in its life. It will remove backlog. */ @@ -900,9 +894,8 @@ void dccp_close(struct sock *sk, long timeout) bh_lock_sock(sk); BUG_TRAP(!sock_owned_by_user(sk)); - /* Have we already been destroyed by a softirq or backlog? */ - if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED) - goto out; + sock_hold(sk); + sock_orphan(sk); /* * The last release_sock may have processed the CLOSE or RESET @@ -922,12 +915,12 @@ void dccp_close(struct sock *sk, long timeout) #endif } + atomic_inc(sk->sk_prot->orphan_count); if (sk->sk_state == DCCP_CLOSED) inet_csk_destroy_sock(sk); /* Otherwise, socket is reprieved until protocol close. */ -out: bh_unlock_sock(sk); local_bh_enable(); sock_put(sk); diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c b/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c index d4c79ce16871..ea9f5aacce85 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c @@ -51,12 +51,11 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft spin_lock_irqsave(&mac->lock, flags); mac->associnfo.associating = 1; mac->associated = 0; /* just to make sure */ + spin_unlock_irqrestore(&mac->lock, flags); /* Set a timer for timeout */ /* FIXME: make timeout configurable */ - if (likely(mac->running)) - schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ); - spin_unlock_irqrestore(&mac->lock, flags); + schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ); } void @@ -320,9 +319,6 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, u16 status = le16_to_cpup(&resp->status); struct ieee80211softmac_network *network = NULL; unsigned long flags; - - if (unlikely(!mac->running)) - return -ENODEV; spin_lock_irqsave(&mac->lock, flags); @@ -381,16 +377,10 @@ ieee80211softmac_handle_disassoc(struct net_device * dev, { struct ieee80211softmac_device *mac = ieee80211_priv(dev); unsigned long flags; - - if (unlikely(!mac->running)) - return -ENODEV; - if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN)) return 0; - if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN)) return 0; - dprintk(KERN_INFO PFX "got disassoc frame\n"); netif_carrier_off(dev); spin_lock_irqsave(&mac->lock, flags); @@ -410,9 +400,6 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev, struct ieee80211softmac_device *mac = ieee80211_priv(dev); struct ieee80211softmac_network *network; - if (unlikely(!mac->running)) - return -ENODEV; - network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3); if (!network) { dprintkl(KERN_INFO PFX "reassoc request from unknown network\n"); diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c b/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c index 06e332624665..9a0eac6c61eb 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c @@ -86,11 +86,6 @@ ieee80211softmac_auth_queue(void *data) /* Lock and set flags */ spin_lock_irqsave(&mac->lock, flags); - if (unlikely(!mac->running)) { - /* Prevent reschedule on workqueue flush */ - spin_unlock_irqrestore(&mac->lock, flags); - return; - } net->authenticated = 0; net->authenticating = 1; /* add a timeout call so we eventually give up waiting for an auth reply */ @@ -129,9 +124,6 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) unsigned long flags; u8 * data; - if (unlikely(!mac->running)) - return -ENODEV; - /* Find correct auth queue item */ spin_lock_irqsave(&mac->lock, flags); list_for_each(list_ptr, &mac->auth_queue) { @@ -306,6 +298,8 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac, /* can't transmit data right now... */ netif_carrier_off(mac->dev); + /* let's try to re-associate */ + schedule_work(&mac->associnfo.work); spin_unlock_irqrestore(&mac->lock, flags); } @@ -344,9 +338,6 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de struct ieee80211softmac_network *net = NULL; struct ieee80211softmac_device *mac = ieee80211_priv(dev); - if (unlikely(!mac->running)) - return -ENODEV; - if (!deauth) { dprintk("deauth without deauth packet. eek!\n"); return 0; @@ -369,8 +360,5 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de } ieee80211softmac_deauth_from_net(mac, net); - - /* let's try to re-associate */ - schedule_work(&mac->associnfo.work); return 0; } diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_module.c b/trunk/net/ieee80211/softmac/ieee80211softmac_module.c index 6252be2c0db9..be83bdc1644a 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_module.c @@ -89,8 +89,6 @@ ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm) ieee80211softmac_wait_for_scan(sm); spin_lock_irqsave(&sm->lock, flags); - sm->running = 0; - /* Free all pending assoc work items */ cancel_delayed_work(&sm->associnfo.work); @@ -206,8 +204,6 @@ void ieee80211softmac_start(struct net_device *dev) assert(0); if (mac->txrates_change) mac->txrates_change(dev, change, &oldrates); - - mac->running = 1; } EXPORT_SYMBOL_GPL(ieee80211softmac_start); diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_scan.c b/trunk/net/ieee80211/softmac/ieee80211softmac_scan.c index d31cf77498c4..2b9e7edfa3ce 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_scan.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_scan.c @@ -115,15 +115,7 @@ void ieee80211softmac_scan(void *d) // TODO: is this if correct, or should we do this only if scanning from assoc request? if (sm->associnfo.req_essid.len) ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0); - - spin_lock_irqsave(&sm->lock, flags); - if (unlikely(!sm->running)) { - /* Prevent reschedule on workqueue flush */ - spin_unlock_irqrestore(&sm->lock, flags); - break; - } schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY); - spin_unlock_irqrestore(&sm->lock, flags); return; } else { dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel); diff --git a/trunk/net/ipv4/ip_input.c b/trunk/net/ipv4/ip_input.c index c9026dbf4c93..18d7fad474d7 100644 --- a/trunk/net/ipv4/ip_input.c +++ b/trunk/net/ipv4/ip_input.c @@ -337,7 +337,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb) * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ - if (skb->dst == NULL) { + if (likely(skb->dst == NULL)) { int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, skb->dev); if (unlikely(err)) { diff --git a/trunk/net/ipv4/ip_options.c b/trunk/net/ipv4/ip_options.c index cbcae6544622..9bebad07bf2e 100644 --- a/trunk/net/ipv4/ip_options.c +++ b/trunk/net/ipv4/ip_options.c @@ -209,7 +209,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) void ip_options_fragment(struct sk_buff * skb) { - unsigned char * optptr = skb->nh.raw + sizeof(struct iphdr); + unsigned char * optptr = skb->nh.raw; struct ip_options * opt = &(IPCB(skb)->opt); int l = opt->optlen; int optlen; diff --git a/trunk/net/ipv4/ipcomp.c b/trunk/net/ipv4/ipcomp.c index 95278b22b669..cd810f41af1a 100644 --- a/trunk/net/ipv4/ipcomp.c +++ b/trunk/net/ipv4/ipcomp.c @@ -210,7 +210,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info) skb->h.icmph->code != ICMP_FRAG_NEEDED) return; - spi = htonl(ntohs(ipch->cpi)); + spi = ntohl(ntohs(ipch->cpi)); x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET); if (!x) diff --git a/trunk/net/ipv4/netfilter/arp_tables.c b/trunk/net/ipv4/netfilter/arp_tables.c index d0d19192026d..c2d92f99a2b8 100644 --- a/trunk/net/ipv4/netfilter/arp_tables.c +++ b/trunk/net/ipv4/netfilter/arp_tables.c @@ -948,7 +948,7 @@ static int do_add_counters(void __user *user, unsigned int len) write_lock_bh(&t->lock); private = t->private; - if (private->number != tmp.num_counters) { + if (private->number != paddc->num_counters) { ret = -EINVAL; goto unlock_up_free; } diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c b/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c index 26dfecadb335..355a53a5b6cd 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c @@ -528,15 +528,14 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) /* Decode */ if ((err = (Decoders[son->type]) (bs, son, base, - level + 1)) < - H323_ERROR_NONE) + level + 1)) > + H323_ERROR_STOP) return err; bs->cur = beg + len; bs->bit = 0; } else if ((err = (Decoders[son->type]) (bs, son, base, - level + 1)) < - H323_ERROR_NONE) + level + 1))) return err; } @@ -555,7 +554,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) /* Decode the extension components */ for (opt = 0; opt < bmp2_len; opt++, i++, son++) { - if (i < f->ub && son->attr & STOP) { + if (son->attr & STOP) { PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name); return H323_ERROR_STOP; @@ -585,8 +584,8 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) beg = bs->cur; if ((err = (Decoders[son->type]) (bs, son, base, - level + 1)) < - H323_ERROR_NONE) + level + 1)) > + H323_ERROR_STOP) return err; bs->cur = beg + len; @@ -661,20 +660,18 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level) i < effective_count ? base : NULL, - level + 1)) < - H323_ERROR_NONE) + level + 1)) > + H323_ERROR_STOP) return err; bs->cur = beg + len; bs->bit = 0; } else - if ((err = (Decoders[son->type]) (bs, son, - i < - effective_count ? - base : NULL, - level + 1)) < - H323_ERROR_NONE) - return err; + if ((err = (Decoders[son->type]) (bs, son, + i < effective_count ? + base : NULL, + level + 1))) + return err; if (base) base += son->offset; @@ -738,14 +735,13 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level) } beg = bs->cur; - if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < - H323_ERROR_NONE) + if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) > + H323_ERROR_STOP) return err; bs->cur = beg + len; bs->bit = 0; - } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < - H323_ERROR_NONE) + } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1))) return err; return H323_ERROR_NONE; diff --git a/trunk/net/ipv4/netfilter/ip_nat_proto_gre.c b/trunk/net/ipv4/netfilter/ip_nat_proto_gre.c index 96ceabaec402..6c4899d8046a 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_proto_gre.c +++ b/trunk/net/ipv4/netfilter/ip_nat_proto_gre.c @@ -49,15 +49,15 @@ gre_in_range(const struct ip_conntrack_tuple *tuple, const union ip_conntrack_manip_proto *min, const union ip_conntrack_manip_proto *max) { - __be16 key; + u_int32_t key; if (maniptype == IP_NAT_MANIP_SRC) key = tuple->src.u.gre.key; else key = tuple->dst.u.gre.key; - return ntohs(key) >= ntohs(min->gre.key) - && ntohs(key) <= ntohs(max->gre.key); + return ntohl(key) >= ntohl(min->gre.key) + && ntohl(key) <= ntohl(max->gre.key); } /* generate unique tuple ... */ @@ -81,14 +81,14 @@ gre_unique_tuple(struct ip_conntrack_tuple *tuple, min = 1; range_size = 0xffff; } else { - min = ntohs(range->min.gre.key); - range_size = ntohs(range->max.gre.key) - min + 1; + min = ntohl(range->min.gre.key); + range_size = ntohl(range->max.gre.key) - min + 1; } DEBUGP("min = %u, range_size = %u\n", min, range_size); for (i = 0; i < range_size; i++, key++) { - *keyptr = htons(min + key % range_size); + *keyptr = htonl(min + key % range_size); if (!ip_nat_used_tuple(tuple, conntrack)) return 1; } diff --git a/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c b/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c index c33244263b90..c62253845538 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -768,7 +768,6 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, len *= sizeof(unsigned long); *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { - kfree(lp); kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); @@ -1004,12 +1003,12 @@ static unsigned char snmp_trap_decode(struct asn1_ctx *ctx, return 1; -err_addr_free: - kfree((unsigned long *)trap->ip_address); - err_id_free: kfree(trap->id); +err_addr_free: + kfree((unsigned long *)trap->ip_address); + return 0; } @@ -1127,10 +1126,11 @@ static int snmp_parse_mangle(unsigned char *msg, struct snmp_v1_trap trap; unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check); - if (ret) { - kfree(trap.id); - kfree((unsigned long *)trap.ip_address); - } else + /* Discard trap allocations regardless */ + kfree(trap.id); + kfree((unsigned long *)trap.ip_address); + + if (!ret) return ret; } else { diff --git a/trunk/net/ipv4/netfilter/ipt_LOG.c b/trunk/net/ipv4/netfilter/ipt_LOG.c index b98f7b08b084..39fd4c2a2386 100644 --- a/trunk/net/ipv4/netfilter/ipt_LOG.c +++ b/trunk/net/ipv4/netfilter/ipt_LOG.c @@ -428,7 +428,7 @@ ipt_log_target(struct sk_buff **pskb, if (loginfo->logflags & IPT_LOG_NFLOG) nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, - "%s", loginfo->prefix); + loginfo->prefix); else ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix); diff --git a/trunk/net/ipv4/netfilter/ipt_recent.c b/trunk/net/ipv4/netfilter/ipt_recent.c index b847ee409efb..143843285702 100644 --- a/trunk/net/ipv4/netfilter/ipt_recent.c +++ b/trunk/net/ipv4/netfilter/ipt_recent.c @@ -821,7 +821,6 @@ checkentry(const char *tablename, /* Create our proc 'status' entry. */ curr_table->status_proc = create_proc_entry(curr_table->name, ip_list_perms, proc_net_ipt_recent); if (!curr_table->status_proc) { - vfree(hold); printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for /proc entry.\n"); /* Destroy the created table */ spin_lock_bh(&recent_lock); @@ -846,6 +845,7 @@ checkentry(const char *tablename, spin_unlock_bh(&recent_lock); vfree(curr_table->time_info); vfree(curr_table->hash_table); + vfree(hold); vfree(curr_table->table); vfree(curr_table); return 0; diff --git a/trunk/net/ipv4/tcp_highspeed.c b/trunk/net/ipv4/tcp_highspeed.c index b72fa55dfb84..e0e9d1383c7c 100644 --- a/trunk/net/ipv4/tcp_highspeed.c +++ b/trunk/net/ipv4/tcp_highspeed.c @@ -137,8 +137,8 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt, if (tp->snd_cwnd < tp->snd_cwnd_clamp) { tp->snd_cwnd_cnt += ca->ai; if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { - tp->snd_cwnd_cnt -= tp->snd_cwnd; tp->snd_cwnd++; + tp->snd_cwnd_cnt -= tp->snd_cwnd; } } } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 4a538bc1683d..9f0cca4c4fae 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -1662,8 +1662,6 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_sock *tp) if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) { TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; tp->lost_out += tcp_skb_pcount(skb); - if (IsReno(tp)) - tcp_remove_reno_sacks(sk, tp, tcp_skb_pcount(skb) + 1); /* clear xmit_retrans hint */ if (tp->retransmit_skb_hint && diff --git a/trunk/net/ipv4/xfrm4_policy.c b/trunk/net/ipv4/xfrm4_policy.c index 8604c747bca5..f285bbf296e2 100644 --- a/trunk/net/ipv4/xfrm4_policy.c +++ b/trunk/net/ipv4/xfrm4_policy.c @@ -221,7 +221,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl) if (pskb_may_pull(skb, xprth + 4 - skb->data)) { u16 *ipcomp_hdr = (u16 *)xprth; - fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); + fl->fl_ipsec_spi = ntohl(ntohs(ipcomp_hdr[1])); } break; default: diff --git a/trunk/net/ipv6/inet6_connection_sock.c b/trunk/net/ipv6/inet6_connection_sock.c index eb2865d5ae28..f8f3a37a1494 100644 --- a/trunk/net/ipv6/inet6_connection_sock.c +++ b/trunk/net/ipv6/inet6_connection_sock.c @@ -173,7 +173,6 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) if (err) { sk->sk_err_soft = -err; - kfree_skb(skb); return err; } @@ -182,7 +181,6 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { sk->sk_route_caps = 0; - kfree_skb(skb); return err; } diff --git a/trunk/net/ipv6/ipcomp6.c b/trunk/net/ipv6/ipcomp6.c index 48636436028a..05eb67def39f 100644 --- a/trunk/net/ipv6/ipcomp6.c +++ b/trunk/net/ipv6/ipcomp6.c @@ -208,7 +208,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (type != ICMPV6_DEST_UNREACH && type != ICMPV6_PKT_TOOBIG) return; - spi = htonl(ntohs(ipcomph->cpi)); + spi = ntohl(ntohs(ipcomph->cpi)); x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); if (!x) return; diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 2e72f89a7019..0a673038344f 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -1103,7 +1103,7 @@ do_add_counters(void __user *user, unsigned int len) write_lock_bh(&t->lock); private = t->private; - if (private->number != tmp.num_counters) { + if (private->number != paddc->num_counters) { ret = -EINVAL; goto unlock_up_free; } diff --git a/trunk/net/ipv6/netfilter/ip6t_LOG.c b/trunk/net/ipv6/netfilter/ip6t_LOG.c index 73c6300109d6..a96c0de14b00 100644 --- a/trunk/net/ipv6/netfilter/ip6t_LOG.c +++ b/trunk/net/ipv6/netfilter/ip6t_LOG.c @@ -439,7 +439,7 @@ ip6t_log_target(struct sk_buff **pskb, if (loginfo->logflags & IP6T_LOG_NFLOG) nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, - "%s", loginfo->prefix); + loginfo->prefix); else ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, loginfo->prefix); diff --git a/trunk/net/ipv6/netfilter/ip6t_eui64.c b/trunk/net/ipv6/netfilter/ip6t_eui64.c index 4f6b84c8f4ab..94dbdb8b458d 100644 --- a/trunk/net/ipv6/netfilter/ip6t_eui64.c +++ b/trunk/net/ipv6/netfilter/ip6t_eui64.c @@ -40,7 +40,7 @@ match(const struct sk_buff *skb, memset(eui64, 0, sizeof(eui64)); - if (eth_hdr(skb)->h_proto == htons(ETH_P_IPV6)) { + if (eth_hdr(skb)->h_proto == ntohs(ETH_P_IPV6)) { if (skb->nh.ipv6h->version == 0x6) { memcpy(eui64, eth_hdr(skb)->h_source, 3); memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3); diff --git a/trunk/net/ipx/af_ipx.c b/trunk/net/ipx/af_ipx.c index 811d998725bc..2dbf134d5266 100644 --- a/trunk/net/ipx/af_ipx.c +++ b/trunk/net/ipx/af_ipx.c @@ -944,9 +944,9 @@ static int ipxitf_create_internal(struct ipx_interface_definition *idef) return rc; } -static __be16 ipx_map_frame_type(unsigned char type) +static int ipx_map_frame_type(unsigned char type) { - __be16 rc = 0; + int rc = 0; switch (type) { case IPX_FRAME_ETHERII: rc = htons(ETH_P_IPX); break; diff --git a/trunk/net/ipx/ipx_route.c b/trunk/net/ipx/ipx_route.c index a394c6fe19a2..67774448efd9 100644 --- a/trunk/net/ipx/ipx_route.c +++ b/trunk/net/ipx/ipx_route.c @@ -119,7 +119,7 @@ static int ipxrtr_create(struct ipx_route_definition *rd) return rc; } -static int ipxrtr_delete(__u32 net) +static int ipxrtr_delete(long net) { struct ipx_route *r, *tmp; int rc; diff --git a/trunk/net/irda/iriap.c b/trunk/net/irda/iriap.c index 2d2e2b1919f4..254f90746900 100644 --- a/trunk/net/irda/iriap.c +++ b/trunk/net/irda/iriap.c @@ -544,8 +544,7 @@ static void iriap_getvaluebyclass_response(struct iriap_cb *self, { struct sk_buff *tx_skb; int n; - __u32 tmp_be32; - __be16 tmp_be16; + __u32 tmp_be32, tmp_be16; __u8 *fp; IRDA_DEBUG(4, "%s()\n", __FUNCTION__); diff --git a/trunk/net/irda/irias_object.c b/trunk/net/irda/irias_object.c index 82e665c79991..c6d169fbdceb 100644 --- a/trunk/net/irda/irias_object.c +++ b/trunk/net/irda/irias_object.c @@ -257,6 +257,7 @@ struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name) /* Unsafe (locking), attrib might change */ return attrib; } +EXPORT_SYMBOL(irias_find_attrib); /* * Function irias_add_attribute (obj, attrib) @@ -483,6 +484,7 @@ struct ias_value *irias_new_string_value(char *string) return value; } +EXPORT_SYMBOL(irias_new_string_value); /* * Function irias_new_octseq_value (octets, len) @@ -517,6 +519,7 @@ struct ias_value *irias_new_octseq_value(__u8 *octseq , int len) memcpy(value->t.oct_seq, octseq , len); return value; } +EXPORT_SYMBOL(irias_new_octseq_value); struct ias_value *irias_new_missing_value(void) { diff --git a/trunk/net/netfilter/nfnetlink_log.c b/trunk/net/netfilter/nfnetlink_log.c index 61cdda4e5d3b..c60273cad778 100644 --- a/trunk/net/netfilter/nfnetlink_log.c +++ b/trunk/net/netfilter/nfnetlink_log.c @@ -321,7 +321,7 @@ static int nfulnl_set_flags(struct nfulnl_instance *inst, u_int16_t flags) { spin_lock_bh(&inst->lock); - inst->flags = flags; + inst->flags = ntohs(flags); spin_unlock_bh(&inst->lock); return 0; @@ -902,7 +902,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, if (nfula[NFULA_CFG_FLAGS-1]) { u_int16_t flags = *(u_int16_t *)NFA_DATA(nfula[NFULA_CFG_FLAGS-1]); - nfulnl_set_flags(inst, ntohs(flags)); + nfulnl_set_flags(inst, ntohl(flags)); } out_put: diff --git a/trunk/net/netrom/af_netrom.c b/trunk/net/netrom/af_netrom.c index 3669cb953e6e..ecd288beca7c 100644 --- a/trunk/net/netrom/af_netrom.c +++ b/trunk/net/netrom/af_netrom.c @@ -1370,6 +1370,8 @@ static struct notifier_block nr_dev_notifier = { static struct net_device **dev_nr; +static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n"; + static int __init nr_proto_init(void) { int i; @@ -1417,6 +1419,7 @@ static int __init nr_proto_init(void) } register_netdevice_notifier(&nr_dev_notifier); + printk(banner); ax25_protocol_register(AX25_P_NETROM, nr_route_frame); ax25_linkfail_register(nr_link_failed); diff --git a/trunk/net/rose/af_rose.c b/trunk/net/rose/af_rose.c index 55564efccf11..ef4538ac84f0 100644 --- a/trunk/net/rose/af_rose.c +++ b/trunk/net/rose/af_rose.c @@ -1469,6 +1469,8 @@ static struct notifier_block rose_dev_notifier = { static struct net_device **dev_rose; +static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62 for AX25.037 Linux 2.4\n"; + static int __init rose_proto_init(void) { int i; @@ -1517,6 +1519,7 @@ static int __init rose_proto_init(void) sock_register(&rose_family_ops); register_netdevice_notifier(&rose_dev_notifier); + printk(banner); ax25_protocol_register(AX25_P_ROSE, rose_route_frame); ax25_linkfail_register(rose_link_failed); diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index 138ea92ed268..31eb83717c26 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -193,10 +193,8 @@ static void dev_watchdog(unsigned long arg) netif_running(dev) && netif_carrier_ok(dev)) { if (netif_queue_stopped(dev) && - time_after(jiffies, dev->trans_start + dev->watchdog_timeo)) { - - printk(KERN_INFO "NETDEV WATCHDOG: %s: transmit timed out\n", - dev->name); + (jiffies - dev->trans_start) > dev->watchdog_timeo) { + printk(KERN_INFO "NETDEV WATCHDOG: %s: transmit timed out\n", dev->name); dev->tx_timeout(dev); } if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo)) diff --git a/trunk/net/sched/sch_hfsc.c b/trunk/net/sched/sch_hfsc.c index f1c7bd29f2cd..91132f6871d7 100644 --- a/trunk/net/sched/sch_hfsc.c +++ b/trunk/net/sched/sch_hfsc.c @@ -974,10 +974,10 @@ hfsc_adjust_levels(struct hfsc_class *cl) do { level = 0; list_for_each_entry(p, &cl->children, siblings) { - if (p->level >= level) - level = p->level + 1; + if (p->level > level) + level = p->level; } - cl->level = level; + cl->level = level + 1; } while ((cl = cl->cl_parent) != NULL); } diff --git a/trunk/net/sctp/input.c b/trunk/net/sctp/input.c index 1662f9cc869e..d117ebc75cf8 100644 --- a/trunk/net/sctp/input.c +++ b/trunk/net/sctp/input.c @@ -73,8 +73,6 @@ static struct sctp_association *__sctp_lookup_association( const union sctp_addr *peer, struct sctp_transport **pt); -static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb); - /* Calculate the SCTP checksum of an SCTP packet. */ static inline int sctp_rcv_checksum(struct sk_buff *skb) @@ -188,6 +186,7 @@ int sctp_rcv(struct sk_buff *skb) */ if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) { + sock_put(sk); if (asoc) { sctp_association_put(asoc); asoc = NULL; @@ -198,6 +197,7 @@ int sctp_rcv(struct sk_buff *skb) sk = sctp_get_ctl_sock(); ep = sctp_sk(sk)->ep; sctp_endpoint_hold(ep); + sock_hold(sk); rcvr = &ep->base; } @@ -253,18 +253,25 @@ int sctp_rcv(struct sk_buff *skb) */ sctp_bh_lock_sock(sk); + /* It is possible that the association could have moved to a different + * socket if it is peeled off. If so, update the sk. + */ + if (sk != rcvr->sk) { + sctp_bh_lock_sock(rcvr->sk); + sctp_bh_unlock_sock(sk); + sk = rcvr->sk; + } + if (sock_owned_by_user(sk)) - sctp_add_backlog(sk, skb); + sk_add_backlog(sk, skb); else - sctp_inq_push(&chunk->rcvr->inqueue, chunk); + sctp_backlog_rcv(sk, skb); + /* Release the sock and the sock ref we took in the lookup calls. + * The asoc/ep ref will be released in sctp_backlog_rcv. + */ sctp_bh_unlock_sock(sk); - - /* Release the asoc/ep ref we took in the lookup calls. */ - if (asoc) - sctp_association_put(asoc); - else - sctp_endpoint_put(ep); + sock_put(sk); return 0; @@ -273,7 +280,8 @@ int sctp_rcv(struct sk_buff *skb) return 0; discard_release: - /* Release the asoc/ep ref we took in the lookup calls. */ + /* Release any structures we may be holding. */ + sock_put(sk); if (asoc) sctp_association_put(asoc); else @@ -282,87 +290,56 @@ int sctp_rcv(struct sk_buff *skb) goto discard_it; } -/* Process the backlog queue of the socket. Every skb on - * the backlog holds a ref on an association or endpoint. - * We hold this ref throughout the state machine to make - * sure that the structure we need is still around. +/* Handle second half of inbound skb processing. If the sock was busy, + * we may have need to delay processing until later when the sock is + * released (on the backlog). If not busy, we call this routine + * directly from the bottom half. */ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) { struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; - struct sctp_inq *inqueue = &chunk->rcvr->inqueue; + struct sctp_inq *inqueue = NULL; struct sctp_ep_common *rcvr = NULL; - int backloged = 0; rcvr = chunk->rcvr; - /* If the rcvr is dead then the association or endpoint - * has been deleted and we can safely drop the chunk - * and refs that we are holding. - */ - if (rcvr->dead) { - sctp_chunk_free(chunk); - goto done; - } - - if (unlikely(rcvr->sk != sk)) { - /* In this case, the association moved from one socket to - * another. We are currently sitting on the backlog of the - * old socket, so we need to move. - * However, since we are here in the process context we - * need to take make sure that the user doesn't own - * the new socket when we process the packet. - * If the new socket is user-owned, queue the chunk to the - * backlog of the new socket without dropping any refs. - * Otherwise, we can safely push the chunk on the inqueue. - */ - - sk = rcvr->sk; - sctp_bh_lock_sock(sk); - - if (sock_owned_by_user(sk)) { - sk_add_backlog(sk, skb); - backloged = 1; - } else - sctp_inq_push(inqueue, chunk); - - sctp_bh_unlock_sock(sk); - - /* If the chunk was backloged again, don't drop refs */ - if (backloged) - return 0; - } else { - sctp_inq_push(inqueue, chunk); - } - -done: - /* Release the refs we took in sctp_add_backlog */ - if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) - sctp_association_put(sctp_assoc(rcvr)); - else if (SCTP_EP_TYPE_SOCKET == rcvr->type) - sctp_endpoint_put(sctp_ep(rcvr)); - else - BUG(); - + BUG_TRAP(rcvr->sk == sk); + + if (rcvr->dead) { + sctp_chunk_free(chunk); + } else { + inqueue = &chunk->rcvr->inqueue; + sctp_inq_push(inqueue, chunk); + } + + /* Release the asoc/ep ref we took in the lookup calls in sctp_rcv. */ + if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) + sctp_association_put(sctp_assoc(rcvr)); + else + sctp_endpoint_put(sctp_ep(rcvr)); + return 0; } -static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb) +void sctp_backlog_migrate(struct sctp_association *assoc, + struct sock *oldsk, struct sock *newsk) { - struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; - struct sctp_ep_common *rcvr = chunk->rcvr; - - /* Hold the assoc/ep while hanging on the backlog queue. - * This way, we know structures we need will not disappear from us - */ - if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) - sctp_association_hold(sctp_assoc(rcvr)); - else if (SCTP_EP_TYPE_SOCKET == rcvr->type) - sctp_endpoint_hold(sctp_ep(rcvr)); - else - BUG(); + struct sk_buff *skb; + struct sctp_chunk *chunk; - sk_add_backlog(sk, skb); + skb = oldsk->sk_backlog.head; + oldsk->sk_backlog.head = oldsk->sk_backlog.tail = NULL; + while (skb != NULL) { + struct sk_buff *next = skb->next; + + chunk = SCTP_INPUT_CB(skb)->chunk; + skb->next = NULL; + if (&assoc->base == chunk->rcvr) + sk_add_backlog(newsk, skb); + else + sk_add_backlog(oldsk, skb); + skb = next; + } } /* Handle icmp frag needed error. */ @@ -435,7 +412,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, union sctp_addr daddr; struct sctp_af *af; struct sock *sk = NULL; - struct sctp_association *asoc; + struct sctp_association *asoc = NULL; struct sctp_transport *transport = NULL; *app = NULL; *tpp = NULL; @@ -476,6 +453,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, return sk; out: + sock_put(sk); if (asoc) sctp_association_put(asoc); return NULL; @@ -485,6 +463,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, void sctp_err_finish(struct sock *sk, struct sctp_association *asoc) { sctp_bh_unlock_sock(sk); + sock_put(sk); if (asoc) sctp_association_put(asoc); } @@ -511,7 +490,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) int type = skb->h.icmph->type; int code = skb->h.icmph->code; struct sock *sk; - struct sctp_association *asoc = NULL; + struct sctp_association *asoc; struct sctp_transport *transport; struct inet_sock *inet; char *saveip, *savesctp; @@ -737,6 +716,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l hit: sctp_endpoint_hold(ep); + sock_hold(epb->sk); read_unlock(&head->lock); return ep; } @@ -838,6 +818,7 @@ static struct sctp_association *__sctp_lookup_association( hit: *pt = transport; sctp_association_hold(asoc); + sock_hold(epb->sk); read_unlock(&head->lock); return asoc; } @@ -865,6 +846,7 @@ int sctp_has_association(const union sctp_addr *laddr, struct sctp_transport *transport; if ((asoc = sctp_lookup_association(laddr, paddr, &transport))) { + sock_put(asoc->base.sk); sctp_association_put(asoc); return 1; } diff --git a/trunk/net/sctp/inqueue.c b/trunk/net/sctp/inqueue.c index cf0c767d43ae..297b8951463e 100644 --- a/trunk/net/sctp/inqueue.c +++ b/trunk/net/sctp/inqueue.c @@ -149,7 +149,6 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) /* This is the first chunk in the packet. */ chunk->singleton = 1; ch = (sctp_chunkhdr_t *) chunk->skb->data; - chunk->data_accepted = 0; } chunk->chunk_hdr = ch; diff --git a/trunk/net/sctp/sm_sideeffect.c b/trunk/net/sctp/sm_sideeffect.c index c5beb2ad7ef7..8d1dc24bab4c 100644 --- a/trunk/net/sctp/sm_sideeffect.c +++ b/trunk/net/sctp/sm_sideeffect.c @@ -498,6 +498,10 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_CLOSED)); + /* Set sk_err to ECONNRESET on a 1-1 style socket. */ + if (!sctp_style(asoc->base.sk, UDP)) + asoc->base.sk->sk_err = ECONNRESET; + /* SEND_FAILED sent later when cleaning up the association. */ asoc->outqueue.error = error; sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); @@ -834,15 +838,6 @@ static void sctp_cmd_del_non_primary(struct sctp_association *asoc) return; } -/* Helper function to set sk_err on a 1-1 style socket. */ -static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error) -{ - struct sock *sk = asoc->base.sk; - - if (!sctp_style(sk, UDP)) - sk->sk_err = error; -} - /* These three macros allow us to pull the debugging code out of the * main flow of sctp_do_sm() to keep attention focused on the real * functionality there. @@ -1463,9 +1458,6 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, local_cork = 0; asoc->peer.retran_path = t; break; - case SCTP_CMD_SET_SK_ERR: - sctp_cmd_set_sk_err(asoc, cmd->obj.error); - break; default: printk(KERN_WARNING "Impossible command: %u, %p\n", cmd->verb, cmd->obj.ptr); diff --git a/trunk/net/sctp/sm_statefuns.c b/trunk/net/sctp/sm_statefuns.c index 8bc279219a72..2b9a832b29a7 100644 --- a/trunk/net/sctp/sm_statefuns.c +++ b/trunk/net/sctp/sm_statefuns.c @@ -93,7 +93,7 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, - __u16 error, int sk_err, + __u16 error, const struct sctp_association *asoc, struct sctp_transport *transport); @@ -448,7 +448,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, __u32 init_tag; struct sctp_chunk *err_chunk; struct sctp_packet *packet; - __u16 error; + sctp_disposition_t ret; if (!sctp_vtag_verify(chunk, asoc)) return sctp_sf_pdiscard(ep, asoc, type, arg, commands); @@ -480,9 +480,11 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, goto nomem; sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); - return sctp_stop_t1_and_abort(commands, SCTP_ERROR_INV_PARAM, - ECONNREFUSED, asoc, - chunk->transport); + sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, + SCTP_STATE(SCTP_STATE_CLOSED)); + SCTP_INC_STATS(SCTP_MIB_ABORTEDS); + sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); + return SCTP_DISPOSITION_DELETE_TCB; } /* Verify the INIT chunk before processing it. */ @@ -509,16 +511,27 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, SCTP_PACKET(packet)); SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); - error = SCTP_ERROR_INV_PARAM; + sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, + SCTP_STATE(SCTP_STATE_CLOSED)); + sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, + SCTP_NULL()); + return SCTP_DISPOSITION_CONSUME; } else { - error = SCTP_ERROR_NO_RESOURCE; + sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, + SCTP_STATE(SCTP_STATE_CLOSED)); + sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, + SCTP_NULL()); + return SCTP_DISPOSITION_NOMEM; } } else { - sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); - error = SCTP_ERROR_INV_PARAM; + ret = sctp_sf_tabort_8_4_8(ep, asoc, type, arg, + commands); + sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, + SCTP_STATE(SCTP_STATE_CLOSED)); + sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, + SCTP_NULL()); + return ret; } - return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, - asoc, chunk->transport); } /* Tag the variable length parameters. Note that we never @@ -623,9 +636,8 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, */ chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; - if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - - sizeof(sctp_chunkhdr_t))) - goto nomem; + skb_pull(chunk->skb, + ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t)); /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint * "Z" will reply with a COOKIE ACK chunk after building a TCB @@ -873,8 +885,6 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep, struct sctp_transport *transport = (struct sctp_transport *) arg; if (asoc->overall_error_count >= asoc->max_retrans) { - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ETIMEDOUT)); /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); @@ -955,8 +965,7 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep, */ chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); - if (!pskb_pull(chunk->skb, paylen)) - goto nomem; + skb_pull(chunk->skb, paylen); reply = sctp_make_heartbeat_ack(asoc, chunk, chunk->subh.hb_hdr, paylen); @@ -1019,12 +1028,6 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, commands); hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data; - /* Make sure that the length of the parameter is what we expect */ - if (ntohs(hbinfo->param_hdr.length) != - sizeof(sctp_sender_hb_info_t)) { - return SCTP_DISPOSITION_DISCARD; - } - from_addr = hbinfo->daddr; link = sctp_assoc_lookup_paddr(asoc, &from_addr); @@ -1857,9 +1860,8 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep, * are in good shape. */ chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; - if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - - sizeof(sctp_chunkhdr_t))) - goto nomem; + skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - + sizeof(sctp_chunkhdr_t)); /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie * of a duplicate COOKIE ECHO match the Verification Tags of the @@ -2121,8 +2123,6 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep, int attempts = asoc->init_err_counter + 1; if (attempts > asoc->max_init_attempts) { - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ETIMEDOUT)); sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(SCTP_ERROR_STALE_COOKIE)); return SCTP_DISPOSITION_DELETE_TCB; @@ -2259,7 +2259,6 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep, if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) error = ((sctp_errhdr_t *)chunk->skb->data)->cause; - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); /* ASSOC_FAILED will DELETE_TCB. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error)); SCTP_INC_STATS(SCTP_MIB_ABORTEDS); @@ -2304,8 +2303,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep, if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) error = ((sctp_errhdr_t *)chunk->skb->data)->cause; - return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, asoc, - chunk->transport); + return sctp_stop_t1_and_abort(commands, error, asoc, chunk->transport); } /* @@ -2317,8 +2315,7 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep void *arg, sctp_cmd_seq_t *commands) { - return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, - ENOPROTOOPT, asoc, + return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, asoc, (struct sctp_transport *)arg); } @@ -2343,7 +2340,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep, * This is common code called by several sctp_sf_*_abort() functions above. */ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, - __u16 error, int sk_err, + __u16 error, const struct sctp_association *asoc, struct sctp_transport *transport) { @@ -2353,7 +2350,6 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, SCTP_INC_STATS(SCTP_MIB_ABORTEDS); sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(sk_err)); /* CMD_INIT_FAILED will DELETE_TCB. */ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(error)); @@ -3337,8 +3333,6 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ECONNABORTED)); sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_ASCONF_ACK)); SCTP_INC_STATS(SCTP_MIB_ABORTEDS); @@ -3365,8 +3359,6 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, * processing the rest of the chunks in the packet. */ sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ECONNABORTED)); sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_ASCONF_ACK)); SCTP_INC_STATS(SCTP_MIB_ABORTEDS); @@ -3719,13 +3711,9 @@ static sctp_disposition_t sctp_sf_violation_chunklen( if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) { sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ECONNREFUSED)); sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); } else { - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ECONNABORTED)); sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); @@ -4043,8 +4031,6 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort( * TCB. This is a departure from our typical NOMEM handling. */ - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ECONNABORTED)); /* Delete the established association. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_USER_ABORT)); @@ -4186,8 +4172,6 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( * TCB. This is a departure from our typical NOMEM handling. */ - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ECONNREFUSED)); /* Delete the established association. */ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(SCTP_ERROR_USER_ABORT)); @@ -4556,8 +4540,6 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep, struct sctp_transport *transport = arg; if (asoc->overall_error_count >= asoc->max_retrans) { - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ETIMEDOUT)); /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); @@ -4677,8 +4659,6 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep, SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d" " max_init_attempts: %d\n", attempts, asoc->max_init_attempts); - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ETIMEDOUT)); sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); return SCTP_DISPOSITION_DELETE_TCB; @@ -4728,8 +4708,6 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); } else { - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ETIMEDOUT)); sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); return SCTP_DISPOSITION_DELETE_TCB; @@ -4761,8 +4739,6 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep, SCTP_DEBUG_PRINTK("Timer T2 expired.\n"); if (asoc->overall_error_count >= asoc->max_retrans) { - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ETIMEDOUT)); /* Note: CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); @@ -4838,8 +4814,6 @@ sctp_disposition_t sctp_sf_t4_timer_expire( if (asoc->overall_error_count >= asoc->max_retrans) { sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ETIMEDOUT)); sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); SCTP_INC_STATS(SCTP_MIB_ABORTEDS); @@ -4893,8 +4867,6 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep, goto nomem; sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ETIMEDOUT)); sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); @@ -5179,9 +5151,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, int tmp; __u32 tsn; int account_value; - struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; struct sock *sk = asoc->base.sk; - int rcvbuf_over = 0; data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data; skb_pull(chunk->skb, sizeof(sctp_datahdr_t)); @@ -5192,16 +5162,10 @@ static int sctp_eat_data(const struct sctp_association *asoc, /* ASSERT: Now skb->data is really the user data. */ /* - * If we are established, and we have used up our receive buffer - * memory, think about droping the frame. - * Note that we have an opportunity to improve performance here. - * If we accept one chunk from an skbuff, we have to keep all the - * memory of that skbuff around until the chunk is read into user - * space. Therefore, once we accept 1 chunk we may as well accept all - * remaining chunks in the skbuff. The data_accepted flag helps us do - * that. - */ - if ((asoc->state == SCTP_STATE_ESTABLISHED) && (!chunk->data_accepted)) { + * if we are established, and we have used up our receive + * buffer memory, drop the frame + */ + if (asoc->state == SCTP_STATE_ESTABLISHED) { /* * If the receive buffer policy is 1, then each * association can allocate up to sk_rcvbuf bytes @@ -5212,25 +5176,9 @@ static int sctp_eat_data(const struct sctp_association *asoc, account_value = atomic_read(&asoc->rmem_alloc); else account_value = atomic_read(&sk->sk_rmem_alloc); - if (account_value > sk->sk_rcvbuf) { - /* - * We need to make forward progress, even when we are - * under memory pressure, so we always allow the - * next tsn after the ctsn ack point to be accepted. - * This lets us avoid deadlocks in which we have to - * drop frames that would otherwise let us drain the - * receive queue. - */ - if ((sctp_tsnmap_get_ctsn(map) + 1) != tsn) - return SCTP_IERROR_IGNORE_TSN; - - /* - * We're going to accept the frame but we should renege - * to make space for it. This will send us down that - * path later in this function. - */ - rcvbuf_over = 1; - } + + if (account_value > sk->sk_rcvbuf) + return SCTP_IERROR_IGNORE_TSN; } /* Process ECN based congestion. @@ -5278,7 +5226,6 @@ static int sctp_eat_data(const struct sctp_association *asoc, datalen -= sizeof(sctp_data_chunk_t); deliver = SCTP_CMD_CHUNK_ULP; - chunk->data_accepted = 1; /* Think about partial delivery. */ if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) { @@ -5295,8 +5242,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, * large spill over. */ if (!asoc->rwnd || asoc->rwnd_over || - (datalen > asoc->rwnd + asoc->frag_point) || - rcvbuf_over) { + (datalen > asoc->rwnd + asoc->frag_point)) { /* If this is the next TSN, consider reneging to make * room. Note: Playing nice with a confused sender. A @@ -5304,8 +5250,8 @@ static int sctp_eat_data(const struct sctp_association *asoc, * space and in the future we may want to detect and * do more drastic reneging. */ - if (sctp_tsnmap_has_gap(map) && - (sctp_tsnmap_get_ctsn(map) + 1) == tsn) { + if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) && + (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) { SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn); deliver = SCTP_CMD_RENEGE; } else { @@ -5334,8 +5280,6 @@ static int sctp_eat_data(const struct sctp_association *asoc, * processing the rest of the chunks in the packet. */ sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, - SCTP_ERROR(ECONNABORTED)); sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_NO_DATA)); SCTP_INC_STATS(SCTP_MIB_ABORTEDS); diff --git a/trunk/net/sctp/sm_statetable.c b/trunk/net/sctp/sm_statetable.c index 8bcca5676151..75ef10408764 100644 --- a/trunk/net/sctp/sm_statetable.c +++ b/trunk/net/sctp/sm_statetable.c @@ -366,9 +366,9 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, /* SCTP_STATE_EMPTY */ \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ /* SCTP_STATE_COOKIE_ECHOED */ \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ /* SCTP_STATE_ESTABLISHED */ \ @@ -380,7 +380,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ } /* TYPE_SCTP_ECN_ECNE */ #define TYPE_SCTP_ECN_CWR { \ @@ -401,7 +401,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ } /* TYPE_SCTP_ECN_CWR */ #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ @@ -647,7 +647,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { /* SCTP_STATE_EMPTY */ \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ + {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ /* SCTP_STATE_COOKIE_WAIT */ \ {.fn = sctp_sf_do_prm_requestheartbeat, \ .name = "sctp_sf_do_prm_requestheartbeat"}, \ diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 174d4d35e951..b6e4b89539b3 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -1057,7 +1057,6 @@ static int __sctp_connect(struct sock* sk, inet_sk(sk)->dport = htons(asoc->peer.port); af = sctp_get_af_specific(to.sa.sa_family); af->to_sk_daddr(&to, sk); - sk->sk_err = 0; timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK); err = sctp_wait_for_connect(asoc, &timeo); @@ -1229,7 +1228,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) ep = sctp_sk(sk)->ep; - /* Walk all associations on an endpoint. */ + /* Walk all associations on a socket, not on an endpoint. */ list_for_each_safe(pos, temp, &ep->asocs) { asoc = list_entry(pos, struct sctp_association, asocs); @@ -1242,13 +1241,13 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) if (sctp_state(asoc, CLOSED)) { sctp_unhash_established(asoc); sctp_association_free(asoc); - continue; - } - } - if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) - sctp_primitive_ABORT(asoc, NULL); - else + } else if (sock_flag(sk, SOCK_LINGER) && + !sk->sk_lingertime) + sctp_primitive_ABORT(asoc, NULL); + else + sctp_primitive_SHUTDOWN(asoc, NULL); + } else sctp_primitive_SHUTDOWN(asoc, NULL); } @@ -5318,7 +5317,6 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, */ sctp_release_sock(sk); current_timeo = schedule_timeout(current_timeo); - BUG_ON(sk != asoc->base.sk); sctp_lock_sock(sk); *timeo_p = current_timeo; @@ -5606,14 +5604,12 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, */ newsp->type = type; - /* Mark the new socket "in-use" by the user so that any packets - * that may arrive on the association after we've moved it are - * queued to the backlog. This prevents a potential race between - * backlog processing on the old socket and new-packet processing - * on the new socket. - */ - sctp_lock_sock(newsk); + spin_lock_bh(&oldsk->sk_lock.slock); + /* Migrate the backlog from oldsk to newsk. */ + sctp_backlog_migrate(assoc, oldsk, newsk); + /* Migrate the association to the new socket. */ sctp_assoc_migrate(assoc, newsk); + spin_unlock_bh(&oldsk->sk_lock.slock); /* If the association on the newsk is already closed before accept() * is called, set RCV_SHUTDOWN flag. @@ -5622,7 +5618,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, newsk->sk_shutdown |= RCV_SHUTDOWN; newsk->sk_state = SCTP_SS_ESTABLISHED; - sctp_release_sock(newsk); } /* This proto struct describes the ULP interface for SCTP. */ diff --git a/trunk/net/sctp/ulpqueue.c b/trunk/net/sctp/ulpqueue.c index 575e556aeb3e..2080b2d28c98 100644 --- a/trunk/net/sctp/ulpqueue.c +++ b/trunk/net/sctp/ulpqueue.c @@ -279,7 +279,6 @@ static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq, static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag) { struct sk_buff *pos; - struct sk_buff *new = NULL; struct sctp_ulpevent *event; struct sk_buff *pnext, *last; struct sk_buff *list = skb_shinfo(f_frag)->frag_list; @@ -298,33 +297,11 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *qu */ if (last) last->next = pos; - else { - if (skb_cloned(f_frag)) { - /* This is a cloned skb, we can't just modify - * the frag_list. We need a new skb to do that. - * Instead of calling skb_unshare(), we'll do it - * ourselves since we need to delay the free. - */ - new = skb_copy(f_frag, GFP_ATOMIC); - if (!new) - return NULL; /* try again later */ - - new->sk = f_frag->sk; - - skb_shinfo(new)->frag_list = pos; - } else - skb_shinfo(f_frag)->frag_list = pos; - } + else + skb_shinfo(f_frag)->frag_list = pos; /* Remove the first fragment from the reassembly queue. */ __skb_unlink(f_frag, queue); - - /* if we did unshare, then free the old skb and re-assign */ - if (new) { - kfree_skb(f_frag); - f_frag = new; - } - while (pos) { pnext = pos->next; diff --git a/trunk/net/sunrpc/cache.c b/trunk/net/sunrpc/cache.c index 7026b0866b7b..3ac4193a78ed 100644 --- a/trunk/net/sunrpc/cache.c +++ b/trunk/net/sunrpc/cache.c @@ -159,7 +159,6 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail, detail->update(tmp, new); tmp->next = *head; *head = tmp; - detail->entries++; cache_get(tmp); is_new = cache_fresh_locked(tmp, new->expiry_time); cache_fresh_locked(old, 0); diff --git a/trunk/net/xfrm/xfrm_input.c b/trunk/net/xfrm/xfrm_input.c index 891a6090cc09..b54971059f16 100644 --- a/trunk/net/xfrm/xfrm_input.c +++ b/trunk/net/xfrm/xfrm_input.c @@ -62,7 +62,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) case IPPROTO_COMP: if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr))) return -EINVAL; - *spi = htonl(ntohs(*(u16*)(skb->h.raw + 2))); + *spi = ntohl(ntohs(*(u16*)(skb->h.raw + 2))); *seq = 0; return 0; default: diff --git a/trunk/scripts/gen_initramfs_list.sh b/trunk/scripts/gen_initramfs_list.sh index 331c079f029b..56b3bed1108f 100644 --- a/trunk/scripts/gen_initramfs_list.sh +++ b/trunk/scripts/gen_initramfs_list.sh @@ -200,11 +200,7 @@ input_file() { print_mtime "$1" >> ${output} cat "$1" >> ${output} else - cat "$1" | while read type dir file perm ; do - if [ "$type" == "file" ]; then - echo "$file \\"; - fi - done + grep ^file "$1" | cut -d ' ' -f 3 fi elif [ -d "$1" ]; then dir_filelist "$1" diff --git a/trunk/scripts/mkmakefile b/trunk/scripts/mkmakefile index 7f9d544f9b6c..a22cbedd3b3e 100644 --- a/trunk/scripts/mkmakefile +++ b/trunk/scripts/mkmakefile @@ -10,10 +10,7 @@ # $4 - patchlevel -test ! -r $2/Makefile -o -O $2/Makefile || exit 0 -echo " GEN $2/Makefile" - -cat << EOF > $2/Makefile +cat << EOF # Automatically generated by $0: don't edit VERSION = $3 diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index d0f86ed43f7a..cd00e9f07589 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -487,14 +487,14 @@ static int strrcmp(const char *s, const char *sub) * atsym =__param* * * Pattern 2: - * Many drivers utilise a *driver container with references to + * Many drivers utilise a *_driver container with references to * add, remove, probe functions etc. * These functions may often be marked __init and we do not want to * warn here. * the pattern is identified by: * tosec = .init.text | .exit.text | .init.data * fromsec = .data - * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one + * atsym = *_driver, *_template, *_sht, *_ops, *_probe, *probe_one **/ static int secref_whitelist(const char *tosec, const char *fromsec, const char *atsym) @@ -502,7 +502,7 @@ static int secref_whitelist(const char *tosec, const char *fromsec, int f1 = 1, f2 = 1; const char **s; const char *pat2sym[] = { - "driver", + "_driver", "_template", /* scsi uses *_template a lot */ "_sht", /* scsi also used *_sht to some extent */ "_ops", @@ -697,79 +697,29 @@ static void check_sec_ref(struct module *mod, const char *modname, /* Walk through all sections */ for (i = 0; i < hdr->e_shnum; i++) { - const char *name = secstrings + sechdrs[i].sh_name; - const char *secname; - Elf_Rela r; - unsigned int r_sym; + Elf_Rela *rela; + Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; + Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; + const char *name = secstrings + sechdrs[i].sh_name + + strlen(".rela"); /* We want to process only relocation sections and not .init */ - if (sechdrs[i].sh_type == SHT_RELA) { - Elf_Rela *rela; - Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; - Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; - name += strlen(".rela"); - if (section_ref_ok(name)) - continue; + if (section_ref_ok(name) || (sechdrs[i].sh_type != SHT_RELA)) + continue; - for (rela = start; rela < stop; rela++) { - r.r_offset = TO_NATIVE(rela->r_offset); -#if KERNEL_ELFCLASS == ELFCLASS64 - if (hdr->e_machine == EM_MIPS) { - r_sym = ELF64_MIPS_R_SYM(rela->r_info); - r_sym = TO_NATIVE(r_sym); - } else { - r.r_info = TO_NATIVE(rela->r_info); - r_sym = ELF_R_SYM(r.r_info); - } -#else - r.r_info = TO_NATIVE(rela->r_info); - r_sym = ELF_R_SYM(r.r_info); -#endif - r.r_addend = TO_NATIVE(rela->r_addend); - sym = elf->symtab_start + r_sym; - /* Skip special sections */ - if (sym->st_shndx >= SHN_LORESERVE) - continue; - - secname = secstrings + - sechdrs[sym->st_shndx].sh_name; - if (section(secname)) - warn_sec_mismatch(modname, name, - elf, sym, r); - } - } else if (sechdrs[i].sh_type == SHT_REL) { - Elf_Rel *rel; - Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset; - Elf_Rel *stop = (void*)start + sechdrs[i].sh_size; - name += strlen(".rel"); - if (section_ref_ok(name)) + for (rela = start; rela < stop; rela++) { + Elf_Rela r; + const char *secname; + r.r_offset = TO_NATIVE(rela->r_offset); + r.r_info = TO_NATIVE(rela->r_info); + r.r_addend = TO_NATIVE(rela->r_addend); + sym = elf->symtab_start + ELF_R_SYM(r.r_info); + /* Skip special sections */ + if (sym->st_shndx >= SHN_LORESERVE) continue; - for (rel = start; rel < stop; rel++) { - r.r_offset = TO_NATIVE(rel->r_offset); -#if KERNEL_ELFCLASS == ELFCLASS64 - if (hdr->e_machine == EM_MIPS) { - r_sym = ELF64_MIPS_R_SYM(rel->r_info); - r_sym = TO_NATIVE(r_sym); - } else { - r.r_info = TO_NATIVE(rel->r_info); - r_sym = ELF_R_SYM(r.r_info); - } -#else - r.r_info = TO_NATIVE(rel->r_info); - r_sym = ELF_R_SYM(r.r_info); -#endif - r.r_addend = 0; - sym = elf->symtab_start + r_sym; - /* Skip special sections */ - if (sym->st_shndx >= SHN_LORESERVE) - continue; - - secname = secstrings + - sechdrs[sym->st_shndx].sh_name; - if (section(secname)) - warn_sec_mismatch(modname, name, - elf, sym, r); - } + secname = secstrings + sechdrs[sym->st_shndx].sh_name; + if (section(secname)) + warn_sec_mismatch(modname, name, elf, sym, r); } } } diff --git a/trunk/scripts/mod/modpost.h b/trunk/scripts/mod/modpost.h index 861d866fcd83..b14255c72a37 100644 --- a/trunk/scripts/mod/modpost.h +++ b/trunk/scripts/mod/modpost.h @@ -21,7 +21,6 @@ #define ELF_ST_BIND ELF32_ST_BIND #define ELF_ST_TYPE ELF32_ST_TYPE -#define Elf_Rel Elf32_Rel #define Elf_Rela Elf32_Rela #define ELF_R_SYM ELF32_R_SYM #define ELF_R_TYPE ELF32_R_TYPE @@ -35,31 +34,11 @@ #define ELF_ST_BIND ELF64_ST_BIND #define ELF_ST_TYPE ELF64_ST_TYPE -#define Elf_Rel Elf64_Rel #define Elf_Rela Elf64_Rela #define ELF_R_SYM ELF64_R_SYM #define ELF_R_TYPE ELF64_R_TYPE #endif -/* The 64-bit MIPS ELF ABI uses an unusual reloc format. */ -typedef struct -{ - Elf32_Word r_sym; /* Symbol index */ - unsigned char r_ssym; /* Special symbol for 2nd relocation */ - unsigned char r_type3; /* 3rd relocation type */ - unsigned char r_type2; /* 2nd relocation type */ - unsigned char r_type1; /* 1st relocation type */ -} _Elf64_Mips_R_Info; - -typedef union -{ - Elf64_Xword r_info_number; - _Elf64_Mips_R_Info r_info_fields; -} _Elf64_Mips_R_Info_union; - -#define ELF64_MIPS_R_SYM(i) \ - ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym) - #if KERNEL_ELFDATA != HOST_ELFDATA static inline void __endian(const void *src, void *dest, unsigned int size) @@ -69,6 +48,8 @@ static inline void __endian(const void *src, void *dest, unsigned int size) ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1]; } + + #define TO_NATIVE(x) \ ({ \ typeof(x) __x; \ diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 21dad415b896..d987048d3f33 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -3231,7 +3231,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) goto out; /* Handle mapped IPv4 packets arriving via IPv6 sockets */ - if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) + if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP)) family = PF_INET; read_lock_bh(&sk->sk_callback_lock); diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index c284dbb8b8c0..7177e98df7f3 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -594,10 +594,6 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) *scontext_len = strlen(initial_sid_to_string[sid]) + 1; scontextp = kmalloc(*scontext_len,GFP_ATOMIC); - if (!scontextp) { - rc = -ENOMEM; - goto out; - } strcpy(scontextp, initial_sid_to_string[sid]); *scontext = scontextp; goto out; diff --git a/trunk/sound/drivers/mpu401/mpu401.c b/trunk/sound/drivers/mpu401/mpu401.c index 77b06009735d..da7ef26995c3 100644 --- a/trunk/sound/drivers/mpu401/mpu401.c +++ b/trunk/sound/drivers/mpu401/mpu401.c @@ -151,7 +151,7 @@ static struct pnp_device_id snd_mpu401_pnpids[] = { MODULE_DEVICE_TABLE(pnp, snd_mpu401_pnpids); -static int __devinit snd_mpu401_pnp(int dev, struct pnp_dev *device, +static int __init snd_mpu401_pnp(int dev, struct pnp_dev *device, const struct pnp_device_id *id) { if (!pnp_port_valid(device, 0) || diff --git a/trunk/sound/isa/es18xx.c b/trunk/sound/isa/es18xx.c index e6945db8ed1b..a36ec1daa5cb 100644 --- a/trunk/sound/isa/es18xx.c +++ b/trunk/sound/isa/es18xx.c @@ -85,8 +85,6 @@ #include #include #include -#include - #include #include #include diff --git a/trunk/sound/oss/ad1848.c b/trunk/sound/oss/ad1848.c index e04fa49b0dc8..49796be955f3 100644 --- a/trunk/sound/oss/ad1848.c +++ b/trunk/sound/oss/ad1848.c @@ -2026,8 +2026,7 @@ int ad1848_init (char *name, struct resource *ports, int irq, int dma_playback, if (irq > 0) { devc->dev_no = my_dev; - if (request_irq(devc->irq, adintr, 0, devc->name, - (void *)(long)my_dev) < 0) + if (request_irq(devc->irq, adintr, 0, devc->name, (void *)my_dev) < 0) { printk(KERN_WARNING "ad1848: Unable to allocate IRQ\n"); /* Don't free it either then.. */ @@ -2176,7 +2175,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int if (!share_dma) { if (devc->irq > 0) /* There is no point in freeing irq, if it wasn't allocated */ - free_irq(devc->irq, (void *)(long)devc->dev_no); + free_irq(devc->irq, (void *)devc->dev_no); sound_free_dma(dma_playback); @@ -2205,7 +2204,7 @@ irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy) unsigned char c930_stat = 0; int cnt = 0; - dev = (long)dev_id; + dev = (int)dev_id; devc = (ad1848_info *) audio_devs[dev]->devc; interrupt_again: /* Jump back here if int status doesn't reset */ @@ -2901,8 +2900,7 @@ static struct pnp_dev *activate_dev(char *devname, char *resname, struct pnp_dev return(dev); } -static struct pnp_dev __init *ad1848_init_generic(struct pnp_card *bus, - struct address_info *hw_config, int slot) +static struct pnp_dev *ad1848_init_generic(struct pnp_card *bus, struct address_info *hw_config, int slot) { /* Configure Audio device */ diff --git a/trunk/sound/oss/nm256_audio.c b/trunk/sound/oss/nm256_audio.c index 6e662ac009ae..7de079b202f2 100644 --- a/trunk/sound/oss/nm256_audio.c +++ b/trunk/sound/oss/nm256_audio.c @@ -960,7 +960,7 @@ static struct ac97_mixer_value_list mixer_defaults[] = { /* Installs the AC97 mixer into CARD. */ -static int __devinit +static int __init nm256_install_mixer (struct nm256_info *card) { int mixer; @@ -995,7 +995,7 @@ nm256_install_mixer (struct nm256_info *card) * RAM. */ -static void __devinit +static void __init nm256_peek_for_sig (struct nm256_info *card) { u32 port1offset @@ -1056,7 +1056,7 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) card->playing = 0; card->recording = 0; card->rev = rev; - spin_lock_init(&card->lock); + spin_lock_init(&card->lock); /* Init the memory port info. */ for (x = 0; x < 2; x++) {