Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Dec 2009 16:13:10 +0000 (08:13 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Dec 2009 16:13:10 +0000 (08:13 -0800)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  ieee1394: Use hweight32
  firewire: cdev: reduce stack usage by ioctl_dispatch
  firewire: ohci: 0 may be a valid DMA address
  firewire: core: WARN on wrong usage of core transaction functions
  firewire: core: optimize Topology Map creation
  firewire: core: clarify generate_config_rom usage
  firewire: optimize config ROM creation
  firewire: cdev: normalize variable names
  firewire: normalize style of queue_work wrappers
  firewire: cdev: fix memory leak in an error path

drivers/firewire/core-card.c
drivers/firewire/core-cdev.c
drivers/firewire/core-topology.c
drivers/firewire/core-transaction.c
drivers/firewire/core.h
drivers/firewire/ohci.c
drivers/firewire/sbp2.c
drivers/ieee1394/ohci1394.c
include/linux/firewire.h

index e4864e894e4f84877cb9a6dfa8c9467194ee2e6b..7083bcc1b9c7c282fe1a56c7a7dba65e1ea9543e 100644 (file)
 
 #include "core.h"
 
-int fw_compute_block_crc(u32 *block)
+int fw_compute_block_crc(__be32 *block)
 {
-       __be32 be32_block[256];
-       int i, length;
+       int length;
+       u16 crc;
 
-       length = (*block >> 16) & 0xff;
-       for (i = 0; i < length; i++)
-               be32_block[i] = cpu_to_be32(block[i + 1]);
-       *block |= crc_itu_t(0, (u8 *) be32_block, length * 4);
+       length = (be32_to_cpu(block[0]) >> 16) & 0xff;
+       crc = crc_itu_t(0, (u8 *)&block[1], length * 4);
+       *block |= cpu_to_be32(crc);
 
        return length;
 }
@@ -57,6 +56,8 @@ static LIST_HEAD(card_list);
 static LIST_HEAD(descriptor_list);
 static int descriptor_count;
 
+static __be32 tmp_config_rom[256];
+
 #define BIB_CRC(v)             ((v) <<  0)
 #define BIB_CRC_LENGTH(v)      ((v) << 16)
 #define BIB_INFO_LENGTH(v)     ((v) << 24)
@@ -72,11 +73,10 @@ static int descriptor_count;
 #define BIB_CMC                        ((1) << 30)
 #define BIB_IMC                        ((1) << 31)
 
-static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
+static size_t generate_config_rom(struct fw_card *card, __be32 *config_rom)
 {
        struct fw_descriptor *desc;
-       static u32 config_rom[256];
-       int i, j, length;
+       int i, j, k, length;
 
        /*
         * Initialize contents of config rom buffer.  On the OHCI
@@ -87,40 +87,39 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
         * the version stored in the OHCI registers.
         */
 
-       memset(config_rom, 0, sizeof(config_rom));
-       config_rom[0] = BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0);
-       config_rom[1] = 0x31333934;
-
-       config_rom[2] =
+       config_rom[0] = cpu_to_be32(
+               BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0));
+       config_rom[1] = cpu_to_be32(0x31333934);
+       config_rom[2] = cpu_to_be32(
                BIB_LINK_SPEED(card->link_speed) |
                BIB_GENERATION(card->config_rom_generation++ % 14 + 2) |
                BIB_MAX_ROM(2) |
                BIB_MAX_RECEIVE(card->max_receive) |
-               BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC;
-       config_rom[3] = card->guid >> 32;
-       config_rom[4] = card->guid;
+               BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC);
+       config_rom[3] = cpu_to_be32(card->guid >> 32);
+       config_rom[4] = cpu_to_be32(card->guid);
 
        /* Generate root directory. */
-       i = 5;
-       config_rom[i++] = 0;
-       config_rom[i++] = 0x0c0083c0; /* node capabilities */
-       j = i + descriptor_count;
+       config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */
+       i = 7;
+       j = 7 + descriptor_count;
 
        /* Generate root directory entries for descriptors. */
        list_for_each_entry (desc, &descriptor_list, link) {
                if (desc->immediate > 0)
-                       config_rom[i++] = desc->immediate;
-               config_rom[i] = desc->key | (j - i);
+                       config_rom[i++] = cpu_to_be32(desc->immediate);
+               config_rom[i] = cpu_to_be32(desc->key | (j - i));
                i++;
                j += desc->length;
        }
 
        /* Update root directory length. */
