[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux1394-user
Subject:    arm_get/set_buf() and iso dma modes for 2.4 branch
From:       "Alexander Neundorf" <a.neundorf-work () gmx ! net>
Date:       2003-12-11 10:25:13
[Download RAW message or body]

This is a MIME encapsulated multipart message -
please use a MIME-compliant e-mail program to open it.

Dies ist eine mehrteilige Nachricht im MIME-Format -
bitte verwenden Sie zum Lesen ein MIME-konformes Mailprogramm.


Hi,  
  
attached is a patch against the current 2.4 branch which adds the
raw1394_arm_get/set_buf() functions and 
the ability to select BUFFER_FILL and PACKET_PER_BUFFER mode for receiving
iso data for the 2.4 
version.  IOW it makes the 2.4 branch "feature-compatible" to the main
branch.  
  
I guess due to the feature freeze it won't be applied, but the people who
would like to use the new  
functionality now can use this patch.  
I will put it on my webseite under
http://www.neundorf.net/?page=linux1394.html in the next days and try to  
keep it uptodate.  
  
Bye  
Alex  
  

-- 
+++ GMX - die erste Adresse für Mail, Message, More +++
Neu: Preissenkung für MMS und FreeMMS! http://www.gmx.net

["ieee1394-linux-2.4.patch.c" (text/x-csrc)]

diff -bup ieee1394/eth1394.c ieee1394.patched/eth1394.c
--- ieee1394/eth1394.c	Thu Aug 28 22:29:33 2003
+++ ieee1394.patched/eth1394.c	Thu Dec 11 11:06:18 2003
@@ -220,7 +220,7 @@ static int ether1394_init_bc(struct net_
 
 			priv->iso = hpsb_iso_recv_init(priv->host, 16 * 4096,
 						       16, priv->broadcast_channel,
-						       1, ether1394_iso);
+						       HPSB_ISO_DMA_PACKET_PER_BUFFER, 1, ether1394_iso);
 			if (priv->iso == NULL) {
 				ETH1394_PRINT(KERN_ERR, dev->name,
 					      "failed to change broadcast "
@@ -475,7 +475,7 @@ static void ether1394_add_host (struct h
 	priv->broadcast_channel = host->csr.broadcast_channel & 0x3f;
 
 	priv->iso = hpsb_iso_recv_init(host, 16 * 4096, 16, priv->broadcast_channel,
-				       1, ether1394_iso);
+				 HPSB_ISO_DMA_PACKET_PER_BUFFER, 1, ether1394_iso);
 	if (priv->iso == NULL) {
 		priv->bc_state = ETHER1394_BC_CLOSED;
 	}
diff -bup ieee1394/iso.c ieee1394.patched/iso.c
--- ieee1394/iso.c	Tue Jul  8 23:30:31 2003
+++ ieee1394.patched/iso.c	Thu Dec 11 11:02:18 2003
@@ -40,6 +40,7 @@ static struct hpsb_iso* hpsb_iso_common_
 					     unsigned int data_buf_size,
 					     unsigned int buf_packets,
 					     int channel,
+					     int dma_mode,
 					     int irq_interval,
 					     void (*callback)(struct hpsb_iso*))
 {
@@ -58,8 +59,13 @@ static struct hpsb_iso* hpsb_iso_common_
 	if (buf_packets < 2)
 		buf_packets = 2;
 
-	if (irq_interval < 1 || irq_interval > buf_packets / 2)
-		irq_interval = buf_packets / 2;
+	if ((dma_mode < HPSB_ISO_DMA_DEFAULT) || (dma_mode > \
HPSB_ISO_DMA_PACKET_PER_BUFFER)) +		dma_mode=HPSB_ISO_DMA_DEFAULT;
+		
+	if (irq_interval == 0)     /* really interrupt for each packet*/
+		irq_interval = 1;
+	else if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
+		irq_interval = buf_packets / 4;
 
 	if (channel < -1 || channel >= 64)
 		return NULL;
@@ -83,6 +89,7 @@ static struct hpsb_iso* hpsb_iso_common_
 	init_waitqueue_head(&iso->waitq);
 	iso->channel = channel;
 	iso->irq_interval = irq_interval;
+	iso->dma_mode = dma_mode;
 	dma_region_init(&iso->data_buf);
 	iso->buf_size = round_up_to_page(data_buf_size);
 	iso->buf_packets = buf_packets;
@@ -136,7 +143,7 @@ struct hpsb_iso* hpsb_iso_xmit_init(stru
 {
 	struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT,
 						    data_buf_size, buf_packets,
-						    channel, irq_interval, callback);
+						channel, HPSB_ISO_DMA_DEFAULT, irq_interval, callback);
 	if (!iso)
 		return NULL;
 
@@ -158,12 +165,13 @@ struct hpsb_iso* hpsb_iso_recv_init(stru
 				    unsigned int data_buf_size,
 				    unsigned int buf_packets,
 				    int channel,
+				    int dma_mode,
 				    int irq_interval,
 				    void (*callback)(struct hpsb_iso*))
 {
 	struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV,
 						    data_buf_size, buf_packets,
-						    channel, irq_interval, callback);
+					channel, dma_mode, irq_interval, callback);
 	if (!iso)
 		return NULL;
 
diff -bup ieee1394/iso.h ieee1394.patched/iso.h
--- ieee1394/iso.h	Tue Jul  8 23:30:31 2003
+++ ieee1394.patched/iso.h	Thu Dec 11 10:56:42 2003
@@ -51,6 +51,14 @@ struct hpsb_iso_packet_info {
 
 enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 };
 
+/* The mode of the dma when receiving iso data. Must be supported by chip */
+enum raw1394_iso_dma_recv_mode {
+	HPSB_ISO_DMA_DEFAULT = -1,
+	HPSB_ISO_DMA_OLD_ABI = 0,
+	HPSB_ISO_DMA_BUFFERFILL = 1,
+	HPSB_ISO_DMA_PACKET_PER_BUFFER = 2
+};
+
 struct hpsb_iso {
 	enum hpsb_iso_type type;
 
@@ -68,6 +76,7 @@ struct hpsb_iso {
 
 	int speed; /* IEEE1394_SPEED_100, 200, or 400 */
 	int channel; /* -1 if multichannel */
+	int dma_mode; /* dma receive mode */
 
 	/* greatest # of packets between interrupts - controls
 	   the maximum latency of the buffer */
@@ -139,6 +148,7 @@ struct hpsb_iso* hpsb_iso_recv_init(stru
 				    unsigned int data_buf_size,
 				    unsigned int buf_packets,
 				    int channel,
+				    int dma_mode,
 				    int irq_interval,
 				    void (*callback)(struct hpsb_iso*));
 
diff -bup ieee1394/ohci1394.c ieee1394.patched/ohci1394.c
--- ieee1394/ohci1394.c	Fri Aug 29 18:47:05 2003
+++ ieee1394.patched/ohci1394.c	Thu Dec 11 10:51:36 2003
@@ -1126,8 +1126,8 @@ struct ohci_iso_recv {
 	struct ohci1394_iso_tasklet task;
 	int task_active;
 
-	enum { BUFFER_FILL_MODE,
-	       PACKET_PER_BUFFER_MODE } dma_mode;
+	enum { BUFFER_FILL_MODE=0,
+	       PACKET_PER_BUFFER_MODE=1 } dma_mode;
 
 	/* memory and PCI mapping for the DMA descriptors */
 	struct dma_prog_region prog;
@@ -1188,7 +1188,8 @@ static int ohci_iso_recv_init(struct hps
 	/* use buffer-fill mode, unless irq_interval is 1
 	   (note: multichannel requires buffer-fill) */
 
-	if (iso->irq_interval == 1 && iso->channel != -1) {
+	if (((iso->irq_interval == 1 && iso->dma_mode == HPSB_ISO_DMA_OLD_ABI) ||
+	   iso->dma_mode == HPSB_ISO_DMA_PACKET_PER_BUFFER) && iso->channel != -1) {
 		recv->dma_mode = PACKET_PER_BUFFER_MODE;
 	} else {
 		recv->dma_mode = BUFFER_FILL_MODE;
@@ -1207,8 +1208,11 @@ static int ohci_iso_recv_init(struct hps
 		}
 
 		/* iso->irq_interval is in packets - translate that to blocks */
-		/* (err, sort of... 1 is always the safest value) */
-		recv->block_irq_interval = iso->irq_interval / recv->nblocks;
+		if (iso->irq_interval == 1)
+			recv->block_irq_interval = 1;
+		else
+			recv->block_irq_interval = iso->irq_interval *
+						((recv->nblocks+1)/iso->buf_packets);
 		if (recv->block_irq_interval*4 > recv->nblocks)
 			recv->block_irq_interval = recv->nblocks/4;
 		if (recv->block_irq_interval < 1)
@@ -1218,6 +1222,10 @@ static int ohci_iso_recv_init(struct hps
 		int max_packet_size;
 
 		recv->nblocks = iso->buf_packets;
+		recv->block_irq_interval = iso->irq_interval;
+		if (recv->block_irq_interval * 4 > iso->buf_packets)
+			recv->block_irq_interval = iso->buf_packets / 4;
+		if (recv->block_irq_interval < 1)
 		recv->block_irq_interval = 1;
 
 		/* choose a buffer stride */
diff -bup ieee1394/raw1394.c ieee1394.patched/raw1394.c
--- ieee1394/raw1394.c	Fri Sep 12 11:57:59 2003
+++ ieee1394.patched/raw1394.c	Thu Dec 11 09:29:22 2003
@@ -1798,6 +1798,92 @@ static int arm_unregister(struct file_in
         free_pending_request(req); /* immediate success or fail */
         return sizeof(struct raw1394_request);
 }
+ /* Copy data from ARM buffer(s) to user buffer. */
+
+static int arm_get_buf(struct file_info *fi, struct pending_request *req)
+{
+	struct arm_addr  *arm_addr = NULL;
+	unsigned long flags;
+	unsigned long offset;
+	struct list_head *entry;
+	DBGMSG("arm_get_buf "
+		"addr(Offset): %04X %08X length: %u",
+		(u32) ((req->req.address >> 32) & 0xFFFF),
+		(u32) (req->req.address & 0xFFFFFFFF),
+		(u32) req->req.length);
+	spin_lock_irqsave(&host_info_lock, flags);
+	entry = fi->addr_list.next;
+	while (entry != &(fi->addr_list)) {
+		arm_addr = list_entry(entry, struct arm_addr, addr_list);
+		if ((arm_addr->start <= req->req.address) &&
+		   (arm_addr->end > req->req.address)) {
+			if (req->req.address + req->req.length <= arm_addr->end) {
+				offset = req->req.address - arm_addr->start;
+				DBGMSG("arm_get_buf copy_to_user( %08X, %08X, %u )",
+				(u32) req->req.recvb,
+				(u32) (arm_addr->addr_space_buffer+offset),
+				(u32) req->req.length);
+				if (copy_to_user(int2ptr(req->req.recvb), arm_addr->addr_space_buffer+offset, \
req->req.length)) { +					spin_unlock_irqrestore(&host_info_lock, flags);
+					return (-EFAULT);
+				}
+				spin_unlock_irqrestore(&host_info_lock, flags);
+				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); +			} else {
+				DBGMSG("arm_get_buf request exceeded mapping");
+				spin_unlock_irqrestore(&host_info_lock, flags);
+				return (-EINVAL);
+			}
+		}
+		entry = entry->next;
+	}
+	spin_unlock_irqrestore(&host_info_lock, flags);
+	return (-EINVAL);
+ }
+ 
+/* Copy data from user buffer to ARM buffer(s). */
+static int arm_set_buf(struct file_info *fi, struct pending_request *req)
+{
+	struct arm_addr  *arm_addr = NULL;
+	unsigned long flags;
+	unsigned long offset;
+	struct list_head *entry;
+	DBGMSG("arm_set_buf "
+		"addr(Offset): %04X %08X length: %u",
+		(u32) ((req->req.address >> 32) & 0xFFFF),
+		(u32) (req->req.address & 0xFFFFFFFF),
+		(u32) req->req.length);
+	spin_lock_irqsave(&host_info_lock, flags);
+	entry = fi->addr_list.next;
+	while (entry != &(fi->addr_list)) {
+		arm_addr = list_entry(entry, struct arm_addr, addr_list);
+		if ((arm_addr->start <= req->req.address) &&
+		   (arm_addr->end > req->req.address)) {
+			if (req->req.address + req->req.length <= arm_addr->end) {
+				offset = req->req.address - arm_addr->start;
+				DBGMSG("arm_set_buf copy_from_user( %08X, %08X, %u )",
+					(u32) (arm_addr->addr_space_buffer+offset),
+					(u32) req->req.sendb,
+					(u32) req->req.length);
+				if (copy_from_user(arm_addr->addr_space_buffer+offset, int2ptr(req->req.sendb), \
req->req.length)) { +					spin_unlock_irqrestore(&host_info_lock, flags);
+					return (-EFAULT);
+				}
+				spin_unlock_irqrestore(&host_info_lock, flags);
+				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); +			} else {
+				DBGMSG("arm_set_buf request exceeded mapping");
+				spin_unlock_irqrestore(&host_info_lock, flags);
+				return (-EINVAL);
+			}
+		}
+		entry = entry->next;
+	}
+	spin_unlock_irqrestore(&host_info_lock, flags);
+	return (-EINVAL);
+}
 
 static int reset_notification(struct file_info *fi, struct pending_request *req)
 {
@@ -1914,6 +2000,12 @@ static int state_connected(struct file_i
         case RAW1394_REQ_ARM_UNREGISTER:
                 return arm_unregister(fi, req);
 
+	case RAW1394_REQ_ARM_SET_BUF:
+		return arm_set_buf(fi, req);
+		
+	case RAW1394_REQ_ARM_GET_BUF:
+		return arm_get_buf(fi, req);
+		
         case RAW1394_REQ_RESET_NOTIFY:
                 return reset_notification(fi, req);
 
@@ -2139,6 +2231,7 @@ static int raw1394_iso_recv_init(struct 
 					    stat.config.data_buf_size,
 					    stat.config.buf_packets,
 					    stat.config.channel,
+					    stat.config.dma_mode,
 					    stat.config.irq_interval,
 					    rawiso_activity_cb);
 	if (!fi->iso_handle)
diff -bup ieee1394/raw1394.h ieee1394.patched/raw1394.h
--- ieee1394/raw1394.h	Fri Aug 29 19:01:04 2003
+++ ieee1394.patched/raw1394.h	Thu Dec 11 08:47:41 2003
@@ -30,6 +30,8 @@
 
 #define RAW1394_REQ_ARM_REGISTER    300
 #define RAW1394_REQ_ARM_UNREGISTER  301
+#define RAW1394_REQ_ARM_SET_BUF     302
+#define RAW1394_REQ_ARM_GET_BUF     303
 
 #define RAW1394_REQ_RESET_NOTIFY    400
 
@@ -148,7 +150,8 @@ struct raw1394_iso_config {
 
 	/* xmit only - iso transmission speed */
 	__u8 speed;
-
+         /* The mode of the dma when receiving iso data. Must be supported by chip \
*/ +         __u8 dma_mode;
 	/* max. latency of buffer, in packets (-1 if you don't care) */
 	__s32 irq_interval;
 };


-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills.  Sign up for IBM's
Free Linux Tutorials.  Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click
_______________________________________________
mailing list Linux1394-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux1394-user

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic