linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hannes Reinecke <hare@suse.de>
To: James Bottomley <jbottomley@parallels.com>
Cc: Christoph Hellwig <hch@lst.de>,
	Ondrey Zary <linux@rainbow-software.org>,
	Doug Gilberg <dgilbert@interlog.com>,
	linux-scsi@vger.kernel.org, Hannes Reinecke <hare@suse.de>
Subject: [PATCH 06/23] advansys: Use dma_pool for sg elements
Date: Fri, 24 Apr 2015 13:18:25 +0200	[thread overview]
Message-ID: <1429874322-85488-8-git-send-email-hare@suse.de> (raw)
In-Reply-To: <1429874322-85488-1-git-send-email-hare@suse.de>

The sg elements should be allocated from a dma pool.
And rename the structure to 'adv_sg_block' as they
are only used by the wide board.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/scsi/advansys.c | 108 ++++++++++++++++++++----------------------------
 1 file changed, 45 insertions(+), 63 deletions(-)

diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 9a7018d..b8b5985 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -1815,15 +1815,15 @@ typedef struct adv_dvc_cfg {
 struct adv_dvc_var;
 struct adv_scsi_req_q;
 
-typedef struct asc_sg_block {
+typedef struct adv_sg_block {
 	uchar reserved1;
 	uchar reserved2;
 	uchar reserved3;
 	uchar sg_cnt;		/* Valid entries in block. */
-	ADV_PADDR sg_ptr;	/* Pointer to next sg block. */
+	__le32 sg_ptr;	/* Pointer to next sg block. */
 	struct {
-		ADV_PADDR sg_addr;	/* SG element address. */
-		ADV_DCNT sg_count;	/* SG element count. */
+		__le32 sg_addr;	/* SG element address. */
+		__le32 sg_count;	/* SG element count. */
 	} sg_list[NO_OF_SG_PER_BLOCK];
 } ADV_SG_BLOCK;
 
@@ -1888,7 +1888,7 @@ typedef struct adv_scsi_req_q {
  */
 typedef struct adv_sgblk {
 	ADV_SG_BLOCK sg_block;	/* Sgblock structure. */
-	uchar align[32];	/* Sgblock structure padding. */
+	dma_addr_t sg_addr;	/* Physical address */
 	struct adv_sgblk *next_sgblkp;	/* Next scatter-gather structure. */
 } adv_sgblk_t;
 
@@ -2381,7 +2381,7 @@ struct asc_board {
 	adv_req_t *adv_reqp;	/* Request structures. */
 	dma_addr_t adv_reqp_addr;
 	size_t adv_reqp_size;
-	adv_sgblk_t *adv_sgblkp;	/* Scatter-gather structures. */
+	struct dma_pool *adv_sgblk_pool;	/* Scatter-gather structures. */
 	ushort bios_signature;	/* BIOS Signature. */
 	ushort bios_version;	/* BIOS Version. */
 	ushort bios_codeseg;	/* BIOS Code Segment. */
@@ -2650,7 +2650,7 @@ static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
 {
 	int i;
 
-	printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
+	printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
 	       (ulong)b, sgblockno);
 	printk("  sg_cnt %u, sg_ptr 0x%lx\n",
 	       b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
@@ -2672,7 +2672,8 @@ static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
 {
 	int sg_blk_cnt;
-	struct asc_sg_block *sg_ptr;
+	struct adv_sg_block *sg_ptr;
+	adv_sgblk_t *sgblkp;
 
 	printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
 
@@ -2699,21 +2700,15 @@ static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
 
 	/* Display the request's ADV_SG_BLOCK structures. */
 	if (q->sg_list_ptr != NULL) {
+		sgblkp = container_of(q->sg_list_ptr, adv_sgblk_t, sg_block);
 		sg_blk_cnt = 0;
-		while (1) {
-			/*
-			 * 'sg_ptr' is a physical address. Convert it to a virtual
-			 * address by indexing 'sg_blk_cnt' into the virtual address
-			 * array 'sg_list_ptr'.
-			 *
-			 * XXX - Assumes all SG physical blocks are virtually contiguous.
-			 */
-			sg_ptr =
-			    &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
+		while (sgblkp) {
+			sg_ptr = &sgblkp->sg_block;
 			asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
 			if (sg_ptr->sg_ptr == 0) {
 				break;
 			}
+			sgblkp = sgblkp->next_sgblkp;
 			sg_blk_cnt++;
 		}
 	}
@@ -6207,9 +6202,8 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
 		/* Remove 'sgblkp' from the request list. */
 		reqp->sgblkp = sgblkp->next_sgblkp;
 
-		/* Add 'sgblkp' to the board free list. */
-		sgblkp->next_sgblkp = boardp->adv_sgblkp;
-		boardp->adv_sgblkp = sgblkp;
+		dma_pool_free(boardp->adv_sgblk_pool, sgblkp,
+			      sgblkp->sg_addr);
 	}
 
 	ASC_DBG(1, "done\n");
@@ -7903,15 +7897,16 @@ static int
 adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp,
 	       ADV_SCSI_REQ_Q *scsiqp, struct scsi_cmnd *scp, int use_sg)
 {
-	adv_sgblk_t *sgblkp;
+	adv_sgblk_t *sgblkp, *prev_sgblkp;
 	struct scatterlist *slp;
 	int sg_elem_cnt;
 	ADV_SG_BLOCK *sg_block, *prev_sg_block;
-	ADV_PADDR sg_block_paddr;
+	dma_addr_t sgblk_paddr;
 	int i;
 
 	slp = scsi_sglist(scp);
 	sg_elem_cnt = use_sg;
+	prev_sgblkp = NULL;
 	prev_sg_block = NULL;
 	reqp->sgblkp = NULL;
 
@@ -7921,7 +7916,9 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp,
 		 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
 		 * (15) scatter-gather elements.
 		 */
-		if ((sgblkp = boardp->adv_sgblkp) == NULL) {
+		sgblkp = dma_pool_alloc(boardp->adv_sgblk_pool, GFP_ATOMIC,
+					&sgblk_paddr);
+		if (!sgblkp) {
 			ASC_DBG(1, "no free adv_sgblk_t\n");
 			ASC_STATS(scp->device->host, adv_build_nosg);
 
@@ -7932,24 +7929,16 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp,
 			while ((sgblkp = reqp->sgblkp) != NULL) {
 				/* Remove 'sgblkp' from the request list. */
 				reqp->sgblkp = sgblkp->next_sgblkp;
-
-				/* Add 'sgblkp' to the board free list. */
-				sgblkp->next_sgblkp = boardp->adv_sgblkp;
-				boardp->adv_sgblkp = sgblkp;
+				sgblkp->next_sgblkp = NULL;
+				dma_pool_free(boardp->adv_sgblk_pool, sgblkp,
+					      sgblkp->sg_addr);
 			}
 			return ASC_BUSY;
 		}
-
 		/* Complete 'adv_sgblk_t' board allocation. */
-		boardp->adv_sgblkp = sgblkp->next_sgblkp;
+		sgblkp->sg_addr = sgblk_paddr;
 		sgblkp->next_sgblkp = NULL;
-
-		/*
-		 * Get 8 byte aligned virtual and physical addresses
-		 * for the allocated ADV_SG_BLOCK structure.
-		 */
-		sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
-		sg_block_paddr = virt_to_bus(sg_block);
+		sg_block = &sgblkp->sg_block;
 
 		/*
 		 * Check if this is the first 'adv_sgblk_t' for the
@@ -7964,17 +7953,16 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp,
 			 * address pointers.
 			 */
 			scsiqp->sg_list_ptr = sg_block;
-			scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
+			scsiqp->sg_real_addr = cpu_to_le32(sgblk_paddr);
 		} else {
 			/* Request's second or later scatter-gather block. */
-			sgblkp->next_sgblkp = reqp->sgblkp;
-			reqp->sgblkp = sgblkp;
+			prev_sgblkp->next_sgblkp = sgblkp;
 
 			/*
 			 * Point the previous ADV_SG_BLOCK structure to
 			 * the newly allocated ADV_SG_BLOCK structure.
 			 */
-			prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
+			prev_sg_block->sg_ptr = cpu_to_le32(sgblk_paddr);
 		}
 
 		for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
@@ -7985,15 +7973,19 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp,
 			ASC_STATS_ADD(scp->device->host, xfer_sect,
 				      DIV_ROUND_UP(sg_dma_len(slp), 512));
 
-			if (--sg_elem_cnt == 0) {	/* Last ADV_SG_BLOCK and scatter-gather entry. */
+			if (--sg_elem_cnt == 0) {
+				/*
+				 * Last ADV_SG_BLOCK and scatter-gather entry.
+				 */
 				sg_block->sg_cnt = i + 1;
-				sg_block->sg_ptr = 0L;	/* Last ADV_SG_BLOCK in list. */
+				sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
 				return ADV_SUCCESS;
 			}
 			slp++;
 		}
 		sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
 		prev_sg_block = sg_block;
+		prev_sgblkp = sgblkp;
 	}
 }
 
@@ -11157,8 +11149,7 @@ static int advansys_wide_init_chip(struct Scsi_Host *shost)
 {
 	struct asc_board *board = shost_priv(shost);
 	struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
-	int sg_cnt = 0;
-	adv_sgblk_t *sgp;
+	size_t sgblk_pool_size;
 	int warn_code, err_code;
 
 	/*
@@ -11195,22 +11186,14 @@ static int advansys_wide_init_chip(struct Scsi_Host *shost)
 	 * Allocate up to ADV_TOT_SG_BLOCK request structures for
 	 * the Wide board. Each structure is about 136 bytes.
 	 */
-	board->adv_sgblkp = NULL;
-	for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
-		sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
-
-		if (!sgp)
-			break;
-
-		sgp->next_sgblkp = board->adv_sgblkp;
-		board->adv_sgblkp = sgp;
-
-	}
+	sgblk_pool_size = sizeof(adv_sgblk_t) * ADV_TOT_SG_BLOCK;
+	board->adv_sgblk_pool = dma_pool_create("adv_sgblk", board->dev,
+						sgblk_pool_size, 32, 0);
 
-	ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", sg_cnt, sizeof(adv_sgblk_t),
-		 sizeof(adv_sgblk_t) * sg_cnt);
+	ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", ADV_TOT_SG_BLOCK,
+		sizeof(adv_sgblk_t), sgblk_pool_size);
 
-	if (!board->adv_sgblkp)
+	if (!board->adv_sgblk_pool)
 		goto kmalloc_failed;
 
 	if (adv_dvc->chip_type == ADV_CHIP_ASC3550) {
@@ -11253,10 +11236,9 @@ static void advansys_wide_free_mem(struct asc_board *board)
 				  board->adv_reqp, board->adv_reqp_addr);
 		board->adv_reqp = NULL;
 	}
-	while (board->adv_sgblkp) {
-		adv_sgblk_t *sgp = board->adv_sgblkp;
-		board->adv_sgblkp = sgp->next_sgblkp;
-		kfree(sgp);
+	if (board->adv_sgblk_pool) {
+		dma_pool_destroy(board->adv_sgblk_pool);
+		board->adv_sgblk_pool = NULL;
 	}
 }
 
-- 
1.8.5.2


  parent reply	other threads:[~2015-04-24 11:18 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-24 11:18 [PATCHv3 00/23] Nobody loves the advansys driver Hannes Reinecke
2015-04-24 11:18 ` [PATCH 1/2] advansys: Update to version 3.5 and remove compilation warning Hannes Reinecke
2015-04-24 11:19   ` Hannes Reinecke
2015-04-24 11:18 ` [PATCH 01/23] advansys: use host_reset Hannes Reinecke
2015-04-24 11:18 ` [PATCH 02/23] advansys: use shared host tag map for command lookup Hannes Reinecke
2015-04-24 11:18 ` [PATCH 03/23] advansys: use DMA-API for mapping sense buffer Hannes Reinecke
2015-04-24 11:18 ` [PATCH 04/23] advansys: Use DMA-API for carrier buffer Hannes Reinecke
2015-04-24 11:18 ` [PATCH 05/23] advansys: Use DMA-API for mapping request blocks Hannes Reinecke
2015-04-24 11:18 ` Hannes Reinecke [this message]
2015-04-24 11:18 ` [PATCH 07/23] advansys: use 'bool' instead of 'int' Hannes Reinecke
2015-04-24 11:18 ` [PATCH 08/23] advansys: use standard data types Hannes Reinecke
2015-04-24 11:18 ` [PATCH 09/23] advansys: Remove 'TRUE' and 'FALSE' definitions Hannes Reinecke
2015-04-24 11:18 ` [PATCH 10/23] advansys: remove 'ERR' definition Hannes Reinecke
2015-04-24 11:18 ` [PATCH 11/23] advansys: Make AscIsrChipHalted() a void function Hannes Reinecke
2015-04-24 11:18 ` [PATCH 12/23] advansys: cleanup function return codes Hannes Reinecke
2015-04-24 11:18 ` [PATCH 13/23] advansys: scsi_q1->data_addr is little endian Hannes Reinecke
2015-04-24 11:18 ` [PATCH 14/23] advansys: Remove ASC_SCSI_REQ_Q Hannes Reinecke
2015-04-24 11:18 ` [PATCH 15/23] advansys: Remove CC_VERY_LONG_SG_LIST Hannes Reinecke
2015-04-24 11:18 ` [PATCH 16/23] advansys: rename 'ASC_RQ_XX' to 'ADV_RQ_XX' Hannes Reinecke
2015-04-24 11:18 ` [PATCH 17/23] advansys: Remove 'a_flag' Hannes Reinecke
2015-04-24 11:18 ` [PATCH 18/23] advansys: Remove obsolete virtual memory mapping comment Hannes Reinecke
2015-04-24 11:18 ` [PATCH 19/23] advansys: Remove cmd_per_lun setting Hannes Reinecke
2015-04-26 14:57   ` Ondrej Zary
2015-04-26 16:55     ` Christoph Hellwig
2015-04-26 18:23       ` Ondrej Zary
2015-04-26 18:52     ` James Bottomley
2015-04-27  7:02       ` Hannes Reinecke
2015-04-28 21:15         ` James Bottomley
2015-04-24 11:18 ` [PATCH 20/23] advansys: Check for DMA mapping errors Hannes Reinecke
2015-04-24 11:18 ` [PATCH 21/23] advansys: use spin_lock_irqsave() in interrupt handler Hannes Reinecke
2015-04-24 11:18 ` [PATCH 22/23] advansys: Remove call to dma_cache_sync() Hannes Reinecke
2015-04-24 11:18 ` [PATCH 23/23] advansys: Update to version 3.5 and remove compilation warning Hannes Reinecke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1429874322-85488-8-git-send-email-hare@suse.de \
    --to=hare@suse.de \
    --cc=dgilbert@interlog.com \
    --cc=hch@lst.de \
    --cc=jbottomley@parallels.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux@rainbow-software.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).