-       config_rom[5] = (i - 5 - 1) << 16;
+       config_rom[5] = cpu_to_be32((i - 5 - 1) << 16);
 
        /* End of root directory, now copy in descriptors. */
        list_for_each_entry (desc, &descriptor_list, link) {
-               memcpy(&config_rom[i], desc->data, desc->length * 4);
+               for (k = 0; k < desc->length; k++)
+                       config_rom[i + k] = cpu_to_be32(desc->data[k]);
                i += desc->length;
        }
 
@@ -131,20 +130,17 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
        for (i = 0; i < j; i += length + 1)
                length = fw_compute_block_crc(config_rom + i);
 
-       *config_rom_length = j;
-
-       return config_rom;
+       return j;
 }
 
 static void update_config_roms(void)
 {
        struct fw_card *card;
-       u32 *config_rom;
        size_t length;
 
        list_for_each_entry (card, &card_list, link) {
-               config_rom = generate_config_rom(card, &length);
-               card->driver->set_config_rom(card, config_rom, length);
+               length = generate_config_rom(card, tmp_config_rom);
+               card->driver->set_config_rom(card, tmp_config_rom, length);
        }
 }
 
@@ -211,11 +207,8 @@ static const char gap_count_table[] = {
 
 void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
 {
-       int scheduled;
-
        fw_card_get(card);
-       scheduled = schedule_delayed_work(&card->work, delay);
-       if (!scheduled)
+       if (!schedule_delayed_work(&card->work, delay))
                fw_card_put(card);
 }
 
@@ -435,7 +428,6 @@ EXPORT_SYMBOL(fw_card_initialize);
 int fw_card_add(struct fw_card *card,
                u32 max_receive, u32 link_speed, u64 guid)
 {
-       u32 *config_rom;
        size_t length;
        int ret;
 
@@ -445,8 +437,8 @@ int fw_card_add(struct fw_card *card,
 
        mutex_lock(&card_mutex);
 
-       config_rom = generate_config_rom(card, &length);
-       ret = card->driver->enable(card, config_rom, length);
+       length = generate_config_rom(card, tmp_config_rom);
+       ret = card->driver->enable(card, tmp_config_rom, length);
        if (ret == 0)
                list_add_tail(&card->link, &card_list);
 
@@ -465,7 +457,8 @@ EXPORT_SYMBOL(fw_card_add);
  * shutdown still need to be provided by the card driver.
  */
 
-static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
+static int dummy_enable(struct fw_card *card,
+                       const __be32 *config_rom, size_t length)
 {
        BUG();
        return -1;
@@ -478,7 +471,7 @@ static int dummy_update_phy_reg(struct fw_card *card, int address,
 }
 
 static int dummy_set_config_rom(struct fw_card *card,
-                               u32 *config_rom, size_t length)
+                               const __be32 *config_rom, size_t length)
 {
        /*
         * We take the card out of card_list before setting the dummy
index 5089331544ed5336e682fdec039be94068314102..231e6ee5ba4397c6aa511ad8ff2df4f54129799b 100644 (file)
@@ -130,9 +130,22 @@ struct iso_resource {
        struct iso_resource_event *e_alloc, *e_dealloc;
 };
 
-static void schedule_iso_resource(struct iso_resource *);
 static void release_iso_resource(struct client *, struct client_resource *);
 
+static void schedule_iso_resource(struct iso_resource *r, unsigned long delay)
+{
+       client_get(r->client);
+       if (!schedule_delayed_work(&r->work, delay))
+               client_put(r->client);
+}
+
+static void schedule_if_iso_resource(struct client_resource *resource)
+{
+       if (resource->release == release_iso_resource)
+               schedule_iso_resource(container_of(resource,
+                                       struct iso_resource, resource), 0);
+}
+
 /*
  * dequeue_event() just kfree()'s the event, so the event has to be
  * the first field in a struct XYZ_event.
@@ -166,7 +179,7 @@ struct iso_interrupt_event {
 
 struct iso_resource_event {
        struct event event;
-       struct fw_cdev_event_iso_resource resource;
+       struct fw_cdev_event_iso_resource iso_resource;
 };
 
 static inline void __user *u64_to_uptr(__u64 value)
@@ -314,11 +327,8 @@ static void for_each_client(struct fw_device *device,
 
 static int schedule_reallocations(int id, void *p, void *data)
 {
-       struct client_resource *r = p;
+       schedule_if_iso_resource(p);
 
-       if (r->release == release_iso_resource)
-               schedule_iso_resource(container_of(r,
-                                       struct iso_resource, resource));
        return 0;
 }
 
@@ -414,9 +424,7 @@ static int add_client_resource(struct client *client,
                                  &resource->handle);
        if (ret >= 0) {
                client_get(client);
-               if (resource->release == release_iso_resource)
-                       schedule_iso_resource(container_of(resource,
-                                               struct iso_resource, resource));
+               schedule_if_iso_resource(resource);
        }
        spin_unlock_irqrestore(&client->lock, flags);
 
@@ -428,26 +436,26 @@ static int add_client_resource(struct client *client,
 
 static int release_client_resource(struct client *client, u32 handle,
                                   client_resource_release_fn_t release,
-                                  struct client_resource **resource)
+                                  struct client_resource **return_resource)
 {
-       struct client_resource *r;
+       struct client_resource *resource;
 
        spin_lock_irq(&client->lock);
        if (client->in_shutdown)
-               r = NULL;
+               resource = NULL;
        else
-               r = idr_find(&client->resource_idr, handle);
-       if (r && r->release == release)
+               resource = idr_find(&client->resource_idr, handle);
+       if (resource && resource->release == release)
                idr_remove(&client->resource_idr, handle);
        spin_unlock_irq(&client->lock);
 
-       if (!(r && r->release == release))
+       if (!(resource && resource->release == release))
                return -EINVAL;
 
-       if (resource)
-               *resource = r;
+       if (return_resource)
+               *return_resource = resource;
        else
-               r->release(client, r);
+               resource->release(client, resource);
 
        client_put(client);
 
@@ -699,6 +707,7 @@ static int ioctl_send_response(struct client *client, void *buffer)
        struct fw_cdev_send_response *request = buffer;
        struct client_resource *resource;
        struct inbound_transaction_resource *r;
+       int ret = 0;
 
        if (release_client_resource(client, request->handle,
                                    release_request, &resource) < 0)
@@ -708,13 +717,17 @@ static int ioctl_send_response(struct client *client, void *buffer)
                         resource);
        if (request->length < r->length)
                r->length = request->length;
-       if (copy_from_user(r->data, u64_to_uptr(request->data), r->length))
-               return -EFAULT;
+
+       if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) {
+               ret = -EFAULT;
+               goto out;
+       }
 
        fw_send_response(client->device->card, r->request, request->rcode);
+ out:
        kfree(r);
 
-       return 0;
+       return ret;
 }
 
 static int ioctl_initiate_bus_reset(struct client *client, void *buffer)
@@ -1028,8 +1041,7 @@ static void iso_resource_work(struct work_struct *work)
        /* Allow 1000ms grace period for other reallocations. */
        if (todo == ISO_RES_ALLOC &&
            time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) {
-               if (schedule_delayed_work(&r->work, DIV_ROUND_UP(HZ, 3)))
-                       client_get(client);
+               schedule_iso_resource(r, DIV_ROUND_UP(HZ, 3));
                skip = true;
        } else {
                /* We could be called twice within the same generation. */
@@ -1097,12 +1109,12 @@ static void iso_resource_work(struct work_struct *work)
                e = r->e_dealloc;
                r->e_dealloc = NULL;
        }
-       e->resource.handle      = r->resource.handle;
-       e->resource.channel     = channel;
-       e->resource.bandwidth   = bandwidth;
+       e->iso_resource.handle    = r->resource.handle;
+       e->iso_resource.channel   = channel;
+       e->iso_resource.bandwidth = bandwidth;
 
        queue_event(client, &e->event,
-                   &e->resource, sizeof(e->resource), NULL, 0);
+                   &e->iso_resource, sizeof(e->iso_resource), NULL, 0);
 
        if (free) {
                cancel_delayed_work(&r->work);
@@ -1114,13 +1126,6 @@ static void iso_resource_work(struct work_struct *work)
        client_put(client);
 }
 
-static void schedule_iso_resource(struct iso_resource *r)
-{
-       client_get(r->client);
-       if (!schedule_delayed_work(&r->work, 0))
-               client_put(r->client);
-}
-
 static void release_iso_resource(struct client *client,
                                 struct client_resource *resource)
 {
@@ -1129,7 +1134,7 @@ static void release_iso_resource(struct client *client,
 
        spin_lock_irq(&client->lock);
        r->todo = ISO_RES_DEALLOC;
-       schedule_iso_resource(r);
+       schedule_iso_resource(r, 0);
        spin_unlock_irq(&client->lock);
 }
 
@@ -1162,10 +1167,10 @@ static int init_iso_resource(struct client *client,
        r->e_alloc      = e1;
        r->e_dealloc    = e2;
 
-       e1->resource.closure    = request->closure;
-       e1->resource.type       = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED;
-       e2->resource.closure    = request->closure;
-       e2->resource.type       = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED;
+       e1->iso_resource.closure = request->closure;
+       e1->iso_resource.type    = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED;
+       e2->iso_resource.closure = request->closure;
+       e2->iso_resource.type    = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED;
 
        if (todo == ISO_RES_ALLOC) {
                r->resource.release = release_iso_resource;
@@ -1175,7 +1180,7 @@ static int init_iso_resource(struct client *client,
        } else {
                r->resource.release = NULL;
                r->resource.handle = -1;
-               schedule_iso_resource(r);
+               schedule_iso_resource(r, 0);
        }
        request->handle = r->resource.handle;
 
@@ -1295,7 +1300,23 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
 static int dispatch_ioctl(struct client *client,
                          unsigned int cmd, void __user *arg)
 {
-       char buffer[256];
+       char buffer[sizeof(union {
+               struct fw_cdev_get_info                 _00;
+               struct fw_cdev_send_request             _01;
+               struct fw_cdev_allocate                 _02;
+               struct fw_cdev_deallocate               _03;
+               struct fw_cdev_send_response            _04;
+               struct fw_cdev_initiate_bus_reset       _05;
+               struct fw_cdev_add_descriptor           _06;
+               struct fw_cdev_remove_descriptor        _07;
+               struct fw_cdev_create_iso_context       _08;
+               struct fw_cdev_queue_iso                _09;
+               struct fw_cdev_start_iso                _0a;
+               struct fw_cdev_stop_iso                 _0b;
+               struct fw_cdev_get_cycle_timer          _0c;
+               struct fw_cdev_allocate_iso_resource    _0d;
+               struct fw_cdev_send_stream_packet       _13;
+       })];
        int ret;
 
        if (_IOC_TYPE(cmd) != '#' ||
@@ -1390,10 +1411,10 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma)
 
 static int shutdown_resource(int id, void *p, void *data)
 {
-       struct client_resource *r = p;
+       struct client_resource *resource = p;
        struct client *client = data;
 
-       r->release(client, r);
+       resource->release(client, resource);
        client_put(client);
 
        return 0;
@@ -1402,7 +1423,7 @@ static int shutdown_resource(int id, void *p, void *data)
 static int fw_device_op_release(struct inode *inode, struct file *file)
 {
        struct client *client = file->private_data;
-       struct event *e, *next_e;
+       struct event *event, *next_event;
 
        mutex_lock(&client->device->client_list_mutex);
        list_del(&client->link);
@@ -1423,8 +1444,8 @@ static int fw_device_op_release(struct inode *inode, struct file *file)
        idr_remove_all(&client->resource_idr);
        idr_destroy(&client->resource_idr);
 
-       list_for_each_entry_safe(e, next_e, &client->event_list, link)
-               kfree(e);
+       list_for_each_entry_safe(event, next_event, &client->event_list, link)
+               kfree(event);
 
        client_put(client);
 
index fddf2b358936bd7b223a79bea5b4bd41147291d8..9a5f38c80b0e4cd5cd18991fb201b429a622c963 100644 (file)
@@ -28,9 +28,9 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/string.h>
 
 #include <asm/atomic.h>
+#include <asm/byteorder.h>
 #include <asm/system.h>
 
 #include "core.h"
@@ -510,13 +510,16 @@ static void update_tree(struct fw_card *card, struct fw_node *root)
 static void update_topology_map(struct fw_card *card,
                                u32 *self_ids, int self_id_count)
 {
-       int node_count;
+       int node_count = (card->root_node->node_id & 0x3f) + 1;
+       __be32 *map = card->topology_map;
+
+       *map++ = cpu_to_be32((self_id_count + 2) << 16);
+       *map++ = cpu_to_be32(be32_to_cpu(card->topology_map[1]) + 1);
+       *map++ = cpu_to_be32((node_count << 16) | self_id_count);
+
+       while (self_id_count--)
+               *map++ = cpu_to_be32p(self_ids++);
 
-       card->topology_map[1]++;
-       node_count = (card->root_node->node_id & 0x3f) + 1;
-       card->topology_map[2] = (node_count << 16) | self_id_count;
-       card->topology_map[0] = (self_id_count + 2) << 16;
-       memcpy(&card->topology_map[3], self_ids, self_id_count * 4);
        fw_compute_block_crc(card->topology_map);
 }
 
index da628c72a4621da3db2cdaf1cd564a555d5dde3f..842739df23e26cbb3f6a8caeec780c0872dc60fa 100644 (file)
@@ -218,12 +218,15 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
                packet->header_length = 16;
                packet->payload_length = 0;
                break;
+
+       default:
+               WARN(1, KERN_ERR "wrong tcode %d", tcode);
        }
  common:
        packet->speed = speed;
        packet->generation = generation;
        packet->ack = 0;
-       packet->payload_bus = 0;
+       packet->payload_mapped = false;
 }
 
 /**
@@ -595,11 +598,10 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header,
                break;
 
        default:
-               BUG();
-               return;
+               WARN(1, KERN_ERR "wrong tcode %d", tcode);
        }
 
-       response->payload_bus = 0;
+       response->payload_mapped = false;
 }
 EXPORT_SYMBOL(fw_fill_response);
 
@@ -810,8 +812,7 @@ static void handle_topology_map(struct fw_card *card, struct fw_request *request
                int speed, unsigned long long offset,
                void *payload, size_t length, void *callback_data)
 {
-       int i, start, end;
-       __be32 *map;
+       int start;
 
        if (!TCODE_IS_READ_REQUEST(tcode)) {
                fw_send_response(card, request, RCODE_TYPE_ERROR);
@@ -824,11 +825,7 @@ static void handle_topology_map(struct fw_card *card, struct fw_request *request
        }
 
        start = (offset - topology_map_region.start) / 4;
-       end = start + length / 4;
-       map = payload;
-
-       for (i = 0; i < length / 4; i++)
-               map[i] = cpu_to_be32(card->topology_map[start + i]);
+       memcpy(payload, &card->topology_map[start], length);
 
        fw_send_response(card, request, RCODE_COMPLETE);
 }
index 7ff6e7585152332f7cf261036920555b06c0528c..ed3b1a765c006887f9e338bb6c6457cb9c0f2f49 100644 (file)
@@ -40,7 +40,8 @@ struct fw_card_driver {
         * enable the PHY or set the link_on bit and initiate a bus
         * reset.
         */
-       int (*enable)(struct fw_card *card, u32 *config_rom, size_t length);
+       int (*enable)(struct fw_card *card,
+                     const __be32 *config_rom, size_t length);
 
        int (*update_phy_reg)(struct fw_card *card, int address,
                              int clear_bits, int set_bits);
@@ -48,10 +49,10 @@ struct fw_card_driver {
        /*
         * Update the config rom for an enabled card.  This function
         * should change the config rom that is presented on the bus
-        * an initiate a bus reset.
+        * and initiate a bus reset.
         */
        int (*set_config_rom)(struct fw_card *card,
-                             u32 *config_rom, size_t length);
+                             const __be32 *config_rom, size_t length);
 
        void (*send_request)(struct fw_card *card, struct fw_packet *packet);
        void (*send_response)(struct fw_card *card, struct fw_packet *packet);
@@ -93,7 +94,7 @@ int fw_card_add(struct fw_card *card,
                u32 max_receive, u32 link_speed, u64 guid);
 void fw_core_remove_card(struct fw_card *card);
 int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
-int fw_compute_block_crc(u32 *block);
+int fw_compute_block_crc(__be32 *block);
 void fw_schedule_bm_work(struct fw_card *card, unsigned long delay);
 
 static inline struct fw_card *fw_card_get(struct fw_card *card)
index 94260aa76aa3a88c87a2d3f805ed1abee38d7d44..ae4556f0c0c14aac573610566764230d77333321 100644 (file)
@@ -205,7 +205,7 @@ struct fw_ohci {
        dma_addr_t config_rom_bus;
        __be32 *next_config_rom;
        dma_addr_t next_config_rom_bus;
-       u32 next_header;
+       __be32 next_header;
 
        struct ar_context ar_request_ctx;
        struct ar_context ar_response_ctx;
@@ -997,7 +997,8 @@ static int at_context_queue_packet(struct context *ctx,
                        packet->ack = RCODE_SEND_ERROR;
                        return -1;
                }
-               packet->payload_bus = payload_bus;
+               packet->payload_bus     = payload_bus;
+               packet->payload_mapped  = true;
 
                d[2].req_count    = cpu_to_le16(packet->payload_length);
                d[2].data_address = cpu_to_le32(payload_bus);
@@ -1025,7 +1026,7 @@ static int at_context_queue_packet(struct context *ctx,
         */
        if (ohci->generation != packet->generation ||
            reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) {
-               if (packet->payload_length > 0)
+               if (packet->payload_mapped)
                        dma_unmap_single(ohci->card.device, payload_bus,
                                         packet->payload_length, DMA_TO_DEVICE);
                packet->ack = RCODE_GENERATION;
@@ -1061,7 +1062,7 @@ static int handle_at_packet(struct context *context,
                /* This packet was cancelled, just continue. */
                return 1;
 
-       if (packet->payload_bus)
+       if (packet->payload_mapped)
                dma_unmap_single(ohci->card.device, packet->payload_bus,
                                 packet->payload_length, DMA_TO_DEVICE);
 
@@ -1357,8 +1358,9 @@ static void bus_reset_tasklet(unsigned long data)
                 */
                reg_write(ohci, OHCI1394_BusOptions,
                          be32_to_cpu(ohci->config_rom[2]));
-               ohci->config_rom[0] = cpu_to_be32(ohci->next_header);
-               reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header);
+               ohci->config_rom[0] = ohci->next_header;
+               reg_write(ohci, OHCI1394_ConfigROMhdr,
+                         be32_to_cpu(ohci->next_header));
        }
 
 #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
@@ -1477,7 +1479,17 @@ static int software_reset(struct fw_ohci *ohci)
        return -EBUSY;
 }
 
-static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
+static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length)
+{
+       size_t size = length * 4;
+
+       memcpy(dest, src, size);
+       if (size < CONFIG_ROM_SIZE)
+               memset(&dest[length], 0, CONFIG_ROM_SIZE - size);
+}
+
+static int ohci_enable(struct fw_card *card,
+                      const __be32 *config_rom, size_t length)
 {
        struct fw_ohci *ohci = fw_ohci(card);
        struct pci_dev *dev = to_pci_dev(card->device);
@@ -1579,8 +1591,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
                if (ohci->next_config_rom == NULL)
                        return -ENOMEM;
 
-               memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE);
-               fw_memcpy_to_be32(ohci->next_config_rom, config_rom, length * 4);
+               copy_config_rom(ohci->next_config_rom, config_rom, length);
        } else {
                /*
                 * In the suspend case, config_rom is NULL, which
@@ -1590,7 +1601,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
                ohci->next_config_rom_bus = ohci->config_rom_bus;
        }
 
-       ohci->next_header = be32_to_cpu(ohci->next_config_rom[0]);
+       ohci->next_header = ohci->next_config_rom[0];
        ohci->next_config_rom[0] = 0;
        reg_write(ohci, OHCI1394_ConfigROMhdr, 0);
        reg_write(ohci, OHCI1394_BusOptions,
@@ -1624,7 +1635,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
 }
 
 static int ohci_set_config_rom(struct fw_card *card,
-                              u32 *config_rom, size_t length)
+                              const __be32 *config_rom, size_t length)
 {
        struct fw_ohci *ohci;
        unsigned long flags;
@@ -1673,9 +1684,7 @@ static int ohci_set_config_rom(struct fw_card *card,
                ohci->next_config_rom = next_config_rom;
                ohci->next_config_rom_bus = next_config_rom_bus;
 
-               memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE);
-               fw_memcpy_to_be32(ohci->next_config_rom, config_rom,
-                                 length * 4);
+               copy_config_rom(ohci->next_config_rom, config_rom, length);
 
                ohci->next_header = config_rom[0];
                ohci->next_config_rom[0] = 0;
@@ -1729,7 +1738,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
        if (packet->ack != 0)
                goto out;
 
-       if (packet->payload_bus)
+       if (packet->payload_mapped)
                dma_unmap_single(ohci->card.device, packet->payload_bus,
                                 packet->payload_length, DMA_TO_DEVICE);
 
index 98dbbda3ad4140d89867e46b1c62d477a37c7179..d485cdd8cbacf0a16410e50fb2b195c0107537f2 100644 (file)
@@ -820,20 +820,25 @@ static void sbp2_release_target(struct kref *kref)
        fw_device_put(device);
 }
 
-static struct workqueue_struct *sbp2_wq;
+static void sbp2_target_get(struct sbp2_target *tgt)
+{
+       kref_get(&tgt->kref);
+}
 
 static void sbp2_target_put(struct sbp2_target *tgt)
 {
        kref_put(&tgt->kref, sbp2_release_target);
 }
 
+static struct workqueue_struct *sbp2_wq;
+
 /*
  * Always get the target's kref when scheduling work on one its units.
  * Each workqueue job is responsible to call sbp2_target_put() upon return.
  */
 static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay)
 {
-       kref_get(&lu->tgt->kref);
+       sbp2_target_get(lu->tgt);
        if (!queue_delayed_work(sbp2_wq, &lu->work, delay))
                sbp2_target_put(lu->tgt);
 }
index 65c1429e412994c6633135b370dfa45842e3fa29..d0dc1db80b295adc31ad88eb38bb82a3106f6175 100644 (file)
@@ -82,6 +82,7 @@
  *
  */
 
+#include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/slab.h>
@@ -434,7 +435,6 @@ static void initialize_dma_trm_ctx(struct dma_trm_ctx *d)
 /* Count the number of available iso contexts */
 static int get_nb_iso_ctx(struct ti_ohci *ohci, int reg)
 {
-       int i,ctx=0;
        u32 tmp;
 
        reg_write(ohci, reg, 0xffffffff);
@@ -443,11 +443,7 @@ static int get_nb_iso_ctx(struct ti_ohci *ohci, int reg)
        DBGMSG("Iso contexts reg: %08x implemented: %08x", reg, tmp);
 
        /* Count the number of contexts */
-       for (i=0; i<32; i++) {
-               if (tmp & 1) ctx++;
-               tmp >>= 1;
-       }
-       return ctx;
+       return hweight32(tmp);
 }
 
 /* Global initialization */
index 7e1d4dec83e70180a231e80863d9d05ea816539b..9416a461b69654b78bf51532cbecff7654f83c8e 100644 (file)
 #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args)
 #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)
 
-static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
-{
-       u32    *dst = _dst;
-       __be32 *src = _src;
-       int i;
-
-       for (i = 0; i < size / 4; i++)
-               dst[i] = be32_to_cpu(src[i]);
-}
-
-static inline void fw_memcpy_to_be32(void *_dst, void *_src, size_t size)
-{
-       fw_memcpy_from_be32(_dst, _src, size);
-}
 #define CSR_REGISTER_BASE              0xfffff0000000ULL
 
 /* register offsets are relative to CSR_REGISTER_BASE */
@@ -131,7 +117,7 @@ struct fw_card {
 
        bool broadcast_channel_allocated;
        u32 broadcast_channel;
-       u32 topology_map[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4];
+       __be32 topology_map[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4];
 };
 
 struct fw_attribute_group {
@@ -281,6 +267,7 @@ struct fw_packet {
        void *payload;
        size_t payload_length;
        dma_addr_t payload_bus;
+       bool payload_mapped;
        u32 timestamp;
 
        /*