patch-2.4.0-test9 linux/drivers/ieee1394/raw1394.c

Next file: linux/drivers/ieee1394/raw1394.h
Previous file: linux/drivers/ieee1394/pcilynx.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/raw1394.c linux/drivers/ieee1394/raw1394.c
@@ -33,6 +33,15 @@
 #include "raw1394.h"
 
 
+#if BITS_PER_LONG == 64
+#define int2ptr(x) ((void *)x)
+#define ptr2int(x) ((u64)x)
+#else
+#define int2ptr(x) ((void *)(u32)x)
+#define ptr2int(x) ((u64)(u32)x)
+#endif
+
+
 static devfs_handle_t devfs_handle = NULL;
 
 LIST_HEAD(host_info_list);
@@ -204,8 +213,13 @@
                                 req->file_info = fi;
                                 req->req.type = RAW1394_REQ_BUS_RESET;
                                 req->req.generation = get_hpsb_generation();
-                                req->req.misc = (host->node_id << 16) 
+                                req->req.misc = (host->node_id << 16)
                                         | host->node_count;
+                                if (fi->protocol_version > 3) {
+                                        req->req.misc |= ((host->irm_id
+                                                           & NODE_MASK) << 8);
+                                }
+
                                 queue_complete_req(req);
                         }
                                 
@@ -268,7 +282,7 @@
                         req->req.type = RAW1394_REQ_ISO_RECEIVE;
                         req->req.generation = get_hpsb_generation();
                         req->req.misc = 0;
-                        req->req.recvb = (u64)fi->iso_buffer;
+                        req->req.recvb = ptr2int(fi->iso_buffer);
                         req->req.length = MIN(length, fi->iso_buffer_length);
                         
                         list_add_tail(&req->list, &reqs);
@@ -337,7 +351,7 @@
                         req->req.type = RAW1394_REQ_FCP_REQUEST;
                         req->req.generation = get_hpsb_generation();
                         req->req.misc = nodeid | (direction << 16);
-                        req->req.recvb = (u64)fi->fcp_buffer;
+                        req->req.recvb = ptr2int(fi->fcp_buffer);
                         req->req.length = length;
                         
                         list_add_tail(&req->list, &reqs);
