]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 15 Jul 2008 19:39:13 +0000 (12:39 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 15 Jul 2008 19:39:13 +0000 (12:39 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire: don't respond to broadcast write requests
  firewire: clean up fw_card reference counting
  firewire: clean up some includes
  firewire: remove unused struct members
  firewire: implement broadcast_channel CSR for 1394a compliance
  ieee1394: dump mmapped iso buffers in core files
  ieee1394: raw1394: Push the BKL down into the driver ioctls
  ieee1394: video1394: reorder module init, prepare BKL removal
  ieee1394: reduce log noise about config ROM CRC errors

12 files changed:
drivers/firewire/fw-card.c
drivers/firewire/fw-device.c
drivers/firewire/fw-device.h
drivers/firewire/fw-ohci.c
drivers/firewire/fw-transaction.c
drivers/firewire/fw-transaction.h
drivers/ieee1394/csr1212.c
drivers/ieee1394/dma.c
drivers/ieee1394/highlevel.c
drivers/ieee1394/highlevel.h
drivers/ieee1394/raw1394.c
drivers/ieee1394/video1394.c

index 5b4c0d9f517346ec79a1426a4d7982ebe07986c8..da873d795aad94bccf9e88a58a4b9bde9821daf1 100644 (file)
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#include <linux/module.h>
-#include <linux/errno.h>
+#include <linux/completion.h>
+#include <linux/crc-itu-t.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kref.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/crc-itu-t.h>
+
 #include "fw-transaction.h"
 #include "fw-topology.h"
 #include "fw-device.h"
@@ -396,14 +399,16 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
 {
        static atomic_t index = ATOMIC_INIT(-1);
 
-       atomic_set(&card->device_count, 0);
        card->index = atomic_inc_return(&index);
        card->driver = driver;
        card->device = device;
        card->current_tlabel = 0;
        card->tlabel_mask = 0;
        card->color = 0;
+       card->broadcast_channel = BROADCAST_CHANNEL_INITIAL;
 
+       kref_init(&card->kref);
+       init_completion(&card->done);
        INIT_LIST_HEAD(&card->transaction_list);
        spin_lock_init(&card->lock);
        setup_timer(&card->flush_timer,
@@ -496,7 +501,6 @@ dummy_enable_phys_dma(struct fw_card *card,
 }
 
 static struct fw_card_driver dummy_driver = {
-       .name            = "dummy",
        .enable          = dummy_enable,
        .update_phy_reg  = dummy_update_phy_reg,
        .set_config_rom  = dummy_set_config_rom,
@@ -506,6 +510,14 @@ static struct fw_card_driver dummy_driver = {
        .enable_phys_dma = dummy_enable_phys_dma,
 };
 
+void
+fw_card_release(struct kref *kref)
+{
+       struct fw_card *card = container_of(kref, struct fw_card, kref);
+
+       complete(&card->done);
+}
+
 void
 fw_core_remove_card(struct fw_card *card)
 {
@@ -521,12 +533,10 @@ fw_core_remove_card(struct fw_card *card)
        card->driver = &dummy_driver;
 
        fw_destroy_nodes(card);
-       /*
-        * Wait for all device workqueue jobs to finish.  Otherwise the
-        * firewire-core module could be unloaded before the jobs ran.
-        */
-       while (atomic_read(&card->device_count) > 0)
-               msleep(100);
+
+       /* Wait for all users, especially device workqueue jobs, to finish. */
+       fw_card_put(card);
+       wait_for_completion(&card->done);
 
        cancel_delayed_work_sync(&card->work);
        fw_flush_transactions(card);
index d9c8daf7ae7d798b29a728464e1365c2fbe10b22..0855fb5568e806cf92546e466b73a702e9f55de6 100644 (file)
@@ -168,7 +168,7 @@ static void fw_device_release(struct device *dev)
        fw_node_put(device->node);
        kfree(device->config_rom);
        kfree(device);
-       atomic_dec(&card->device_count);
+       fw_card_put(card);
 }
 
 int fw_device_enable_phys_dma(struct fw_device *device)
@@ -946,8 +946,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
                 */
                device_initialize(&device->device);
                atomic_set(&device->state, FW_DEVICE_INITIALIZING);
-               atomic_inc(&card->device_count);
-               device->card = card;
+               device->card = fw_card_get(card);
                device->node = fw_node_get(node);
                device->node_id = node->node_id;
                device->generation = card->generation;
index 5f131f5129dae5d0cfee7a293bcea04b99430782..42305bbac72fb3237c5826c7b6671bc64b6cc931 100644 (file)
@@ -62,7 +62,6 @@ struct fw_device {
        bool cmc;
        struct fw_card *card;
        struct device device;
-       struct list_head link;
        struct list_head client_list;
        u32 *config_rom;
        size_t config_rom_length;
index 0b66306af479e4d9fdd359dac87f335b31ae89b6..333b12544dd1b0991bd9cc22ac079e2f3313210a 100644 (file)
@@ -2292,7 +2292,6 @@ ohci_queue_iso(struct fw_iso_context *base,
 }
 
 static const struct fw_card_driver ohci_driver = {
-       .name                   = ohci_driver_name,
        .enable                 = ohci_enable,
        .update_phy_reg         = ohci_update_phy_reg,
        .set_config_rom         = ohci_set_config_rom,
index 03ae8a77c479f680da86de9cc1e407336bd23750..40db8075227259c849007a92b4ea9c045745d9b2 100644 (file)
@@ -55,6 +55,9 @@
 #define HEADER_GET_DATA_LENGTH(q)      (((q) >> 16) & 0xffff)
 #define HEADER_GET_EXTENDED_TCODE(q)   (((q) >> 0) & 0xffff)
 
+#define HEADER_DESTINATION_IS_BROADCAST(q) \
+       (((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f))
+
 #define PHY_CONFIG_GAP_COUNT(gap_count)        (((gap_count) << 16) | (1 << 22))
 #define PHY_CONFIG_ROOT_ID(node_id)    ((((node_id) & 0x3f) << 24) | (1 << 23))
 #define PHY_IDENTIFIER(id)             ((id) << 30)
@@ -624,12 +627,9 @@ allocate_request(struct fw_packet *p)
 void
 fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
 {
-       /*
-        * Broadcast packets are reported as ACK_COMPLETE, so this
-        * check is sufficient to ensure we don't send response to
-        * broadcast packets or posted writes.
-        */
-       if (request->ack != ACK_PENDING) {
+       /* unified transaction or broadcast transaction: don't respond */
+       if (request->ack != ACK_PENDING ||
+           HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
                kfree(request);
                return;
        }
@@ -817,12 +817,13 @@ handle_registers(struct fw_card *card, struct fw_request *request,
        int reg = offset & ~CSR_REGISTER_BASE;
        unsigned long long bus_time;
        __be32 *data = payload;
+       int rcode = RCODE_COMPLETE;
 
        switch (reg) {
        case CSR_CYCLE_TIME:
        case CSR_BUS_TIME:
                if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) {
-                       fw_send_response(card, request, RCODE_TYPE_ERROR);
+                       rcode = RCODE_TYPE_ERROR;
                        break;
                }
 
@@ -831,7 +832,17 @@ handle_registers(struct fw_card *card, struct fw_request *request,
                        *data = cpu_to_be32(bus_time);
                else
                        *data = cpu_to_be32(bus_time >> 25);
-               fw_send_response(card, request, RCODE_COMPLETE);
+               break;
+
+       case CSR_BROADCAST_CHANNEL:
+               if (tcode == TCODE_READ_QUADLET_REQUEST)
+                       *data = cpu_to_be32(card->broadcast_channel);
+               else if (tcode == TCODE_WRITE_QUADLET_REQUEST)
+                       card->broadcast_channel =
+                           (be32_to_cpu(*data) & BROADCAST_CHANNEL_VALID) |
+                           BROADCAST_CHANNEL_INITIAL;
+               else
+                       rcode = RCODE_TYPE_ERROR;
                break;
 
        case CSR_BUS_MANAGER_ID:
@@ -850,10 +861,13 @@ handle_registers(struct fw_card *card, struct fw_request *request,
 
        case CSR_BUSY_TIMEOUT:
                /* FIXME: Implement this. */
+
        default:
-               fw_send_response(card, request, RCODE_ADDRESS_ERROR);
+               rcode = RCODE_ADDRESS_ERROR;
                break;
        }
+
+       fw_send_response(card, request, rcode);
 }
 
 static struct fw_address_handler registers = {
index 04d3854f65600924e53183b63f4001d048d047eb..2ae1b0d6cb7bdfaa6929ccc06a00d63501acebcf 100644 (file)
 #ifndef __fw_transaction_h
 #define __fw_transaction_h
 
+#include <linux/completion.h>
 #include <linux/device.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/fs.h>
 #include <linux/dma-mapping.h>
 #include <linux/firewire-constants.h>
-#include <asm/atomic.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/spinlock_types.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
 
 #define TCODE_IS_READ_REQUEST(tcode)   (((tcode) & ~1) == 4)
 #define TCODE_IS_BLOCK_PACKET(tcode)   (((tcode) &  1) != 0)
@@ -80,6 +81,9 @@
 #define CSR_SPEED_MAP                  0x2000
 #define CSR_SPEED_MAP_END              0x3000
 
+#define BROADCAST_CHANNEL_INITIAL      (1 << 31 | 31)
+#define BROADCAST_CHANNEL_VALID                (1 << 30)
+
 #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args)
 #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)
 
@@ -216,7 +220,8 @@ extern struct bus_type fw_bus_type;
 struct fw_card {
        const struct fw_card_driver *driver;
        struct device *device;
-       atomic_t device_count;
+       struct kref kref;
+       struct completion done;
 
        int node_id;
        int generation;
@@ -236,6 +241,7 @@ struct fw_card {
         */
        int self_id_count;
        u32 topology_map[252 + 3];
+       u32 broadcast_channel;
 
        spinlock_t lock; /* Take this lock when handling the lists in
                          * this struct. */
@@ -256,6 +262,20 @@ struct fw_card {
        int bm_generation;
 };
 
+static inline struct fw_card *fw_card_get(struct fw_card *card)
+{
+       kref_get(&card->kref);
+
+       return card;
+}
+
+void fw_card_release(struct kref *kref);
+
+static inline void fw_card_put(struct fw_card *card)
+{
+       kref_put(&card->kref, fw_card_release);
+}
+
 /*
  * The iso packet format allows for an immediate header/payload part
  * stored in 'header' immediately after the packet info plus an
@@ -348,8 +368,6 @@ int
 fw_iso_context_stop(struct fw_iso_context *ctx);
 
 struct fw_card_driver {
-       const char *name;
-
        /*
         * Enable the given card with the given initial config rom.
         * This function is expected to activate the card, and either
index e8122def164d69fff2675e7607b1718b64758b2d..9f95337139e3144424aba9c2e452939563f24586 100644 (file)
@@ -1049,6 +1049,24 @@ int csr1212_read(struct csr1212_csr *csr, u32 offset, void *buffer, u32 len)
        return -ENOENT;
 }
 
+/*
+ * Apparently there are many different wrong implementations of the CRC
+ * algorithm.  We don't fail, we just warn... approximately once per GUID.
+ */
+static void
+csr1212_check_crc(const u32 *buffer, size_t length, u16 crc, __be32 *guid)
+{
+       static u64 last_bad_eui64;
+       u64 eui64 = ((u64)be32_to_cpu(guid[0]) << 32) | be32_to_cpu(guid[1]);
+
+       if (csr1212_crc16(buffer, length) == crc ||
+           csr1212_msft_crc16(buffer, length) == crc ||
+           eui64 == last_bad_eui64)
+               return;
+
+       printk(KERN_DEBUG "ieee1394: config ROM CRC error\n");
+       last_bad_eui64 = eui64;
+}
 
 /* Parse a chunk of data as a Config ROM */
 
@@ -1092,11 +1110,8 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
                        return ret;
        }
 
-       /* Apparently there are many different wrong implementations of the CRC
-        * algorithm.  We don't fail, we just warn. */
-       if ((csr1212_crc16(bi->data, bi->crc_length) != bi->crc) &&
-           (csr1212_msft_crc16(bi->data, bi->crc_length) != bi->crc))
-               printk(KERN_DEBUG "IEEE 1394 device has ROM CRC error\n");
+       csr1212_check_crc(bi->data, bi->crc_length, bi->crc,
+                         &csr->bus_info_data[3]);
 
        cr = CSR1212_MALLOC(sizeof(*cr));
        if (!cr)
@@ -1205,11 +1220,8 @@ int csr1212_parse_keyval(struct csr1212_keyval *kv,
                &cache->data[bytes_to_quads(kv->offset - cache->offset)];
        kvi_len = be16_to_cpu(kvi->length);
 
-       /* Apparently there are many different wrong implementations of the CRC
-        * algorithm.  We don't fail, we just warn. */
-       if ((csr1212_crc16(kvi->data, kvi_len) != kvi->crc) &&
-           (csr1212_msft_crc16(kvi->data, kvi_len) != kvi->crc))
-               printk(KERN_DEBUG "IEEE 1394 device has ROM CRC error\n");
+       /* GUID is wrong in here in case of extended ROM.  We don't care. */
+       csr1212_check_crc(kvi->data, kvi_len, kvi->crc, &cache->data[3]);
 
        switch (kv->key.type) {
        case CSR1212_KV_TYPE_DIRECTORY:
index 73685e7dc7e4c9e6acea24c454e737686768b7e3..1aba8c13fe8fb87b8c04337df31ed28bb6d1afc3 100644 (file)
@@ -274,7 +274,7 @@ int dma_region_mmap(struct dma_region *dma, struct file *file,
        vma->vm_ops = &dma_region_vm_ops;
        vma->vm_private_data = dma;
        vma->vm_file = file;
-       vma->vm_flags |= VM_RESERVED;
+       vma->vm_flags |= VM_RESERVED | VM_ALWAYSDUMP;
 
        return 0;
 }
index fa2bfec0fca2e00ec16114894422f6f5c41a4ccf..918ffc4fc8ace2923f660d452d6f389a488c8b25 100644 (file)
@@ -228,10 +228,8 @@ void hpsb_register_highlevel(struct hpsb_highlevel *hl)
 {
        unsigned long flags;
 
+       hpsb_init_highlevel(hl);
        INIT_LIST_HEAD(&hl->addr_list);
-       INIT_LIST_HEAD(&hl->host_info_list);
-
-       rwlock_init(&hl->host_info_lock);
 
        down_write(&hl_drivers_sem);
        list_add_tail(&hl->hl_list, &hl_drivers);
index eb9fe321e09a37507c6527df82c7abd352db0b2a..bc5d0854c17e940c9509009b098cbf9482f6a695 100644 (file)
@@ -2,7 +2,7 @@
 #define IEEE1394_HIGHLEVEL_H
 
 #include <linux/list.h>
-#include <linux/spinlock_types.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 
 struct module;
@@ -103,6 +103,17 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
 void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
                           void *data, size_t length);
 
+/**
+ * hpsb_init_highlevel - initialize a struct hpsb_highlevel
+ *
+ * This is only necessary if hpsb_get_hostinfo_bykey can be called
+ * before hpsb_register_highlevel.
+ */
+static inline void hpsb_init_highlevel(struct hpsb_highlevel *hl)
+{
+       rwlock_init(&hl->host_info_lock);
+       INIT_LIST_HEAD(&hl->host_info_list);
+}
 void hpsb_register_highlevel(struct hpsb_highlevel *hl);
 void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
 
index ec2a0adbedb248f2a493b2ca716fc8d7971c98ed..96f2847b0405e03ced5c4d3ec5b50a973caf6129 100644 (file)
@@ -2549,8 +2549,8 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
 }
 
 /* ioctl is only used for rawiso operations */
-static int raw1394_ioctl(struct inode *inode, struct file *file,
-                        unsigned int cmd, unsigned long arg)
+static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
+                                                       unsigned long arg)
 {
        struct file_info *fi = file->private_data;
        void __user *argp = (void __user *)arg;
@@ -2656,6 +2656,16 @@ static int raw1394_ioctl(struct inode *inode, struct file *file,
        return -EINVAL;
 }
 
+static long raw1394_ioctl(struct file *file, unsigned int cmd,
+                                                       unsigned long arg)
+{
+       long ret;
+       lock_kernel();
+       ret = do_raw1394_ioctl(file, cmd, arg);
+       unlock_kernel();
+       return ret;
+}
+
 #ifdef CONFIG_COMPAT
 struct raw1394_iso_packets32 {
         __u32 n_packets;
@@ -2690,7 +2700,7 @@ static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
            !copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
                infos = compat_ptr(infos32);
                if (!copy_to_user(&dst->infos, &infos, sizeof infos))
-                       err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst);
+                       err = do_raw1394_ioctl(file, cmd, (unsigned long)dst);
        }
        return err;
 }
@@ -2731,7 +2741,7 @@ static long raw1394_compat_ioctl(struct file *file,
        case RAW1394_IOC_ISO_GET_STATUS:
        case RAW1394_IOC_ISO_SHUTDOWN:
        case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
-               err = raw1394_ioctl(NULL, file, cmd, arg);
+               err = do_raw1394_ioctl(file, cmd, arg);
                break;
        /* These request have different format. */
        case RAW1394_IOC_ISO_RECV_PACKETS32:
@@ -2984,7 +2994,7 @@ static const struct file_operations raw1394_fops = {
        .read = raw1394_read,
        .write = raw1394_write,
        .mmap = raw1394_mmap,
-       .ioctl = raw1394_ioctl,
+       .unlocked_ioctl = raw1394_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = raw1394_compat_ioctl,
 #endif
index e24772d336e1ae6c726d8e0a05ae5ea25a9207e0..069b9f6bf16dae8396d871673c8618eb544967a7 100644 (file)
@@ -1503,6 +1503,8 @@ static int __init video1394_init_module (void)
 {
        int ret;
 
+       hpsb_init_highlevel(&video1394_highlevel);
+
        cdev_init(&video1394_cdev, &video1394_fops);
        video1394_cdev.owner = THIS_MODULE;
        ret = cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16);