]> pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Jul 2008 15:33:25 +0000 (08:33 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Jul 2008 15:33:25 +0000 (08:33 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
  sparc: Set CONFIG_HAVE_ARCH_TRACEHOOK
  sparc: Add task_pt_regs().
  sparc: Add call to tracehook_signal_handler().
  sparc: Create and use TIF_NOTIFY_RESUME.
  sparc: Use tracehook routines in syscall_trace().
  sparc64: tracehook: CONFIG_HAVE_ARCH_TRACEHOOK
  sparc: Add user_stack_pointer().
  sparc64: tracehook_signal_handler
  sparc64: tracehook: TIF_NOTIFY_RESUME
  sparc: Add asm/syscall.h
  sparc64: tracehook syscall
  sparc: enable headers_export again
  sparc, sparc64: use arch/sparc/include

23 files changed:
Documentation/SubmittingPatches
Documentation/i2c/upgrading-clients [new file with mode: 0644]
drivers/acpi/processor_idle.c
drivers/base/memory.c
drivers/char/pcmcia/ipwireless/hardware.c
drivers/char/pcmcia/ipwireless/hardware.h
drivers/char/pcmcia/ipwireless/main.c
drivers/char/pcmcia/ipwireless/main.h
drivers/char/pcmcia/ipwireless/network.c
drivers/char/pcmcia/ipwireless/network.h
drivers/char/pcmcia/ipwireless/tty.c
drivers/cpuidle/cpuidle.c
drivers/i2c/busses/i2c-bfin-twi.c
drivers/i2c/busses/i2c-gpio.c
drivers/i2c/busses/i2c-s3c2410.c
include/asm-arm/plat-s3c/iic.h
net/dccp/dccp.h
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/output.c
net/dccp/timer.c
net/ipv4/ipcomp.c
net/ipv6/ipcomp6.c

index 118ca6e9404f47ded06c7ee3a287003d00377e56..f79ad9ff6031aa4ee622d9f0be3e0c1604e2d14b 100644 (file)
@@ -528,7 +528,33 @@ See more details on the proper patch format in the following
 references.
 
 
+16) Sending "git pull" requests  (from Linus emails)
 
+Please write the git repo address and branch name alone on the same line
+so that I can't even by mistake pull from the wrong branch, and so
+that a triple-click just selects the whole thing.
+
+So the proper format is something along the lines of:
+
+       "Please pull from
+
+               git://jdelvare.pck.nerim.net/jdelvare-2.6 i2c-for-linus
+
+        to get these changes:"
+
+so that I don't have to hunt-and-peck for the address and inevitably
+get it wrong (actually, I've only gotten it wrong a few times, and
+checking against the diffstat tells me when I get it wrong, but I'm
+just a lot more comfortable when I don't have to "look for" the right
+thing to pull, and double-check that I have the right branch-name).
+
+
+Please use "git diff -M --stat --summary" to generate the diffstat:
+the -M enables rename detection, and the summary enables a summary of
+new/deleted or renamed files.
+
+With rename detection, the statistics are rather different [...]
+because git will notice that a fair number of the changes are renames.
 
 -----------------------------------
 SECTION 2 - HINTS, TIPS, AND TRICKS
diff --git a/Documentation/i2c/upgrading-clients b/Documentation/i2c/upgrading-clients
new file mode 100644 (file)
index 0000000..9a45f9b
--- /dev/null
@@ -0,0 +1,281 @@
+Upgrading I2C Drivers to the new 2.6 Driver Model
+=================================================
+
+Ben Dooks <ben-linux@fluff.org>
+
+Introduction
+------------
+
+This guide outlines how to alter existing Linux 2.6 client drivers from
+the old to the new new binding methods.
+
+
+Example old-style driver
+------------------------
+
+
+struct example_state {
+       struct i2c_client       client;
+       ....
+};
+
+static struct i2c_driver example_driver;
+
+static unsigned short ignore[] = { I2C_CLIENT_END };
+static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
+
+I2C_CLIENT_INSMOD;
+
+static int example_attach(struct i2c_adapter *adap, int addr, int kind)
+{
+       struct example_state *state;
+       struct device *dev = &adap->dev;  /* to use for dev_ reports */
+       int ret;
+
+       state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
+       if (state == NULL) {
+               dev_err(dev, "failed to create our state\n");
+               return -ENOMEM;
+       }
+
+       example->client.addr    = addr;
+       example->client.flags   = 0;
+       example->client.adapter = adap;
+
+       i2c_set_clientdata(&state->i2c_client, state);
+       strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
+
+       ret = i2c_attach_client(&state->i2c_client);
+       if (ret < 0) {
+               dev_err(dev, "failed to attach client\n");
+               kfree(state);
+               return ret;
+       }
+
+       dev = &state->i2c_client.dev;
+
+       /* rest of the initialisation goes here. */
+
+       dev_info(dev, "example client created\n");
+
+       return 0;
+}
+
+static int __devexit example_detach(struct i2c_client *client)
+{
+       struct example_state *state = i2c_get_clientdata(client);
+
+       i2c_detach_client(client);
+       kfree(state);
+       return 0;
+}
+
+static int example_attach_adapter(struct i2c_adapter *adap)
+{
+       return i2c_probe(adap, &addr_data, example_attach);
+}
+
+static struct i2c_driver example_driver = {
+       .driver         = {
+               .owner          = THIS_MODULE,
+               .name           = "example",
+       },
+       .attach_adapter = example_attach_adapter,
+       .detach_client  = __devexit_p(example_detach),
+       .suspend        = example_suspend,
+       .resume         = example_resume,
+};
+
+
+Updating the client
+-------------------
+
+The new style binding model will check against a list of supported
+devices and their associated address supplied by the code registering
+the busses. This means that the driver .attach_adapter and
+.detach_adapter methods can be removed, along with the addr_data,
+as follows:
+
+- static struct i2c_driver example_driver;
+
+- static unsigned short ignore[] = { I2C_CLIENT_END };
+- static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
+
+- I2C_CLIENT_INSMOD;
+
+- static int example_attach_adapter(struct i2c_adapter *adap)
+- {
+-      return i2c_probe(adap, &addr_data, example_attach);
+- }
+
+ static struct i2c_driver example_driver = {
+-      .attach_adapter = example_attach_adapter,
+-      .detach_client  = __devexit_p(example_detach),
+ }
+
+Add the probe and remove methods to the i2c_driver, as so:
+
+ static struct i2c_driver example_driver = {
++      .probe          = example_probe,
++      .remove         = __devexit_p(example_remove),
+ }
+
+Change the example_attach method to accept the new parameters
+which include the i2c_client that it will be working with:
+
+- static int example_attach(struct i2c_adapter *adap, int addr, int kind)
++ static int example_probe(struct i2c_client *client,
++                         const struct i2c_device_id *id)
+
+Change the name of example_attach to example_probe to align it with the
+i2c_driver entry names. The rest of the probe routine will now need to be
+changed as the i2c_client has already been setup for use.
+
+The necessary client fields have already been setup before
+the probe function is called, so the following client setup
+can be removed:
+
+-      example->client.addr    = addr;
+-      example->client.flags   = 0;
+-      example->client.adapter = adap;
+-
+-      strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
+
+The i2c_set_clientdata is now:
+
+-      i2c_set_clientdata(&state->client, state);
++      i2c_set_clientdata(client, state);
+
+The call to i2c_attach_client is no longer needed, if the probe
+routine exits successfully, then the driver will be automatically
+attached by the core. Change the probe routine as so:
+
+-      ret = i2c_attach_client(&state->i2c_client);
+-      if (ret < 0) {
+-              dev_err(dev, "failed to attach client\n");
+-              kfree(state);
+-              return ret;
+-      }
+
+
+Remove the storage of 'struct i2c_client' from the 'struct example_state'
+as we are provided with the i2c_client in our example_probe. Instead we
+store a pointer to it for when it is needed.
+
+struct example_state {
+-      struct i2c_client       client;
++      struct i2c_client       *client;
+
+the new i2c client as so:
+
+-      struct device *dev = &adap->dev;  /* to use for dev_ reports */
++      struct device *dev = &i2c_client->dev;  /* to use for dev_ reports */
+
+And remove the change after our client is attached, as the driver no
+longer needs to register a new client structure with the core:
+
+-      dev = &state->i2c_client.dev;
+
+In the probe routine, ensure that the new state has the client stored
+in it:
+
+static int example_probe(struct i2c_client *i2c_client,
+                        const struct i2c_device_id *id)
+{
+       struct example_state *state;
+       struct device *dev = &i2c_client->dev;
+       int ret;
+
+       state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
+       if (state == NULL) {
+               dev_err(dev, "failed to create our state\n");
+               return -ENOMEM;
+       }
+
++      state->client = i2c_client;
+
+Update the detach method, by changing the name to _remove and
+to delete the i2c_detach_client call. It is possible that you
+can also remove the ret variable as it is not not needed for
+any of the core functions.
+
+- static int __devexit example_detach(struct i2c_client *client)
++ static int __devexit example_remove(struct i2c_client *client)
+{
+       struct example_state *state = i2c_get_clientdata(client);
+
+-      i2c_detach_client(client);
+
+And finally ensure that we have the correct ID table for the i2c-core
+and other utilities:
+
++ struct i2c_device_id example_idtable[] = {
++       { "example", 0 },
++       { }
++};
++
++MODULE_DEVICE_TABLE(i2c, example_idtable);
+
+static struct i2c_driver example_driver = {
+       .driver         = {
+               .owner          = THIS_MODULE,
+               .name           = "example",
+       },
++      .id_table       = example_ids,
+
+
+Our driver should now look like this:
+
+struct example_state {
+       struct i2c_client       *client;
+       ....
+};
+
+static int example_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct example_state *state;
+       struct device *dev = &client->dev;
+
+       state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
+       if (state == NULL) {
+               dev_err(dev, "failed to create our state\n");
+               return -ENOMEM;
+       }
+
+       state->client = client;
+       i2c_set_clientdata(client, state);
+
+       /* rest of the initialisation goes here. */
+
+       dev_info(dev, "example client created\n");
+
+       return 0;
+}
+
+static int __devexit example_remove(struct i2c_client *client)
+{
+       struct example_state *state = i2c_get_clientdata(client);
+
+       kfree(state);
+       return 0;
+}
+
+static struct i2c_device_id example_idtable[] = {
+       { "example", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, example_idtable);
+
+static struct i2c_driver example_driver = {
+       .driver         = {
+               .owner          = THIS_MODULE,
+               .name           = "example",
+       },
+       .id_table       = example_idtable,
+       .probe          = example_probe,
+       .remove         = __devexit_p(example_remove),
+       .suspend        = example_suspend,
+       .resume         = example_resume,
+};
index b7f2963693a7b40fa2bc336dad5ae4cf0d9a8fbf..283c08f5f4d4390bfd12a7bfd820787a1344dbde 100644 (file)
@@ -1332,9 +1332,15 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
        if (!pr->flags.power_setup_done)
                return -ENODEV;
 
-       /* Fall back to the default idle loop */
-       pm_idle = pm_idle_save;
-       synchronize_sched();    /* Relies on interrupts forcing exit from idle. */
+       /*
+        * Fall back to the default idle loop, when pm_idle_save had
+        * been initialized.
+        */
+       if (pm_idle_save) {
+               pm_idle = pm_idle_save;
+               /* Relies on interrupts forcing exit from idle. */
+               synchronize_sched();
+       }
 
        pr->flags.power = 0;
        result = acpi_processor_get_power_info(pr);
@@ -1896,7 +1902,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
 
        /* Unregister the idle handler when processor #0 is removed. */
        if (pr->id == 0) {
-               pm_idle = pm_idle_save;
+               if (pm_idle_save)
+                       pm_idle = pm_idle_save;
 
                /*
                 * We are about to unload the current idle thread pm callback
index 3ad49a00029ff91c39f00bb430de302f7ab409b7..af0d175c025dcd168c5a6de866351fd0b1f83d5a 100644 (file)
@@ -103,7 +103,8 @@ static ssize_t show_mem_phys_index(struct sys_device *dev,
 /*
  * Show whether the section of memory is likely to be hot-removable
  */
-static ssize_t show_mem_removable(struct sys_device *dev, char *buf)
+static ssize_t show_mem_removable(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        unsigned long start_pfn;
        int ret;
index 929101ecbae29c180889a1d10e8c7f0549bcd713..7d500f82195a08b22d1ab550ab95bb43e541dd7a 100644 (file)
 static void ipw_send_setup_packet(struct ipw_hardware *hw);
 static void handle_received_SETUP_packet(struct ipw_hardware *ipw,
                                         unsigned int address,
-                                        unsigned char *data, int len,
+                                        const unsigned char *data, int len,
                                         int is_last);
 static void ipwireless_setup_timer(unsigned long data);
 static void handle_received_CTRL_packet(struct ipw_hardware *hw,
-               unsigned int channel_idx, unsigned char *data, int len);
+               unsigned int channel_idx, const unsigned char *data, int len);
 
 /*#define TIMING_DIAGNOSTICS*/
 
@@ -79,8 +79,7 @@ static void report_timing(void)
                timing_stats.last_report_time = jiffies;
                if (!first)
                        printk(KERN_INFO IPWIRELESS_PCCARD_NAME
-                              ": %u us elapsed - read %lu bytes in %u us, "
-                              "wrote %lu bytes in %u us\n",
+                              ": %u us elapsed - read %lu bytes in %u us, wrote %lu bytes in %u us\n",
                               jiffies_to_usecs(since),
                               timing_stats.read_bytes,
                               jiffies_to_usecs(timing_stats.read_time),
@@ -133,29 +132,17 @@ enum {
 #define NL_FOLLOWING_PACKET_HEADER_SIZE    1
 
 struct nl_first_packet_header {
-#if defined(__BIG_ENDIAN_BITFIELD)
-       unsigned char packet_rank:2;
-       unsigned char address:3;
-       unsigned char protocol:3;
-#else
        unsigned char protocol:3;
        unsigned char address:3;
        unsigned char packet_rank:2;
-#endif
        unsigned char length_lsb;
        unsigned char length_msb;
 };
 
 struct nl_packet_header {
-#if defined(__BIG_ENDIAN_BITFIELD)
-       unsigned char packet_rank:2;
-       unsigned char address:3;
-       unsigned char protocol:3;
-#else
        unsigned char protocol:3;
        unsigned char address:3;
        unsigned char packet_rank:2;
-#endif
 };
 
 /* Value of 'packet_rank' above */
@@ -227,15 +214,12 @@ struct MEMINFREG {
        unsigned short memreg_tx_new;   /* TX2 (new) Register (R/W) */
 };
 
-#define IODMADPR 0x00          /* DMA Data Port Register (R/W) */
-
 #define CARD_PRESENT_VALUE (0xBEEFCAFEUL)
 
 #define MEMTX_TX                       0x0001
 #define MEMRX_RX                       0x0001
 #define MEMRX_RX_DONE                  0x0001
 #define MEMRX_PCINTACKK                0x0001
-#define MEMRX_MEMSPURIOUSINT           0x0001
 
 #define NL_NUM_OF_PRIORITIES       3
 #define NL_NUM_OF_PROTOCOLS        3
@@ -245,7 +229,7 @@ struct ipw_hardware {
        unsigned int base_port;
        short hw_version;
        unsigned short ll_mtu;
-       spinlock_t spinlock;
+       spinlock_t lock;
 
        int initializing;
        int init_loops;
@@ -386,26 +370,52 @@ static void dump_data_bytes(const char *type, const unsigned char *data,
                        length < DUMP_MAX_BYTES ? length : DUMP_MAX_BYTES);
 }
 
-static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data,
+static void swap_packet_bitfield_to_le(unsigned char *data)
+{
+#ifdef __BIG_ENDIAN_BITFIELD
+       unsigned char tmp = *data, ret = 0;
+
+       /*
+        * transform bits from aa.bbb.ccc to ccc.bbb.aa
+        */
+       ret |= tmp & 0xc0 >> 6;
+       ret |= tmp & 0x38 >> 1;
+       ret |= tmp & 0x07 << 5;
+       *data = ret & 0xff;
+#endif
+}
+
+static void swap_packet_bitfield_from_le(unsigned char *data)
+{
+#ifdef __BIG_ENDIAN_BITFIELD
+       unsigned char tmp = *data, ret = 0;
+
+       /*
+        * transform bits from ccc.bbb.aa to aa.bbb.ccc
+        */
+       ret |= tmp & 0xe0 >> 5;
+       ret |= tmp & 0x1c << 1;
+       ret |= tmp & 0x03 << 6;
+       *data = ret & 0xff;
+#endif
+}
+
+static void do_send_fragment(struct ipw_hardware *hw, unsigned char *data,
                            unsigned length)
 {
-       int i;
+       unsigned i;
        unsigned long flags;
 
        start_timing();
-
-       if (length == 0)
-               return 0;
-
-       if (length > hw->ll_mtu)
-               return -1;
+       BUG_ON(length > hw->ll_mtu);
 
        if (ipwireless_debug)
                dump_data_bytes("send", data, length);
 
-       spin_lock_irqsave(&hw->spinlock, flags);
+       spin_lock_irqsave(&hw->lock, flags);
 
        hw->tx_ready = 0;
+       swap_packet_bitfield_to_le(data);
 
        if (hw->hw_version == HW_VERSION_1) {
                outw((unsigned short) length, hw->base_port + IODWR);
@@ -414,7 +424,7 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data,
                        unsigned short d = data[i];
                        __le16 raw_data;
 
-                       if (likely(i + 1 < length))
+                       if (i + 1 < length)
                                d |= data[i + 1] << 8;
                        raw_data = cpu_to_le16(d);
                        outw(raw_data, hw->base_port + IODWR);
@@ -422,32 +432,30 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data,
 
                outw(DCR_TXDONE, hw->base_port + IODCR);
        } else if (hw->hw_version == HW_VERSION_2) {
-               outw((unsigned short) length, hw->base_port + IODMADPR);
+               outw((unsigned short) length, hw->base_port);
 
                for (i = 0; i < length; i += 2) {
                        unsigned short d = data[i];
                        __le16 raw_data;
 
-                       if ((i + 1 < length))
+                       if (i + 1 < length)
                                d |= data[i + 1] << 8;
                        raw_data = cpu_to_le16(d);
-                       outw(raw_data, hw->base_port + IODMADPR);
+                       outw(raw_data, hw->base_port);
                }
                while ((i & 3) != 2) {
-                       outw((unsigned short) 0xDEAD, hw->base_port + IODMADPR);
+                       outw((unsigned short) 0xDEAD, hw->base_port);
                        i += 2;
                }
                writew(MEMRX_RX, &hw->memory_info_regs->memreg_rx);
        }
 
-       spin_unlock_irqrestore(&hw->spinlock, flags);
+       spin_unlock_irqrestore(&hw->lock, flags);
 
        end_write_timing(length);
-
-       return 0;
 }
 
-static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
+static void do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
 {
        unsigned short fragment_data_len;
        unsigned short data_left = packet->length - packet->offset;
@@ -462,6 +470,10 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
        if (data_left < fragment_data_len)
                fragment_data_len = data_left;
 
+       /*
+        * hdr_first is now in machine bitfield order, which will be swapped
+        * to le just before it goes to hw
+        */
        pkt.hdr_first.protocol = packet->protocol;
        pkt.hdr_first.address = packet->dest_addr;
        pkt.hdr_first.packet_rank = 0;
@@ -493,25 +505,23 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
                 */
                unsigned long flags;
 
-               spin_lock_irqsave(&hw->spinlock, flags);
+               spin_lock_irqsave(&hw->lock, flags);
                list_add(&packet->queue, &hw->tx_queue[0]);
                hw->tx_queued++;
-               spin_unlock_irqrestore(&hw->spinlock, flags);
+               spin_unlock_irqrestore(&hw->lock, flags);
        } else {
                if (packet->packet_callback)
                        packet->packet_callback(packet->callback_data,
                                        packet->length);
                kfree(packet);
        }
-
-       return 0;
 }
 
 static void ipw_setup_hardware(struct ipw_hardware *hw)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&hw->spinlock, flags);
+       spin_lock_irqsave(&hw->lock, flags);
        if (hw->hw_version == HW_VERSION_1) {
                /* Reset RX FIFO */
                outw(DCR_RXRESET, hw->base_port + IODCR);
@@ -530,7 +540,7 @@ static void ipw_setup_hardware(struct ipw_hardware *hw)
                csr |= 1;
                writew(csr, &hw->memregs_CCR->reg_config_and_status);
        }
-       spin_unlock_irqrestore(&hw->spinlock, flags);
+       spin_unlock_irqrestore(&hw->lock, flags);
 }
 
 /*
@@ -549,28 +559,23 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw,
        if (!packet) {
                unsigned long flags;
 
-               /*
-                * If this is the first fragment, then we will need to fetch a
-                * packet to put it in.
-                */
-               spin_lock_irqsave(&hw->spinlock, flags);
-               /* If we have one in our pool, then pull it out. */
+               spin_lock_irqsave(&hw->lock, flags);
                if (!list_empty(&hw->rx_pool)) {
                        packet = list_first_entry(&hw->rx_pool,
                                        struct ipw_rx_packet, queue);
-                       list_del(&packet->queue);
                        hw->rx_pool_size--;
-                       spin_unlock_irqrestore(&hw->spinlock, flags);
+                       spin_unlock_irqrestore(&hw->lock, flags);
+                       list_del(&packet->queue);
                } else {
-                       /* Otherwise allocate a new one. */
-                       static int min_capacity = 256;
+                       const int min_capacity =
+                               ipwireless_ppp_mru(hw->network + 2);
                        int new_capacity;
 
-                       spin_unlock_irqrestore(&hw->spinlock, flags);
+                       spin_unlock_irqrestore(&hw->lock, flags);
                        new_capacity =
-                           minimum_free_space > min_capacity
-                           ? minimum_free_space
-                           : min_capacity;
+                               (minimum_free_space > min_capacity
+                                ? minimum_free_space
+                                : min_capacity);
                        packet = kmalloc(sizeof(struct ipw_rx_packet)
                                        + new_capacity, GFP_ATOMIC);
                        if (!packet)
@@ -580,10 +585,6 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw,
                packet->length = 0;
        }
 
-       /*
-        * If this packet does not have sufficient capacity for the data we
-        * want to add, then make it bigger.
-        */
        if (packet->length + minimum_free_space > packet->capacity) {
                struct ipw_rx_packet *old_packet = packet;
 
@@ -610,13 +611,15 @@ static void pool_free(struct ipw_hardware *hw, struct ipw_rx_packet *packet)
                kfree(packet);
        else {
                hw->rx_pool_size++;
-               list_add_tail(&packet->queue, &hw->rx_pool);
+               list_add(&packet->queue, &hw->rx_pool);
        }
 }
 
 static void queue_received_packet(struct ipw_hardware *hw,
-                                 unsigned int protocol, unsigned int address,
-                                 unsigned char *data, int length, int is_last)
+                                 unsigned int protocol,
+                                 unsigned int address,
+                                 const unsigned char *data, int length,
+                                 int is_last)
 {
        unsigned int channel_idx = address - 1;
        struct ipw_rx_packet *packet = NULL;
@@ -658,9 +661,9 @@ static void queue_received_packet(struct ipw_hardware *hw,
                        packet = *assem;
                        *assem = NULL;
                        /* Count queued DATA bytes only */
-                       spin_lock_irqsave(&hw->spinlock, flags);
+                       spin_lock_irqsave(&hw->lock, flags);
                        hw->rx_bytes_queued += packet->length;
-                       spin_unlock_irqrestore(&hw->spinlock, flags);
+                       spin_unlock_irqrestore(&hw->lock, flags);
                }
        } else {
                /* If it's a CTRL packet, don't assemble, just queue it. */
@@ -682,13 +685,13 @@ static void queue_received_packet(struct ipw_hardware *hw,
         * network layer.
         */
        if (packet) {
-               spin_lock_irqsave(&hw->spinlock, flags);
+               spin_lock_irqsave(&hw->lock, flags);
                list_add_tail(&packet->queue, &hw->rx_queue);
                /* Block reception of incoming packets if queue is full. */
                hw->blocking_rx =
-                       hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE;
+                       (hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE);
 
-               spin_unlock_irqrestore(&hw->spinlock, flags);
+               spin_unlock_irqrestore(&hw->lock, flags);
                schedule_work(&hw->work_rx);
        }
 }
@@ -702,7 +705,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx)
            container_of(work_rx, struct ipw_hardware, work_rx);
        unsigned long flags;
 
-       spin_lock_irqsave(&hw->spinlock, flags);
+       spin_lock_irqsave(&hw->lock, flags);
        while (!list_empty(&hw->rx_queue)) {
                struct ipw_rx_packet *packet =
                        list_first_entry(&hw->rx_queue,
@@ -720,7 +723,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx)
                if (packet->protocol == TL_PROTOCOLID_COM_DATA) {
                        if (hw->network != NULL) {
                                /* If the network hasn't been disconnected. */
-                               spin_unlock_irqrestore(&hw->spinlock, flags);
+                               spin_unlock_irqrestore(&hw->lock, flags);
                                /*
                                 * This must run unlocked due to tty processing
                                 * and mutex locking
@@ -731,7 +734,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx)
                                                (unsigned char *)packet
                                                + sizeof(struct ipw_rx_packet),
                                                packet->length);
-                               spin_lock_irqsave(&hw->spinlock, flags);
+                               spin_lock_irqsave(&hw->lock, flags);
                        }
                        /* Count queued DATA bytes only */
                        hw->rx_bytes_queued -= packet->length;
@@ -755,15 +758,15 @@ static void ipw_receive_data_work(struct work_struct *work_rx)
                if (hw->shutting_down)
                        break;
        }
-       spin_unlock_irqrestore(&hw->spinlock, flags);
+       spin_unlock_irqrestore(&hw->lock, flags);
 }
 
 static void handle_received_CTRL_packet(struct ipw_hardware *hw,
                                        unsigned int channel_idx,
-                                       unsigned char *data, int len)
+                                       const unsigned char *data, int len)
 {
-       struct ipw_control_packet_body *body =
-               (struct ipw_control_packet_body *) data;
+       const struct ipw_control_packet_body *body =
+               (const struct ipw_control_packet_body *) data;
        unsigned int changed_mask;
 
        if (len != sizeof(struct ipw_control_packet_body)) {
@@ -805,13 +808,13 @@ static void handle_received_CTRL_packet(struct ipw_hardware *hw,
 }
 
 static void handle_received_packet(struct ipw_hardware *hw,
-                                  union nl_packet *packet,
+                                  const union nl_packet *packet,
                                   unsigned short len)
 {
        unsigned int protocol = packet->hdr.protocol;
        unsigned int address = packet->hdr.address;
        unsigned int header_length;
-       unsigned char *data;
+       const unsigned char *data;
        unsigned int data_len;
        int is_last = packet->hdr.packet_rank & NL_LAST_PACKET;
 
@@ -850,7 +853,7 @@ static void acknowledge_data_read(struct ipw_hardware *hw)
 static void do_receive_packet(struct ipw_hardware *hw)
 {
        unsigned len;
-       unsigned int i;
+       unsigned i;
        unsigned char pkt[LL_MTU_MAX];
 
        start_timing();
@@ -859,8 +862,7 @@ static void do_receive_packet(struct ipw_hardware *hw)
                len = inw(hw->base_port + IODRR);
                if (len > hw->ll_mtu) {
                        printk(KERN_INFO IPWIRELESS_PCCARD_NAME
-                              ": received a packet of %u bytes - "
-                              "longer than the MTU!\n", len);
+                              ": received a packet of %u bytes - longer than the MTU!\n", len);
                        outw(DCR_RXDONE | DCR_RXRESET, hw->base_port + IODCR);
                        return;
                }
@@ -873,18 +875,17 @@ static void do_receive_packet(struct ipw_hardware *hw)
                        pkt[i + 1] = (unsigned char) (data >> 8);
                }
        } else {
-               len = inw(hw->base_port + IODMADPR);
+               len = inw(hw->base_port);
                if (len > hw->ll_mtu) {
                        printk(KERN_INFO IPWIRELESS_PCCARD_NAME
-                              ": received a packet of %u bytes - "
-                              "longer than the MTU!\n", len);
+                              ": received a packet of %u bytes - longer than the MTU!\n", len);
                        writew(MEMRX_PCINTACKK,
                                &hw->memory_info_regs->memreg_pc_interrupt_ack);
                        return;
                }
 
                for (i = 0; i < len; i += 2) {
-                       __le16 raw_data = inw(hw->base_port + IODMADPR);
+                       __le16 raw_data = inw(hw->base_port);
                        unsigned short data = le16_to_cpu(raw_data);
 
                        pkt[i] = (unsigned char) data;
@@ -892,13 +893,15 @@ static void do_receive_packet(struct ipw_hardware *hw)
                }
 
                while ((i & 3) != 2) {
-                       inw(hw->base_port + IODMADPR);
+                       inw(hw->base_port);
                        i += 2;
                }
        }
 
        acknowledge_data_read(hw);
 
+       swap_packet_bitfield_from_le(pkt);
+
        if (ipwireless_debug)
                dump_data_bytes("recv", pkt, len);
 
@@ -916,8 +919,7 @@ static int get_current_packet_priority(struct ipw_hardware *hw)
         * until setup is complete.
         */
        return (hw->to_setup || hw->initializing
-                       ? PRIO_SETUP + 1 :
-                       NL_NUM_OF_PRIORITIES);
+                       ? PRIO_SETUP + 1 : NL_NUM_OF_PRIORITIES);
 }
 
 /*
@@ -928,17 +930,17 @@ static int get_packets_from_hw(struct ipw_hardware *hw)
        int received = 0;
        unsigned long flags;
 
-       spin_lock_irqsave(&hw->spinlock, flags);
+       spin_lock_irqsave(&hw->lock, flags);
        while (hw->rx_ready && !hw->blocking_rx) {
                received = 1;
                hw->rx_ready--;
-               spin_unlock_irqrestore(&hw->spinlock, flags);
+               spin_unlock_irqrestore(&hw->lock, flags);
 
                do_receive_packet(hw);
 
-               spin_lock_irqsave(&hw->spinlock, flags);
+               spin_lock_irqsave(&hw->lock, flags);
        }
-       spin_unlock_irqrestore(&hw->spinlock, flags);
+       spin_unlock_irqrestore(&hw->lock, flags);
 
        return received;
 }
@@ -954,7 +956,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
        int more_to_send = 0;
        unsigned long flags;
 
-       spin_lock_irqsave(&hw->spinlock, flags);
+       spin_lock_irqsave(&hw->lock, flags);
        if (hw->tx_queued && hw->tx_ready) {
                int priority;
                struct ipw_tx_packet *packet = NULL;
@@ -975,17 +977,17 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
                }
                if (!packet) {
                        hw->tx_queued = 0;
-                       spin_unlock_irqrestore(&hw->spinlock, flags);
+                       spin_unlock_irqrestore(&hw->lock, flags);
                        return 0;
                }
 
-               spin_unlock_irqrestore(&hw->spinlock, flags);
+               spin_unlock_irqrestore(&hw->lock, flags);
 
                /* Send */
                do_send_packet(hw, packet);
 
                /* Check if more to send */
-               spin_lock_irqsave(&hw->spinlock, flags);
+               spin_lock_irqsave(&hw->lock, flags);
                for (priority = 0; priority < priority_limit; priority++)
                        if (!list_empty(&hw->tx_queue[priority])) {
                                more_to_send = 1;
@@ -995,7 +997,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
                if (!more_to_send)
                        hw->tx_queued = 0;
        }
-       spin_unlock_irqrestore(&hw->spinlock, flags);
+       spin_unlock_irqrestore(&hw->lock, flags);
 
        return more_to_send;
 }
@@ -1008,9 +1010,9 @@ static void ipwireless_do_tasklet(unsigned long hw_)
        struct ipw_hardware *hw = (struct ipw_hardware *) hw_;
        unsigned long flags;
 
-       spin_lock_irqsave(&hw->spinlock, flags);
+       spin_lock_irqsave(&hw->lock, flags);
        if (hw->shutting_down) {
-               spin_unlock_irqrestore(&hw->spinlock, flags);
+               spin_unlock_irqrestore(&hw->lock, flags);
                return;
        }
 
@@ -1019,7 +1021,7 @@ static void ipwireless_do_tasklet(unsigned long hw_)
                 * Initial setup data sent to hardware
                 */
                hw->to_setup = 2;
-               spin_unlock_irqrestore(&hw->spinlock, flags);
+               spin_unlock_irqrestore(&hw->lock, flags);
 
                ipw_setup_hardware(hw);
                ipw_send_setup_packet(hw);
@@ -1030,7 +1032,7 @@ static void ipwireless_do_tasklet(unsigned long hw_)
                int priority_limit = get_current_packet_priority(hw);
                int again;
 
-               spin_unlock_irqrestore(&hw->spinlock, flags);
+               spin_unlock_irqrestore(&hw->lock, flags);
 
                do {
                        again = send_pending_packet(hw, priority_limit);
@@ -1068,16 +1070,16 @@ static irqreturn_t ipwireless_handle_v1_interrupt(int irq,
                /* Transmit complete. */
                if (irqn & IR_TXINTR) {
                        ack |= IR_TXINTR;
-                       spin_lock_irqsave(&hw->spinlock, flags);
+                       spin_lock_irqsave(&hw->lock, flags);
                        hw->tx_ready = 1;
-                       spin_unlock_irqrestore(&hw->spinlock, flags);
+                       spin_unlock_irqrestore(&hw->lock, flags);
                }
                /* Received data */
                if (irqn & IR_RXINTR) {
                        ack |= IR_RXINTR;
-                       spin_lock_irqsave(&hw->spinlock, flags);
+                       spin_lock_irqsave(&hw->lock, flags);
                        hw->rx_ready++;
-                       spin_unlock_irqrestore(&hw->spinlock, flags);
+                       spin_unlock_irqrestore(&hw->lock, flags);
                }
                if (ack != 0) {
                        outw(ack, hw->base_port + IOIR);
@@ -1128,9 +1130,8 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
                        } else {
                                return IRQ_NONE;
                        }
-               } else {
+               } else
                        return IRQ_NONE;
-               }
        }
 
        /*
@@ -1149,9 +1150,9 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
                if (hw->serial_number_detected) {
                        if (memtx_serial != hw->last_memtx_serial) {
                                hw->last_memtx_serial = memtx_serial;
-                               spin_lock_irqsave(&hw->spinlock, flags);
+                               spin_lock_irqsave(&hw->lock, flags);
                                hw->rx_ready++;
-                               spin_unlock_irqrestore(&hw->spinlock, flags);
+                               spin_unlock_irqrestore(&hw->lock, flags);
                                rx = 1;
                        } else
                                /* Ignore 'Timer Recovery' duplicates. */