@@ -387,7 +401,7 @@
         req = list_entry(lh, struct pending_request, list);
 
         if (req->req.length) {
-                if (copy_to_user((void *)req->req.recvb, req->data,
+                if (copy_to_user(int2ptr(req->req.recvb), req->data,
                                  req->req.length)) {
                         req->req.error = RAW1394_ERROR_MEMFAULT;
                 }
@@ -402,11 +416,16 @@
 static int state_opened(struct file_info *fi, struct pending_request *req)
 {
         if (req->req.type == RAW1394_REQ_INITIALIZE) {
-                if (req->req.misc == RAW1394_KERNELAPI_VERSION) {
+                switch (req->req.misc) {
+                case RAW1394_KERNELAPI_VERSION:
+                case 3:
                         fi->state = initialized;
+                        fi->protocol_version = req->req.misc;
                         req->req.error = RAW1394_ERROR_NONE;
                         req->req.generation = get_hpsb_generation();
-                } else {
+                        break;
+
+                default:
                         req->req.error = RAW1394_ERROR_COMPAT;
                         req->req.misc = RAW1394_KERNELAPI_VERSION;
                 }
@@ -488,6 +507,10 @@
                         req->req.error = RAW1394_ERROR_NONE;
                         req->req.misc = (fi->host->node_id << 16) 
                                 | fi->host->node_count;
+                        if (fi->protocol_version > 3) {
+                                req->req.misc |=
+                                        (fi->host->irm_id & NODE_MASK) << 8;
+                        }
                 } else {
                         req->req.error = RAW1394_ERROR_INVALID_ARG;
                 }
@@ -519,7 +542,7 @@
                 } else {
                         fi->listen_channels |= 1ULL << channel;
                         hpsb_listen_channel(hl_handle, fi->host, channel);
-                        fi->iso_buffer = (void *)req->req.recvb;
+                        fi->iso_buffer = int2ptr(req->req.recvb);
                         fi->iso_buffer_length = req->req.length;
                 }
         } else {
@@ -545,7 +568,7 @@
                 if (fi->fcp_buffer) {
                         req->req.error = RAW1394_ERROR_ALREADY;
                 } else {
-                        fi->fcp_buffer = (u8 *)req->req.recvb;
+                        fi->fcp_buffer = (u8 *)int2ptr(req->req.recvb);
                 }
         } else {
                 if (!fi->fcp_buffer) {
@@ -575,7 +598,7 @@
                 break;
 
         case RAW1394_REQ_ASYNC_WRITE:
-                if (copy_from_user(req->data, (void *)req->req.sendb, 
+                if (copy_from_user(req->data, int2ptr(req->req.sendb),
                                    req->req.length)) {
                         req->req.error = RAW1394_ERROR_MEMFAULT;
                         break;
@@ -600,7 +623,7 @@
                         }
                 }
 
-                if (copy_from_user(req->data, (void *)req->req.sendb,
+                if (copy_from_user(req->data, int2ptr(req->req.sendb),
                                    req->req.length)) {
                         req->req.error = RAW1394_ERROR_MEMFAULT;
                         break;
@@ -658,7 +681,7 @@
                 if (req->req.length == 4) {
                         quadlet_t x;
 
-                        if (copy_from_user(&x, (void *)req->req.sendb, 4)) {
+                        if (copy_from_user(&x, int2ptr(req->req.sendb), 4)) {
                                 req->req.error = RAW1394_ERROR_MEMFAULT;
                         }
 
@@ -670,7 +693,7 @@
                                                         req->req.length);
                         if (!packet) return -ENOMEM;
 
-                        if (copy_from_user(packet->data, (void *)req->req.sendb,
+                        if (copy_from_user(packet->data, int2ptr(req->req.sendb),
                                            req->req.length)) {
                                 req->req.error = RAW1394_ERROR_MEMFAULT;
                         }
@@ -696,7 +719,7 @@
                                               req->req.misc);
                 if (!packet) return -ENOMEM;
 
-                if (copy_from_user(packet->data, (void *)req->req.sendb,
+                if (copy_from_user(packet->data, int2ptr(req->req.sendb),
                                    req->req.length)) {
                         req->req.error = RAW1394_ERROR_MEMFAULT;
                         break;
@@ -735,12 +758,52 @@
         return sizeof(struct raw1394_request);
 }
 
+static int handle_iso_send(struct file_info *fi, struct pending_request *req,
+                           int channel)
+{
+        struct hpsb_packet *packet;
+
+        packet = alloc_hpsb_packet(req->req.length);
+        if (!packet) return -ENOMEM;
+        req->packet = packet;
+
+        fill_iso_packet(packet, req->req.length, channel & 0x3f,
+                        (req->req.misc >> 16) & 0x3, req->req.misc & 0xf);
+        packet->type = iso;
+        packet->speed_code = req->req.address & 0x3;
+        packet->host = fi->host;
+
+        if (copy_from_user(packet->data, int2ptr(req->req.sendb),
+                           req->req.length)) {
+                req->req.error = RAW1394_ERROR_MEMFAULT;
+                req->req.length = 0;
+                queue_complete_req(req);
+                return sizeof(struct raw1394_request);
+        }
+
+        req->tq.data = req;
+        req->tq.routine = (void (*)(void*))queue_complete_req;
+        req->req.length = 0;
+        queue_task(&req->tq, &packet->complete_tq);
+
+        if (!hpsb_send_packet(packet)) {
+                req->req.error = RAW1394_ERROR_SEND_ERROR;
+                queue_complete_req(req);
+        }
+
+        return sizeof(struct raw1394_request);
+}
+
 static int state_connected(struct file_info *fi, struct pending_request *req)
 {
         int node = req->req.address >> 48;
 
         req->req.error = RAW1394_ERROR_NONE;
 
+        if (req->req.type ==  RAW1394_REQ_ISO_SEND) {
+                return handle_iso_send(fi, req, node);
+        }
+
         if (req->req.generation != get_hpsb_generation()) {
                 req->req.error = RAW1394_ERROR_GENERATION;
                 req->req.generation = get_hpsb_generation();
@@ -749,14 +812,18 @@
                 return sizeof(struct raw1394_request);
         }
 
-        if (req->req.type == RAW1394_REQ_ISO_LISTEN) {
+        switch (req->req.type) {
+        case RAW1394_REQ_ISO_LISTEN:
                 handle_iso_listen(fi, req);
                 return sizeof(struct raw1394_request);
-        }
 
-        if (req->req.type == RAW1394_REQ_FCP_LISTEN) {
+        case RAW1394_REQ_FCP_LISTEN:
                 handle_fcp_listen(fi, req);
                 return sizeof(struct raw1394_request);
+
+        case RAW1394_REQ_RESET_BUS:
+                hpsb_reset_bus(fi->host);
+                return sizeof(struct raw1394_request);
         }
 
         if (req->req.length == 0) {
@@ -870,7 +937,7 @@
         struct pending_request *req;
         int done = 0, i;
 
-	lock_kernel();
+        lock_kernel();
         for (i = 0; i < 64; i++) {
                 if (fi->listen_channels & (1ULL << i)) {
                         hpsb_unlisten_channel(hl_handle, fi->host, i);
@@ -915,7 +982,7 @@
         kfree(fi);
 
         V22_COMPAT_MOD_DEC_USE_COUNT;
-	unlock_kernel();
+        unlock_kernel();
         return 0;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)