]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/can_queue.c
LinCAN driver major structured comments and documentation update
[lincan.git] / lincan / src / can_queue.c
index 83b083933ddf6be9652acaeefd5ffa20155fa524..62d8e19b49fa40e358684e006a4ce0f6e51fe97f 100644 (file)
@@ -105,6 +105,18 @@ int canque_fifo_done(struct canque_fifo_t *fifo)
  list_entry(ptr, type, member)
 */
 
+/**
+ * canque_get_inslot - finds one outgoing edge and allocates slot from it
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to  allocated slot
+ * @cmd: command type for slot
+ *
+ * Function looks for the first non-blocked outgoing edge in @qends structure
+ * and tries to allocate slot from it.
+ * Return Value: If there is no usable edge or there is no free slot in edge
+ *     negative value is returned.
+ */
 int canque_get_inslot(struct canque_ends_t *qends,
        struct canque_edge_t **qedgep, struct canque_slot_t **slotp, int cmd)
 {
@@ -136,6 +148,23 @@ int canque_get_inslot(struct canque_ends_t *qends,
        return ret;
 }
 
+/**
+ * canque_get_inslot4id - finds best outgoing edge and slot for given ID
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to  allocated slot
+ * @cmd: command type for slot
+ * @id: communication ID of message to send into edge
+ * @prio: optional priority of message
+ *
+ * Function looks for the non-blocked outgoing edge accepting messages
+ * with given ID. If edge is found, slot is allocated from that edge.
+ * The edges with non-zero mask are preferred over edges open to all messages.
+ * If more edges with mask accepts given message ID, the edge with
+ * highest priority below or equal to required priority is selected.
+ * Return Value: If there is no usable edge or there is no free slot in edge
+ *     negative value is returned.
+ */
 int canque_get_inslot4id(struct canque_ends_t *qends,
        struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
        int cmd, unsigned long id, int prio)
@@ -189,6 +218,17 @@ int canque_get_inslot4id(struct canque_ends_t *qends,
 }
 
 
+/**
+ * canque_put_inslot - schedules filled slot for processing
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: edge slot belong to
+ * @slot: pointer to the prepared slot
+ *
+ * Puts slot previously acquired by canque_get_inslot() or canque_get_inslot4id()
+ * function call into FIFO queue and activates edge processing if needed.
+ * Return Value: Positive value informs, that activation of output end
+ *     has been necessary
+ */
 int canque_put_inslot(struct canque_ends_t *qends,
        struct canque_edge_t *qedge, struct canque_slot_t *slot)
 {
@@ -207,6 +247,16 @@ int canque_put_inslot(struct canque_ends_t *qends,
        return ret;
 }
 
+/**
+ * canque_abort_inslot - aborts preparation of the message in the slot
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: edge slot belong to
+ * @slot: pointer to the previously allocated slot
+ *
+ * Frees slot previously acquired by canque_get_inslot() or canque_get_inslot4id()
+ * function call. Used when message copying into slot fails.
+ * Return Value: Positive value informs, that queue full state has been negated.
+ */
 int canque_abort_inslot(struct canque_ends_t *qends,
        struct canque_edge_t *qedge, struct canque_slot_t *slot)
 {
@@ -224,6 +274,15 @@ int canque_abort_inslot(struct canque_ends_t *qends,
        return ret;
 }
 
+/**
+ * canque_filter_msg2edges - sends message into all edges which accept its ID
+ * @qends: ends structure belonging to calling communication object
+ * @msg: pointer to CAN message
+ *
+ * Sends message to all outgoing edges connected to the given ends, which accepts
+ * message communication ID.
+ * Return Value: Returns number of edges message has been send to
+ */
 int canque_filter_msg2edges(struct canque_ends_t *qends, struct canmsg_t *msg)
 {
        int destnr=0;
@@ -264,6 +323,18 @@ int canque_filter_msg2edges(struct canque_ends_t *qends, struct canmsg_t *msg)
        return destnr;
 }
 
+/**
+ * canque_test_outslot - test and retrieve ready slot for given ends
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to received slot
+ *
+ * Function takes highest priority active incoming edge and retrieves
+ * oldest ready slot from it.
+ * Return Value: Negative value informs, that there is no ready output
+ *     slot for given ends. Positive value is equal to the command
+ *     slot has been allocated by the input side.
+ */
 int canque_test_outslot(struct canque_ends_t *qends,
        struct canque_edge_t **qedgep, struct canque_slot_t **slotp)
 {
@@ -288,6 +359,17 @@ int canque_test_outslot(struct canque_ends_t *qends,
        return -1;
 }
 
+/**
+ * canque_free_outslot - frees processed output slot
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: edge slot belong to
+ * @slot: pointer to the processed slot
+ *
+ * Function releases processed slot previously acquired by canque_test_outslot()
+ * function call.
+ * Return Value: Return value informs if input side has been notified
+ *     to know about change of edge state
+ */
 int canque_free_outslot(struct canque_ends_t *qends,
        struct canque_edge_t *qedge, struct canque_slot_t *slot)
 {
@@ -321,17 +403,22 @@ int canque_free_outslot(struct canque_ends_t *qends,
        return ret;
 }
 
+/**
+ * canque_again_outslot - reschedule output slot to process it again later
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: edge slot belong to
+ * @slot: pointer to the slot for re-processing
+ *
+ * Function reschedules slot previously acquired by canque_test_outslot()
+ * function call for second time processing.
+ * Return Value: Function cannot fail.
+ */
 int canque_again_outslot(struct canque_ends_t *qends,
        struct canque_edge_t *qedge, struct canque_slot_t *slot)
 {
        int ret;
        unsigned long flags;
        ret=canque_fifo_again_outslot(&qedge->fifo, slot);
-       if(ret&CAN_FIFOF_EMPTY){
-               canque_notify_inends(qedge,CANQUEUE_NOTIFY_EMPTY);
-       }
-       if(ret&CAN_FIFOF_FULL)
-               canque_notify_inends(qedge,CANQUEUE_NOTIFY_SPACE);
        spin_lock_irqsave(&qends->ends_lock, flags);
        if(atomic_dec_and_test(&qedge->edge_used))
                canque_notify_bothends(qedge,CANQUEUE_NOTIFY_NOUSR);
@@ -340,6 +427,14 @@ int canque_again_outslot(struct canque_ends_t *qends,
        return ret;
 }
 
+/**
+ * canque_set_filt - sets filter for specified edge
+ * @qedge: pointer to the edge
+ * @filtid: ID to set for the edge
+ * @filtmask: mask used for ID match check
+ *
+ * Return Value: Negative value is returned if edge is in the process of delete.
+ */
 int canque_set_filt(struct canque_edge_t *qedge,
        unsigned long filtid, unsigned long filtmask)
 {
@@ -367,6 +462,16 @@ int canque_set_filt(struct canque_edge_t *qedge,
        return ret;
 }
 
+/**
+ * canque_flush - fluesh all ready slots in the edge
+ * @qedge: pointer to the edge
+ *
+ * Tries to flush all allocated slots from the edge, but there could
+ * exist some slots associated to edge which are processed by input
+ * or output side and cannot be flushed at this moment.
+ * Return Value: The nonzero value indicates, that queue has not been
+ *     empty before the function call.
+ */
 int canque_flush(struct canque_edge_t *qedge)
 {
        int ret;
@@ -392,6 +497,12 @@ int canque_flush(struct canque_edge_t *qedge)
        return ret;
 }
 
+/**
+ * canqueue_ends_init_gen - subsystem independent routine to initialize ends state
+ * @qends: pointer to the ends structure
+ *
+ * Return Value: Cannot fail.
+ */
 int canqueue_ends_init_gen(struct canque_ends_t *qends)
 {
        int i;
@@ -405,6 +516,12 @@ int canqueue_ends_init_gen(struct canque_ends_t *qends)
 }
 
 
+/**
+ * canqueue_notify_kern - notification callback handler for Linux userspace clients
+ * @qends: pointer to the callback side ends structure
+ * @qedge: edge which invoked notification 
+ * @what: notification type
+ */
 void canqueue_notify_kern(struct canque_ends_t *qends, struct canque_edge_t *qedge, int what)
 {
        DEBUGQUE("canqueue_notify_kern for edge %d and event %d\n",qedge->edge_num,what);
@@ -433,6 +550,10 @@ void canqueue_notify_kern(struct canque_ends_t *qends, struct canque_edge_t *qed
        }
 }
 
+/**
+ * canqueue_ends_init_kern - Linux userspace clients specific ends initialization
+ * @qends: pointer to the callback side ends structure
+ */
 int canqueue_ends_init_kern(struct canque_ends_t *qends)
 {
        canqueue_ends_init_gen(qends);
@@ -446,6 +567,19 @@ int canqueue_ends_init_kern(struct canque_ends_t *qends)
 }
 
 
+/**
+ * canque_get_inslot4id_wait_kern - find or wait for best outgoing edge and slot for given ID
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to  allocated slot
+ * @cmd: command type for slot
+ * @id: communication ID of message to send into edge
+ * @prio: optional priority of message
+ *
+ * Same as canque_get_inslot4id(), except, that it waits for free slot
+ * in case, that queue is full. Function is specific for Linux userspace clients.
+ * Return Value: If there is no usable edge negative value is returned.
+ */
 int canque_get_inslot4id_wait_kern(struct canque_ends_t *qends,
        struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
        int cmd, unsigned long id, int prio)
@@ -457,6 +591,18 @@ int canque_get_inslot4id_wait_kern(struct canque_ends_t *qends,
        return ret;
 }
 
+/**
+ * canque_get_outslot_wait_kern - receive or wait for ready slot for given ends
+ * @qends: ends structure belonging to calling communication object
+ * @qedgep: place to store pointer to found edge
+ * @slotp: place to store pointer to received slot
+ *
+ * The same as canque_test_outslot(), except it waits in the case, that there is
+ * no ready slot for given ends. Function is specific for Linux userspace clients.
+ * Return Value: Negative value informs, that there is no ready output
+ *     slot for given ends. Positive value is equal to the command
+ *     slot has been allocated by the input side.
+ */
 int canque_get_outslot_wait_kern(struct canque_ends_t *qends,
        struct canque_edge_t **qedgep, struct canque_slot_t **slotp)
 {
@@ -467,16 +613,32 @@ int canque_get_outslot_wait_kern(struct canque_ends_t *qends,
        return ret;
 }
 
+/**
+ * canque_sync_wait_kern - wait for all slots processing
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: pointer to edge
+ *
+ * Functions waits for ends transition into empty state.
+ * Return Value: Positive value indicates, that edge empty state has been reached.
+ *     Negative or zero value informs about interrupted wait or other problem.
+ */
 int canque_sync_wait_kern(struct canque_ends_t *qends, struct canque_edge_t *qedge)
 {
        int ret=-1;
        DEBUGQUE("canque_sync_wait_kern\n");
        wait_event_interruptible((qends->endinfo.fileinfo.emptyq), 
-               (ret=canque_fifo_test_fl(&qedge->fifo,EMPTY)));
+               (ret=canque_fifo_test_fl(&qedge->fifo,EMPTY)?1:0));
        return ret;
 }
 
 
+/**
+ * canque_new_edge_kern - allocate new edge structure in the Linux kernel context
+ * @slotsnr: required number of slots in the newly allocated edge structure
+ *
+ * Return Value: Returns pointer to allocated slot structure or %NULL if
+ *     there is not enough memory to process operation.
+ */
 struct canque_edge_t *canque_new_edge_kern(int slotsnr)
 {
        struct canque_edge_t *qedge;
@@ -503,6 +665,14 @@ struct canque_edge_t *canque_new_edge_kern(int slotsnr)
        return qedge;
 }
 
+/**
+ * canqueue_connect_edge - connect edge between two communication entities
+ * @qedge: pointer to edge
+ * @inends: pointer to ends the input of the edge should be connected to
+ * @outends: pointer to ends the output of the edge should be connected to
+ *
+ * Return Value: Negative value informs about failed operation.
+ */
 int canqueue_connect_edge(struct canque_edge_t *qedge, struct canque_ends_t *inends, struct canque_ends_t *outends)
 {
        unsigned long flags;
@@ -528,6 +698,13 @@ int canqueue_connect_edge(struct canque_edge_t *qedge, struct canque_ends_t *ine
        return 0;
 }
 
+/**
+ * canqueue_disconnect_edge - disconnect edge from communicating entities
+ * @qedge: pointer to edge
+ *
+ * Return Value: Negative value means, that edge is used and cannot
+ *     be disconnected. Operation has to be delayed.
+ */
 int canqueue_disconnect_edge(struct canque_edge_t *qedge)
 {
        int ret;
@@ -557,6 +734,16 @@ int canqueue_disconnect_edge(struct canque_edge_t *qedge)
        return ret;
 }
 
+/**
+ * canqueue_disconnect_edge_kern - disconnect edge from communicating entities with wait
+ * @qends: ends structure belonging to calling communication object
+ * @qedge: pointer to edge
+ *
+ * Same as canqueue_disconnect_edge(), but tries to wait for state with zero
+ * use counter.
+ * Return Value: Negative value means, that edge is used and cannot
+ *     be disconnected yet. Operation has to be delayed.
+ */
 int canqueue_disconnect_edge_kern(struct canque_ends_t *qends, struct canque_edge_t *qedge)
 {
        canque_fifo_set_fl(&qedge->fifo,BLOCK);
@@ -620,6 +807,14 @@ void canqueue_block_list(struct canque_ends_t *qends, struct list_head *list)
 }
 
 
+/**
+ * canqueue_ends_done_kern - finalizing of the ends structure for Linux kernel clients
+ * @qends: pointer to ends structure
+ * @sync: flag indicating, that user wants to wait for processing of all remaining
+ *     messages
+ *
+ * Return Value: Function should be designed such way to not fail.
+ */
 int canqueue_ends_done_kern(struct canque_ends_t *qends, int sync)
 {
        unsigned long flags;