@@ -1166,18 +1167,18 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
                                printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME
                                        ": memreg_tx serial num detected\n");
 
-                               spin_lock_irqsave(&hw->spinlock, flags);
+                               spin_lock_irqsave(&hw->lock, flags);
                                hw->rx_ready++;
-                               spin_unlock_irqrestore(&hw->spinlock, flags);
+                               spin_unlock_irqrestore(&hw->lock, flags);
                        }
                        rx = 1;
                }
        }
        if (memrxdone & MEMRX_RX_DONE) {
                writew(0, &hw->memory_info_regs->memreg_rx_done);
-               spin_lock_irqsave(&hw->spinlock, flags);
+               spin_lock_irqsave(&hw->lock, flags);
                hw->tx_ready = 1;
-               spin_unlock_irqrestore(&hw->spinlock, flags);
+               spin_unlock_irqrestore(&hw->lock, flags);
                tx = 1;
        }
        if (tx)
@@ -1195,8 +1196,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
                                        ": spurious interrupt - new_tx mode\n");
                        else {
                                printk(KERN_WARNING IPWIRELESS_PCCARD_NAME
-                                       ": no valid memreg_tx value - "
-                                       "switching to the old memreg_tx\n");
+                                       ": no valid memreg_tx value - switching to the old memreg_tx\n");
                                hw->memreg_tx =
                                        &hw->memory_info_regs->memreg_tx_old;
                                try_mem_tx_old = 1;
