]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ieee1394/raw1394.c
ieee1394: convert ieee1394 from "struct class_device" to "struct device"
[linux-2.6-omap-h63xx.git] / drivers / ieee1394 / raw1394.c
index bb897a37d9f778cf2f64661c06069461d5d63fc5..1dadd5a15ba13e7630619a3fa0b3a75bc145b817 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
 #include <linux/cdev.h>
@@ -435,7 +434,11 @@ struct compat_raw1394_req {
 
        __u64 sendb;
        __u64 recvb;
-} __attribute__((packed));
+}
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+__attribute__((packed))
+#endif
+;
 
 static const char __user *raw1394_compat_write(const char __user *buf)
 {
@@ -460,7 +463,7 @@ static const char __user *raw1394_compat_write(const char __user *buf)
 static int
 raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
 {
-       struct compat_raw1394_req __user *cr = (typeof(cr)) r;
+       struct compat_raw1394_req __user *cr = (typeof(cr)) buf;
        if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) ||
            P(type) ||
            P(error) ||
@@ -588,7 +591,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req)
 
        req->req.length = 0;
        queue_complete_req(req);
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int state_initialized(struct file_info *fi, struct pending_request *req)
@@ -602,7 +605,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
                req->req.generation = atomic_read(&internal_generation);
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        switch (req->req.type) {
@@ -674,7 +677,7 @@ out_set_card:
        }
 
        queue_complete_req(req);
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
@@ -866,7 +869,7 @@ static int handle_async_request(struct file_info *fi,
        if (req->req.error) {
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        hpsb_set_packet_complete_task(packet,
@@ -884,7 +887,7 @@ static int handle_async_request(struct file_info *fi,
                hpsb_free_tlabel(packet);
                queue_complete_req(req);
        }
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int handle_iso_send(struct file_info *fi, struct pending_request *req,
@@ -908,7 +911,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
                req->req.error = RAW1394_ERROR_MEMFAULT;
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        req->req.length = 0;
@@ -928,7 +931,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
                queue_complete_req(req);
        }
 
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int handle_async_send(struct file_info *fi, struct pending_request *req)
@@ -937,15 +940,18 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
        struct hpsb_packet *packet;
        int header_length = req->req.misc & 0xffff;
        int expect_response = req->req.misc >> 16;
+       size_t data_size;
 
-       if ((header_length > req->req.length) || (header_length < 12)) {
+       if (header_length > req->req.length || header_length < 12 ||
+           header_length > FIELD_SIZEOF(struct hpsb_packet, header)) {
                req->req.error = RAW1394_ERROR_INVALID_ARG;
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
-       packet = hpsb_alloc_packet(req->req.length - header_length);
+       data_size = req->req.length - header_length;
+       packet = hpsb_alloc_packet(data_size);
        req->packet = packet;
        if (!packet)
                return -ENOMEM;
@@ -955,16 +961,16 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
                req->req.error = RAW1394_ERROR_MEMFAULT;
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        if (copy_from_user
            (packet->data, int2ptr(req->req.sendb) + header_length,
-            packet->data_size)) {
+            data_size)) {
                req->req.error = RAW1394_ERROR_MEMFAULT;
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        packet->type = hpsb_async;
@@ -974,7 +980,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
        packet->host = fi->host;
        packet->expect_response = expect_response;
        packet->header_size = header_length;
-       packet->data_size = req->req.length - header_length;
+       packet->data_size = data_size;
 
        req->req.length = 0;
        hpsb_set_packet_complete_task(packet,
@@ -992,7 +998,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
                queue_complete_req(req);
        }
 
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
@@ -1867,7 +1873,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
                spin_lock_irqsave(&host_info_lock, flags);
                list_add_tail(&addr->addr_list, &fi->addr_list);
                spin_unlock_irqrestore(&host_info_lock, flags);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
        retval =
            hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops,
@@ -1885,7 +1891,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
                return (-EALREADY);
        }
        free_pending_request(req);      /* immediate success or fail */
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int arm_unregister(struct file_info *fi, struct pending_request *req)
@@ -1953,7 +1959,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
                vfree(addr->addr_space_buffer);
                kfree(addr);
                free_pending_request(req);      /* immediate success or fail */
-               return sizeof(struct raw1394_request);
+               return 0;
        }
        retval =
            hpsb_unregister_addrspace(&raw1394_highlevel, fi->host,
@@ -1969,7 +1975,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
        vfree(addr->addr_space_buffer);
        kfree(addr);
        free_pending_request(req);      /* immediate success or fail */
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 /* Copy data from ARM buffer(s) to user buffer. */
@@ -2011,7 +2017,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req)
                                 * queue no response, and therefore nobody
                                 * will free it. */
                                free_pending_request(req);
-                               return sizeof(struct raw1394_request);
+                               return 0;
                        } else {
                                DBGMSG("arm_get_buf request exceeded mapping");
                                spin_unlock_irqrestore(&host_info_lock, flags);
@@ -2063,7 +2069,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req)
                                 * queue no response, and therefore nobody
                                 * will free it. */
                                free_pending_request(req);
-                               return sizeof(struct raw1394_request);
+                               return 0;
                        } else {
                                DBGMSG("arm_set_buf request exceeded mapping");
                                spin_unlock_irqrestore(&host_info_lock, flags);
@@ -2084,7 +2090,7 @@ static int reset_notification(struct file_info *fi, struct pending_request *req)
            (req->req.misc == RAW1394_NOTIFY_ON)) {
                fi->notification = (u8) req->req.misc;
                free_pending_request(req);      /* we have to free the request, because we queue no response, and therefore nobody will free it */
-               return sizeof(struct raw1394_request);
+               return 0;
        }
        /* error EINVAL (22) invalid argument */
        return (-EINVAL);
@@ -2117,12 +2123,12 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
                req->req.length = 0;
                queue_complete_req(req);
        }
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int get_config_rom(struct file_info *fi, struct pending_request *req)
 {
-       int ret = sizeof(struct raw1394_request);
+       int ret = 0;
        quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
        int status;
 
@@ -2152,7 +2158,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req)
 
 static int update_config_rom(struct file_info *fi, struct pending_request *req)
 {
-       int ret = sizeof(struct raw1394_request);
+       int ret = 0;
        quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
        if (!data)
                return -ENOMEM;
@@ -2219,7 +2225,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
 
                        hpsb_update_config_rom_image(fi->host);
                        free_pending_request(req);
-                       return sizeof(struct raw1394_request);
+                       return 0;
                }
        }
 
