emac: Fix clock control for 405EX and 405EXr chips
[safe/jmp/linux-2.6] / drivers / ieee1394 / iso.c
index 615541b..1cf6487 100644 (file)
@@ -9,10 +9,17 @@
  * directory of the kernel sources for details.
  */
 
-#include <linux/slab.h>
+#include <linux/pci.h>
 #include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include "hosts.h"
 #include "iso.h"
 
+/**
+ * hpsb_iso_stop - stop DMA
+ */
 void hpsb_iso_stop(struct hpsb_iso *iso)
 {
        if (!(iso->flags & HPSB_ISO_DRIVER_STARTED))
@@ -23,6 +30,9 @@ void hpsb_iso_stop(struct hpsb_iso *iso)
        iso->flags &= ~HPSB_ISO_DRIVER_STARTED;
 }
 
+/**
+ * hpsb_iso_shutdown - deallocate buffer and DMA context
+ */
 void hpsb_iso_shutdown(struct hpsb_iso *iso)
 {
        if (iso->flags & HPSB_ISO_DRIVER_INIT) {
@@ -36,20 +46,22 @@ void hpsb_iso_shutdown(struct hpsb_iso *iso)
        kfree(iso);
 }
 
-static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_iso_type type,
+static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host,
+                                            enum hpsb_iso_type type,
                                             unsigned int data_buf_size,
                                             unsigned int buf_packets,
-                                            int channel,
-                                            int dma_mode,
+                                            int channel, int dma_mode,
                                             int irq_interval,
-                                            void (*callback)(struct hpsb_iso*))
+                                            void (*callback) (struct hpsb_iso
+                                                              *))
 {
        struct hpsb_iso *iso;
        int dma_direction;
 
        /* make sure driver supports the ISO API */
        if (!host->driver->isoctl) {
-               printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n",
+               printk(KERN_INFO
+                      "ieee1394: host driver '%s' does not support the rawiso API\n",
                       host->driver->name);
                return NULL;
        }
@@ -59,12 +71,13 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
        if (buf_packets < 2)
                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 ((dma_mode < HPSB_ISO_DMA_DEFAULT)
+           || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
+               dma_mode = HPSB_ISO_DMA_DEFAULT;
 
        if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
-               irq_interval = buf_packets / 4;
-       if (irq_interval == 0)     /* really interrupt for each packet*/
+               irq_interval = buf_packets / 4;
+       if (irq_interval == 0)  /* really interrupt for each packet */
                irq_interval = 1;
 
        if (channel < -1 || channel >= 64)
@@ -76,7 +89,10 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
 
        /* allocate and write the struct hpsb_iso */
 
-       iso = kmalloc(sizeof(*iso) + buf_packets * sizeof(struct hpsb_iso_packet_info), GFP_KERNEL);
+       iso =
+           kmalloc(sizeof(*iso) +
+                   buf_packets * sizeof(struct hpsb_iso_packet_info),
+                   GFP_KERNEL);
        if (!iso)
                return NULL;
 
@@ -111,17 +127,21 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
        iso->prebuffer = 0;
 
        /* allocate the packet buffer */
-       if (dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
+       if (dma_region_alloc
+           (&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
                goto err;
 
        return iso;
 
-err:
+      err:
        hpsb_iso_shutdown(iso);
        return NULL;
 }
 
-int hpsb_iso_n_ready(struct hpsb_iso* iso)
+/**
+ * hpsb_iso_n_ready - returns number of packets ready to send or receive
+ */
+int hpsb_iso_n_ready(struct hpsb_iso *iso)
 {
        unsigned long flags;
        int val;
@@ -133,18 +153,22 @@ int hpsb_iso_n_ready(struct hpsb_iso* iso)
        return val;
 }
 
-
-struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
+/**
+ * hpsb_iso_xmit_init - allocate the buffer and DMA context
+ */
+struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host,
                                    unsigned int data_buf_size,
                                    unsigned int buf_packets,
                                    int channel,
                                    int speed,
                                    int irq_interval,
-                                   void (*callback)(struct hpsb_iso*))
+                                   void (*callback) (struct hpsb_iso *))
 {
        struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT,
                                                    data_buf_size, buf_packets,
-                                                   channel, HPSB_ISO_DMA_DEFAULT, irq_interval, callback);
+                                                   channel,
+                                                   HPSB_ISO_DMA_DEFAULT,
+                                                   irq_interval, callback);
        if (!iso)
                return NULL;
 
@@ -157,22 +181,28 @@ struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
        iso->flags |= HPSB_ISO_DRIVER_INIT;
        return iso;
 
-err:
+      err:
        hpsb_iso_shutdown(iso);
        return NULL;
 }
 
-struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
+/**
+ * hpsb_iso_recv_init - allocate the buffer and DMA context
+ *
+ * Note, if channel = -1, multi-channel receive is enabled.
+ */
+struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host,
                                    unsigned int data_buf_size,
                                    unsigned int buf_packets,
                                    int channel,
                                    int dma_mode,
                                    int irq_interval,
-                                   void (*callback)(struct hpsb_iso*))
+                                   void (*callback) (struct hpsb_iso *))
 {
        struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV,
                                                    data_buf_size, buf_packets,
-                                                   channel, dma_mode, irq_interval, callback);
+                                                   channel, dma_mode,
+                                                   irq_interval, callback);
        if (!iso)
                return NULL;
 
@@ -183,11 +213,16 @@ struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
        iso->flags |= HPSB_ISO_DRIVER_INIT;
        return iso;
 
-err:
+      err:
        hpsb_iso_shutdown(iso);
        return NULL;
 }
 
+/**
+ * hpsb_iso_recv_listen_channel
+ *
+ * multi-channel only
+ */
 int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel)
 {
        if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
@@ -195,20 +230,37 @@ int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel)
        return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel);
 }
 
+/**
+ * hpsb_iso_recv_unlisten_channel
+ *
+ * multi-channel only
+ */
 int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel)
 {
-       if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
-               return -EINVAL;
-       return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
+       if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
+               return -EINVAL;
+       return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
 }
 
+/**
+ * hpsb_iso_recv_set_channel_mask
+ *
+ * multi-channel only
+ */
 int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
 {
        if (iso->type != HPSB_ISO_RECV || iso->channel != -1)
                return -EINVAL;
-       return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask);
+       return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK,
+                                        (unsigned long)&mask);
 }
 
+/**
+ * hpsb_iso_recv_flush - check for arrival of new packets
+ *
+ * check for arrival of new packets immediately (even if irq_interval
+ * has not yet been reached)
+ */
 int hpsb_iso_recv_flush(struct hpsb_iso *iso)
 {
        if (iso->type != HPSB_ISO_RECV)
@@ -226,6 +278,9 @@ static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle)
        return retval;
 }
 
+/**
+ * hpsb_iso_xmit_start - start DMA
+ */
 int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
 {
        if (iso->type != HPSB_ISO_XMIT)
@@ -258,6 +313,9 @@ int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
        return 0;
 }
 
+/**
+ * hpsb_iso_recv_start - start DMA
+ */
 int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
 {
        int retval = 0;
@@ -283,7 +341,9 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
 
        isoctl_args[2] = sync;
 
-       retval = iso->host->driver->isoctl(iso, RECV_START, (unsigned long) &isoctl_args[0]);
+       retval =
+           iso->host->driver->isoctl(iso, RECV_START,
+                                     (unsigned long)&isoctl_args[0]);
        if (retval)
                return retval;
 
@@ -292,11 +352,11 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
 }
 
 /* check to make sure the user has not supplied bogus values of offset/len
-   that would cause the kernel to access memory outside the buffer */
-
+ * that would cause the kernel to access memory outside the buffer */
 static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
                                     unsigned int offset, unsigned short len,
-                                    unsigned int *out_offset, unsigned short *out_len)
+                                    unsigned int *out_offset,
+                                    unsigned short *out_len)
 {
        if (offset >= iso->buf_size)
                return -EFAULT;
@@ -316,8 +376,14 @@ static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
        return 0;
 }
 
-
-int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy)
+/**
+ * hpsb_iso_xmit_queue_packet - queue a packet for transmission.
+ *
+ * @offset is relative to the beginning of the DMA buffer, where the packet's
+ * data payload should already have been placed.
+ */
+int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
+                              u8 tag, u8 sy)
 {
        struct hpsb_iso_packet_info *info;
        unsigned long flags;
@@ -334,7 +400,8 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag
        info = &iso->infos[iso->first_packet];
 
        /* check for bogus offset/length */
-       if (hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len))
+       if (hpsb_iso_check_offset_len
+           (iso, offset, len, &info->offset, &info->len))
                return -EFAULT;
 
        info->tag = tag;