@@ -1211,7 +1211,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
        return IRQ_HANDLED;
 }
 
-irqreturn_t ipwireless_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t ipwireless_interrupt(int irq, void *dev_id)
 {
        struct ipw_hardware *hw = dev_id;
 
@@ -1226,9 +1226,9 @@ static void flush_packets_to_hw(struct ipw_hardware *hw)
        int priority_limit;
        unsigned long flags;
 
-       spin_lock_irqsave(&hw->spinlock, flags);
+       spin_lock_irqsave(&hw->lock, flags);
        priority_limit = get_current_packet_priority(hw);
-       spin_unlock_irqrestore(&hw->spinlock, flags);
+       spin_unlock_irqrestore(&hw->lock, flags);
 
        while (send_pending_packet(hw, priority_limit));
 }
@@ -1238,10 +1238,10 @@ static void send_packet(struct ipw_hardware *hw, int priority,
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&hw->spinlock, flags);
+       spin_lock_irqsave(&hw->lock, flags);
        list_add_tail(&packet->queue, &hw->tx_queue[priority]);
        hw->tx_queued++;
-       spin_unlock_irqrestore(&hw->spinlock, flags);
+       spin_unlock_irqrestore(&hw->lock, flags);
 
        flush_packets_to_hw(hw);
 }
