All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] SCSI/libsrp: document the libsrp source code
@ 2009-12-15 20:33 Bart Van Assche
  2009-12-15 22:34 ` Randy Dunlap
  0 siblings, 1 reply; 2+ messages in thread
From: Bart Van Assche @ 2009-12-15 20:33 UTC (permalink / raw)
  To: linux-scsi, linux-rdma; +Cc: James E.J. Bottomley, FUJITA Tomonori

Adds documentation to the libsrp source code.

Signed-off-by: Bart Van Assche <bart.vanassche@gmail.com>
Cc: James E.J. Bottomley <James.Bottomley@suse.de>
Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>

diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
index 9ad38e8..bd3229e 100644
--- a/drivers/scsi/libsrp.c
+++ b/drivers/scsi/libsrp.c
@@ -29,6 +29,10 @@
 #include <scsi/srp.h>
 #include <scsi/libsrp.h>
 
+/*
+ * Allowed values for the 'TASK ATTRIBUTE' field of an SRP_CMD request. See
+ * also section 6.8 of the T10 SRP r16a document.
+ */
 enum srp_task_attributes {
 	SRP_SIMPLE_TASK = 0,
 	SRP_HEAD_TASK = 1,
@@ -44,6 +48,16 @@ do {								\
 /* #define dprintk eprintk */
 #define dprintk(fmt, args...)
 
+/**
+ * Allocate a pool of information units for use by an SRP target.
+ * @q: pointer to the pool structure that will be initialized.
+ * @max: number of information units the pool will contain.
+ * @ring: pointer to an array of 'max' SRP buffer pointers. Each information
+ *   unit allocated for the pool will be initialized such that it points to
+ *   the corresponding SRP buffer in array 'ring'.
+ *
+ * Returns zero upon success and a negative error code upon failure.
+ */
 static int srp_iu_pool_alloc(struct srp_queue *q, size_t max,
 			     struct srp_buf **ring)
 {
@@ -77,12 +91,26 @@ free_pool:
 	return -ENOMEM;
 }
 
+/**
+ * Free the memory allocated by srp_iu_pool_alloc().
+ *
+ * Note: the memory occupied by the struct srp_queue itself is not freed
+ * -- this is the responsibility of the caller.
+ */
 static void srp_iu_pool_free(struct srp_queue *q)
 {
 	kfree(q->items);
 	kfree(q->pool);
 }
 
+/**
+ * Allocate a ring of SRP buffers and set up a coherent DMA mapping for each
+ * buffer.
+ * @max: number of elements the ring will contain.
+ * @size: size in bytes of one ring element.
+ *
+ * Returns a pointer to an array of 'max' pointers to SRP buffers.
+ */
 static struct srp_buf **srp_ring_alloc(struct device *dev,
 				       size_t max, size_t size)
 {
@@ -115,6 +143,7 @@ out:
 	return NULL;
 }
 
+/** Free the memory allocated by srp_ring_alloc(). */
 static void srp_ring_free(struct device *dev, struct srp_buf **ring, size_t max,
 			  size_t size)
 {
@@ -127,6 +156,15 @@ static void srp_ring_free(struct device *dev, struct srp_buf **ring, size_t max,
 	kfree(ring);
 }
 
+/**
+ * Initialize an SRP target structure and allocate an SRP information unit ring.
+ * @target: pointer to the SRP target structure to be initialized.
+ * @dev: device to be associated with the SRP target.
+ * @nr: number of elements the SRP receive ring will contain.
+ * @iu_size: size in bytes of a single information unit.
+ *
+ * Returns zero upon success and a negative error code upon failure.
+ */
 int srp_target_alloc(struct srp_target *target, struct device *dev,
 		     size_t nr, size_t iu_size)
 {
@@ -155,6 +193,7 @@ free_ring:
 }
 EXPORT_SYMBOL_GPL(srp_target_alloc);
 
+/** Free the memory allocated by srp_target_alloc(). */
 void srp_target_free(struct srp_target *target)
 {
 	srp_ring_free(target->dev, target->rx_ring, target->rx_ring_size,
@@ -163,6 +202,11 @@ void srp_target_free(struct srp_target *target)
 }
 EXPORT_SYMBOL_GPL(srp_target_free);
 
+/**
+ * Get an information unit from the SRP target receive ring that is not in use.
+ * Initialize the ilist and flags members of the information unit before
+ * returning.
+ */
 struct iu_entry *srp_iu_get(struct srp_target *target)
 {
 	struct iu_entry *iue = NULL;
@@ -177,12 +221,24 @@ struct iu_entry *srp_iu_get(struct srp_target *target)
 }
 EXPORT_SYMBOL_GPL(srp_iu_get);
 
+/** Put an information unit back in the SRP target receive ring. */
 void srp_iu_put(struct iu_entry *iue)
 {
 	kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
 }
 EXPORT_SYMBOL_GPL(srp_iu_put);
 
+/**
+ * Transfer the data referred to by an SRP direct data buffer descriptor
+ * via RDMA.
+ * @sc: SCSI command.
+ * @md: SRP direct data buffer descriptor.
+ * @dir: DMA data direction, the second last parameter passed to the function
+ *       'rdma_io'.
+ * @rdma_io: pointer to a callback function that performs the actual I/O.
+ * @dma_map: whether or not to map and unmap the scsi_sglist(sc).
+ * @ext_desc: ignored.
+ */
 static int srp_direct_data(struct scsi_cmnd *sc, struct srp_direct_buf *md,
 			   enum dma_data_direction dir, srp_rdma_t rdma_io,
 			   int dma_map, int ext_desc)
@@ -216,6 +272,17 @@ static int srp_direct_data(struct scsi_cmnd *sc, struct srp_direct_buf *md,
 	return err;
 }
 
+/**
+ * Transfer the data referred to by an SRP indirect data buffer descriptor via
+ * RDMA.
+ * @sc: SCSI command.
+ * @md: SRP indirect data buffer descriptor.
+ * @dir: DMA data direction, the second last parameter passed to the function
+ *       'rdma_io'.
+ * @rdma_io: pointer to a callback function that performs the actual I/O.
+ * @dma_map: whether or not to map and unmap the scsi_sglist(sc).
+ * @ext_desc: whether or not this command uses an external indirect buffer.
+ */
 static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
 			     struct srp_indirect_buf *id,
 			     enum dma_data_direction dir, srp_rdma_t rdma_io,
@@ -292,6 +359,10 @@ free_mem:
 	return err;
 }
 
+/**
+ * Compute the number of bytes occupied by the DATA-OUT descriptor in an
+ * SRP_CMD request.
+ */
 static int data_out_desc_size(struct srp_cmd *cmd)
 {
 	int size = 0;
@@ -314,7 +385,16 @@ static int data_out_desc_size(struct srp_cmd *cmd)
 	return size;
 }
 
-/*
+/**
+ * Transfer the data associated with an SRP_CMD request.
+ * @sc: SCSI command.
+ * @cmd: SRP_CMD request.
+ * @rdma_io: callback function for performing RDMA I/O.
+ * @dma_map: second-last parameter passed to rdma_io.
+ * @ext_desc: whether this command uses an external indirect buffer.
+ *
+ * Note: does not support bidirectional commands.
+ *
  * TODO: this can be called multiple times for a single command if it
  * has very long data.
  */
@@ -327,10 +407,23 @@ int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
 	int offset, err = 0;
 	u8 format;
 
+	/*
+	 * 'offset' is the offset in bytes of the data buffer descriptor in
+	 * an SRP_CMD request. For an SRP request that transfers data from
+	 * initiator to target, 'offset' is the offset of the data-out buffer
+	 * descriptor. For an SRP request that transfers data from target to
+	 * initiator, 'offset' is the offset of the data-in buffer descriptor.
+	 * In an SRP_CMD request the following descriptors are present starting
+	 * from cmd->add_data: additional CDB, data-out buffer descriptor and
+	 * data-in buffer descriptor.
+	 */
+
+	/* Skip over 'additional CDB' to start of data-out descriptor. */
 	offset = cmd->add_cdb_len * 4;
 
 	dir = srp_cmd_direction(cmd);
 	if (dir == DMA_FROM_DEVICE)
+		/* Skip over data-out descriptor to start of data-in. */
 		offset += data_out_desc_size(cmd);
 
 	if (dir == DMA_TO_DEVICE)
@@ -361,6 +454,13 @@ int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
 }
 EXPORT_SYMBOL_GPL(srp_transfer_data);
 
+/**
+ * Compute the size in bytes of one of the two data descriptors at the end of
+ * an SRP_CMD request.
+ * @cmd: SRP_CMD request.
+ * @dir: DMA_TO_DEVICE for the size of the data-out buffer descriptor;
+ * DMA_FROM_DEVICE for the size of the data-in buffer descriptor.
+ */
 static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir)
 {
 	struct srp_direct_buf *md;
@@ -393,6 +493,10 @@ static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir)
 	return len;
 }
 
+/**
+ * Queue an SRP_CMD request for processing by appropriate target software,
+ * e.g. the user space process tgtd.
+ */
 int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info,
 		  u64 itn_id, u64 addr)
 {
diff --git a/include/scsi/libsrp.h b/include/scsi/libsrp.h
index ba615e4..e783830 100644
--- a/include/scsi/libsrp.h
+++ b/include/scsi/libsrp.h
@@ -1,11 +1,17 @@
 #ifndef __LIBSRP_H__
 #define __LIBSRP_H__
 
+/*
+ * Structures and constants exported by libsrp, a library for implementing
+ * SRP initiators and targets.
+ */
+
 #include <linux/list.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
 #include <scsi/srp.h>
 
+/* Names assigned to the bits of iu_entry::flags by the ibmvstgt driver. */
 enum iue_flags {
 	V_DIOVER,
 	V_WRITE,
@@ -13,43 +19,73 @@ enum iue_flags {
 	V_FLYING,
 };
 
+/* SRP data buffer as managed by libsrp. */
 struct srp_buf {
 	dma_addr_t dma;
 	void *buf;
 };
 
+/* Pool of SRP information units. */
 struct srp_queue {
+	/* kfifo storage; an array of n struct iu_entry* items. */
 	void *pool;
+	/* information unit storage; an array of n struct iu_entry items. */
 	void *items;
+	/* kfifo containing pointers to iu_entry items currently not in use. */
 	struct kfifo *queue;
+	/* spinlock associated with the above kfifo. */
 	spinlock_t lock;
 };
 
+/* SRP target. */
 struct srp_target {
+	/* Pointer to the SCSI host associated with the SRP target. */
 	struct Scsi_Host *shost;
+	/* Pointer to the device node associated with the SRP target. */
 	struct device *dev;
 
+	/* Initialized but not used otherwise inside libsrp. */
 	spinlock_t lock;
+	/* Initialized but not used otherwise inside libsrp. */
 	struct list_head cmd_queue;
 
+	/* Size in bytes of a single information unit. */
 	size_t srp_iu_size;
+	/* Information unit receive ring. */
 	struct srp_queue iu_queue;
+	/* Number of elements in the information unit receive ring. */
 	size_t rx_ring_size;
+	/* Pointer to an array of SRP buffers associated with the rx ring. */
 	struct srp_buf **rx_ring;
 
+	/* Pointer to target-private data. */
 	void *ldata;
 };
 
+/* Information unit as processed by an SRP target. */
 struct iu_entry {
+	/* Backpointer to the SRP target processing this information unit. */
 	struct srp_target *target;
 
+	/* Used by ibmvscsi for insertion in the srp_target::cmd_queue list. */
 	struct list_head ilist;
+	/* Used by the ibmvscsi driver but not by libsrp. */
 	dma_addr_t remote_token;
+	/* Initialized by libsrp but not used otherwise by libsrp. */
 	unsigned long flags;
 
+	/* SRP buffer associated with this information unit. */
 	struct srp_buf *sbuf;
 };
 
+/*
+ * Pointer to a callback function that performs RDMA I/O.
+ *
+ * Arguments (in order): SCSI command pointer, scatterlist pointer,
+ * number of entries in the scatterlist, pointer to an array of SRP
+ * memory descriptor pointers, number of elements in this array, DMA
+ * data direction, maximum number of bytes to transfer.
+ */
 typedef int (srp_rdma_t)(struct scsi_cmnd *, struct scatterlist *, int,
 			 struct srp_direct_buf *, int,
 			 enum dma_data_direction, unsigned int);
@@ -69,6 +105,16 @@ static inline struct srp_target *host_to_srp_target(struct Scsi_Host *host)
 	return (struct srp_target *) host->hostdata;
 }
 
+/*
+ * Find out whether an SRP_CMD request is transferring data from initiator to
+ * target or from target to initiator.
+ *
+ * Returns DMA_TO_DEVICE when transferring data from initiator to target and
+ * DMA_FROM_DEVICE when transferring data from target to initiator. This
+ * reflects the point of view of an SRP initiator implementation.
+ *
+ * Note: do not use this function for bidirectional commands.
+ */
 static inline int srp_cmd_direction(struct srp_cmd *cmd)
 {
 	return (cmd->buf_fmt >> 4) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
diff --git a/include/scsi/srp.h b/include/scsi/srp.h
index ad178fa..ebb6096 100644
--- a/include/scsi/srp.h
+++ b/include/scsi/srp.h
@@ -38,11 +38,13 @@
 /*
  * Structures and constants for the SCSI RDMA Protocol (SRP) as
  * defined by the INCITS T10 committee.  This file was written using
- * draft Revision 16a of the SRP standard.
+ * draft Revision 16a of the SRP standard. See also
+ * http://www.t10.org/drafts.htm#SCSI3_SRP.
  */
 
 #include <linux/types.h>
 
+/* SRP information unit types. */
 enum {
 	SRP_LOGIN_REQ	= 0x00,
 	SRP_TSK_MGMT	= 0x01,
@@ -58,17 +60,31 @@ enum {
 	SRP_AER_RSP	= 0x42
 };
 
+/*
+ * Flags for the 'REQUIRED BUFFER FORMATS' field of the SRP_LOGIN_REQ request
+ * (srp_login_req::req_buf_fmt) or the 'SUPPORTED BUFFER FORMATS' field of the
+ * SRP_LOGIN_RSP response (srp_login_rsp::buf_fmt). See also section 5.6.2.2
+ * in the T10 SRP r16a document.
+ */
 enum {
 	SRP_BUF_FORMAT_DIRECT	= 1 << 1,
 	SRP_BUF_FORMAT_INDIRECT	= 1 << 2
 };
 
+/*
+ * Format of data-in and data-out buffer descriptors in an SRP_CMD
+ * request. See also section 5.6.2.1 in the T10 SRP r16a document.
+ */
 enum {
 	SRP_NO_DATA_DESC	= 0,
 	SRP_DATA_DESC_DIRECT	= 1,
 	SRP_DATA_DESC_INDIRECT	= 2
 };
 
+/*
+ * Allowed values for the 'TASK MANAGEMENT FUNCTION' field of the SRP_TSK_MGMT
+ * request. See also section 6.7 in the T10 SRP r16a document.
+ */
 enum {
 	SRP_TSK_ABORT_TASK	= 0x01,
 	SRP_TSK_ABORT_TASK_SET	= 0x02,
@@ -77,6 +93,10 @@ enum {
 	SRP_TSK_CLEAR_ACA	= 0x40
 };
 
+/*
+ * Allowed values for the 'REASON' field of the SRP_LOGIN_REJ response. See
+ * also section 6.4 in the T10 SRP r16a document.
+ */
 enum srp_login_rej_reason {
 	SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL		= 0x00010000,
 	SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES		= 0x00010001,
@@ -87,11 +107,20 @@ enum srp_login_rej_reason {
 	SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED		= 0x00010006
 };
 
+/*
+ * IB I/O class assigned to revisions 10 and r16a of the SRP protocol.
+ * See also section B.7 in the T10 SRP r16a document.
+ */
 enum {
 	SRP_REV10_IB_IO_CLASS	= 0xff00,
 	SRP_REV16A_IB_IO_CLASS	= 0x0100
 };
 
+/*
+ * Direct data buffer descriptor as defined in section 5.6.2.4 of the T10 SRP
+ * r16a document. Each direct data buffer descriptor consists of a virtual
+ * address, a memory handle and a data length.
+ */
 struct srp_direct_buf {
 	__be64	va;
 	__be32	key;
@@ -99,6 +128,9 @@ struct srp_direct_buf {
 };
 
 /*
+ * Indirect data buffer descriptor as defined in section 5.6.2.5 of the T10
+ * SRP r16a document.
+ *
  * We need the packed attribute because the SRP spec puts the list of
  * descriptors at an offset of 20, which is not aligned to the size of
  * struct srp_direct_buf.  The whole structure must be packed to avoid
@@ -110,11 +142,20 @@ struct srp_indirect_buf {
 	struct srp_direct_buf	desc_list[0];
 } __attribute__((packed));
 
+/*
+ * Allowed values for the 'MULTI-CHANNEL ACTION CODE' field of the
+ * SRP_LOGIN_REQ request, as defined in section 6.2 of the T10 SRP r16a
+ * document.
+ */
 enum {
 	SRP_MULTICHAN_SINGLE = 0,
 	SRP_MULTICHAN_MULTI  = 1
 };
 
+/*
+ * SRP_LOGIN_REQ request, also defined in section 6.2 of the T10 SRP r16a
+ * document.
+ */
 struct srp_login_req {
 	u8	opcode;
 	u8	reserved1[7];
@@ -129,6 +170,9 @@ struct srp_login_req {
 };
 
 /*
+ * SRP_LOGIN_RSP response, as defined in section 6.3 of the T10 SRP r16a
+ * document.
+ *
  * The SRP spec defines the size of the LOGIN_RSP structure to be 52
  * bytes, so it needs to be packed to avoid having it padded to 56
  * bytes on 64-bit architectures.
@@ -145,6 +189,10 @@ struct srp_login_rsp {
 	u8	reserved2[25];
 } __attribute__((packed));
 
+/*
+ * SRP_LOGIN_REJ response, as defined in section 6.4 of the T10 SRP r16a
+ * document.
+ */
 struct srp_login_rej {
 	u8	opcode;
 	u8	reserved1[3];
@@ -155,12 +203,19 @@ struct srp_login_rej {
 	u8	reserved3[6];
 };
 
+/*
+ * SRP_I_LOGOUT request, as defined in section 6.5 of the T10 SRP r16a
+ * document.
+ */
 struct srp_i_logout {
 	u8	opcode;
 	u8	reserved[7];
 	u64	tag;
 };
 
+/*
+ * SRP_T_LOGOUT request, as defined in section 6.6 of the T10 SRP r16a document.
+ */
 struct srp_t_logout {
 	u8	opcode;
 	u8	sol_not;
@@ -170,6 +225,8 @@ struct srp_t_logout {
 };
 
 /*
+ * SRP_TSK_MGMT request, as defined in section 6.7 of the T10 SRP r16a document.
+ *
  * We need the packed attribute because the SRP spec only aligns the
  * 8-byte LUN field to 4 bytes.
  */
@@ -188,6 +245,9 @@ struct srp_tsk_mgmt {
 };
 
 /*
+ * SRP_CMD request with a single CDB as defined in section 6.8 of the T10 SRP
+ * r16a document.
+ *
  * We need the packed attribute because the SRP spec only aligns the
  * 8-byte LUN field to 4 bytes.
  */
@@ -209,6 +269,10 @@ struct srp_cmd {
 	u8	add_data[0];
 };
 
+/*
+ * Allowed flags for the flags field of the SRP_RSP response. See also
+ * section 6.9 of the T10 SRP r16a document.
+ */
 enum {
 	SRP_RSP_FLAG_RSPVALID = 1 << 0,
 	SRP_RSP_FLAG_SNSVALID = 1 << 1,
@@ -219,6 +283,8 @@ enum {
 };
 
 /*
+ * SRP_RSP response, as defined in section 6.9 of the T10 SRP r16a document.
+ *
  * The SRP spec defines the size of the RSP structure to be 36 bytes,
  * so it needs to be packed to avoid having it padded to 40 bytes on
  * 64-bit architectures.

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] SCSI/libsrp: document the libsrp source code
  2009-12-15 20:33 [PATCH] SCSI/libsrp: document the libsrp source code Bart Van Assche
@ 2009-12-15 22:34 ` Randy Dunlap
  0 siblings, 0 replies; 2+ messages in thread
