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;
 };