@@ -1291,21 +1291,20 @@ static void *alloc_ctrl_packet(int header_size,
 }
 
 int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx,
-                           unsigned char *data, unsigned int length,
+                           const unsigned char *data, unsigned int length,
                            void (*callback) (void *cb, unsigned int length),
                            void *callback_data)
 {
        struct ipw_tx_packet *packet;
 
-       packet = alloc_data_packet(length,
-                              (unsigned char) (channel_idx + 1),
-                              TL_PROTOCOLID_COM_DATA);
+       packet = alloc_data_packet(length, (channel_idx + 1),
+                       TL_PROTOCOLID_COM_DATA);
        if (!packet)
                return -ENOMEM;
        packet->packet_callback = callback;
        packet->callback_data = callback_data;
-       memcpy((unsigned char *) packet +
-                       sizeof(struct ipw_tx_packet), data, length);
+       memcpy((unsigned char *) packet + sizeof(struct ipw_tx_packet), data,
+                       length);
 
        send_packet(hw, PRIO_DATA, packet);
        return 0;
@@ -1321,12 +1320,11 @@ static int set_control_line(struct ipw_hardware *hw, int prio,
                protocolid = TL_PROTOCOLID_SETUP;
 
        packet = alloc_ctrl_packet(sizeof(struct ipw_control_packet),
-                       (unsigned char) (channel_idx + 1),
-                       protocolid, line);
+                       (channel_idx + 1), protocolid, line);
        if (!packet)
                return -ENOMEM;
        packet->header.length = sizeof(struct ipw_control_packet_body);
-       packet->body.value = (unsigned char) (state == 0 ? 0 : 1);
+       packet->body.value = (state == 0 ? 0 : 1);
        send_packet(hw, prio, &packet->header);
        return 0;
 }
@@ -1504,8 +1502,7 @@ static void handle_setup_get_version_rsp(struct ipw_hardware *hw,
        if (vers_no == TL_SETUP_VERSION)
                __handle_setup_get_version_rsp(hw);
        else
-               printk(KERN_ERR
-                               IPWIRELESS_PCCARD_NAME
+               printk(KERN_ERR IPWIRELESS_PCCARD_NAME
                                ": invalid hardware version no %u\n",
                                (unsigned int) vers_no);
 }
@@ -1528,10 +1525,10 @@ static void ipw_send_setup_packet(struct ipw_hardware *hw)
 
 static void handle_received_SETUP_packet(struct ipw_hardware *hw,
                                         unsigned int address,
-                                        unsigned char *data, int len,
+                                        const unsigned char *data, int len,
                                         int is_last)
 {
-       union ipw_setup_rx_msg *rx_msg = (union ipw_setup_rx_msg *) data;
+       const union ipw_setup_rx_msg *rx_msg = (const union ipw_setup_rx_msg *) data;
 
        if (address != ADDR_SETUP_PROT) {
                printk(KERN_INFO IPWIRELESS_PCCARD_NAME
@@ -1629,7 +1626,7 @@ struct ipw_hardware *ipwireless_hardware_create(void)
 
        INIT_LIST_HEAD(&hw->rx_queue);
        INIT_LIST_HEAD(&hw->rx_pool);
-       spin_lock_init(&hw->spinlock);
+       spin_lock_init(&hw->lock);
        tasklet_init(&hw->tasklet, ipwireless_do_tasklet, (unsigned long) hw);
        INIT_WORK(&hw->work_rx, ipw_receive_data_work);
        setup_timer(&hw->setup_timer, ipwireless_setup_timer,
@@ -1651,8 +1648,8 @@ void ipwireless_init_hardware_v1(struct ipw_hardware *hw,
                enable_irq(hw->irq);
        }
        hw->base_port = base_port;
-       hw->hw_version = is_v2_card ? HW_VERSION_2 : HW_VERSION_1;
-       hw->ll_mtu = hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2;
+       hw->hw_version = (is_v2_card ? HW_VERSION_2 : HW_VERSION_1);
+       hw->ll_mtu = (hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2);
        hw->memregs_CCR = (struct MEMCCR __iomem *)
                        ((unsigned short __iomem *) attr_memory + 0x200);
        hw->memory_info_regs = (struct MEMINFREG __iomem *) common_memory;
@@ -1695,10 +1692,10 @@ static void ipwireless_setup_timer(unsigned long data)
                if (is_card_present(hw)) {
                        unsigned long flags;
 
-                       spin_lock_irqsave(&hw->spinlock, flags);
+                       spin_lock_irqsave(&hw->lock, flags);
                        hw->to_setup = 1;
                        hw->tx_ready = 1;
-                       spin_unlock_irqrestore(&hw->spinlock, flags);
+                       spin_unlock_irqrestore(&hw->lock, flags);
                        tasklet_schedule(&hw->tasklet);
                }
 
index 19ce5eb266b19fcc5150c1b0d821547a493eda3d..90a8590e43b0b056ae86548b825dbdb6ad55c036 100644 (file)
@@ -34,14 +34,14 @@ struct ipw_network;
 
 struct ipw_hardware *ipwireless_hardware_create(void);
 void ipwireless_hardware_free(struct ipw_hardware *hw);
-irqreturn_t ipwireless_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t ipwireless_interrupt(int irq, void *dev_id);
 int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx,
                int state);
 int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx,
                int state);
 int ipwireless_send_packet(struct ipw_hardware *hw,
                            unsigned int channel_idx,
-                           unsigned char *data,
+                           const unsigned char *data,
                            unsigned int length,
                            void (*packet_sent_callback) (void *cb,
                                                          unsigned int length),
index cc7dcea2d2830599d05c955589456c14cf9aa37b..5eca7a99afe6c3daf1c793f4c0990e5125a72862 100644 (file)
@@ -49,7 +49,7 @@ static void ipwireless_detach(struct pcmcia_device *link);
 /* Debug mode: more verbose, print sent/recv bytes */
 int ipwireless_debug;
 int ipwireless_loopback;
-int ipwireless_out_queue = 1;
+int ipwireless_out_queue = 10;
 
 module_param_named(debug, ipwireless_debug, int, 0);
 module_param_named(loopback, ipwireless_loopback, int, 0);
@@ -57,7 +57,7 @@ module_param_named(out_queue, ipwireless_out_queue, int, 0);
 MODULE_PARM_DESC(debug, "switch on debug messages [0]");
 MODULE_PARM_DESC(loopback,
                "debug: enable ras_raw channel [0]");
-MODULE_PARM_DESC(out_queue, "debug: set size of outgoing queue [1]");
+MODULE_PARM_DESC(out_queue, "debug: set size of outgoing PPP queue [10]");
 
 /* Executes in process context. */
 static void signalled_reboot_work(struct work_struct *work_reboot)
@@ -88,8 +88,6 @@ static int config_ipwireless(struct ipw_dev *ipw)
        unsigned short buf[64];
        cisparse_t parse;
        unsigned short cor_value;
-       win_req_t request_attr_memory;
-       win_req_t request_common_memory;
        memreq_t memreq_attr_memory;
        memreq_t memreq_common_memory;
 
@@ -188,6 +186,9 @@ static int config_ipwireless(struct ipw_dev *ipw)
                goto exit0;
        }
 
+       request_region(link->io.BasePort1, link->io.NumPorts1,
+                       IPWIRELESS_PCCARD_NAME);
+
        /* memory settings */
 
        tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
@@ -214,16 +215,16 @@ static int config_ipwireless(struct ipw_dev *ipw)
        }
 
        if (parse.cftable_entry.mem.nwin > 0) {
-               request_common_memory.Attributes =
+               ipw->request_common_memory.Attributes =
                        WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
-               request_common_memory.Base =
+               ipw->request_common_memory.Base =
                        parse.cftable_entry.mem.win[0].host_addr;
-               request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
-               if (request_common_memory.Size < 0x1000)
-                       request_common_memory.Size = 0x1000;
-               request_common_memory.AccessSpeed = 0;
+               ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
+               if (ipw->request_common_memory.Size < 0x1000)
+                       ipw->request_common_memory.Size = 0x1000;
+               ipw->request_common_memory.AccessSpeed = 0;
 
-               ret = pcmcia_request_window(&link, &request_common_memory,
+               ret = pcmcia_request_window(&link, &ipw->request_common_memory,
                                &ipw->handle_common_memory);
 
                if (ret != CS_SUCCESS) {
@@ -246,16 +247,18 @@ static int config_ipwireless(struct ipw_dev *ipw)
                ipw->is_v2_card =
                        parse.cftable_entry.mem.win[0].len == 0x100;
 
-               ipw->common_memory = ioremap(request_common_memory.Base,
-                               request_common_memory.Size);
+               ipw->common_memory = ioremap(ipw->request_common_memory.Base,
+                               ipw->request_common_memory.Size);
+               request_mem_region(ipw->request_common_memory.Base,
+                               ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME);
 
-               request_attr_memory.Attributes =
+               ipw->request_attr_memory.Attributes =
                        WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
-               request_attr_memory.Base = 0;
-               request_attr_memory.Size = 0;   /* this used to be 0x1000 */
-               request_attr_memory.AccessSpeed = 0;
+               ipw->request_attr_memory.Base = 0;
+               ipw->request_attr_memory.Size = 0;      /* this used to be 0x1000 */
+               ipw->request_attr_memory.AccessSpeed = 0;
 
-               ret = pcmcia_request_window(&link, &request_attr_memory,
+               ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
                                &ipw->handle_attr_memory);
 
                if (ret != CS_SUCCESS) {
@@ -274,8 +277,10 @@ static int config_ipwireless(struct ipw_dev *ipw)
                        goto exit2;
                }
 
-               ipw->attr_memory = ioremap(request_attr_memory.Base,
-                               request_attr_memory.Size);
+               ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
+                               ipw->request_attr_memory.Size);
+               request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size,
+                               IPWIRELESS_PCCARD_NAME);
        }
 
        INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
@@ -311,14 +316,13 @@ static int config_ipwireless(struct ipw_dev *ipw)
                        (unsigned int) link->irq.AssignedIRQ);
        if (ipw->attr_memory && ipw->common_memory)
                printk(KERN_INFO IPWIRELESS_PCCARD_NAME
-                               ": attr memory 0x%08lx-0x%08lx, "
-                               "common memory 0x%08lx-0x%08lx\n",
-                               request_attr_memory.Base,
-                               request_attr_memory.Base
-                               + request_attr_memory.Size - 1,
-                               request_common_memory.Base,
-                               request_common_memory.Base
-                               + request_common_memory.Size - 1);
+                       ": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n",
+                       ipw->request_attr_memory.Base,
+                       ipw->request_attr_memory.Base
+                       + ipw->request_attr_memory.Size - 1,
+                       ipw->request_common_memory.Base,
+                       ipw->request_common_memory.Base
+                       + ipw->request_common_memory.Size - 1);
 
        ipw->network = ipwireless_network_create(ipw->hardware);
        if (!ipw->network)
@@ -350,12 +354,16 @@ exit4:
        pcmcia_disable_device(link);
 exit3:
        if (ipw->attr_memory) {
+               release_mem_region(ipw->request_attr_memory.Base,
+                               ipw->request_attr_memory.Size);
                iounmap(ipw->attr_memory);
                pcmcia_release_window(ipw->handle_attr_memory);
                pcmcia_disable_device(link);
        }
 exit2:
        if (ipw->common_memory) {
+               release_mem_region(ipw->request_common_memory.Base,
+                               ipw->request_common_memory.Size);
                iounmap(ipw->common_memory);
                pcmcia_release_window(ipw->handle_common_memory);
        }
@@ -367,19 +375,25 @@ exit0:
 
 static void release_ipwireless(struct ipw_dev *ipw)
 {
-       struct pcmcia_device *link = ipw->link;
-
-       pcmcia_disable_device(link);
+       pcmcia_disable_device(ipw->link);
 
-       if (ipw->common_memory)
+       if (ipw->common_memory) {
+               release_mem_region(ipw->request_common_memory.Base,
+                               ipw->request_common_memory.Size);
                iounmap(ipw->common_memory);
-       if (ipw->attr_memory)
+       }
+       if (ipw->attr_memory) {
+               release_mem_region(ipw->request_attr_memory.Base,
+                               ipw->request_attr_memory.Size);
                iounmap(ipw->attr_memory);
+       }
        if (ipw->common_memory)
                pcmcia_release_window(ipw->handle_common_memory);
        if (ipw->attr_memory)
                pcmcia_release_window(ipw->handle_attr_memory);
-       pcmcia_disable_device(link);
+
+       /* Break the link with Card Services */
+       pcmcia_disable_device(ipw->link);
 }
 
 /*
@@ -437,10 +451,6 @@ static void ipwireless_detach(struct pcmcia_device *link)
 
        release_ipwireless(ipw);
 
-       /* Break the link with Card Services */
-       if (link)
-               pcmcia_disable_device(link);
-
        if (ipw->tty != NULL)
                ipwireless_tty_free(ipw->tty);
        if (ipw->network != NULL)
index 1bfdcc8d47d63300398d325a00699b28d655a250..0e0363af9ab240f55ad34edc0cb1b672417d3b53 100644 (file)
@@ -45,10 +45,15 @@ struct ipw_tty;
 struct ipw_dev {
        struct pcmcia_device *link;
        int is_v2_card;
+
        window_handle_t handle_attr_memory;
        void __iomem *attr_memory;
+       win_req_t request_attr_memory;
+
        window_handle_t handle_common_memory;
        void __iomem *common_memory;
+       win_req_t request_common_memory;
+
        dev_node_t nodes[2];
        /* Reference to attribute memory, containing CIS data */
        void *attribute_memory;
index fe914d34f7f6f63e10e452c775d364b1d2ba1930..590762a7f21790d64ea2b65725ff2a88902b1946 100644 (file)
@@ -29,7 +29,6 @@
 #include "main.h"
 #include "tty.h"
 
-#define MAX_OUTGOING_PACKETS_QUEUED   ipwireless_out_queue
 #define MAX_ASSOCIATED_TTYS 2
 
 #define SC_RCV_BITS     (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
@@ -46,7 +45,7 @@ struct ipw_network {
        /* Number of packets queued up in hardware module. */
        int outgoing_packets_queued;
        /* Spinlock to avoid interrupts during shutdown */
-       spinlock_t spinlock;
+       spinlock_t lock;
        struct mutex close_lock;
 
        /* PPP ioctl data, not actually used anywere */
@@ -68,20 +67,20 @@ static void notify_packet_sent(void *callback_data, unsigned int packet_length)
        struct ipw_network *network = callback_data;
        unsigned long flags;
 
-       spin_lock_irqsave(&network->spinlock, flags);
+       spin_lock_irqsave(&network->lock, flags);
        network->outgoing_packets_queued--;
        if (network->ppp_channel != NULL) {
                if (network->ppp_blocked) {
                        network->ppp_blocked = 0;
-                       spin_unlock_irqrestore(&network->spinlock, flags);
+                       spin_unlock_irqrestore(&network->lock, flags);
                        ppp_output_wakeup(network->ppp_channel);
                        if (ipwireless_debug)
-                               printk(KERN_INFO IPWIRELESS_PCCARD_NAME
+                               printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME
                                       ": ppp unblocked\n");
                } else
-                       spin_unlock_irqrestore(&network->spinlock, flags);
+                       spin_unlock_irqrestore(&network->lock, flags);
        } else
-               spin_unlock_irqrestore(&network->spinlock, flags);
+               spin_unlock_irqrestore(&network->lock, flags);
 }
 
 /*
@@ -93,8 +92,8 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
        struct ipw_network *network = ppp_channel->private;
        unsigned long flags;
 
-       spin_lock_irqsave(&network->spinlock, flags);
-       if (network->outgoing_packets_queued < MAX_OUTGOING_PACKETS_QUEUED) {
+       spin_lock_irqsave(&network->lock, flags);
+       if (network->outgoing_packets_queued < ipwireless_out_queue) {
                unsigned char *buf;
                static unsigned char header[] = {
                        PPP_ALLSTATIONS, /* 0xff */
@@ -103,7 +102,7 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
                int ret;
 
                network->outgoing_packets_queued++;
-               spin_unlock_irqrestore(&network->spinlock, flags);
+               spin_unlock_irqrestore(&network->lock, flags);
 
                /*
                 * If we have the requested amount of headroom in the skb we
@@ -144,7 +143,9 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
                 * needs to be unblocked once we are ready to send.
                 */
                network->ppp_blocked = 1;
-               spin_unlock_irqrestore(&network->spinlock, flags);
+               spin_unlock_irqrestore(&network->lock, flags);
+               if (ipwireless_debug)
+                       printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": ppp blocked\n");
                return 0;
        }
 }
@@ -249,11 +250,11 @@ static void do_go_online(struct work_struct *work_go_online)
                                work_go_online);
        unsigned long flags;
 
-       spin_lock_irqsave(&network->spinlock, flags);
+       spin_lock_irqsave(&network->lock, flags);
        if (!network->ppp_channel) {
                struct ppp_channel *channel;
 
-               spin_unlock_irqrestore(&network->spinlock, flags);
+               spin_unlock_irqrestore(&network->lock, flags);
                channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL);
                if (!channel) {
                        printk(KERN_ERR IPWIRELESS_PCCARD_NAME
@@ -273,10 +274,10 @@ static void do_go_online(struct work_struct *work_go_online)
                network->xaccm[3] = 0x60000000U;
                network->raccm = ~0U;
                ppp_register_channel(channel);
-               spin_lock_irqsave(&network->spinlock, flags);
+               spin_lock_irqsave(&network->lock, flags);
                network->ppp_channel = channel;
        }
-       spin_unlock_irqrestore(&network->spinlock, flags);
+       spin_unlock_irqrestore(&network->lock, flags);
 }
 
 static void do_go_offline(struct work_struct *work_go_offline)
@@ -287,16 +288,16 @@ static void do_go_offline(struct work_struct *work_go_offline)
        unsigned long flags;
 
        mutex_lock(&network->close_lock);
-       spin_lock_irqsave(&network->spinlock, flags);
+       spin_lock_irqsave(&network->lock, flags);
        if (network->ppp_channel != NULL) {
                struct ppp_channel *channel = network->ppp_channel;
 
                network->ppp_channel = NULL;
-               spin_unlock_irqrestore(&network->spinlock, flags);
+               spin_unlock_irqrestore(&network->lock, flags);
                mutex_unlock(&network->close_lock);
                ppp_unregister_channel(channel);
        } else {
-               spin_unlock_irqrestore(&network->spinlock, flags);
+               spin_unlock_irqrestore(&network->lock, flags);
                mutex_unlock(&network->close_lock);
        }
 }
@@ -381,18 +382,18 @@ void ipwireless_network_packet_received(struct ipw_network *network,
                         * the PPP layer.
                         */
                        mutex_lock(&network->close_lock);
-                       spin_lock_irqsave(&network->spinlock, flags);
+                       spin_lock_irqsave(&network->lock, flags);
                        if (network->ppp_channel != NULL) {
                                struct sk_buff *skb;
 
-                               spin_unlock_irqrestore(&network->spinlock,
+                               spin_unlock_irqrestore(&network->lock,
                                                flags);
 
                                /* Send the data to the ppp_generic module. */
                                skb = ipw_packet_received_skb(data, length);
                                ppp_input(network->ppp_channel, skb);
                        } else
-                               spin_unlock_irqrestore(&network->spinlock,
+                               spin_unlock_irqrestore(&network->lock,
                                                flags);
                        mutex_unlock(&network->close_lock);
                }
@@ -410,7 +411,7 @@ struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw)
        if (!network)
                return NULL;
 
-       spin_lock_init(&network->spinlock);
+       spin_lock_init(&network->lock);
        mutex_init(&network->close_lock);
 
        network->hardware = hw;
@@ -478,10 +479,10 @@ int ipwireless_ppp_channel_index(struct ipw_network *network)
        int ret = -1;
        unsigned long flags;
 
-       spin_lock_irqsave(&network->spinlock, flags);
+       spin_lock_irqsave(&network->lock, flags);
        if (network->ppp_channel != NULL)
                ret = ppp_channel_index(network->ppp_channel);
-       spin_unlock_irqrestore(&network->spinlock, flags);
+       spin_unlock_irqrestore(&network->lock, flags);
 
        return ret;
 }
@@ -491,10 +492,15 @@ int ipwireless_ppp_unit_number(struct ipw_network *network)
        int ret = -1;
        unsigned long flags;
 
-       spin_lock_irqsave(&network->spinlock, flags);
+       spin_lock_irqsave(&network->lock, flags);
        if (network->ppp_channel != NULL)
                ret = ppp_unit_number(network->ppp_channel);
-       spin_unlock_irqrestore(&network->spinlock, flags);
+       spin_unlock_irqrestore(&network->lock, flags);
 
        return ret;
 }
+
+int ipwireless_ppp_mru(const struct ipw_network *network)
+{
+       return network->mru;
+}
index ccacd26fc7efdf3c9836e80aa3a536190359a809..561f765b333419fa1aa4a48095efe734b89efd8e 100644 (file)
@@ -48,5 +48,6 @@ void ipwireless_ppp_open(struct ipw_network *net);
 void ipwireless_ppp_close(struct ipw_network *net);
 int ipwireless_ppp_channel_index(struct ipw_network *net);
 int ipwireless_ppp_unit_number(struct ipw_network *net);
+int ipwireless_ppp_mru(const struct ipw_network *net);
 
 #endif
index 42f3815c5ce3cac25437c435519c2b61d87f0d8f..b1414507997c663db2c56afbeaaa338846ede37c 100644 (file)
@@ -259,7 +259,7 @@ static int ipw_write(struct tty_struct *linux_tty,
        }
 
        ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS,
-                              (unsigned char *) buf, count,
+                              buf, count,
                               ipw_write_packet_sent_callback, tty);
        if (ret == -1) {
                mutex_unlock(&tty->ipw_tty_mutex);
index 5405769020a1c13aa727e9a70e4e2dad99d1aef8..5ce07b517c5875def9106c5041402032c3f70fc1 100644 (file)
@@ -94,7 +94,7 @@ void cpuidle_install_idle_handler(void)
  */
 void cpuidle_uninstall_idle_handler(void)
 {
-       if (enabled_devices && (pm_idle != pm_idle_old)) {
+       if (enabled_devices && pm_idle_old && (pm_idle != pm_idle_old)) {
                pm_idle = pm_idle_old;
                cpuidle_kick_cpus();
        }
index 48d084bdf7c8e1d590b18130882c39bc44e3d038..3c855ff2992f0ad513500c9820b6e0a03eaa0719 100644 (file)
@@ -49,6 +49,8 @@ struct bfin_twi_iface {
        struct i2c_msg          *pmsg;
        int                     msg_num;
        int                     cur_msg;
+       u16                     saved_clkdiv;
+       u16                     saved_control;
        void __iomem            *regs_base;
 };
 
@@ -565,32 +567,43 @@ static u32 bfin_twi_functionality(struct i2c_adapter *adap)
               I2C_FUNC_I2C;
 }
 
-
 static struct i2c_algorithm bfin_twi_algorithm = {
        .master_xfer   = bfin_twi_master_xfer,
        .smbus_xfer    = bfin_twi_smbus_xfer,
        .functionality = bfin_twi_functionality,
 };
 
-
-static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
+static int i2c_bfin_twi_suspend(struct platform_device *pdev, pm_message_t state)
 {
-       struct bfin_twi_iface *iface = platform_get_drvdata(dev);
+       struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
+
+       iface->saved_clkdiv = read_CLKDIV(iface);
+       iface->saved_control = read_CONTROL(iface);
+
+       free_irq(iface->irq, iface);
 
        /* Disable TWI */
-       write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA);
-       SSYNC();
+       write_CONTROL(iface, iface->saved_control & ~TWI_ENA);
 
        return 0;
 }
 
-static int i2c_bfin_twi_resume(struct platform_device *dev)
+static int i2c_bfin_twi_resume(struct platform_device *pdev)
 {
-       struct bfin_twi_iface *iface = platform_get_drvdata(dev);
+       struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
 
-       /* Enable TWI */
-       write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
-       SSYNC();
+       int rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
+               IRQF_DISABLED, pdev->name, iface);
+       if (rc) {
+               dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
+               return -ENODEV;
+       }
+
+       /* Resume TWI interface clock as specified */
+       write_CLKDIV(iface, iface->saved_clkdiv);
+
+       /* Resume TWI */
+       write_CONTROL(iface, iface->saved_control);
 
        return 0;
 }
