Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 25 Apr 2008 19:24:06 +0000 (12:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 25 Apr 2008 19:24:06 +0000 (12:24 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  ieee1394: silence defined but not used warning in non-modular builds
  ieee1394: rawiso: requeue packet for transmission after skipped cycle

drivers/ieee1394/dv1394.c
drivers/ieee1394/iso.h
drivers/ieee1394/ohci1394.c
drivers/ieee1394/raw1394.c
drivers/ieee1394/video1394.c

index 6228fadacd388d7ffd014548796dec4263cfe454..9d19aec5820a303145d8b286e2d1ce2e72b4a586 100644 (file)
@@ -2167,6 +2167,7 @@ static const struct file_operations dv1394_fops=
 /*
  * Export information about protocols/devices supported by this driver.
  */
+#ifdef MODULE
 static struct ieee1394_device_id dv1394_id_table[] = {
        {
                .match_flags    = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
@@ -2177,6 +2178,7 @@ static struct ieee1394_device_id dv1394_id_table[] = {
 };
 
 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
+#endif /* MODULE */
 
 static struct hpsb_protocol_driver dv1394_driver = {
        .name = "dv1394",
index b94e55e6eaa59034c9c5825fc656f2de3a7fe54e..b5de5f21ef78a57e45032500867fdb24538de00e 100644 (file)
@@ -123,6 +123,8 @@ struct hpsb_iso {
 
        /* how many times the buffer has overflowed or underflowed */
        atomic_t overflows;
+       /* how many cycles were skipped for a given context */
+       atomic_t skips;
 
        /* Current number of bytes lost in discarded packets */
        int bytes_discarded;
index 0690469fcecf9acfdb53ce4140c5ba4e5c99dd9a..e509e13cb7a7cdb4c2d154835dea19857082f418 100644 (file)
@@ -1723,6 +1723,8 @@ struct ohci_iso_xmit {
        struct dma_prog_region prog;
        struct ohci1394_iso_tasklet task;
        int task_active;
+       int last_cycle;
+       atomic_t skips;
 
        u32 ContextControlSet;
        u32 ContextControlClear;
@@ -1759,6 +1761,8 @@ static int ohci_iso_xmit_init(struct hpsb_iso *iso)
        iso->hostdata = xmit;
        xmit->ohci = iso->host->hostdata;
        xmit->task_active = 0;
+       xmit->last_cycle = -1;
+       atomic_set(&iso->skips, 0);
 
        dma_prog_region_init(&xmit->prog);
 
@@ -1856,6 +1860,26 @@ static void ohci_iso_xmit_task(unsigned long data)
                /* parse cycle */
                cycle = le32_to_cpu(cmd->output_last.status) & 0x1FFF;
 
+               if (xmit->last_cycle > -1) {
+                       int cycle_diff = cycle - xmit->last_cycle;
+                       int skip;
+
+                       /* unwrap */
+                       if (cycle_diff < 0) {
+                               cycle_diff += 8000;
+                               if (cycle_diff < 0)
+                                       PRINT(KERN_ERR, "bogus cycle diff %d\n",
+                                             cycle_diff);
+                       }
+
+                       skip = cycle_diff - 1;
+                       if (skip > 0) {
+                               DBGMSG("skipped %d cycles without packet loss", skip);
+                               atomic_add(skip, &iso->skips);
+                       }
+               }
+               xmit->last_cycle = cycle;
+
                /* tell the subsystem the packet has gone out */
                hpsb_iso_packet_sent(iso, cycle, event != 0x11);
 
@@ -1943,6 +1967,16 @@ static int ohci_iso_xmit_queue(struct hpsb_iso *iso, struct hpsb_iso_packet_info
        prev->output_last.branchAddress = cpu_to_le32(
                dma_prog_region_offset_to_bus(&xmit->prog, sizeof(struct iso_xmit_cmd) * next_i) | 3);
 
+       /*
+        * Link the skip address to this descriptor itself. This causes a
+        * context to skip a cycle whenever lost cycles or FIFO overruns occur,
+        * without dropping the data at that point the application should then
+        * decide whether this is an error condition or not. Some protocols
+        * can deal with this by dropping some rate-matching padding packets.
+        */
+       next->output_more_immediate.branchAddress =
+                       prev->output_last.branchAddress;
+
        /* disable interrupt, unless required by the IRQ interval */
        if (prev_i % iso->irq_interval) {
                prev->output_last.control &= cpu_to_le32(~(3 << 20)); /* no interrupt */
index 04e96ba56e090af3cd4ff6ab44e5b1fb147d2fd1..ec2a0adbedb248f2a493b2ca716fc8d7971c98ed 100644 (file)
@@ -2356,13 +2356,16 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
 static void raw1394_iso_fill_status(struct hpsb_iso *iso,
                                    struct raw1394_iso_status *stat)
 {
+       int overflows = atomic_read(&iso->overflows);
+       int skips = atomic_read(&iso->skips);
+
        stat->config.data_buf_size = iso->buf_size;
        stat->config.buf_packets = iso->buf_packets;
        stat->config.channel = iso->channel;
        stat->config.speed = iso->speed;
        stat->config.irq_interval = iso->irq_interval;
        stat->n_packets = hpsb_iso_n_ready(iso);
-       stat->overflows = atomic_read(&iso->overflows);
+       stat->overflows = ((skips & 0xFFFF) << 16) | ((overflows & 0xFFFF));
        stat->xmit_cycle = iso->xmit_cycle;
 }
 
@@ -2437,6 +2440,8 @@ static int raw1394_iso_get_status(struct file_info *fi, void __user * uaddr)
 
        /* reset overflow counter */
        atomic_set(&iso->overflows, 0);
+       /* reset skip counter */
+       atomic_set(&iso->skips, 0);
 
        return 0;
 }
@@ -2935,6 +2940,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
 /*
  * Export information about protocols/devices supported by this driver.
  */
+#ifdef MODULE
 static struct ieee1394_device_id raw1394_id_table[] = {
        {
         .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
@@ -2956,6 +2962,7 @@ static struct ieee1394_device_id raw1394_id_table[] = {
 };
 
 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
+#endif /* MODULE */
 
 static struct hpsb_protocol_driver raw1394_driver = {
        .name = "raw1394",
index e03024eeeac135fac1da8b5422b7b84e3a4d16d3..e24772d336e1ae6c726d8e0a05ae5ea25a9207e0 100644 (file)
@@ -1293,6 +1293,7 @@ static const struct file_operations video1394_fops=
 /*
  * Export information about protocols/devices supported by this driver.
  */
+#ifdef MODULE
 static struct ieee1394_device_id video1394_id_table[] = {
        {
                .match_flags    = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
@@ -1313,6 +1314,7 @@ static struct ieee1394_device_id video1394_id_table[] = {
 };
 
 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
+#endif /* MODULE */
 
 static struct hpsb_protocol_driver video1394_driver = {
        .name = VIDEO1394_DRIVER_NAME,