@@ -342,13 +409,13 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag
 
        spin_lock_irqsave(&iso->lock, flags);
 
-       rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long) info);
+       rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long)info);
        if (rv)
                goto out;
 
        /* increment cursors */
-       iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
-       iso->xmit_cycle = (iso->xmit_cycle+1) % 8000;
+       iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
+       iso->xmit_cycle = (iso->xmit_cycle + 1) % 8000;
        iso->n_ready_packets--;
 
        if (iso->prebuffer != 0) {
@@ -359,19 +426,33 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag
                }
        }
 
-out:
+      out:
        spin_unlock_irqrestore(&iso->lock, flags);
        return rv;
 }
 
+/**
+ * hpsb_iso_xmit_sync - wait until all queued packets have been transmitted
+ */
 int hpsb_iso_xmit_sync(struct hpsb_iso *iso)
 {
        if (iso->type != HPSB_ISO_XMIT)
                return -EINVAL;
 
-       return wait_event_interruptible(iso->waitq, hpsb_iso_n_ready(iso) == iso->buf_packets);
+       return wait_event_interruptible(iso->waitq,
+                                       hpsb_iso_n_ready(iso) ==
+                                       iso->buf_packets);
 }
 
+/**
+ * hpsb_iso_packet_sent
+ *
+ * Available to low-level drivers.
+ *
+ * Call after a packet has been transmitted to the bus (interrupt context is
+ * OK).  @cycle is the _exact_ cycle the packet was sent on.  @error should be
+ * non-zero if some sort of error occurred when sending the packet.
+ */
 void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
 {
        unsigned long flags;
@@ -395,8 +476,16 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
        spin_unlock_irqrestore(&iso->lock, flags);
 }
 
+/**
+ * hpsb_iso_packet_received
+ *
+ * Available to low-level drivers.
+ *
+ * Call after a packet has been received (interrupt context is OK).
+ */
 void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
-                             u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy)
+                             u16 total_len, u16 cycle, u8 channel, u8 tag,
+                             u8 sy)
 {
        unsigned long flags;
        spin_lock_irqsave(&iso->lock, flags);
@@ -416,13 +505,18 @@ void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
                info->tag = tag;
                info->sy = sy;
 
-               iso->pkt_dma = (iso->pkt_dma+1) % iso->buf_packets;
+               iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets;
                iso->n_ready_packets++;
        }
 
        spin_unlock_irqrestore(&iso->lock, flags);
 }
 
+/**
+ * hpsb_iso_recv_release_packets - release packets, reuse buffer
+ *
+ * @n_packets have been read out of the buffer, re-use the buffer space
+ */
 int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
 {
        unsigned long flags;
@@ -435,20 +529,21 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
        spin_lock_irqsave(&iso->lock, flags);
        for (i = 0; i < n_packets; i++) {
                rv = iso->host->driver->isoctl(iso, RECV_RELEASE,
-                                              (unsigned long) &iso->infos[iso->first_packet]);
+                                              (unsigned long)&iso->infos[iso->
+                                                                         first_packet]);
                if (rv)
                        break;
 
-               iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
+               iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
                iso->n_ready_packets--;
 
                /* release memory from packets discarded when queue was full  */
-               if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */
+               if (iso->n_ready_packets == 0) {        /* Release only after all prior packets handled */
                        if (iso->bytes_discarded != 0) {
                                struct hpsb_iso_packet_info inf;
                                inf.total_len = iso->bytes_discarded;
                                iso->host->driver->isoctl(iso, RECV_RELEASE,
-                                                       (unsigned long) &inf);
+                                                         (unsigned long)&inf);
                                iso->bytes_discarded = 0;
                        }
                }
@@ -457,6 +552,13 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
        return rv;
 }
 
+/**
+ * hpsb_iso_wake
+ *
+ * Available to low-level drivers.
+ *
+ * Call to wake waiting processes after buffer space has opened up.
+ */
 void hpsb_iso_wake(struct hpsb_iso *iso)
 {
        wake_up_interruptible(&iso->waitq);