index 79b455a1f090587c4c63d5b29b76d8474c81b122..32104eac8d3db3d61e12907558262f1fe4ecffed 100644 (file)
@@ -77,7 +77,7 @@ static int i2c_gpio_getscl(void *data)
        return gpio_get_value(pdata->scl_pin);
 }
 
-static int __init i2c_gpio_probe(struct platform_device *pdev)
+static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
        struct i2c_gpio_platform_data *pdata;
        struct i2c_algo_bit_data *bit_data;
@@ -174,7 +174,7 @@ err_alloc_adap:
        return ret;
 }
 
-static int __exit i2c_gpio_remove(struct platform_device *pdev)
+static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
        struct i2c_gpio_platform_data *pdata;
        struct i2c_adapter *adap;
@@ -196,14 +196,15 @@ static struct platform_driver i2c_gpio_driver = {
                .name   = "i2c-gpio",
                .owner  = THIS_MODULE,
        },
-       .remove         = __exit_p(i2c_gpio_remove),
+       .probe          = i2c_gpio_probe,
+       .remove         = __devexit_p(i2c_gpio_remove),
 };
 
 static int __init i2c_gpio_init(void)
 {
        int ret;
 
-       ret = platform_driver_probe(&i2c_gpio_driver, i2c_gpio_probe);
+       ret = platform_driver_register(&i2c_gpio_driver);
        if (ret)
                printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret);
 
index 007390ad9810555b0fe7f2ba6077445601ec919b..4864723c74257b6e63e2d25d6c4d3ae8676f1675 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/cpufreq.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
@@ -64,6 +65,7 @@ struct s3c24xx_i2c {
        unsigned int            tx_setup;
 
        enum s3c24xx_i2c_state  state;
+       unsigned long           clkrate;
 
        void __iomem            *regs;
        struct clk              *clk;
@@ -71,6 +73,10 @@ struct s3c24xx_i2c {
        struct resource         *irq;
        struct resource         *ioarea;
        struct i2c_adapter      adap;
+
+#ifdef CONFIG_CPU_FREQ
+       struct notifier_block   freq_transition;
+#endif
 };
 
 /* default platform data to use if not supplied in the platform_device
@@ -501,6 +507,9 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int
        unsigned long timeout;
        int ret;
 
+       if (!readl(i2c->regs + S3C2410_IICCON) & S3C2410_IICCON_IRQEN)
+               return -EIO;
+
        ret = s3c24xx_i2c_set_master(i2c);
        if (ret != 0) {
                dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
@@ -636,27 +645,28 @@ static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
        return (diff >= -2 && diff <= 2);
 }
 
-/* s3c24xx_i2c_getdivisor
+/* s3c24xx_i2c_clockrate
  *
  * work out a divisor for the user requested frequency setting,
  * either by the requested frequency, or scanning the acceptable
  * range of frequencies until something is found
 */
 
-static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c,
-                                 struct s3c2410_platform_i2c *pdata,
-                                 unsigned long *iicon,
-                                 unsigned int *got)
+static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
 {
+       struct s3c2410_platform_i2c *pdata;
        unsigned long clkin = clk_get_rate(i2c->clk);
-       
        unsigned int divs, div1;
+       u32 iiccon;
        int freq;
        int start, end;
 
+       i2c->clkrate = clkin;
+
+       pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent);
        clkin /= 1000;          /* clkin now in KHz */
      
-       dev_dbg(i2c->dev,  "pdata %p, freq %lu %lu..%lu\n",
+       dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
                 pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq);
 
        if (pdata->bus_freq != 0) {
@@ -688,11 +698,79 @@ static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c,
 
  found:
        *got = freq;
-       *iicon |= (divs-1);
-       *iicon |= (div1 == 512) ? S3C2410_IICCON_TXDIV_512 : 0;
+
+       iiccon = readl(i2c->regs + S3C2410_IICCON);
+       iiccon &= ~(S3C2410_IICCON_SCALEMASK | S3C2410_IICCON_TXDIV_512);
+       iiccon |= (divs-1);
+
+       if (div1 == 512)
+               iiccon |= S3C2410_IICCON_TXDIV_512;
+
+       writel(iiccon, i2c->regs + S3C2410_IICCON);
+
+       return 0;
+}
+
+#ifdef CONFIG_CPU_FREQ
+
+#define freq_to_i2c(_n) container_of(_n, struct s3c24xx_i2c, freq_transition)
+
+static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
+                                         unsigned long val, void *data)
+{
+       struct s3c24xx_i2c *i2c = freq_to_i2c(nb);
+       unsigned long flags;
+       unsigned int got;
+       int delta_f;
+       int ret;
+
+       delta_f = clk_get_rate(i2c->clk) - i2c->clkrate;
+
+       /* if we're post-change and the input clock has slowed down
+        * or at pre-change and the clock is about to speed up, then
+        * adjust our clock rate. <0 is slow, >0 speedup.
+        */
+
+       if ((val == CPUFREQ_POSTCHANGE && delta_f < 0) ||
+           (val == CPUFREQ_PRECHANGE && delta_f > 0)) {
+               spin_lock_irqsave(&i2c->lock, flags);
+               ret = s3c24xx_i2c_clockrate(i2c, &got);
+               spin_unlock_irqrestore(&i2c->lock, flags);
+
+               if (ret < 0)
+                       dev_err(i2c->dev, "cannot find frequency\n");
+               else
+                       dev_info(i2c->dev, "setting freq %d\n", got);
+       }
+
+       return 0;
+}
+
+static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
+{
+       i2c->freq_transition.notifier_call = s3c24xx_i2c_cpufreq_transition;
+
+       return cpufreq_register_notifier(&i2c->freq_transition,
+                                        CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
+{
+       cpufreq_unregister_notifier(&i2c->freq_transition,
+                                   CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+#else
+static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
+{
        return 0;
 }
 
+static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
+{
+}
+#endif
+
 /* s3c24xx_i2c_init
  *
  * initialise the controller, set the IO lines and frequency 
@@ -719,9 +797,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
 
        dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
 
+       writel(iicon, i2c->regs + S3C2410_IICCON);
+
        /* we need to work out the divisors for the clock... */
 
-       if (s3c24xx_i2c_getdivisor(i2c, pdata, &iicon, &freq) != 0) {
+       if (s3c24xx_i2c_clockrate(i2c, &freq) != 0) {
+               writel(0, i2c->regs + S3C2410_IICCON);
                dev_err(i2c->dev, "cannot meet bus frequency required\n");
                return -EINVAL;
        }
@@ -730,8 +811,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
 
        dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
        dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon);
-       
-       writel(iicon, i2c->regs + S3C2410_IICCON);
 
        /* check for s3c2440 i2c controller  */
 
@@ -752,9 +831,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
 static int s3c24xx_i2c_probe(struct platform_device *pdev)
 {
        struct s3c24xx_i2c *i2c = &s3c24xx_i2c;
+       struct s3c2410_platform_i2c *pdata;
        struct resource *res;
        int ret;
 
+       pdata = s3c24xx_i2c_get_platformdata(&pdev->dev);
+
        /* find the clock and enable it */
 
        i2c->dev = &pdev->dev;
@@ -832,17 +914,34 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res,
                (unsigned long)res->start);
 
-       ret = i2c_add_adapter(&i2c->adap);
+       ret = s3c24xx_i2c_register_cpufreq(i2c);
        if (ret < 0) {
-               dev_err(&pdev->dev, "failed to add bus to i2c core\n");
+               dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
                goto err_irq;
        }
 
+       /* Note, previous versions of the driver used i2c_add_adapter()
+        * to add the bus at any number. We now pass the bus number via
+        * the platform data, so if unset it will now default to always
+        * being bus 0.
+        */
+
+       i2c->adap.nr = pdata->bus_num;
+
+       ret = i2c_add_numbered_adapter(&i2c->adap);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to add bus to i2c core\n");
+               goto err_cpufreq;
+       }
+
        platform_set_drvdata(pdev, i2c);
 
        dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
        return 0;
 
+ err_cpufreq:
+       s3c24xx_i2c_deregister_cpufreq(i2c);
+
  err_irq:
        free_irq(i2c->irq->start, i2c);
 
@@ -870,6 +969,8 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
 {
        struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
 
+       s3c24xx_i2c_deregister_cpufreq(i2c);
+
        i2c_del_adapter(&i2c->adap);
        free_irq(i2c->irq->start, i2c);
 
index 71211c8b5384a85d76a8b7b03ccf845ac287f0e8..d08a1f2863e472051e3e60327c13b3bfbfcf99d6 100644 (file)
@@ -21,6 +21,7 @@
 */
 
 struct s3c2410_platform_i2c {
+       int             bus_num;        /* bus number to use */
        unsigned int    flags;
        unsigned int    slave_addr;     /* slave address for controller */
        unsigned long   bus_freq;       /* standard bus frequency */
index 743d85fcd6518d6551a88f6362da60d3895269c9..1c2e3ec2eb57331cd7d6945d543d47446fc31ac0 100644 (file)
@@ -226,7 +226,7 @@ static inline void dccp_csum_outgoing(struct sk_buff *skb)
 
 extern void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb);
 
-extern int  dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb);
+extern int  dccp_retransmit_skb(struct sock *sk);
 
 extern void dccp_send_ack(struct sock *sk);
 extern void dccp_reqsk_send_ack(struct sk_buff *sk, struct request_sock *rsk);
index a835b88237cbb77d295ba7a036c57b17a1871f91..882c5c4de69e69ef390f73059fba96b3cad23799 100644 (file)
@@ -196,8 +196,8 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
 static void dccp_v4_err(struct sk_buff *skb, u32 info)
 {
        const struct iphdr *iph = (struct iphdr *)skb->data;
-       const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data +
-                                                       (iph->ihl << 2));
+       const u8 offset = iph->ihl << 2;
+       const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
        struct dccp_sock *dp;
        struct inet_sock *inet;
        const int type = icmp_hdr(skb)->type;
@@ -207,7 +207,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
        int err;
        struct net *net = dev_net(skb->dev);
 
-       if (skb->len < (iph->ihl << 2) + 8) {
+       if (skb->len < offset + sizeof(*dh) ||
+           skb->len < offset + __dccp_basic_hdr_len(dh)) {
                ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
                return;
        }
@@ -238,7 +239,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
        dp = dccp_sk(sk);
        seq = dccp_hdr_seq(dh);
        if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) &&
-           !between48(seq, dp->dccps_swl, dp->dccps_swh)) {
+           !between48(seq, dp->dccps_awl, dp->dccps_awh)) {
                NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
                goto out;
        }
index da509127e00cbc8077eb8058f74085e3beb03627..5e1ee0da2c40cab9c7f44ffd431e4df4455e08f5 100644 (file)
@@ -89,12 +89,19 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 {
        struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
        const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
+       struct dccp_sock *dp;
        struct ipv6_pinfo *np;
        struct sock *sk;
        int err;
        __u64 seq;
        struct net *net = dev_net(skb->dev);
 
+       if (skb->len < offset + sizeof(*dh) ||
+           skb->len < offset + __dccp_basic_hdr_len(dh)) {
+               ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
+               return;
+       }
+
        sk = inet6_lookup(net, &dccp_hashinfo,
                        &hdr->daddr, dh->dccph_dport,
                        &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
@@ -116,6 +123,14 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        if (sk->sk_state == DCCP_CLOSED)
                goto out;
 
+       dp = dccp_sk(sk);
+       seq = dccp_hdr_seq(dh);
+       if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) &&
+           !between48(seq, dp->dccps_awl, dp->dccps_awh)) {
+               NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
+               goto out;
+       }
+
        np = inet6_sk(sk);
 
        if (type == ICMPV6_PKT_TOOBIG) {
@@ -168,7 +183,6 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 
        icmpv6_err_convert(type, code, &err);
 
-       seq = dccp_hdr_seq(dh);
        /* Might be for an request_sock */
        switch (sk->sk_state) {
                struct request_sock *req, **prev;
index fe20068c5d8e581add6c25a543d046f3fd49071d..d06945c7d3dfc3e1201a00840516a457e9773303 100644 (file)
@@ -53,8 +53,11 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                                          dccp_packet_hdr_len(dcb->dccpd_type);
                int err, set_ack = 1;
                u64 ackno = dp->dccps_gsr;
-
-               dccp_inc_seqno(&dp->dccps_gss);
+               /*
+                * Increment GSS here already in case the option code needs it.
+                * Update GSS for real only if option processing below succeeds.
+                */
+               dcb->dccpd_seq = ADD48(dp->dccps_gss, 1);
 
                switch (dcb->dccpd_type) {
                case DCCP_PKT_DATA:
@@ -66,6 +69,9 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 
                case DCCP_PKT_REQUEST:
                        set_ack = 0;
+                       /* Use ISS on the first (non-retransmitted) Request. */
+                       if (icsk->icsk_retransmits == 0)
+                               dcb->dccpd_seq = dp->dccps_iss;
                        /* fall through */
 
                case DCCP_PKT_SYNC:
@@ -84,8 +90,6 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                        break;
                }
 
-               dcb->dccpd_seq = dp->dccps_gss;
-
                if (dccp_insert_options(sk, skb)) {
                        kfree_skb(skb);
                        return -EPROTO;
@@ -103,7 +107,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                /* XXX For now we're using only 48 bits sequence numbers */
                dh->dccph_x     = 1;
 
-               dp->dccps_awh = dp->dccps_gss;
+               dccp_update_gss(sk, dcb->dccpd_seq);
                dccp_hdr_set_seq(dh, dp->dccps_gss);
                if (set_ack)
                        dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), ackno);
@@ -112,6 +116,11 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                case DCCP_PKT_REQUEST:
                        dccp_hdr_request(skb)->dccph_req_service =
                                                        dp->dccps_service;
+                       /*
+                        * Limit Ack window to ISS <= P.ackno <= GSS, so that
+                        * only Responses to Requests we sent are considered.
+                        */
+                       dp->dccps_awl = dp->dccps_iss;
                        break;
                case DCCP_PKT_RESET:
                        dccp_hdr_reset(skb)->dccph_reset_code =
@@ -284,14 +293,26 @@ void dccp_write_xmit(struct sock *sk, int block)
        }
 }
 
-int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
+/**
+ * dccp_retransmit_skb  -  Retransmit Request, Close, or CloseReq packets
+ * There are only four retransmittable packet types in DCCP:
+ * - Request  in client-REQUEST  state (sec. 8.1.1),
+ * - CloseReq in server-CLOSEREQ state (sec. 8.3),
+ * - Close    in   node-CLOSING  state (sec. 8.3),
+ * - Acks in client-PARTOPEN state (sec. 8.1.5, handled by dccp_delack_timer()).
+ * This function expects sk->sk_send_head to contain the original skb.
+ */
+int dccp_retransmit_skb(struct sock *sk)
 {
+       WARN_ON(sk->sk_send_head == NULL);
+
        if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0)
                return -EHOSTUNREACH; /* Routing failure or similar. */
 
-       return dccp_transmit_skb(sk, (skb_cloned(skb) ?
-                                     pskb_copy(skb, GFP_ATOMIC):
-                                     skb_clone(skb, GFP_ATOMIC)));
+       /* this count is used to distinguish original and retransmitted skb */
+       inet_csk(sk)->icsk_retransmits++;
+
+       return dccp_transmit_skb(sk, skb_clone(sk->sk_send_head, GFP_ATOMIC));
 }
 
 struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
@@ -437,19 +458,7 @@ static inline void dccp_connect_init(struct sock *sk)
 
        dccp_sync_mss(sk, dst_mtu(dst));
 
-       /*
-        * SWL and AWL are initially adjusted so that they are not less than
-        * the initial Sequence Numbers received and sent, respectively:
-        *      SWL := max(GSR + 1 - floor(W/4), ISR),
-        *      AWL := max(GSS - W' + 1, ISS).
-        * These adjustments MUST be applied only at the beginning of the
-        * connection.
-        */
-       dccp_update_gss(sk, dp->dccps_iss);
-       dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
-
-       /* S.GAR - greatest valid acknowledgement number received on a non-Sync;
-        *         initialized to S.ISS (sec. 8.5)                            */
+       /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */
        dp->dccps_gar = dp->dccps_iss;
 
        icsk->icsk_retransmits = 0;
index 6a5b961b6f5c08fdec108f72e66a2352c0199c78..54b3c7e9e016737eab1614fde3b22afa67456345 100644 (file)
@@ -98,22 +98,12 @@ static void dccp_retransmit_timer(struct sock *sk)
                goto backoff;
        }
 
-       /*
-        * sk->sk_send_head has to have one skb with
-        * DCCP_SKB_CB(skb)->dccpd_type set to one of the retransmittable DCCP
-        * packet types. The only packets eligible for retransmission are:
-        *      -- Requests in client-REQUEST  state (sec. 8.1.1)
-        *      -- Acks     in client-PARTOPEN state (sec. 8.1.5)
-        *      -- CloseReq in server-CLOSEREQ state (sec. 8.3)
-        *      -- Close    in   node-CLOSING  state (sec. 8.3)                */
-       WARN_ON(sk->sk_send_head == NULL);
-
        /*
         * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was
         * sent, no need to retransmit, this sock is dead.
         */
        if (dccp_write_timeout(sk))
-               goto out;
+               return;
 
        /*
         * We want to know the number of packets retransmitted, not the
@@ -122,30 +112,28 @@ static void dccp_retransmit_timer(struct sock *sk)
        if (icsk->icsk_retransmits == 0)
                DCCP_INC_STATS_BH(DCCP_MIB_TIMEOUTS);
 
-       if (dccp_retransmit_skb(sk, sk->sk_send_head) < 0) {
+       if (dccp_retransmit_skb(sk) != 0) {
                /*
                 * Retransmission failed because of local congestion,
                 * do not backoff.
                 */
-               if (icsk->icsk_retransmits == 0)
+               if (--icsk->icsk_retransmits == 0)
                        icsk->icsk_retransmits = 1;
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
                                          min(icsk->icsk_rto,
                                              TCP_RESOURCE_PROBE_INTERVAL),
                                          DCCP_RTO_MAX);
-               goto out;
+               return;
        }
 
 backoff:
        icsk->icsk_backoff++;
-       icsk->icsk_retransmits++;
 
        icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);
        inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto,
                                  DCCP_RTO_MAX);
        if (icsk->icsk_retransmits > sysctl_dccp_retries1)
                __sk_dst_reset(sk);
-out:;
 }
 
 static void dccp_write_timer(unsigned long data)
index a42b64d040c407efb0d862644fd2169e61451812..38ccb6dfb02e1c755f8ec03f6d793ec16121784f 100644 (file)
@@ -104,9 +104,7 @@ out:
 
 static int ipcomp4_init_state(struct xfrm_state *x)
 {
-       int err;
-       struct ipcomp_data *ipcd;
-       struct xfrm_algo_desc *calg_desc;
+       int err = -EINVAL;
 
        x->props.header_len = 0;
        switch (x->props.mode) {
index 0cfcea42153a1a8444dfc95f548872c4056586bc..4545e4306862b104217aa5189eac1d4b64c1b43e 100644 (file)
@@ -134,9 +134,7 @@ out:
 
 static int ipcomp6_init_state(struct xfrm_state *x)
 {
-       int err;
-       struct ipcomp_data *ipcd;
-       struct xfrm_algo_desc *calg_desc;
+       int err = -EINVAL;
 
        x->props.header_len = 0;
        switch (x->props.mode) {