]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ieee1394 update (r925)
authorBen Collins <bcollins@debian.org>
Sun, 4 May 2003 09:21:12 +0000 (02:21 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 4 May 2003 09:21:12 +0000 (02:21 -0700)
- Remove some 2.4 compatibility macros
- Fix userspace pointer misuse in video1394 ioctl. Caught by the
  Stanford Checker. Gotta love the automated systems.
- Move our hotplug stuff around, to make the transition to putting our
  module dev table in mod_devicetable.h.
- Fix ohci1394 for possible crash with async stream packets. Cleaned up
  some debug messages.

16 files changed:
drivers/ieee1394/amdtp.c
drivers/ieee1394/dv1394.c
drivers/ieee1394/eth1394.c
drivers/ieee1394/eth1394.h
drivers/ieee1394/hosts.c
drivers/ieee1394/hosts.h
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_hotplug.h
drivers/ieee1394/ieee1394_types.h
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.h
drivers/ieee1394/ohci1394.c
drivers/ieee1394/pcilynx.c
drivers/ieee1394/raw1394.c
drivers/ieee1394/sbp2.c
drivers/ieee1394/video1394.c

index 8b65837f5b8c25151fee42e26eea4cf98a9f0b3b..4ba93358e95228f0058eed9c2713364a035bf344 100644 (file)
@@ -835,8 +835,8 @@ static int stream_alloc_packet_lists(struct stream *s)
                max_nevents = fraction_ceil(&s->samples_per_cycle);
 
        max_packet_size = max_nevents * s->dimension * 4 + 8;
-       s->packet_pool = hpsb_pci_pool_create("packet pool", s->host->ohci->dev,
-                                        max_packet_size, 0, 0 ,SLAB_KERNEL);
+       s->packet_pool = pci_pool_create("packet pool", s->host->ohci->dev,
+                                        max_packet_size, 0, 0);
 
        if (s->packet_pool == NULL)
                return -1;
@@ -1021,9 +1021,9 @@ struct stream *stream_alloc(struct amdtp_host *host)
                return NULL;
        }
 