From: Randy Dunlap @ 2009-12-15 22:34 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: linux-scsi, linux-rdma, James E.J. Bottomley, FUJITA Tomonori

On Tue, 15 Dec 2009 21:33:20 +0100 Bart Van Assche wrote:

> Adds documentation to the libsrp source code.

adds almost kernel-doc to the libsrp source code.
(see below)

> Signed-off-by: Bart Van Assche <bart.vanassche@gmail.com>
> Cc: James E.J. Bottomley <James.Bottomley@suse.de>
> Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
> 
> diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
> index 9ad38e8..bd3229e 100644
> --- a/drivers/scsi/libsrp.c
> +++ b/drivers/scsi/libsrp.c
> @@ -29,6 +29,10 @@
>  #include <scsi/srp.h>
>  #include <scsi/libsrp.h>
>  
> +/*
> + * Allowed values for the 'TASK ATTRIBUTE' field of an SRP_CMD request. See
> + * also section 6.8 of the T10 SRP r16a document.
> + */
>  enum srp_task_attributes {
>  	SRP_SIMPLE_TASK = 0,
>  	SRP_HEAD_TASK = 1,
> @@ -44,6 +48,16 @@ do {								\
>  /* #define dprintk eprintk */
>  #define dprintk(fmt, args...)
>  
> +/**

"/**" means begin kernel-doc.  Please see
Documentation/kernel-doc-nano-HOWTO.txt for the required format of
kernel-doc notation.
It's only missing the function name on the first line, before
the short function description. (same below in more functions)

> + * Allocate a pool of information units for use by an SRP target.
> + * @q: pointer to the pool structure that will be initialized.
> + * @max: number of information units the pool will contain.
> + * @ring: pointer to an array of 'max' SRP buffer pointers. Each information
> + *   unit allocated for the pool will be initialized such that it points to
> + *   the corresponding SRP buffer in array 'ring'.
> + *
> + * Returns zero upon success and a negative error code upon failure.
> + */
>  static int srp_iu_pool_alloc(struct srp_queue *q, size_t max,
>  			     struct srp_buf **ring)
>  {
> @@ -77,12 +91,26 @@ free_pool:
>  	return -ENOMEM;
>  }
>  
> +/**
> + * Free the memory allocated by srp_iu_pool_alloc().
> + *

and missing function parameter notation.

> + * Note: the memory occupied by the struct srp_queue itself is not freed
> + * -- this is the responsibility of the caller.
> + */
>  static void srp_iu_pool_free(struct srp_queue *q)
>  {
>  	kfree(q->items);
>  	kfree(q->pool);
>  }
>  
> +/**
> + * Allocate a ring of SRP buffers and set up a coherent DMA mapping for each
> + * buffer.
> + * @max: number of elements the ring will contain.
> + * @size: size in bytes of one ring element.
> + *
> + * Returns a pointer to an array of 'max' pointers to SRP buffers.
> + */
>  static struct srp_buf **srp_ring_alloc(struct device *dev,
>  				       size_t max, size_t size)
>  {
> @@ -115,6 +143,7 @@ out:
>  	return NULL;
>  }
>  
> +/** Free the memory allocated by srp_ring_alloc(). */

That's not kernel-doc at all.

>  static void srp_ring_free(struct device *dev, struct srp_buf **ring, size_t max,
>  			  size_t size)
>  {
> @@ -127,6 +156,15 @@ static void srp_ring_free(struct device *dev, struct srp_buf **ring, size_t max,
>  	kfree(ring);
>  }
>  
> +/**
> + * Initialize an SRP target structure and allocate an SRP information unit ring.
> + * @target: pointer to the SRP target structure to be initialized.
> + * @dev: device to be associated with the SRP target.
> + * @nr: number of elements the SRP receive ring will contain.
> + * @iu_size: size in bytes of a single information unit.
> + *
> + * Returns zero upon success and a negative error code upon failure.
> + */
>  int srp_target_alloc(struct srp_target *target, struct device *dev,
>  		     size_t nr, size_t iu_size)
>  {
> @@ -155,6 +193,7 @@ free_ring:
>  }
>  EXPORT_SYMBOL_GPL(srp_target_alloc);
>  
> +/** Free the memory allocated by srp_target_alloc(). */

nor is that.

>  void srp_target_free(struct srp_target *target)
>  {
>  	srp_ring_free(target->dev, target->rx_ring, target->rx_ring_size,
> @@ -163,6 +202,11 @@ void srp_target_free(struct srp_target *target)
>  }
>  EXPORT_SYMBOL_GPL(srp_target_free);
>  
> +/**
> + * Get an information unit from the SRP target receive ring that is not in use.
> + * Initialize the ilist and flags members of the information unit before
> + * returning.
> + */
>  struct iu_entry *srp_iu_get(struct srp_target *target)
>  {
>  	struct iu_entry *iue = NULL;
> @@ -177,12 +221,24 @@ struct iu_entry *srp_iu_get(struct srp_target *target)
>  }
>  EXPORT_SYMBOL_GPL(srp_iu_get);
>  
> +/** Put an information unit back in the SRP target receive ring. */

nor that.

>  void srp_iu_put(struct iu_entry *iue)
>  {
>  	kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
>  }
>  EXPORT_SYMBOL_GPL(srp_iu_put);
>  
> +/**
> + * Transfer the data referred to by an SRP direct data buffer descriptor
> + * via RDMA.
> + * @sc: SCSI command.
> + * @md: SRP direct data buffer descriptor.
> + * @dir: DMA data direction, the second last parameter passed to the function
> + *       'rdma_io'.
> + * @rdma_io: pointer to a callback function that performs the actual I/O.
> + * @dma_map: whether or not to map and unmap the scsi_sglist(sc).
> + * @ext_desc: ignored.
> + */
>  static int srp_direct_data(struct scsi_cmnd *sc, struct srp_direct_buf *md,
>  			   enum dma_data_direction dir, srp_rdma_t rdma_io,
>  			   int dma_map, int ext_desc)
> @@ -216,6 +272,17 @@ static int srp_direct_data(struct scsi_cmnd *sc, struct srp_direct_buf *md,
>  	return err;
>  }
>  
> +/**
> + * Transfer the data referred to by an SRP indirect data buffer descriptor via
> + * RDMA.
> + * @sc: SCSI command.
> + * @md: SRP indirect data buffer descriptor.
> + * @dir: DMA data direction, the second last parameter passed to the function
> + *       'rdma_io'.
> + * @rdma_io: pointer to a callback function that performs the actual I/O.
> + * @dma_map: whether or not to map and unmap the scsi_sglist(sc).
> + * @ext_desc: whether or not this command uses an external indirect buffer.
> + */
>  static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
>  			     struct srp_indirect_buf *id,
>  			     enum dma_data_direction dir, srp_rdma_t rdma_io,
> @@ -292,6 +359,10 @@ free_mem:
>  	return err;
>  }
>  
> +/**
> + * Compute the number of bytes occupied by the DATA-OUT descriptor in an
> + * SRP_CMD request.
> + */
>  static int data_out_desc_size(struct srp_cmd *cmd)
>  {
>  	int size = 0;
> @@ -314,7 +385,16 @@ static int data_out_desc_size(struct srp_cmd *cmd)
>  	return size;
>  }
>  
> -/*
> +/**
> + * Transfer the data associated with an SRP_CMD request.
> + * @sc: SCSI command.
> + * @cmd: SRP_CMD request.
> + * @rdma_io: callback function for performing RDMA I/O.
> + * @dma_map: second-last parameter passed to rdma_io.
> + * @ext_desc: whether this command uses an external indirect buffer.
> + *
> + * Note: does not support bidirectional commands.
> + *
>   * TODO: this can be called multiple times for a single command if it
>   * has very long data.
>   */
> @@ -327,10 +407,23 @@ int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
>  	int offset, err = 0;
>  	u8 format;
>  
> +	/*
> +	 * 'offset' is the offset in bytes of the data buffer descriptor in
> +	 * an SRP_CMD request. For an SRP request that transfers data from
> +	 * initiator to target, 'offset' is the offset of the data-out buffer
> +	 * descriptor. For an SRP request that transfers data from target to
> +	 * initiator, 'offset' is the offset of the data-in buffer descriptor.
> +	 * In an SRP_CMD request the following descriptors are present starting
> +	 * from cmd->add_data: additional CDB, data-out buffer descriptor and
> +	 * data-in buffer descriptor.
> +	 */
> +
> +	/* Skip over 'additional CDB' to start of data-out descriptor. */
>  	offset = cmd->add_cdb_len * 4;
>  
>  	dir = srp_cmd_direction(cmd);
>  	if (dir == DMA_FROM_DEVICE)
> +		/* Skip over data-out descriptor to start of data-in. */
>  		offset += data_out_desc_size(cmd);
>  
>  	if (dir == DMA_TO_DEVICE)
> @@ -361,6 +454,13 @@ int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
>  }
>  EXPORT_SYMBOL_GPL(srp_transfer_data);
>  
> +/**
> + * Compute the size in bytes of one of the two data descriptors at the end of
> + * an SRP_CMD request.
> + * @cmd: SRP_CMD request.
> + * @dir: DMA_TO_DEVICE for the size of the data-out buffer descriptor;
> + * DMA_FROM_DEVICE for the size of the data-in buffer descriptor.
> + */
>  static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir)
>  {
>  	struct srp_direct_buf *md;
> @@ -393,6 +493,10 @@ static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir)
>  	return len;
>  }
>  
> +/**
> + * Queue an SRP_CMD request for processing by appropriate target software,
> + * e.g. the user space process tgtd.
> + */
>  int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info,
>  		  u64 itn_id, u64 addr)
>  {
> diff --git a/include/scsi/libsrp.h b/include/scsi/libsrp.h
> index ba615e4..e783830 100644
> --- a/include/scsi/libsrp.h
> +++ b/include/scsi/libsrp.h
> @@ -1,11 +1,17 @@
>  #ifndef __LIBSRP_H__
>  #define __LIBSRP_H__
>  
> +/*
> + * Structures and constants exported by libsrp, a library for implementing
> + * SRP initiators and targets.
> + */
> +
>  #include <linux/list.h>
>  #include <scsi/scsi_cmnd.h>
>  #include <scsi/scsi_host.h>
>  #include <scsi/srp.h>
>  
> +/* Names assigned to the bits of iu_entry::flags by the ibmvstgt driver. */
>  enum iue_flags {
>  	V_DIOVER,
>  	V_WRITE,
> @@ -13,43 +19,73 @@ enum iue_flags {
>  	V_FLYING,
>  };
>  
> +/* SRP data buffer as managed by libsrp. */
>  struct srp_buf {
>  	dma_addr_t dma;
>  	void *buf;
>  };
>  
> +/* Pool of SRP information units. */

kernel-doc also supports struct notation if you are interested in using it.

>  struct srp_queue {
> +	/* kfifo storage; an array of n struct iu_entry* items. */
>  	void *pool;
> +	/* information unit storage; an array of n struct iu_entry items. */
>  	void *items;
> +	/* kfifo containing pointers to iu_entry items currently not in use. */
>  	struct kfifo *queue;
> +	/* spinlock associated with the above kfifo. */
>  	spinlock_t lock;
>  };
>  
> +/* SRP target. */
>  struct srp_target {
> +	/* Pointer to the SCSI host associated with the SRP target. */
>  	struct Scsi_Host *shost;
> +	/* Pointer to the device node associated with the SRP target. */
>  	struct device *dev;
>  
> +	/* Initialized but not used otherwise inside libsrp. */
>  	spinlock_t lock;
> +	/* Initialized but not used otherwise inside libsrp. */
>  	struct list_head cmd_queue;
>  
> +	/* Size in bytes of a single information unit. */
>  	size_t srp_iu_size;
> +	/* Information unit receive ring. */
>  	struct srp_queue iu_queue;
> +	/* Number of elements in the information unit receive ring. */
>  	size_t rx_ring_size;
> +	/* Pointer to an array of SRP buffers associated with the rx ring. */
>  	struct srp_buf **rx_ring;
>  
> +	/* Pointer to target-private data. */
>  	void *ldata;
>  };
>  
> +/* Information unit as processed by an SRP target. */
>  struct iu_entry {
> +	/* Backpointer to the SRP target processing this information unit. */
>  	struct srp_target *target;
>  
> +	/* Used by ibmvscsi for insertion in the srp_target::cmd_queue list. */
>  	struct list_head ilist;
> +	/* Used by the ibmvscsi driver but not by libsrp. */
>  	dma_addr_t remote_token;
> +	/* Initialized by libsrp but not used otherwise by libsrp. */
>  	unsigned long flags;
>  
> +	/* SRP buffer associated with this information unit. */
>  	struct srp_buf *sbuf;
>  };
>  
> +/*
> + * Pointer to a callback function that performs RDMA I/O.
> + *
> + * Arguments (in order): SCSI command pointer, scatterlist pointer,
> + * number of entries in the scatterlist, pointer to an array of SRP
> + * memory descriptor pointers, number of elements in this array, DMA
> + * data direction, maximum number of bytes to transfer.
> + */
>  typedef int (srp_rdma_t)(struct scsi_cmnd *, struct scatterlist *, int,
>  			 struct srp_direct_buf *, int,
>  			 enum dma_data_direction, unsigned int);
> @@ -69,6 +105,16 @@ static inline struct srp_target *host_to_srp_target(struct Scsi_Host *host)
>  	return (struct srp_target *) host->hostdata;
>  }
>  
> +/*
> + * Find out whether an SRP_CMD request is transferring data from initiator to
> + * target or from target to initiator.
> + *
> + * Returns DMA_TO_DEVICE when transferring data from initiator to target and
> + * DMA_FROM_DEVICE when transferring data from target to initiator. This
> + * reflects the point of view of an SRP initiator implementation.
> + *
> + * Note: do not use this function for bidirectional commands.
> + */
>  static inline int srp_cmd_direction(struct srp_cmd *cmd)
>  {
>  	return (cmd->buf_fmt >> 4) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
> diff --git a/include/scsi/srp.h b/include/scsi/srp.h
> index ad178fa..ebb6096 100644
> --- a/include/scsi/srp.h
> +++ b/include/scsi/srp.h
> @@ -38,11 +38,13 @@
>  /*
>   * Structures and constants for the SCSI RDMA Protocol (SRP) as
>   * defined by the INCITS T10 committee.  This file was written using
> - * draft Revision 16a of the SRP standard.
> + * draft Revision 16a of the SRP standard. See also
> + * http://www.t10.org/drafts.htm#SCSI3_SRP.
>   */
>  
>  #include <linux/types.h>
>  
> +/* SRP information unit types. */
>  enum {
>  	SRP_LOGIN_REQ	= 0x00,
>  	SRP_TSK_MGMT	= 0x01,
> @@ -58,17 +60,31 @@ enum {
>  	SRP_AER_RSP	= 0x42
>  };
>  
> +/*
> + * Flags for the 'REQUIRED BUFFER FORMATS' field of the SRP_LOGIN_REQ request
> + * (srp_login_req::req_buf_fmt) or the 'SUPPORTED BUFFER FORMATS' field of the
> + * SRP_LOGIN_RSP response (srp_login_rsp::buf_fmt). See also section 5.6.2.2
> + * in the T10 SRP r16a document.
> + */
>  enum {
>  	SRP_BUF_FORMAT_DIRECT	= 1 << 1,
>  	SRP_BUF_FORMAT_INDIRECT	= 1 << 2
>  };
>  
> +/*
> + * Format of data-in and data-out buffer descriptors in an SRP_CMD
> + * request. See also section 5.6.2.1 in the T10 SRP r16a document.
> + */
>  enum {
>  	SRP_NO_DATA_DESC	= 0,
>  	SRP_DATA_DESC_DIRECT	= 1,
>  	SRP_DATA_DESC_INDIRECT	= 2
>  };
>  
> +/*
> + * Allowed values for the 'TASK MANAGEMENT FUNCTION' field of the SRP_TSK_MGMT
> + * request. See also section 6.7 in the T10 SRP r16a document.
> + */
>  enum {
>  	SRP_TSK_ABORT_TASK	= 0x01,
>  	SRP_TSK_ABORT_TASK_SET	= 0x02,
> @@ -77,6 +93,10 @@ enum {
>  	SRP_TSK_CLEAR_ACA	= 0x40
>  };
>  
> +/*
> + * Allowed values for the 'REASON' field of the SRP_LOGIN_REJ response. See
> + * also section 6.4 in the T10 SRP r16a document.
> + */
>  enum srp_login_rej_reason {
>  	SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL		= 0x00010000,
>  	SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES		= 0x00010001,
> @@ -87,11 +107,20 @@ enum srp_login_rej_reason {
>  	SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED		= 0x00010006
>  };
>  
> +/*
> + * IB I/O class assigned to revisions 10 and r16a of the SRP protocol.
> + * See also section B.7 in the T10 SRP r16a document.
> + */
>  enum {
>  	SRP_REV10_IB_IO_CLASS	= 0xff00,
>  	SRP_REV16A_IB_IO_CLASS	= 0x0100
>  };
>  
> +/*
> + * Direct data buffer descriptor as defined in section 5.6.2.4 of the T10 SRP
> + * r16a document. Each direct data buffer descriptor consists of a virtual
> + * address, a memory handle and a data length.
> + */
>  struct srp_direct_buf {
>  	__be64	va;
>  	__be32	key;
> @@ -99,6 +128,9 @@ struct srp_direct_buf {
>  };
>  
>  /*
> + * Indirect data buffer descriptor as defined in section 5.6.2.5 of the T10
> + * SRP r16a document.
> + *
>   * We need the packed attribute because the SRP spec puts the list of
>   * descriptors at an offset of 20, which is not aligned to the size of
>   * struct srp_direct_buf.  The whole structure must be packed to avoid
> @@ -110,11 +142,20 @@ struct srp_indirect_buf {
>  	struct srp_direct_buf	desc_list[0];
>  } __attribute__((packed));
>  
> +/*
> + * Allowed values for the 'MULTI-CHANNEL ACTION CODE' field of the
> + * SRP_LOGIN_REQ request, as defined in section 6.2 of the T10 SRP r16a
> + * document.
> + */
>  enum {
>  	SRP_MULTICHAN_SINGLE = 0,
>  	SRP_MULTICHAN_MULTI  = 1
>  };
>  
> +/*
> + * SRP_LOGIN_REQ request, also defined in section 6.2 of the T10 SRP r16a
> + * document.
> + */
>  struct srp_login_req {
>  	u8	opcode;
>  	u8	reserved1[7];
> @@ -129,6 +170,9 @@ struct srp_login_req {
>  };
>  
>  /*
> + * SRP_LOGIN_RSP response, as defined in section 6.3 of the T10 SRP r16a
> + * document.
> + *
>   * The SRP spec defines the size of the LOGIN_RSP structure to be 52
>   * bytes, so it needs to be packed to avoid having it padded to 56
>   * bytes on 64-bit architectures.
> @@ -145,6 +189,10 @@ struct srp_login_rsp {
>  	u8	reserved2[25];
>  } __attribute__((packed));
>  
> +/*
> + * SRP_LOGIN_REJ response, as defined in section 6.4 of the T10 SRP r16a
> + * document.
> + */
>  struct srp_login_rej {
>  	u8	opcode;
>  	u8	reserved1[3];
> @@ -155,12 +203,19 @@ struct srp_login_rej {
>  	u8	reserved3[6];
>  };
>  
> +/*
> + * SRP_I_LOGOUT request, as defined in section 6.5 of the T10 SRP r16a
> + * document.
> + */
>  struct srp_i_logout {
>  	u8	opcode;
>  	u8	reserved[7];
>  	u64	tag;
>  };
>  
> +/*
> + * SRP_T_LOGOUT request, as defined in section 6.6 of the T10 SRP r16a document.
> + */
>  struct srp_t_logout {
>  	u8	opcode;
>  	u8	sol_not;
> @@ -170,6 +225,8 @@ struct srp_t_logout {
>  };
>  
>  /*
> + * SRP_TSK_MGMT request, as defined in section 6.7 of the T10 SRP r16a document.
> + *
>   * We need the packed attribute because the SRP spec only aligns the
>   * 8-byte LUN field to 4 bytes.
>   */
> @@ -188,6 +245,9 @@ struct srp_tsk_mgmt {
>  };
>  
>  /*
> + * SRP_CMD request with a single CDB as defined in section 6.8 of the T10 SRP
> + * r16a document.
> + *
>   * We need the packed attribute because the SRP spec only aligns the
>   * 8-byte LUN field to 4 bytes.
>   */
> @@ -209,6 +269,10 @@ struct srp_cmd {
>  	u8	add_data[0];
>  };
>  
> +/*
> + * Allowed flags for the flags field of the SRP_RSP response. See also
> + * section 6.9 of the T10 SRP r16a document.
> + */
>  enum {
>  	SRP_RSP_FLAG_RSPVALID = 1 << 0,
>  	SRP_RSP_FLAG_SNSVALID = 1 << 1,
> @@ -219,6 +283,8 @@ enum {
>  };
>  
>  /*
> + * SRP_RSP response, as defined in section 6.9 of the T10 SRP r16a document.
> + *
>   * The SRP spec defines the size of the RSP structure to be 36 bytes,
>   * so it needs to be packed to avoid having it padded to 40 bytes on
>   * 64-bit architectures.
> --


---
~Randy

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-12-15 22:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-15 20:33 [PATCH] SCSI/libsrp: document the libsrp source code Bart Van Assche
2009-12-15 22:34 ` Randy Dunlap

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.