@@ -2284,7 +2290,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
                /* we have to free the request, because we queue no response,
                 * and therefore nobody will free it */
                free_pending_request(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        } else {
                for (dentry =
                     fi->csr1212_dirs[dr]->value.directory.dentries_head;
@@ -2309,7 +2315,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
 
        case RAW1394_REQ_ECHO:
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
 
        case RAW1394_REQ_ISO_SEND:
                print_old_iso_deprecation();
@@ -2333,24 +2339,24 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
        case RAW1394_REQ_ISO_LISTEN:
                print_old_iso_deprecation();
                handle_iso_listen(fi, req);
-               return sizeof(struct raw1394_request);
+               return 0;
 
        case RAW1394_REQ_FCP_LISTEN:
                handle_fcp_listen(fi, req);
-               return sizeof(struct raw1394_request);
+               return 0;
 
        case RAW1394_REQ_RESET_BUS:
                if (req->req.misc == RAW1394_LONG_RESET) {
                        DBGMSG("busreset called (type: LONG)");
                        hpsb_reset_bus(fi->host, LONG_RESET);
                        free_pending_request(req);      /* we have to free the request, because we queue no response, and therefore nobody will free it */
-                       return sizeof(struct raw1394_request);
+                       return 0;
                }
                if (req->req.misc == RAW1394_SHORT_RESET) {
                        DBGMSG("busreset called (type: SHORT)");
                        hpsb_reset_bus(fi->host, SHORT_RESET);
                        free_pending_request(req);      /* we have to free the request, because we queue no response, and therefore nobody will free it */
-                       return sizeof(struct raw1394_request);
+                       return 0;
                }
                /* error EINVAL (22) invalid argument */
                return (-EINVAL);
@@ -2369,7 +2375,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
                req->req.generation = get_hpsb_generation(fi->host);
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        switch (req->req.type) {
@@ -2382,7 +2388,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
        if (req->req.length == 0) {
                req->req.error = RAW1394_ERROR_INVALID_ARG;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        return handle_async_request(fi, req, node);
@@ -2393,7 +2399,7 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
 {
        struct file_info *fi = (struct file_info *)file->private_data;
        struct pending_request *req;
-       ssize_t retval = 0;
+       ssize_t retval = -EBADFD;
 
 #ifdef CONFIG_COMPAT
        if (count == sizeof(struct compat_raw1394_req) &&
@@ -2435,6 +2441,9 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
 
        if (retval < 0) {
                free_pending_request(req);
+       } else {
+               BUG_ON(retval);
+               retval = count;
        }
 
        return retval;
@@ -2800,6 +2809,103 @@ static int raw1394_ioctl(struct inode *inode, struct file *file,
        return -EINVAL;
 }
 
+#ifdef CONFIG_COMPAT
+struct raw1394_iso_packets32 {
+        __u32 n_packets;
+        compat_uptr_t infos;
+} __attribute__((packed));
+
+struct raw1394_cycle_timer32 {
+        __u32 cycle_timer;
+        __u64 local_time;
+}
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+__attribute__((packed))
+#endif
+;
+
+#define RAW1394_IOC_ISO_RECV_PACKETS32          \
+        _IOW ('#', 0x25, struct raw1394_iso_packets32)
+#define RAW1394_IOC_ISO_XMIT_PACKETS32          \
+        _IOW ('#', 0x27, struct raw1394_iso_packets32)
+#define RAW1394_IOC_GET_CYCLE_TIMER32           \
+        _IOR ('#', 0x30, struct raw1394_cycle_timer32)
+
+static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
+                                          struct raw1394_iso_packets32 __user *arg)
+{
+       compat_uptr_t infos32;
+       void *infos;
+       long err = -EFAULT;
+       struct raw1394_iso_packets __user *dst = compat_alloc_user_space(sizeof(struct raw1394_iso_packets));
+
+       if (!copy_in_user(&dst->n_packets, &arg->n_packets, sizeof arg->n_packets) &&
+           !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);
+       }
+       return err;
+}
+
+static long raw1394_read_cycle_timer32(struct file_info *fi, void __user * uaddr)
+{
+       struct raw1394_cycle_timer32 ct;
+       int err;
+
+       err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time);
+       if (!err)
+               if (copy_to_user(uaddr, &ct, sizeof(ct)))
+                       err = -EFAULT;
+       return err;
+}
+
+static long raw1394_compat_ioctl(struct file *file,
+                                unsigned int cmd, unsigned long arg)
+{
+       struct file_info *fi = file->private_data;
+       void __user *argp = (void __user *)arg;
+       long err;
+
+       lock_kernel();
+       switch (cmd) {
+       /* These requests have same format as long as 'int' has same size. */
+       case RAW1394_IOC_ISO_RECV_INIT:
+       case RAW1394_IOC_ISO_RECV_START:
+       case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
+       case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
+       case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:
+       case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
+       case RAW1394_IOC_ISO_RECV_FLUSH:
+       case RAW1394_IOC_ISO_XMIT_RECV_STOP:
+       case RAW1394_IOC_ISO_XMIT_INIT:
+       case RAW1394_IOC_ISO_XMIT_START:
+       case RAW1394_IOC_ISO_XMIT_SYNC:
+       case RAW1394_IOC_ISO_GET_STATUS:
+       case RAW1394_IOC_ISO_SHUTDOWN:
+       case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
+               err = raw1394_ioctl(NULL, file, cmd, arg);
+               break;
+       /* These request have different format. */
+       case RAW1394_IOC_ISO_RECV_PACKETS32:
+               err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_RECV_PACKETS, argp);
+               break;
+       case RAW1394_IOC_ISO_XMIT_PACKETS32:
+               err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_XMIT_PACKETS, argp);
+               break;
+       case RAW1394_IOC_GET_CYCLE_TIMER32:
+               err = raw1394_read_cycle_timer32(fi, argp);
+               break;
+       default:
+               err = -EINVAL;
+               break;
+       }
+       unlock_kernel();
+
+       return err;
+}
+#endif
+
 static unsigned int raw1394_poll(struct file *file, poll_table * pt)
 {
        struct file_info *fi = file->private_data;
@@ -3039,7 +3145,9 @@ static const struct file_operations raw1394_fops = {
        .write = raw1394_write,
        .mmap = raw1394_mmap,
        .ioctl = raw1394_ioctl,
-       // .compat_ioctl = ... someone needs to do this
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = raw1394_compat_ioctl,
+#endif
        .poll = raw1394_poll,
        .open = raw1394_open,
        .release = raw1394_release,
@@ -3052,9 +3160,9 @@ static int __init init_raw1394(void)
        hpsb_register_highlevel(&raw1394_highlevel);
 
        if (IS_ERR
-           (class_device_create
-            (hpsb_protocol_class, NULL,
-             MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL,
+           (device_create(
+             hpsb_protocol_class, NULL,
+             MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
              RAW1394_DEVICE_NAME))) {
                ret = -EFAULT;
                goto out_unreg;
@@ -3081,9 +3189,9 @@ static int __init init_raw1394(void)
        goto out;
 
       out_dev:
-       class_device_destroy(hpsb_protocol_class,
-                            MKDEV(IEEE1394_MAJOR,
-                                  IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+       device_destroy(hpsb_protocol_class,
+                      MKDEV(IEEE1394_MAJOR,
+                            IEEE1394_MINOR_BLOCK_RAW1394 * 16));
       out_unreg:
        hpsb_unregister_highlevel(&raw1394_highlevel);
       out:
@@ -3092,9 +3200,9 @@ static int __init init_raw1394(void)
 
 static void __exit cleanup_raw1394(void)
 {
-       class_device_destroy(hpsb_protocol_class,
-                            MKDEV(IEEE1394_MAJOR,
-                                  IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+       device_destroy(hpsb_protocol_class,
+                      MKDEV(IEEE1394_MAJOR,
+                            IEEE1394_MINOR_BLOCK_RAW1394 * 16));
        cdev_del(&raw1394_cdev);
        hpsb_unregister_highlevel(&raw1394_highlevel);
        hpsb_unregister_protocol(&raw1394_driver);