-       s->descriptor_pool = hpsb_pci_pool_create("descriptor pool", host->ohci->dev,
+       s->descriptor_pool = pci_pool_create("descriptor pool", host->ohci->dev,
                                             sizeof(struct descriptor_block),
-                                            16, 0 ,SLAB_KERNEL);
+                                            16, 0);
 
        if (s->descriptor_pool == NULL) {
                kfree(s->input);
index 728fda4bb93a08ffd40faa0a2ec397b5c016151e..a5a2e682fbd6bb6397485be06695798b117a8383 100644 (file)
 
 #include "ieee1394.h"
 #include "ieee1394_types.h"
-#include "ieee1394_hotplug.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "ieee1394_core.h"
 #include "highlevel.h" 
index c3d86da42577122559d9b162db28c7d989c3b116..29ae22c7e8a9ff3df63b406930867ed5de54a741 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/tcp.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
+#include <linux/workqueue.h>
 #include <asm/delay.h>
 #include <asm/semaphore.h>
 #include <net/arp.h>
@@ -78,7 +79,7 @@
        printk(KERN_ERR fmt, ## args)
 
 static char version[] __devinitdata =
-       "$Rev: 906 $ Ben Collins <bcollins@debian.org>";
+       "$Rev: 918 $ Ben Collins <bcollins@debian.org>";
 
 /* Our ieee1394 highlevel driver */
 #define ETHER1394_DRIVER_NAME "ether1394"
@@ -853,8 +854,8 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
        ptask->dest_node = dest_node;
        /* TODO: When 2.4 is out of the way, give each of our ethernet
         * dev's a workqueue to handle these.  */
-       HPSB_INIT_WORK(&ptask->tq, hpsb_write_sched, ptask);
-       hpsb_schedule_work(&ptask->tq);
+       INIT_WORK(&ptask->tq, hpsb_write_sched, ptask);
+       schedule_work(&ptask->tq);
 
        return 0;
 fail:
index 40fa50d026167e8fef01f8e6a553564e8429d19f..584f1b1a41ac72083302c3f0ff4a2ab22c846f14 100644 (file)
@@ -67,7 +67,7 @@ struct packet_task {
        struct sk_buff *skb;    /* Socket buffer we are sending */
        nodeid_t dest_node;     /* Destination of the packet */
        u64 addr;               /* Address */
-       struct hpsb_queue_struct tq;    /* The task */
+       struct work_struct tq;  /* The task */
        eth1394_tx_type tx_type;        /* Send data via GASP or Write Req. */
 };
 
index 5d66cbc1d690f7ead637ab33cbeb2e275b73ce6f..8e2963455ec0dc7472e8ed03a63aaf28d6cde697 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/workqueue.h>
 
 #include "ieee1394_types.h"
 #include "hosts.h"
@@ -140,7 +141,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
 
        atomic_set(&h->generation, 0);
 
-       HPSB_INIT_WORK(&h->timeout_tq, (void (*)(void*))abort_timedouts, h);
+       INIT_WORK(&h->timeout_tq, (void (*)(void*))abort_timedouts, h);
 
         h->topology_map = h->csr.topology_map + 3;
         h->speed_map = (u8 *)(h->csr.speed_map + 2);
index de108f27cd978e24ff96b84c12e33efa1e97f8f3..7b6728c57f619cbd34e4cbeb7ff54d3b2feccb2b 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/device.h>
 #include <linux/wait.h>
 #include <linux/list.h>
+#include <linux/workqueue.h>
 #include <asm/semaphore.h>
 
 #include "ieee1394_types.h"
@@ -32,7 +33,7 @@ struct hpsb_host {
 
         struct list_head pending_packets;
         spinlock_t pending_pkt_lock;
-        struct hpsb_queue_struct timeout_tq;
+        struct work_struct timeout_tq;
 
         unsigned char iso_listen_count[64];
 
index 262d62ab43ebc9864da47ad59f1bc7bf00dae3a7..2b0b811248a4b10ba7f6a870699195a7cab52735 100644 (file)
@@ -31,6 +31,8 @@
 #include <linux/moduleparam.h>
 #include <linux/proc_fs.h>
 #include <linux/bitops.h>
+#include <linux/workqueue.h>
+#include <linux/kdev_t.h>
 #include <asm/byteorder.h>
 #include <asm/semaphore.h>
 
@@ -42,7 +44,6 @@
 #include "ieee1394_transactions.h"
 #include "csr.h"
 #include "nodemgr.h"
-#include "ieee1394_hotplug.h"
 #include "dma.h"
 #include "iso.h"
 
@@ -437,7 +438,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
         spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 
         up(&packet->state_change);
-        hpsb_schedule_work(&host->timeout_tq);
+        schedule_work(&host->timeout_tq);
 }
 
 /**
@@ -985,7 +986,7 @@ void abort_timedouts(struct hpsb_host *host)
         }
 
         if (!list_empty(&host->pending_packets))
-               hpsb_schedule_work(&host->timeout_tq);
+               schedule_work(&host->timeout_tq);
 
         spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 
index 2720f6a2cebdb74a891412b32cd9f2c83de1ae03..5be70d31b007151492e306a3e621812d3ce07e7d 100644 (file)
@@ -1,24 +1,24 @@
 #ifndef _IEEE1394_HOTPLUG_H
 #define _IEEE1394_HOTPLUG_H
 
-#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mod_devicetable.h>
 
-#include "ieee1394_core.h"
-#include "nodemgr.h"
+/* Unit spec id and sw version entry for some protocols */
+#define AVC_UNIT_SPEC_ID_ENTRY         0x0000A02D
+#define AVC_SW_VERSION_ENTRY           0x00010001
+#define CAMERA_UNIT_SPEC_ID_ENTRY      0x0000A02D
+#define CAMERA_SW_VERSION_ENTRY                0x00000100
+
+/* Check to make sure this all isn't already defined */
+#ifndef IEEE1394_MATCH_VENDOR_ID
 
 #define IEEE1394_MATCH_VENDOR_ID       0x0001
 #define IEEE1394_MATCH_MODEL_ID                0x0002
 #define IEEE1394_MATCH_SPECIFIER_ID    0x0004
 #define IEEE1394_MATCH_VERSION         0x0008
 
-/*
- * Unit spec id and sw version entry for some protocols
- */
-#define AVC_UNIT_SPEC_ID_ENTRY                                 0x0000A02D
-#define AVC_SW_VERSION_ENTRY                                   0x00010001
-#define CAMERA_UNIT_SPEC_ID_ENTRY                              0x0000A02D
-#define CAMERA_SW_VERSION_ENTRY                                        0x00000100
-
 struct ieee1394_device_id {
        u32 match_flags;
        u32 vendor_id;
@@ -28,33 +28,6 @@ struct ieee1394_device_id {
        void *driver_data;
 };
 
-struct hpsb_protocol_driver {
-       /* The name of the driver, e.g. SBP2 or IP1394 */
-       const char *name;
-
-       /* 
-        * The device id table describing the protocols and/or devices
-        * supported by this driver.  This is used by the nodemgr to
-        * decide if a driver could support a given node, but the
-        * probe function below can implement further protocol
-        * dependent or vendor dependent checking.
-        */
-       struct ieee1394_device_id *id_table;
-
-       /* 
-        * The update function is called when the node has just
-        * survived a bus reset, i.e. it is still present on the bus.
-        * However, it may be necessary to reestablish the connection
-        * or login into the node again, depending on the protocol.
-        */
-       void (*update)(struct unit_directory *ud);
-
-
-       /* Our LDM structure */
-       struct device_driver driver;
-};
-
-int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
-void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
+#endif
 
 #endif /* _IEEE1394_HOTPLUG_H */
index b544fcd7b13553772a19f83cf0b572cf542ace8e..315f11031ab2497383dcdd8b5b90c102d5ed6b2d 100644 (file)
 #define minor(dev) MINOR(dev)
 #endif
 
-#ifndef __devexit_p
-#define __devexit_p(x) x
-#endif
-
 #include <linux/spinlock.h>
 
-#ifndef list_for_each_safe
-#define list_for_each_safe(pos, n, head) \
-       for (pos = (head)->next, n = pos->next; pos != (head); \
-               pos = n, n = pos->next)
-
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5)
-#define pte_offset_kernel pte_offset
-#endif
-
 #ifndef MIN
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
 
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-
-/* Compatibility for task/work queues */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,42)
-/* Use task queue */
-#include <linux/tqueue.h>
-#define hpsb_queue_struct tq_struct
-#define hpsb_queue_list list
-#define hpsb_schedule_work(x) schedule_task(x)
-#define HPSB_INIT_WORK(x,y,z) INIT_TQUEUE(x,y,z)
-#define HPSB_PREPARE_WORK(x,y,z) PREPARE_TQUEUE(x,y,z)
-#else
-/* Use work queue */
-#include <linux/workqueue.h>
-#define hpsb_queue_struct work_struct
-#define hpsb_queue_list entry
-#define hpsb_schedule_work(x) schedule_work(x)
-#define HPSB_INIT_WORK(x,y,z) INIT_WORK(x,y,z)
-#define HPSB_PREPARE_WORK(x,y,z) PREPARE_WORK(x,y,z)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44)
-/* pci_pool_create changed. does not take the flags arg any longer */
-#define hpsb_pci_pool_create(a,b,c,d,e,f) pci_pool_create(a,b,c,d,e,f)
-#else
-#define hpsb_pci_pool_create(a,b,c,d,e,f) pci_pool_create(a,b,c,d,e)
-#endif
-
 /* Transaction Label handling */
 struct hpsb_tlabel_pool {
        DECLARE_BITMAP(pool, 64);
index 5f38985849e7873a9b71f6c21138903537467986..ee8ff312508ab5fa25d41bb0b90848c8de275b45 100644 (file)
@@ -22,9 +22,9 @@
 
 #include "ieee1394_types.h"
 #include "ieee1394.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "ieee1394_transactions.h"
-#include "ieee1394_hotplug.h"
 #include "highlevel.h"
 #include "csr.h"
 #include "nodemgr.h"
index e6a5d3f22548faef52cd356666a5c151805a49ef..f4fce32a187ac4c6a5ad6c022ae66b5cfc473a9d 100644 (file)
@@ -21,6 +21,8 @@
 #define _IEEE1394_NODEMGR_H
 
 #include <linux/device.h>
+#include "ieee1394_core.h"
+#include "ieee1394_hotplug.h"
 
 #define CONFIG_ROM_BUS_INFO_LENGTH(q)          ((q) >> 24)
 #define CONFIG_ROM_BUS_CRC_LENGTH(q)           (((q) >> 16) & 0xff)
@@ -142,6 +144,34 @@ struct node_entry {
        quadlet_t quadlets[0];
 };
 
+struct hpsb_protocol_driver {
+       /* The name of the driver, e.g. SBP2 or IP1394 */
+       const char *name;
+
+       /*
+        * The device id table describing the protocols and/or devices
+        * supported by this driver.  This is used by the nodemgr to
+        * decide if a driver could support a given node, but the
+        * probe function below can implement further protocol
+        * dependent or vendor dependent checking.
+        */
+       struct ieee1394_device_id *id_table;
+
+       /*
+        * The update function is called when the node has just
+        * survived a bus reset, i.e. it is still present on the bus.
+        * However, it may be necessary to reestablish the connection
+        * or login into the node again, depending on the protocol.
+        */
+       void (*update)(struct unit_directory *ud);
+
+       /* Our LDM structure */
+       struct device_driver driver;
+};
+
+int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
+void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
+
 static inline int hpsb_node_entry_valid(struct node_entry *ne)
 {
        return ne->generation == get_hpsb_generation(ne->host);
index f0ad0474343e5f2f1d2a2530097a6a544043a3d6..bd3a58c0273a9133b3f61e4add69a58ed18ab6f1 100644 (file)
@@ -164,7 +164,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
 printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
 
 static char version[] __devinitdata =
-       "$Rev: 908 $ Ben Collins <bcollins@debian.org>";
+       "$Rev: 921 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 static int phys_dma = 1;
@@ -623,8 +623,10 @@ static void insert_packet(struct ti_ohci *ohci,
        u32 cycleTimer;
        int idx = d->prg_ind;
 
-       DBGMSG(ohci->id, "Inserting packet for node %d, tlabel=%d, tcode=0x%x, speed=%d",
-                       packet->node_id, packet->tlabel, packet->tcode, packet->speed_code);
+       DBGMSG(ohci->id, "Inserting packet for node " NODE_BUS_FMT
+              ", tlabel=%d, tcode=0x%x, speed=%d",
+              NODE_BUS_ARGS(packet->node_id), packet->tlabel,
+              packet->tcode, packet->speed_code);
 
        d->prg_cpu[idx]->begin.address = 0;
        d->prg_cpu[idx]->begin.branchAddress = 0;
@@ -1505,6 +1507,7 @@ static void ohci_iso_recv_release_block(struct ohci_iso_recv *recv, int block)
           so disable branch and enable interrupt */
        next->branchAddress = 0;
        next->control |= cpu_to_le32(3 << 20);
+       next->status = cpu_to_le32(recv->buf_stride);
 
        /* link prev to next */ 
        prev->branchAddress = cpu_to_le32(dma_prog_region_offset_to_bus(&recv->prog,
@@ -2691,19 +2694,25 @@ static void dma_trm_tasklet (unsigned long data)
 
 #ifdef OHCI1394_DEBUG
                if (datasize)
-                       DBGMSG(ohci->id,
-                              "Packet sent to node %d tcode=0x%X tLabel="
-                              "0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d", 
-                                (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])
-                                        >>16)&0x3f,
-                                (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
-                                        >>4)&0xf,
-                                (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
-                                        >>10)&0x3f,
-                                status&0x1f, (status>>5)&0x3, 
-                                le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3])
-                                        >>16,
-                                d->ctx);
+                       if(((le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf) == 0xa)
+                               DBGMSG(ohci->id,
+                                      "Stream packet sent to channel %d tcode=0x%X "
+                                      "ack=0x%X spd=%d dataLength=%d ctx=%d", 
+                                      (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>8)&0x3f,
+                                      (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf,
+                                      status&0x1f, (status>>5)&0x3, 
+                                      le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16,
+                                      d->ctx);
+                       else
+                               DBGMSG(ohci->id,
+                                      "Packet sent to node %d tcode=0x%X tLabel="
+                                      "0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d", 
+                                      (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16)&0x3f,
+                                      (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf,
+                                      (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>10)&0x3f,
+                                      status&0x1f, (status>>5)&0x3,
+                                      le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3])>>16,
+                                      d->ctx);
                else 
                        DBGMSG(ohci->id,
                               "Packet sent to node %d tcode=0x%X tLabel="
@@ -2888,8 +2897,8 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
                return -ENOMEM;
        }
 
-       d->prg_pool = hpsb_pci_pool_create("ohci1394 rcv prg", ohci->dev,
-                               sizeof(struct dma_cmd), 4, 0, SLAB_KERNEL);
+       d->prg_pool = pci_pool_create("ohci1394 rcv prg", ohci->dev,
+                               sizeof(struct dma_cmd), 4, 0);
        OHCI_DMA_ALLOC("dma_rcv prg pool");
 
        for (i=0; i<d->num_desc; i++) {
@@ -3016,8 +3025,8 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
        memset(d->prg_cpu, 0, d->num_desc * sizeof(struct at_dma_prg*));
        memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));
 
-       d->prg_pool = hpsb_pci_pool_create("ohci1394 trm prg", ohci->dev,
-                               sizeof(struct at_dma_prg), 4, 0, SLAB_KERNEL);
+       d->prg_pool = pci_pool_create("ohci1394 trm prg", ohci->dev,
+                               sizeof(struct at_dma_prg), 4, 0);
        OHCI_DMA_ALLOC("dma_rcv prg pool");
 
        for (i = 0; i < d->num_desc; i++) {
index fde6613f922b7a84abefe1b0474f1c93f1cc10b6..d1a707c2cfc47312db324df1ae5c2337323fa07b 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/poll.h>
+#include <linux/kdev_t.h>
 #include <asm/byteorder.h>
 #include <asm/atomic.h>
 #include <asm/io.h>
index 69fc9ec8468a729f07da051f37c6ea29f422b2dc..72bafa9e1e9a418086262dad98a0923959d3fab9 100644 (file)
 #include "ieee1394.h"
 #include "ieee1394_types.h"
 #include "ieee1394_core.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "highlevel.h"
 #include "iso.h"
 #include "ieee1394_transactions.h"
-#include "ieee1394_hotplug.h"
 #include "raw1394.h"
 #include "raw1394-private.h"
 
index 8f37ffdbca16efd906a92a515fa50eccffa3578b..1ac8a2ed6f1b995a7b3ee2f06f4a08ef5955d0ad 100644 (file)
 
 #include "../scsi/scsi.h"
 #include "../scsi/hosts.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,47)
-#include "../scsi/sd.h"
-#endif
 
 #include "ieee1394.h"
 #include "ieee1394_types.h"
 #include "ieee1394_core.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "nodemgr.h"
 #include "highlevel.h"
 #include "ieee1394_transactions.h"
-#include "ieee1394_hotplug.h"
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-       "$Rev: 912 $ James Goodwin <jamesg@filanet.com>";
+       "$Rev: 919 $ James Goodwin <jamesg@filanet.com>";
 
 /*
  * Module load parameter definitions
@@ -2914,15 +2911,9 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
        /*
         * Tell scsi stack that we're done with this command
         */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       spin_lock_irqsave(&io_request_lock,flags);
-       done (SCpnt);
-       spin_unlock_irqrestore(&io_request_lock,flags);
-#else
        spin_lock_irqsave(scsi_id->hi->scsi_host->host_lock,flags);
        done (SCpnt);
        spin_unlock_irqrestore(scsi_id->hi->scsi_host->host_lock,flags);
-#endif
 
        return;
 }
index 8c28fce4939f26e4024ba144c83d207bc974e5d9..cbfa8f1fd32f7bf5f79fe51a9c6624ceb1be3415 100644 (file)
 
 #include "ieee1394.h"
 #include "ieee1394_types.h"
-#include "ieee1394_hotplug.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "ieee1394_core.h"
 #include "highlevel.h"
 #include "video1394.h"
+#include "nodemgr.h"
 #include "dma.h"
 
 #include "ohci1394.h"
@@ -991,6 +992,8 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
                struct video1394_queue_variable qv;
                struct dma_iso_ctx *d;
 
+               qv.packet_sizes = NULL;
+
                if(copy_from_user(&v, (void *)arg, sizeof(v)))
                        return -EFAULT;
 
@@ -1003,12 +1006,22 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
                }
                
                if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) {
+                       unsigned int *psizes;
+                       int buf_size = d->nb_cmd * sizeof(unsigned int);
+
                        if (copy_from_user(&qv, (void *)arg, sizeof(qv))) 
                                return -EFAULT;
-                       if (!access_ok(VERIFY_READ, qv.packet_sizes, 
-                                      d->nb_cmd * sizeof(unsigned int))) {
+
+                       psizes = kmalloc(buf_size, GFP_KERNEL);
+                       if (!psizes)
+                               return -ENOMEM;
+
+                       if (copy_from_user(psizes, qv.packet_sizes, buf_size)) {
+                               kfree(psizes);
                                return -EFAULT;
                        }
+
+                       qv.packet_sizes = psizes;
                }
 
                spin_lock_irqsave(&d->lock,flags);
@@ -1017,6 +1030,8 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
                        PRINT(KERN_ERR, ohci->id, 
                              "Buffer %d is already used",v.buffer);
                        spin_unlock_irqrestore(&d->lock,flags);
+                       if (qv.packet_sizes)
+                               kfree(qv.packet_sizes);
                        return -EFAULT;
                }
                
@@ -1070,6 +1085,10 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
                                reg_write(ohci, d->ctrlSet, 0x1000);
                        }
                }
+
+               if (qv.packet_sizes)
+                       kfree(qv.packet_sizes);
+
                return 0;
                
        }