linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] sg_ring: Gentler scsi merge
@ 2008-01-03  7:00 Rusty Russell
  2008-01-03  8:50 ` [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count Rusty Russell
  2008-01-03  9:42 ` [PATCH 0/2] sg_ring: Gentler scsi merge Boaz Harrosh
  0 siblings, 2 replies; 7+ messages in thread
From: Rusty Russell @ 2008-01-03  7:00 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-scsi

OK, after wading through many scsi drivers, I decided to change tack and try 
to provide a transition path.  This is in two stages:

1) These two patches.  sg_ring used underneath, but if any driver asks for 
scsi_sglist() they get a 2.6.24-style chained sg.  No other patches are 
necessary.

2) Once all chained-sg-needing scsi drivers change to use cmd->sg (ie. 
sg_ring) directly, and the chained sg patches can be reverted.  scsi_sglist() 
and scsi_sg_count() then become:

	/* You should only use these if you never need chained sgs */
	static inline struct scatterlist *scsi_sglist(struct scsi_cmd *cmd)
	{
		BUG_ON(!list_empty(&cmd->sg->list));
		return &cmd->sg->sg[0];
	}

	static unsigned int scsi_sg_count(struct scsi_cmd *cmd)
	{
		if (!cmd->sg)
			return 0;
		BUG_ON(!list_empty(&cmd->sg->list));
		return cmd->sg->num;
	}

Thanks,
Rusty.

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

* [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count
  2008-01-03  7:00 [PATCH 0/2] sg_ring: Gentler scsi merge Rusty Russell
@ 2008-01-03  8:50 ` Rusty Russell
  2008-01-03  8:54   ` [PATCH 2/3] usb_storage: usb_stor_bulk_transfer_sg cleanup Rusty Russell
  2008-01-03  9:26   ` [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count Boaz Harrosh
  2008-01-03  9:42 ` [PATCH 0/2] sg_ring: Gentler scsi merge Boaz Harrosh
  1 sibling, 2 replies; 7+ messages in thread
From: Rusty Russell @ 2008-01-03  8:50 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-scsi

This patch simply converts direct uses of ->use_sg and ->request_buffer to
use the wrapper macros.  This removes the assumption that the sg list is
overloaded on request_buffer, and that there's an explicit use_sg field.

The ->request_buffer assumption is explicit in scsi_debug.c's paranoid
checking, so that code had to be shuffled a little.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 drivers/scsi/NCR5380.c       |    6 +++---
 drivers/scsi/NCR53C9x.c      |    6 +++---
 drivers/scsi/aha1542.c       |   14 +++++++-------
 drivers/scsi/atari_NCR5380.c |    2 +-
 drivers/scsi/atp870u.c       |   22 +++++++++++-----------
 drivers/scsi/eata_pio.c      |    6 +++---
 drivers/scsi/fd_mcs.c        |    6 +++---
 drivers/scsi/imm.c           |    5 ++---
 drivers/scsi/in2000.c        |    6 +++---
 drivers/scsi/libsrp.c        |   12 ++++++------
 drivers/scsi/pcmcia/nsp_cs.c |    8 ++++----
 drivers/scsi/ppa.c           |    4 ++--
 drivers/scsi/qlogicpti.c     |   12 ++++++------
 drivers/scsi/scsi_debug.c    |   14 +++++++-------
 drivers/scsi/seagate.c       |    4 ++--
 drivers/scsi/sr.c            |    6 +++---
 drivers/scsi/sun3_NCR5380.c  |    6 +++---
 drivers/scsi/sun3x_esp.c     |    4 ++--
 drivers/scsi/wd33c93.c       |    6 +++---
 21 files changed, 77 insertions(+), 76 deletions(-)

diff -r 297d045c5da1 drivers/scsi/NCR5380.c
--- a/drivers/scsi/NCR5380.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/NCR5380.c	Wed Jan 02 18:00:10 2008 +1100
@@ -295,9 +295,9 @@ static __inline__ void initialize_SCp(Sc
 	 * various queues are valid.
 	 */
 
-	if (cmd->use_sg) {
-		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
-		cmd->SCp.buffers_residual = cmd->use_sg - 1;
+	if (scsi_sg_count(cmd)) {
+		cmd->SCp.buffer = scsi_sglist(cmd);
+		cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
 		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
diff -r 297d045c5da1 drivers/scsi/NCR53C9x.c
--- a/drivers/scsi/NCR53C9x.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/NCR53C9x.c	Wed Jan 02 18:00:10 2008 +1100
@@ -910,7 +910,7 @@ EXPORT_SYMBOL(esp_proc_info);
 
 static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
-	if(sp->use_sg == 0) {
+	if(scsi_sg_count(sp) == 0) {
 		sp->SCp.this_residual = sp->request_bufflen;
 		sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
 		sp->SCp.buffers_residual = 0;
@@ -920,8 +920,8 @@ static void esp_get_dmabufs(struct NCR_E
 			sp->SCp.ptr =
 				(char *) virt_to_phys(sp->request_buffer);
 	} else {
-		sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
-		sp->SCp.buffers_residual = sp->use_sg - 1;
+		sp->SCp.buffer = scsi_sglist(sp->request_buffer);
+		sp->SCp.buffers_residual = scsi_sg_count(sp) - 1;
 		sp->SCp.this_residual = sp->SCp.buffer->length;
 		if (esp->dma_mmu_get_scsi_sgl)
 			esp->dma_mmu_get_scsi_sgl(esp, sp);
diff -r 297d045c5da1 drivers/scsi/aha1542.c
--- a/drivers/scsi/aha1542.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/aha1542.c	Wed Jan 02 18:00:10 2008 +1100
@@ -689,7 +689,7 @@ static int aha1542_queuecommand(Scsi_Cmn
 
 	memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
 
-	if (SCpnt->use_sg) {
+	if (scsi_sg_count(SCpnt)) {
 		struct scatterlist *sg;
 		struct chain *cptr;
 #ifdef DEBUG
@@ -704,12 +704,12 @@ static int aha1542_queuecommand(Scsi_Cmn
 			HOSTDATA(SCpnt->device->host)->SCint[mbo] = NULL;
 			return SCSI_MLQUEUE_HOST_BUSY;
 		}
-		scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
-			if (sg->length == 0 || SCpnt->use_sg > 16 ||
+		scsi_for_each_sg(SCpnt, sg, scsi_sg_count(SCpnt), i) {
+			if (sg->length == 0 || scsi_sg_count(SCpnt) > 16 ||
 			    (((int) sg->offset) & 1) || (sg->length & 1)) {
 				unsigned char *ptr;
-				printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
-				scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
+				printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", scsi_sg_count(SCpnt), i);
+				scsi_for_each_sg(SCpnt, sg, scsi_sg_count(SCpnt), i) {
 					printk(KERN_CRIT "%d: %p %d\n", i,
 					       sg_virt(sg), sg->length);
 				};
@@ -721,10 +721,10 @@ static int aha1542_queuecommand(Scsi_Cmn
 			};
 			any2scsi(cptr[i].dataptr, SCSI_SG_PA(sg));
 			if (SCSI_SG_PA(sg) + sg->length - 1 > ISA_DMA_THRESHOLD)
-				BAD_SG_DMA(SCpnt, sg, SCpnt->use_sg, i);
+				BAD_SG_DMA(SCpnt, sg, scsi_sg_count(SCpnt), i);
 			any2scsi(cptr[i].datalen, sg->length);
 		};
-		any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
+		any2scsi(ccb[mbo].datalen, scsi_sg_count(SCpnt) * sizeof(struct chain));
 		any2scsi(ccb[mbo].dataptr, SCSI_BUF_PA(cptr));
 #ifdef DEBUG
 		printk("cptr %x: ", cptr);
diff -r 297d045c5da1 drivers/scsi/atari_NCR5380.c
--- a/drivers/scsi/atari_NCR5380.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/atari_NCR5380.c	Wed Jan 02 18:00:10 2008 +1100
@@ -512,7 +512,7 @@ static inline void initialize_SCp(Scsi_C
 	 */
 
 	if (cmd->use_sg) {
-		cmd->SCp.buffer = (struct scatterlist *)cmd->request_buffer;
+		cmd->SCp.buffer = scsi_sglist(cmd->request_buffer);
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
 		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
diff -r 297d045c5da1 drivers/scsi/atp870u.c
--- a/drivers/scsi/atp870u.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/atp870u.c	Wed Jan 02 18:00:10 2008 +1100
@@ -471,10 +471,10 @@ go_42:
 			/*
 			 *	Complete the command
 			 */
-			if (workreq->use_sg) {
+			if (scsi_sg_count(workreq)) {
 				pci_unmap_sg(dev->pdev,
-					(struct scatterlist *)workreq->request_buffer,
-					workreq->use_sg,
+					scsi_sglist(workreq->request_buffer),
+					scsi_sg_count(workreq), 
 					workreq->sc_data_direction);
 			} else if (workreq->request_bufflen &&
 					workreq->sc_data_direction != DMA_NONE) {
@@ -855,18 +855,18 @@ oktosend:
 	/*
 	 *	Figure out the transfer size
 	 */
-	if (workreq->use_sg) {
+	if (scsi_sg_count(workreq)) {
 #ifdef ED_DBGP
 		printk("Using SGL\n");
 #endif		
 		l = 0;
 		
-		sgpnt = (struct scatterlist *) workreq->request_buffer;
-		sg_count = pci_map_sg(dev->pdev, sgpnt, workreq->use_sg,
+		sgpnt = scsi_sglist(workreq);
+		sg_count = pci_map_sg(dev->pdev, sgpnt, scsi_sg_count(workreq),
 	   			workreq->sc_data_direction);		
 		
-		for (i = 0; i < workreq->use_sg; i++) {
-			if (sgpnt[i].length == 0 || workreq->use_sg > ATP870U_SCATTER) {
+		for (i = 0; i < scsi_sg_count(workreq); i++) {
+			if (sgpnt[i].length == 0 || scsi_sg_count(workreq) > ATP870U_SCATTER) {
 				panic("Foooooooood fight!");
 			}
 			l += sgpnt[i].length;
@@ -938,10 +938,10 @@ oktosend:
 	 *	a linear chain.
 	 */
 
-	if (workreq->use_sg) {
-		sgpnt = (struct scatterlist *) workreq->request_buffer;
+	if (scsi_sg_count(workreq)) {
+		sgpnt = scsi_sglist(workreq->request_buffer);
 		i = 0;
-		for (j = 0; j < workreq->use_sg; j++) {
+		for (j = 0; j < scsi_sg_count(workreq); j++) {
 			bttl = sg_dma_address(&sgpnt[j]);
 			l=sg_dma_len(&sgpnt[j]);
 #ifdef ED_DBGP		
diff -r 297d045c5da1 drivers/scsi/eata_pio.c
--- a/drivers/scsi/eata_pio.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/eata_pio.c	Wed Jan 02 18:00:10 2008 +1100
@@ -402,14 +402,14 @@ static int eata_pio_queue(struct scsi_cm
 	cp->cmd = cmd;
 	cmd->host_scribble = (char *) &hd->ccb[y];
 
-	if (cmd->use_sg == 0) {
+	if (scsi_sg_count(cmd) == 0) {
 		cmd->SCp.buffers_residual = 1;
 		cmd->SCp.ptr = cmd->request_buffer;
 		cmd->SCp.this_residual = cmd->request_bufflen;
 		cmd->SCp.buffer = NULL;
 	} else {
-		cmd->SCp.buffer = cmd->request_buffer;
-		cmd->SCp.buffers_residual = cmd->use_sg;
+		cmd->SCp.buffer = scsi_sglist(cmd);
+		cmd->SCp.buffers_residual = scsi_sg_count(cmd);
 		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	}
diff -r 297d045c5da1 drivers/scsi/fd_mcs.c
--- a/drivers/scsi/fd_mcs.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/fd_mcs.c	Wed Jan 02 18:00:10 2008 +1100
@@ -1107,11 +1107,11 @@ static int fd_mcs_queue(Scsi_Cmnd * SCpn
 
 	/* Initialize static data */
 
-	if (current_SC->use_sg) {
-		current_SC->SCp.buffer = (struct scatterlist *) current_SC->request_buffer;
+	if (scsi_sg_count(current_SC)) {
+		current_SC->SCp.buffer = scsi_sglist(current_SC->request_buffer);
 		current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 		current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
-		current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
+		current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
 	} else {
 		current_SC->SCp.ptr = (char *) current_SC->request_buffer;
 		current_SC->SCp.this_residual = current_SC->request_bufflen;
diff -r 297d045c5da1 drivers/scsi/imm.c
--- a/drivers/scsi/imm.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/imm.c	Wed Jan 02 18:00:10 2008 +1100
@@ -837,10 +837,9 @@ static int imm_engine(imm_struct *dev, s
 
 		/* Phase 4 - Setup scatter/gather buffers */
 	case 4:
-		if (cmd->use_sg) {
+		if (scsi_sg_count(cmd)) {
 			/* if many buffers are available, start filling the first */
-			cmd->SCp.buffer =
-			    (struct scatterlist *) cmd->request_buffer;
+			cmd->SCp.buffer = scsi_sglist(cmd);
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
 			cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		} else {
diff -r 297d045c5da1 drivers/scsi/in2000.c
--- a/drivers/scsi/in2000.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/in2000.c	Wed Jan 02 18:00:10 2008 +1100
@@ -369,9 +369,9 @@ static int in2000_queuecommand(Scsi_Cmnd
  *  - SCp.phase records this command's SRCID_ER bit setting
  */
 
-	if (cmd->use_sg) {
-		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
-		cmd->SCp.buffers_residual = cmd->use_sg - 1;
+	if (scsi_sg_count(cmd)) {
+		cmd->SCp.buffer = scsi_sglist(cmd->request_buffer);
+		cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
 		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
diff -r 297d045c5da1 drivers/scsi/libsrp.c
--- a/drivers/scsi/libsrp.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/libsrp.c	Wed Jan 02 18:00:10 2008 +1100
@@ -192,15 +192,15 @@ static int srp_direct_data(struct scsi_c
 
 	if (dma_map) {
 		iue = (struct iu_entry *) sc->SCp.ptr;
-		sg = sc->request_buffer;
+		sg = scsi_sglist(sc);
 
 		dprintk("%p %u %u %d\n", iue, sc->request_bufflen,
 			md->len, sc->use_sg);
 
-		nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg,
+		nsg = dma_map_sg(iue->target->dev, sg, scsi_sg_count(sc),
 				 DMA_BIDIRECTIONAL);
 		if (!nsg) {
-			printk("fail to map %p %d\n", iue, sc->use_sg);
+			printk("fail to map %p %d\n", iue, scsi_sg_count(sc));
 			return 0;
 		}
 		len = min(sc->request_bufflen, md->len);
@@ -229,7 +229,7 @@ static int srp_indirect_data(struct scsi
 
 	if (dma_map || ext_desc) {
 		iue = (struct iu_entry *) sc->SCp.ptr;
-		sg = sc->request_buffer;
+		sg = scsi_sglist(sc);
 
 		dprintk("%p %u %u %d %d\n",
 			iue, sc->request_bufflen, id->len,
@@ -268,9 +268,9 @@ static int srp_indirect_data(struct scsi
 
 rdma:
 	if (dma_map) {
-		nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg, DMA_BIDIRECTIONAL);
+		nsg = dma_map_sg(iue->target->dev, sg, scsi_sg_count(sc), DMA_BIDIRECTIONAL);
 		if (!nsg) {
-			eprintk("fail to map %p %d\n", iue, sc->use_sg);
+			eprintk("fail to map %p %d\n", iue, scsi_sg_count(sc));
 			err = -EIO;
 			goto free_mem;
 		}
diff -r 297d045c5da1 drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/pcmcia/nsp_cs.c	Wed Jan 02 18:00:10 2008 +1100
@@ -233,11 +233,11 @@ static int nsp_queuecommand(struct scsi_
 	   SCp.buffer		: next buffer
 	   SCp.buffers_residual : left buffers in list
 	   SCp.phase		: current state of the command */
-	if (SCpnt->use_sg) {
-		SCpnt->SCp.buffer	    = (struct scatterlist *) SCpnt->request_buffer;
+	if (scsi_sg_count(SCpnt)) {
+		SCpnt->SCp.buffer	    = scsi_sglist(SCpnt);
 		SCpnt->SCp.ptr		    = BUFFER_ADDR;
 		SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;
-		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
+		SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
 	} else {
 		SCpnt->SCp.ptr		    = (char *) SCpnt->request_buffer;
 		SCpnt->SCp.this_residual    = SCpnt->request_bufflen;
@@ -911,7 +911,7 @@ static int nsp_nexus(struct scsi_cmnd *S
 	nsp_index_write(base, SYNCREG,	sync->SyncRegister);
 	nsp_index_write(base, ACKWIDTH, sync->AckWidth);
 
-	if (SCpnt->use_sg    == 0        ||
+	if (scsi_sg_count(SCpnt) == 0    ||
 	    SCpnt->resid % 4 != 0        ||
 	    SCpnt->resid     <= PAGE_SIZE ) {
 		data->TransferMode = MODE_IO8;
diff -r 297d045c5da1 drivers/scsi/ppa.c
--- a/drivers/scsi/ppa.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/ppa.c	Wed Jan 02 18:00:10 2008 +1100
@@ -750,9 +750,9 @@ static int ppa_engine(ppa_struct *dev, s
 		cmd->SCp.phase++;
 
 	case 4:		/* Phase 4 - Setup scatter/gather buffers */
-		if (cmd->use_sg) {
+		if (scsi_sg_count(cmd)) {
 			/* if many buffers are available, start filling the first */
-			cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
+			cmd->SCp.buffer = scsi_sglist(cmd);
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
 			cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		} else {
diff -r 297d045c5da1 drivers/scsi/qlogicpti.c
--- a/drivers/scsi/qlogicpti.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/qlogicpti.c	Wed Jan 02 18:00:10 2008 +1100
@@ -871,11 +871,11 @@ static inline int load_cmd(struct scsi_c
 	struct scatterlist *sg, *s;
 	int i, n;
 
-	if (Cmnd->use_sg) {
+	if (scsi_sg_count(Cmnd)) {
 		int sg_count;
 
-		sg = (struct scatterlist *) Cmnd->request_buffer;
-		sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction);
+		sg = scsi_sglist(Cmnd);
+		sg_count = sbus_map_sg(qpti->sdev, sg, scsi_sg_count(Cmnd), Cmnd->sc_data_direction);
 
 		ds = cmd->dataseg;
 		cmd->segment_cnt = sg_count;
@@ -1159,10 +1159,10 @@ static struct scsi_cmnd *qlogicpti_intr_
 		else
 			Cmnd->result = DID_ERROR << 16;
 
-		if (Cmnd->use_sg) {
+		if (scsi_sg_count(Cmnd)) {
 			sbus_unmap_sg(qpti->sdev,
-				      (struct scatterlist *)Cmnd->request_buffer,
-				      Cmnd->use_sg,
+				      scsi_sglist(Cmnd->request_buffer),
+				      scsi_sg_count(Cmnd),
 				      Cmnd->sc_data_direction);
 		} else if (Cmnd->request_bufflen) {
 			sbus_unmap_single(qpti->sdev,
diff -r 297d045c5da1 drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/scsi_debug.c	Wed Jan 02 18:00:10 2008 +1100
@@ -605,12 +605,10 @@ static int fill_from_dev_buffer(struct s
 
 	if (0 == scp->request_bufflen)
 		return 0;
-	if (NULL == scp->request_buffer)
-		return (DID_ERROR << 16);
 	if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
 	      (scp->sc_data_direction == DMA_FROM_DEVICE)))
 		return (DID_ERROR << 16);
-	if (0 == scp->use_sg) {
+	if (0 == scsi_sg_count(scp)) {
 		req_len = scp->request_bufflen;
 		act_len = (req_len < arr_len) ? req_len : arr_len;
 		memcpy(scp->request_buffer, arr, act_len);
@@ -620,9 +618,11 @@ static int fill_from_dev_buffer(struct s
 			scp->resid = req_len - act_len;
 		return 0;
 	}
+	if (!scsi_sglist(scp))
+		return (DID_ERROR << 16);
 	active = 1;
 	req_len = act_len = 0;
-	scsi_for_each_sg(scp, sg, scp->use_sg, k) {
+	scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) {
 		if (active) {
 			kaddr = (unsigned char *)
 				kmap_atomic(sg_page(sg), KM_USER0);
@@ -658,12 +658,12 @@ static int fetch_to_dev_buffer(struct sc
 
 	if (0 == scp->request_bufflen)
 		return 0;
-	if (NULL == scp->request_buffer)
+	if (NULL == scsi_sglist(scp))
 		return -1;
 	if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
 	      (scp->sc_data_direction == DMA_TO_DEVICE)))
 		return -1;
-	if (0 == scp->use_sg) {
+	if (0 == scsi_sg_count(scp)) {
 		req_len = scp->request_bufflen;
 		len = (req_len < max_arr_len) ? req_len : max_arr_len;
 		memcpy(arr, scp->request_buffer, len);
@@ -671,7 +671,7 @@ static int fetch_to_dev_buffer(struct sc
 	}
 	sg = scsi_sglist(scp);
 	req_len = fin = 0;
-	for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
+	for (k = 0; k < scsi_sg_count(scp); ++k, sg = sg_next(sg)) {
 		kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
 		if (NULL == kaddr)
 			return -1;
diff -r 297d045c5da1 drivers/scsi/seagate.c
--- a/drivers/scsi/seagate.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/seagate.c	Wed Jan 02 18:00:10 2008 +1100
@@ -991,7 +991,7 @@ connect_loop:
 
 		/* Establish current pointers.  Take into account scatter / gather */
 
-		if ((nobuffs = SCint->use_sg)) {
+		if ((nobuffs = scsi_sg_count(SCint))) {
 #if (DEBUG & DEBUG_SG)
 			{
 				int i;
@@ -1004,7 +1004,7 @@ connect_loop:
 			}
 #endif
 
-			buffer = (struct scatterlist *) SCint->request_buffer;
+			buffer = scsi_sglist(SCint->request_buffer);
 			len = buffer->length;
 			data = sg_virt(buffer);
 		} else {
diff -r 297d045c5da1 drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/sr.c	Wed Jan 02 18:00:10 2008 +1100
@@ -366,12 +366,12 @@ static int sr_prep_fn(struct request_que
 	}
 
 	{
-		struct scatterlist *sg = SCpnt->request_buffer;
+		struct scatterlist *sg = scsi_sglist(SCpnt);
 		int i, size = 0;
-		for (i = 0; i < SCpnt->use_sg; i++)
+		for (i = 0; i < scsi_sg_count(SCpnt); i++)
 			size += sg[i].length;
 
-		if (size != SCpnt->request_bufflen && SCpnt->use_sg) {
+		if (size != SCpnt->request_bufflen && scsi_sg_count(SCpnt)) {
 			scmd_printk(KERN_ERR, SCpnt,
 				"mismatch count %d, bytes %d\n",
 				size, SCpnt->request_bufflen);
diff -r 297d045c5da1 drivers/scsi/sun3_NCR5380.c
--- a/drivers/scsi/sun3_NCR5380.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/sun3_NCR5380.c	Wed Jan 02 18:00:10 2008 +1100
@@ -515,9 +515,9 @@ static __inline__ void initialize_SCp(st
      * various queues are valid.
      */
 
-    if (cmd->use_sg) {
-	cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
-	cmd->SCp.buffers_residual = cmd->use_sg - 1;
+    if (scsi_sg_count(cmd)) {
+	cmd->SCp.buffer = scsi_sglist(cmd);
+	cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
 	cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer);
 	cmd->SCp.this_residual = cmd->SCp.buffer->length;
 
diff -r 297d045c5da1 drivers/scsi/sun3x_esp.c
--- a/drivers/scsi/sun3x_esp.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/sun3x_esp.c	Wed Jan 02 18:00:10 2008 +1100
@@ -346,8 +346,8 @@ static void dma_mmu_release_scsi_one (st
 
 static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
-    int sz = sp->use_sg - 1;
-    struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
+    int sz = scsi_sg_count(sp) - 1;
+    struct scatterlist *sg = scsi_sglist(sp);
                         
     while(sz >= 0) {
         dvma_unmap((char *)sg[sz].dma_address);
diff -r 297d045c5da1 drivers/scsi/wd33c93.c
--- a/drivers/scsi/wd33c93.c	Wed Jan 02 17:18:59 2008 +1100
+++ b/drivers/scsi/wd33c93.c	Wed Jan 02 18:00:10 2008 +1100
@@ -407,9 +407,9 @@ wd33c93_queuecommand(struct scsi_cmnd *c
  *  - SCp.phase records this command's SRCID_ER bit setting
  */
 
-	if (cmd->use_sg) {
-		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
-		cmd->SCp.buffers_residual = cmd->use_sg - 1;
+	if (scsi_sgcount(cmd)) {
+		cmd->SCp.buffer = scsi_sg_list(cmd);
+		cmd->SCp.buffers_residual = scsi_sgcount(cmd) - 1;
 		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {

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

* [PATCH 2/3] usb_storage: usb_stor_bulk_transfer_sg cleanup
  2008-01-03  8:50 ` [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count Rusty Russell
@ 2008-01-03  8:54   ` Rusty Russell
  2008-01-03  8:55     ` [PATCH 3/3] scsi: convert core to sg_ring Rusty Russell
  2008-01-03  9:26   ` [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count Boaz Harrosh
  1 sibling, 1 reply; 7+ messages in thread
From: Rusty Russell @ 2008-01-03  8:54 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-scsi

usb_stor_bulk_transfer_sg() assumes buf is a scatterlist array if
use_sg is non-NULL.  Change it to an explicit sg arg, instead, to
allow the callers to change to scsi_sglist().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

diff -r 09247461cfda drivers/usb/storage/freecom.c
--- a/drivers/usb/storage/freecom.c	Thu Jan 03 19:30:25 2008 +1100
+++ b/drivers/usb/storage/freecom.c	Thu Jan 03 19:51:09 2008 +1100
@@ -133,7 +133,7 @@ freecom_readdata (struct scsi_cmnd *srb,
 	/* Now transfer all of our blocks. */
 	US_DEBUGP("Start of read\n");
 	result = usb_stor_bulk_transfer_sg(us, ipipe, srb->request_buffer,
-			count, srb->use_sg, &srb->resid);
+			count, scsi_sglist(srb), scsi_sg_count(srb), &srb->resid);
 	US_DEBUGP("freecom_readdata done!\n");
 
 	if (result > USB_STOR_XFER_SHORT)
@@ -167,7 +167,7 @@ freecom_writedata (struct scsi_cmnd *srb
 	/* Now transfer all of our blocks. */
 	US_DEBUGP("Start of write\n");
 	result = usb_stor_bulk_transfer_sg(us, opipe, srb->request_buffer,
-			count, srb->use_sg, &srb->resid);
+			count, scsi_sglist(srb), scsi_sg_count(srb), &srb->resid);
 
 	US_DEBUGP("freecom_writedata done!\n");
 	if (result > USB_STOR_XFER_SHORT)
diff -r 09247461cfda drivers/usb/storage/sddr09.c
--- a/drivers/usb/storage/sddr09.c	Thu Jan 03 19:30:25 2008 +1100
+++ b/drivers/usb/storage/sddr09.c	Thu Jan 03 19:51:09 2008 +1100
@@ -355,7 +355,7 @@ static int
 static int
 sddr09_readX(struct us_data *us, int x, unsigned long fromaddress,
 	     int nr_of_pages, int bulklen, unsigned char *buf,
-	     int use_sg) {
+	     struct scatterlist *sg, int use_sg) {
 
 	unsigned char *command = us->iobuf;
 	int result;
@@ -382,7 +382,7 @@ sddr09_readX(struct us_data *us, int x, 
 	}
 
 	result = usb_stor_bulk_transfer_sg(us, us->recv_bulk_pipe,
-				       buf, bulklen, use_sg, NULL);
+					   buf, bulklen, sg, use_sg, NULL);
 
 	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n",
@@ -403,12 +403,13 @@ sddr09_readX(struct us_data *us, int x, 
  */
 static int
 sddr09_read20(struct us_data *us, unsigned long fromaddress,
-	      int nr_of_pages, int pageshift, unsigned char *buf, int use_sg) {
+	      int nr_of_pages, int pageshift, unsigned char *buf,
+	      struct scatterlist *sg, int use_sg) {
 	int bulklen = nr_of_pages << pageshift;
 
 	/* The last 8 bits of fromaddress are ignored. */
 	return sddr09_readX(us, 0, fromaddress, nr_of_pages, bulklen,
-			    buf, use_sg);
+			    buf, sg, use_sg);
 }
 
 /*
@@ -426,11 +427,12 @@ sddr09_read20(struct us_data *us, unsign
  */
 static int
 sddr09_read21(struct us_data *us, unsigned long fromaddress,
-	      int count, int controlshift, unsigned char *buf, int use_sg) {
+	      int count, int controlshift, unsigned char *buf,
+	      struct scatterlist *sg, int use_sg) {
 
 	int bulklen = (count << controlshift);
 	return sddr09_readX(us, 1, fromaddress, count, bulklen,
-			    buf, use_sg);
+			    buf, sg, use_sg);
 }
 
 /*
@@ -444,13 +446,14 @@ sddr09_read21(struct us_data *us, unsign
  */
 static int
 sddr09_read22(struct us_data *us, unsigned long fromaddress,
-	      int nr_of_pages, int pageshift, unsigned char *buf, int use_sg) {
+	      int nr_of_pages, int pageshift, unsigned char *buf,
+	      struct scatterlist *sg, int use_sg) {
 
 	int bulklen = (nr_of_pages << pageshift) + (nr_of_pages << CONTROL_SHIFT);
 	US_DEBUGP("sddr09_read22: reading %d pages, %d bytes\n",
 		  nr_of_pages, bulklen);
 	return sddr09_readX(us, 2, fromaddress, nr_of_pages, bulklen,
-			    buf, use_sg);
+			    buf, sg, use_sg);
 }
 
 #if 0
@@ -538,7 +541,8 @@ static int
 static int
 sddr09_writeX(struct us_data *us,
 	      unsigned long Waddress, unsigned long Eaddress,
-	      int nr_of_pages, int bulklen, unsigned char *buf, int use_sg) {
+	      int nr_of_pages, int bulklen, unsigned char *buf,
+	      struct scatterlist *sg, int use_sg) {
 
 	unsigned char *command = us->iobuf;
 	int result;
@@ -568,7 +572,7 @@ sddr09_writeX(struct us_data *us,
 	}
 
 	result = usb_stor_bulk_transfer_sg(us, us->send_bulk_pipe,
-				       buf, bulklen, use_sg, NULL);
+				       buf, bulklen, sg, use_sg, NULL);
 
 	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n",
@@ -582,10 +586,10 @@ static int
 static int
 sddr09_write_inplace(struct us_data *us, unsigned long address,
 		     int nr_of_pages, int pageshift, unsigned char *buf,
-		     int use_sg) {
+		     struct scatterlist *sg, int use_sg) {
 	int bulklen = (nr_of_pages << pageshift) + (nr_of_pages << CONTROL_SHIFT);
 	return sddr09_writeX(us, address, address, nr_of_pages, bulklen,
-			     buf, use_sg);
+			     buf, sg, use_sg);
 }
 
 #if 0
@@ -772,7 +776,7 @@ sddr09_read_data(struct us_data *us,
 				info->pageshift;
 
 			result = sddr09_read20(us, address>>1,
-					pages, info->pageshift, buffer, 0);
+					pages, info->pageshift, buffer, NULL, 0);
 			if (result)
 				break;
 		}
@@ -858,7 +862,7 @@ sddr09_write_lba(struct us_data *us, uns
 	/* read old contents */
 	address = (pba << (info->pageshift + info->blockshift));
 	result = sddr09_read22(us, address>>1, info->blocksize,
-			       info->pageshift, blockbuffer, 0);
+			       info->pageshift, blockbuffer, NULL, 0);
 	if (result)
 		return result;
 
@@ -898,7 +902,7 @@ sddr09_write_lba(struct us_data *us, uns
 	US_DEBUGP("Rewrite PBA %d (LBA %d)\n", pba, lba);
 
 	result = sddr09_write_inplace(us, address>>1, info->blocksize,
-				      info->pageshift, blockbuffer, 0);
+				      info->pageshift, blockbuffer, NULL, 0);
 
 	US_DEBUGP("sddr09_write_inplace returns %d\n", result);
 
@@ -1014,13 +1018,14 @@ sddr09_read_control(struct us_data *us,
 		unsigned long address,
 		unsigned int blocks,
 		unsigned char *content,
+		struct scatterlist *sg,
 		int use_sg) {
 
 	US_DEBUGP("Read control address %lu, blocks %d\n",
 		address, blocks);
 
 	return sddr09_read21(us, address, blocks,
-			     CONTROL_SHIFT, content, use_sg);
+			     CONTROL_SHIFT, content, sg, use_sg);
 }
 
 /*
@@ -1220,7 +1225,7 @@ sddr09_read_map(struct us_data *us) {
 			result = sddr09_read_control(
 				us, address>>1,
 				min(alloc_blocks, numblocks - i),
-				buffer, 0);
+				buffer, NULL, 0);
 			if (result) {
 				result = -1;
 				goto done;
@@ -1639,7 +1644,8 @@ int sddr09_transport(struct scsi_cmnd *s
 		result = usb_stor_bulk_transfer_sg(us, pipe,
 					srb->request_buffer,
 					srb->request_bufflen,
-					srb->use_sg, &srb->resid);
+					scsi_sglist(srb), scsi_sg_count(srb),
+					&srb->resid);
 
 		return (result == USB_STOR_XFER_GOOD ?
 			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
diff -r 09247461cfda drivers/usb/storage/shuttle_usbat.c
--- a/drivers/usb/storage/shuttle_usbat.c	Thu Jan 03 19:30:25 2008 +1100
+++ b/drivers/usb/storage/shuttle_usbat.c	Thu Jan 03 19:51:09 2008 +1100
@@ -132,13 +132,14 @@ static int usbat_bulk_read(struct us_dat
 static int usbat_bulk_read(struct us_data *us,
 			   unsigned char *data,
 			   unsigned int len,
+			   struct scatterlist *sg,
 			   int use_sg)
 {
 	if (len == 0)
 		return USB_STOR_XFER_GOOD;
 
 	US_DEBUGP("usbat_bulk_read: len = %d\n", len);
-	return usb_stor_bulk_transfer_sg(us, us->recv_bulk_pipe, data, len, use_sg, NULL);
+	return usb_stor_bulk_transfer_sg(us, us->recv_bulk_pipe, data, len, sg, use_sg, NULL);
 }
 
 /*
@@ -147,13 +148,14 @@ static int usbat_bulk_write(struct us_da
 static int usbat_bulk_write(struct us_data *us,
 			    unsigned char *data,
 			    unsigned int len,
+			    struct scatterlist *sg,
 			    int use_sg)
 {
 	if (len == 0)
 		return USB_STOR_XFER_GOOD;
 
 	US_DEBUGP("usbat_bulk_write:  len = %d\n", len);
-	return usb_stor_bulk_transfer_sg(us, us->send_bulk_pipe, data, len, use_sg, NULL);
+	return usb_stor_bulk_transfer_sg(us, us->send_bulk_pipe, data, len, sg, use_sg, NULL);
 }
 
 /*
@@ -316,6 +318,7 @@ static int usbat_read_block(struct us_da
 static int usbat_read_block(struct us_data *us,
 			    unsigned char *content,
 			    unsigned short len,
+			    struct scatterlist *sg,
 			    int use_sg)
 {
 	int result;
@@ -337,7 +340,7 @@ static int usbat_read_block(struct us_da
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
-	result = usbat_bulk_read(us, content, len, use_sg);
+	result = usbat_bulk_read(us, content, len, sg, use_sg);
 	return (result == USB_STOR_XFER_GOOD ?
 			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
 }
@@ -350,6 +353,7 @@ static int usbat_write_block(struct us_d
 			     unsigned char *content,
 			     unsigned short len,
 			     int minutes,
+			     struct scatterlist *sg,
 			     int use_sg)
 {
 	int result;
@@ -372,7 +376,7 @@ static int usbat_write_block(struct us_d
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
-	result = usbat_bulk_write(us, content, len, use_sg);
+	result = usbat_bulk_write(us, content, len, sg, use_sg);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
@@ -394,6 +398,7 @@ static int usbat_hp8200e_rw_block_test(s
 				       int direction,
 				       unsigned char *content,
 				       unsigned short len,
+				       struct scatterlist *sg,
 				       int use_sg,
 				       int minutes)
 {
@@ -465,14 +470,15 @@ static int usbat_hp8200e_rw_block_test(s
 				data[1+(j<<1)] = data_out[j];
 			}
 
-			result = usbat_bulk_write(us, data, num_registers*2, 0);
+			result = usbat_bulk_write(us, data, num_registers*2,
+						  NULL, 0);
 			if (result != USB_STOR_XFER_GOOD)
 				return USB_STOR_TRANSPORT_ERROR;
 
 		}
 
 		result = usb_stor_bulk_transfer_sg(us,
-			pipe, content, len, use_sg, NULL);
+			pipe, content, len, sg, use_sg, NULL);
 
 		/*
 		 * If we get a stall on the bulk download, we'll retry
@@ -583,7 +589,7 @@ static int usbat_multiple_write(struct u
 	}
 
 	/* Send the data */
-	result = usbat_bulk_write(us, data, num_registers*2, 0);
+	result = usbat_bulk_write(us, data, num_registers*2, NULL,0);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
@@ -608,6 +614,7 @@ static int usbat_read_blocks(struct us_d
 static int usbat_read_blocks(struct us_data *us,
 			     unsigned char *buffer,
 			     int len,
+			     struct scatterlist *sg,
 			     int use_sg)
 {
 	int result;
@@ -628,7 +635,7 @@ static int usbat_read_blocks(struct us_d
 		return USB_STOR_TRANSPORT_FAILED;
 	
 	/* Read the blocks we just asked for */
-	result = usbat_bulk_read(us, buffer, len, use_sg);
+	result = usbat_bulk_read(us, buffer, len, sg, use_sg);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_FAILED;
 
@@ -650,6 +657,7 @@ static int usbat_write_blocks(struct us_
 static int usbat_write_blocks(struct us_data *us,
 							  unsigned char *buffer,
 			      int len,
+			      struct scatterlist *sg,
 			      int use_sg)
 {
 	int result;
@@ -670,7 +678,7 @@ static int usbat_write_blocks(struct us_
 		return USB_STOR_TRANSPORT_FAILED;
 	
 	/* Write the data */
-	result = usbat_bulk_write(us, buffer, len, use_sg);
+	result = usbat_bulk_write(us, buffer, len, sg, use_sg);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_FAILED;
 
@@ -955,7 +963,7 @@ static int usbat_flash_get_sector_count(
 	msleep(100);
 
 	/* Read the device identification data */
-	rc = usbat_read_block(us, reply, 512, 0);
+	rc = usbat_read_block(us, reply, 512, NULL, 0);
 	if (rc != USB_STOR_TRANSPORT_GOOD)
 		goto leave;
 
@@ -1040,7 +1048,7 @@ static int usbat_flash_read_data(struct 
 			goto leave;
 
 		/* Read the data we just requested */
-		result = usbat_read_blocks(us, buffer, len, 0);
+		result = usbat_read_blocks(us, buffer, len, NULL, 0);
 		if (result != USB_STOR_TRANSPORT_GOOD)
 			goto leave;
   	 
@@ -1135,7 +1143,7 @@ static int usbat_flash_write_data(struct
 			goto leave;
 
 		/* Write the data */
-		result = usbat_write_blocks(us, buffer, len, 0);
+		result = usbat_write_blocks(us, buffer, len, NULL, 0);
 		if (result != USB_STOR_TRANSPORT_GOOD)
 			goto leave;
 
@@ -1178,7 +1186,8 @@ static int usbat_hp8200e_handle_read10(s
 			(USBAT_QUAL_FCQ | USBAT_QUAL_ALQ),
 			DMA_FROM_DEVICE,
 			srb->request_buffer, 
-			srb->request_bufflen, srb->use_sg, 1);
+		        srb->request_bufflen,
+			scsi_sglist(srb), scsi_sg_count(srb), 1);
 
 		return result;
 	}
@@ -1247,7 +1256,7 @@ static int usbat_hp8200e_handle_read10(s
 			(USBAT_QUAL_FCQ | USBAT_QUAL_ALQ),
 			DMA_FROM_DEVICE,
 			buffer,
-			len, 0, 1);
+			len, NULL, 0, 1);
 
 		if (result != USB_STOR_TRANSPORT_GOOD)
 			break;
@@ -1473,7 +1482,7 @@ static int usbat_hp8200e_transport(struc
 			(USBAT_QUAL_FCQ | USBAT_QUAL_ALQ),
 			DMA_TO_DEVICE,
 			srb->request_buffer, 
-			len, srb->use_sg, 10);
+			len, scsi_sglist(srb), scsi_sg_count(srb), 10);
 
 		if (result == USB_STOR_TRANSPORT_GOOD) {
 			transferred += len;
@@ -1512,7 +1521,7 @@ static int usbat_hp8200e_transport(struc
 
 	if ((result = usbat_write_block(us,
 			USBAT_ATA, srb->cmnd, 12,
-				(srb->cmnd[0]==GPCMD_BLANK ? 75 : 10), 0) !=
+				(srb->cmnd[0]==GPCMD_BLANK ? 75 : 10), NULL, 0) !=
 			     USB_STOR_TRANSPORT_GOOD)) {
 		return result;
 	}
@@ -1540,11 +1549,12 @@ static int usbat_hp8200e_transport(struc
 			len = *status;
 
 
-		result = usbat_read_block(us, srb->request_buffer, len, srb->use_sg);
+		result = usbat_read_block(us, srb->request_buffer, len,
+		       	 		  scsi_sglist(srb), scsi_sg_count(srb));
 
 		/* Debug-print the first 32 bytes of the transfer */
 
-		if (!srb->use_sg) {
+		if (!scsi_sg_count(srb)) {
 			string[0] = 0;
 			for (i=0; i<len && i<32; i++) {
 				sprintf(string+strlen(string), "%02X ",
diff -r 09247461cfda drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	Thu Jan 03 19:30:25 2008 +1100
+++ b/drivers/usb/storage/transport.c	Thu Jan 03 19:51:09 2008 +1100
@@ -468,7 +468,8 @@ static int usb_stor_bulk_transfer_sglist
  * scatter-gather or not, and acts appropriately.
  */
 int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe,
-		void *buf, unsigned int length_left, int use_sg, int *residual)
+			      void *buf, unsigned int length_left,
+			      struct scatterlist *sg, int use_sg, int *residual)
 {
 	int result;
 	unsigned int partial;
@@ -477,7 +478,7 @@ int usb_stor_bulk_transfer_sg(struct us_
 	if (use_sg) {
 		/* use the usb core scatter-gather primitives */
 		result = usb_stor_bulk_transfer_sglist(us, pipe,
-				(struct scatterlist *) buf, use_sg,
+				sg, use_sg,
 				length_left, &partial);
 		length_left -= partial;
 	} else {
@@ -739,7 +740,8 @@ int usb_stor_CBI_transport(struct scsi_c
 				us->recv_bulk_pipe : us->send_bulk_pipe;
 		result = usb_stor_bulk_transfer_sg(us, pipe,
 					srb->request_buffer, transfer_length,
-					srb->use_sg, &srb->resid);
+					scsi_sglist(srb), scsi_sg_count(srb),
+					&srb->resid);
 		US_DEBUGP("CBI data stage result is 0x%x\n", result);
 
 		/* if we stalled the data transfer it means command failed */
@@ -838,7 +840,8 @@ int usb_stor_CB_transport(struct scsi_cm
 				us->recv_bulk_pipe : us->send_bulk_pipe;
 		result = usb_stor_bulk_transfer_sg(us, pipe,
 					srb->request_buffer, transfer_length,
-					srb->use_sg, &srb->resid);
+					scsi_sglist(srb), scsi_sg_count(srb),
+					&srb->resid);
 		US_DEBUGP("CB data stage result is 0x%x\n", result);
 
 		/* if we stalled the data transfer it means command failed */
@@ -957,7 +960,8 @@ int usb_stor_Bulk_transport(struct scsi_
 				us->recv_bulk_pipe : us->send_bulk_pipe;
 		result = usb_stor_bulk_transfer_sg(us, pipe,
 					srb->request_buffer, transfer_length,
-					srb->use_sg, &srb->resid);
+					scsi_sglist(srb), scsi_sg_count(srb),
+					&srb->resid);
 		US_DEBUGP("Bulk data transfer result 0x%x\n", result);
 		if (result == USB_STOR_XFER_ERROR)
 			return USB_STOR_TRANSPORT_ERROR;
diff -r 09247461cfda drivers/usb/storage/transport.h
--- a/drivers/usb/storage/transport.h	Thu Jan 03 19:30:25 2008 +1100
+++ b/drivers/usb/storage/transport.h	Thu Jan 03 19:51:09 2008 +1100
@@ -138,7 +138,8 @@ extern int usb_stor_bulk_transfer_buf(st
 extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
 		void *buf, unsigned int length, unsigned int *act_len);
 extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
-		void *buf, unsigned int length, int use_sg, int *residual);
+		void *buf, unsigned int length, struct scatterlist *sg,
+		int use_sg, int *residual);
 
 extern int usb_stor_port_reset(struct us_data *us);
 #endif

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

* [PATCH 3/3] scsi: convert core to sg_ring
  2008-01-03  8:54   ` [PATCH 2/3] usb_storage: usb_stor_bulk_transfer_sg cleanup Rusty Russell
@ 2008-01-03  8:55     ` Rusty Russell
  0 siblings, 0 replies; 7+ messages in thread
From: Rusty Russell @ 2008-01-03  8:55 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-scsi

A 'struct sg_ring *sg' element is added to struct scsi_cmd, and the
use_sg and __use_sg fields are removed.  If this field is null,
request_buffer point to the data (as was previously indicated by
use_sg == 0).

To ease transition, scsi_sglist() is now a backwards-compat routine
which chains the sg_ring entries so they can be iterated using
sg_next().  Once all the drivers which actually want to use chained
sgs are converted to sg_ring, the remaining drivers can revert to
using simple sg arrays.

The backwards-compat conversion is placed under an (always-on) config
option (CONFIG_SCSI_SG_CHAIN).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 drivers/scsi/Kconfig        |    6 +
 drivers/scsi/scsi_error.c   |   15 +--
 drivers/scsi/scsi_lib.c     |  219 +++++++++++++++++++++-----------------------
 drivers/scsi/scsi_lib_dma.c |   27 ++---
 drivers/scsi/scsi_tgt_lib.c |   17 +--
 include/scsi/scsi_cmnd.h    |   38 +++++--
 include/scsi/scsi_eh.h      |    6 -
 7 files changed, 170 insertions(+), 158 deletions(-)

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -29,6 +29,12 @@ config SCSI
 
 	  However, do not compile this as a module if your root file system
 	  (the one containing the directory /) is located on a SCSI device.
+
+config SCSI_SG_CHAIN
+	bool
+	default y
+	---help---
+	  Support sg chaining for older SCSI drivers.
 
 config SCSI_DMA
 	bool
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -617,20 +617,21 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd 
 	ses->cmd_len = scmd->cmd_len;
 	memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd));
 	ses->data_direction = scmd->sc_data_direction;
+	ses->sg = scmd->sg;
 	ses->bufflen = scmd->request_bufflen;
 	ses->buffer = scmd->request_buffer;
-	ses->use_sg = scmd->use_sg;
 	ses->resid = scmd->resid;
 	ses->result = scmd->result;
 
 	if (sense_bytes) {
 		scmd->request_bufflen = min_t(unsigned,
 		                       sizeof(scmd->sense_buffer), sense_bytes);
-		sg_init_one(&ses->sense_sgl, scmd->sense_buffer,
-		                                       scmd->request_bufflen);
-		scmd->request_buffer = &ses->sense_sgl;
+
+		sg_ring_single(&ses->sense_sg.ring, scmd->sense_buffer,
+			       scmd->request_bufflen);
+		scmd->sg = &ses->sense_sg.ring;
+		scmd->request_buffer = NULL;
 		scmd->sc_data_direction = DMA_FROM_DEVICE;
-		scmd->use_sg = 1;
 		memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
 		scmd->cmnd[0] = REQUEST_SENSE;
 		scmd->cmnd[4] = scmd->request_bufflen;
@@ -639,7 +640,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd 
 		scmd->request_buffer = NULL;
 		scmd->request_bufflen = 0;
 		scmd->sc_data_direction = DMA_NONE;
-		scmd->use_sg = 0;
+		scmd->sg = NULL;
 		if (cmnd) {
 			memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
 			memcpy(scmd->cmnd, cmnd, cmnd_size);
@@ -678,7 +679,7 @@ void scsi_eh_restore_cmnd(struct scsi_cm
 	scmd->sc_data_direction = ses->data_direction;
 	scmd->request_bufflen = ses->bufflen;
 	scmd->request_buffer = ses->buffer;
-	scmd->use_sg = ses->use_sg;
+	scmd->sg = ses->sg;
 	scmd->resid = ses->resid;
 	scmd->result = ses->result;
 }
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -17,7 +17,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/hardirq.h>
-#include <linux/scatterlist.h>
+#include <linux/sg_ring.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -34,12 +34,20 @@
 #define SG_MEMPOOL_NR		ARRAY_SIZE(scsi_sg_pools)
 #define SG_MEMPOOL_SIZE		2
 
+/* If we support old-style SG chaining, we need an extra sg element to overwrite
+ * with the chain's next pointer. */
+#ifdef CONFIG_SCSI_SG_CHAIN
+#define SCSI_SG_PAD 1
+#else
+#define SCSI_SG_PAD 0
+#endif
+
 /*
  * The maximum number of SG segments that we will put inside a scatterlist
  * (unless chaining is used). Should ideally fit inside a single page, to
  * avoid a higher order allocation.
  */
-#define SCSI_MAX_SG_SEGMENTS	128
+#define SCSI_MAX_SG_SEGMENTS	(128 - SCSI_SG_PAD)
 
 struct scsi_host_sg_pool {
 	size_t		size;
@@ -707,7 +715,7 @@ static inline unsigned int scsi_sgtable_
 {
 	unsigned int index;
 
-	switch (nents) {
+	switch (nents + SCSI_SG_PAD) {
 	case 1 ... 8:
 		index = 0;
 		break;
@@ -737,21 +745,41 @@ static inline unsigned int scsi_sgtable_
 	return index;
 }
 
-struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+static void free_sgring(struct sg_ring *head)
 {
 	struct scsi_host_sg_pool *sgp;
-	struct scatterlist *sgl, *prev, *ret;
+	struct sg_ring *sg, *n;
+
+	/* Free any other entries in the ring. */
+	list_for_each_entry_safe(sg, n, &head->list, list) {
+		list_del(&sg->list);
+		sgp = scsi_sg_pools + scsi_sgtable_index(sg->max);
+		mempool_free(sg, sgp->pool);
+	}
+
+	/* Now free the head of the ring. */
+	BUG_ON(!list_empty(&head->list));
+
+	sgp = scsi_sg_pools + scsi_sgtable_index(head->max);
+	mempool_free(head, sgp->pool);
+}
+
+struct sg_ring *scsi_alloc_sgring(struct scsi_cmnd *cmd, unsigned int num,
+				  gfp_t gfp_mask)
+{
+	struct scsi_host_sg_pool *sgp;
+	struct sg_ring *sg, *ret;
 	unsigned int index;
 	int this, left;
 
-	BUG_ON(!cmd->use_sg);
+	BUG_ON(!num);
 
-	left = cmd->use_sg;
-	ret = prev = NULL;
+	left = num;
+	ret = NULL;
 	do {
 		this = left;
 		if (this > SCSI_MAX_SG_SEGMENTS) {
-			this = SCSI_MAX_SG_SEGMENTS - 1;
+			this = SCSI_MAX_SG_SEGMENTS;
 			index = SG_MEMPOOL_NR - 1;
 		} else
 			index = scsi_sgtable_index(this);
@@ -760,32 +788,20 @@ struct scatterlist *scsi_alloc_sgtable(s
 
 		sgp = scsi_sg_pools + index;
 
-		sgl = mempool_alloc(sgp->pool, gfp_mask);
-		if (unlikely(!sgl))
+		sg = mempool_alloc(sgp->pool, gfp_mask);
+		if (unlikely(!sg))
 			goto enomem;
 
-		sg_init_table(sgl, sgp->size);
+		sg_ring_init(sg, sgp->size - SCSI_SG_PAD);
 
 		/*
-		 * first loop through, set initial index and return value
+		 * first loop through, set return value, otherwise
+		 * attach this to the tail.
 		 */
 		if (!ret)
-			ret = sgl;
-
-		/*
-		 * chain previous sglist, if any. we know the previous
-		 * sglist must be the biggest one, or we would not have
-		 * ended up doing another loop.
-		 */
-		if (prev)
-			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
-
-		/*
-		 * if we have nothing left, mark the last segment as
-		 * end-of-list
-		 */
-		if (!left)
-			sg_mark_end(&sgl[this - 1]);
+			ret = sg;
+		else
+			list_add_tail(&sg->list, &ret->list);
 
 		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
@@ -793,85 +809,21 @@ struct scatterlist *scsi_alloc_sgtable(s
 		 */
 		gfp_mask &= ~__GFP_WAIT;
 		gfp_mask |= __GFP_HIGH;
-		prev = sgl;
 	} while (left);
 
-	/*
-	 * ->use_sg may get modified after dma mapping has potentially
-	 * shrunk the number of segments, so keep a copy of it for free.
-	 */
-	cmd->__use_sg = cmd->use_sg;
 	return ret;
 enomem:
-	if (ret) {
-		/*
-		 * Free entries chained off ret. Since we were trying to
-		 * allocate another sglist, we know that all entries are of
-		 * the max size.
-		 */
-		sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
-		prev = ret;
-		ret = &ret[SCSI_MAX_SG_SEGMENTS - 1];
-
-		while ((sgl = sg_chain_ptr(ret)) != NULL) {
-			ret = &sgl[SCSI_MAX_SG_SEGMENTS - 1];
-			mempool_free(sgl, sgp->pool);
-		}
-
-		mempool_free(prev, sgp->pool);
-	}
+	if (ret)
+		free_sgring(ret);
 	return NULL;
 }
+EXPORT_SYMBOL(scsi_alloc_sgring);
 
-EXPORT_SYMBOL(scsi_alloc_sgtable);
-
-void scsi_free_sgtable(struct scsi_cmnd *cmd)
+void scsi_free_sgring(struct scsi_cmnd *cmd)
 {
-	struct scatterlist *sgl = cmd->request_buffer;
-	struct scsi_host_sg_pool *sgp;
-
-	/*
-	 * if this is the biggest size sglist, check if we have
-	 * chained parts we need to free
-	 */
-	if (cmd->__use_sg > SCSI_MAX_SG_SEGMENTS) {
-		unsigned short this, left;
-		struct scatterlist *next;
-		unsigned int index;
-
-		left = cmd->__use_sg - (SCSI_MAX_SG_SEGMENTS - 1);
-		next = sg_chain_ptr(&sgl[SCSI_MAX_SG_SEGMENTS - 1]);
-		while (left && next) {
-			sgl = next;
-			this = left;
-			if (this > SCSI_MAX_SG_SEGMENTS) {
-				this = SCSI_MAX_SG_SEGMENTS - 1;
-				index = SG_MEMPOOL_NR - 1;
-			} else
-				index = scsi_sgtable_index(this);
-
-			left -= this;
-
-			sgp = scsi_sg_pools + index;
-
-			if (left)
-				next = sg_chain_ptr(&sgl[sgp->size - 1]);
-
-			mempool_free(sgl, sgp->pool);
-		}
-
-		/*
-		 * Restore original, will be freed below
-		 */
-		sgl = cmd->request_buffer;
-		sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
-	} else
-		sgp = scsi_sg_pools + scsi_sgtable_index(cmd->__use_sg);
-
-	mempool_free(sgl, sgp->pool);
+	free_sgring(cmd->sg);
 }
-
-EXPORT_SYMBOL(scsi_free_sgtable);
+EXPORT_SYMBOL(scsi_free_sgring);
 
 /*
  * Function:    scsi_release_buffers()
@@ -892,13 +844,14 @@ EXPORT_SYMBOL(scsi_free_sgtable);
  */
 static void scsi_release_buffers(struct scsi_cmnd *cmd)
 {
-	if (cmd->use_sg)
-		scsi_free_sgtable(cmd);
+	if (cmd->sg)
+		scsi_free_sgring(cmd);
 
 	/*
 	 * Zero these out.  They now point to freed memory, and it is
 	 * dangerous to hang onto the pointers.
 	 */
+	cmd->sg = NULL;
 	cmd->request_buffer = NULL;
 	cmd->request_bufflen = 0;
 }
@@ -976,7 +929,10 @@ void scsi_io_completion(struct scsi_cmnd
 	SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, "
 				      "%d bytes done.\n",
 				      req->nr_sectors, good_bytes));
-	SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg));
+	SCSI_LOG_HLCOMPLETE(1, printk("sg elems %d%s\n",
+				      cmd->sg ? cmd->sg->num : 0,
+				      cmd->sg && !list_empty(&cmd->sg->list) ?
+				      "+" : ""));
 
 	if (clear_errors)
 		req->errors = 0;
@@ -1107,20 +1063,20 @@ static int scsi_init_io(struct scsi_cmnd
 static int scsi_init_io(struct scsi_cmnd *cmd)
 {
 	struct request     *req = cmd->request;
-	int		   count;
 
 	/*
 	 * We used to not use scatter-gather for single segment request,
 	 * but now we do (it makes highmem I/O easier to support without
 	 * kmapping pages)
 	 */
-	cmd->use_sg = req->nr_phys_segments;
 
+	cmd->request_buffer = NULL;
 	/*
 	 * If sg table allocation fails, requeue request later.
 	 */
-	cmd->request_buffer = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
-	if (unlikely(!cmd->request_buffer)) {
+	cmd->sg = scsi_alloc_sgring(cmd, req->nr_phys_segments, GFP_ATOMIC);
+	if (unlikely(!cmd->sg)) {
+		BUG();
 		scsi_unprep_request(req);
 		return BLKPREP_DEFER;
 	}
@@ -1135,9 +1091,7 @@ static int scsi_init_io(struct scsi_cmnd
 	 * Next, walk the list, and fill in the addresses and sizes of
 	 * each segment.
 	 */
-	count = blk_rq_map_sg(req->q, req, cmd->request_buffer);
-	BUG_ON(count > cmd->use_sg);
-	cmd->use_sg = count;
+	blk_rq_map_sg_ring(req->q, req, cmd->sg);
 	return BLKPREP_OK;
 }
 
@@ -1206,7 +1160,7 @@ int scsi_setup_blk_pc_cmnd(struct scsi_d
 
 		cmd->request_bufflen = 0;
 		cmd->request_buffer = NULL;
-		cmd->use_sg = 0;
+		cmd->sg = NULL;
 		req->buffer = NULL;
 	}
 
@@ -1765,7 +1719,7 @@ int __init scsi_init_queue(void)
 
 	for (i = 0; i < SG_MEMPOOL_NR; i++) {
 		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
-		int size = sgp->size * sizeof(struct scatterlist);
+		int size = sizeof(struct sg_ring) + sgp->size * sizeof(struct scatterlist);
 
 		sgp->slab = kmem_cache_create(sgp->name, size, 0,
 				SLAB_HWCACHE_ALIGN, NULL);
@@ -2523,3 +2477,46 @@ void scsi_kunmap_atomic_sg(void *virt)
 	kunmap_atomic(virt, KM_BIO_SRC_IRQ);
 }
 EXPORT_SYMBOL(scsi_kunmap_atomic_sg);
+
+#ifdef CONFIG_SCSI_SG_CHAIN
+int scsi_sg_count(struct scsi_cmnd *cmd)
+{
+	return sg_ring_num(cmd->sg);
+}
+EXPORT_SYMBOL(scsi_sg_count);
+
+struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd)
+{
+	struct sg_ring *sg;
+	struct scatterlist *last = NULL;
+
+	if (!cmd->sg)
+		return NULL;
+
+	/* Convert to a chained sg. */
+	for (sg = cmd->sg; sg; sg = sg_ring_next(sg, cmd->sg)) {
+		unsigned int i;
+
+		/* We currently don't set up any 0-len sg rings, but
+		 * let's handle it anyway. */
+		if (!sg->num)
+			continue;
+
+		if (last)
+			last[1].page_link = ((unsigned long)&sg->sg[0] | 0x01);
+
+		/* Clear any end or chain bits. */
+		for (i = 0; i < sg->num; i++)
+			sg->sg[i].page_link &= ~0x3;
+		last = &sg->sg[sg->num - 1];
+	}
+
+	/* End marker */
+	last->page_link |= 0x02;
+
+	/* Assumes first one isn't empty. */
+	return &cmd->sg->sg[0];
+}
+EXPORT_SYMBOL(scsi_sglist);
+	
+#endif /* CONFIG_SCSI_SG_CHAIN */
diff --git a/drivers/scsi/scsi_lib_dma.c b/drivers/scsi/scsi_lib_dma.c
--- a/drivers/scsi/scsi_lib_dma.c
+++ b/drivers/scsi/scsi_lib_dma.c
@@ -5,6 +5,7 @@
 #include <linux/blkdev.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/sg_ring.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -15,22 +16,21 @@
  * scsi_dma_map - perform DMA mapping against command's sg lists
  * @cmd:	scsi command
  *
- * Returns the number of sg lists actually used, zero if the sg lists
- * is NULL, or -ENOMEM if the mapping failed.
+ * Returns -ENOMEM if the mapping failed, or the number of elements mapped
+ * (ie. sg_ring_num(cmd->sg)).
  */
 int scsi_dma_map(struct scsi_cmnd *cmd)
 {
-	int nseg = 0;
+	if (cmd->sg) {
+		struct device *dev = cmd->device->host->shost_gendev.parent;
+		int err;
 
-	if (scsi_sg_count(cmd)) {
-		struct device *dev = cmd->device->host->shost_gendev.parent;
-
-		nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
-				  cmd->sc_data_direction);
-		if (unlikely(!nseg))
-			return -ENOMEM;
+		err = dma_map_sg_ring(dev, cmd->sg, cmd->sc_data_direction);
+		if (err)
+			return err;
+		return sg_ring_num(cmd->sg);
 	}
-	return nseg;
+	return 0;
 }
 EXPORT_SYMBOL(scsi_dma_map);
 
@@ -40,11 +40,10 @@ EXPORT_SYMBOL(scsi_dma_map);
  */
 void scsi_dma_unmap(struct scsi_cmnd *cmd)
 {
-	if (scsi_sg_count(cmd)) {
+	if (cmd->sg) {
 		struct device *dev = cmd->device->host->shost_gendev.parent;
 
-		dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
-			     cmd->sc_data_direction);
+		dma_unmap_sg_ring(dev, cmd->sg, cmd->sc_data_direction);
 	}
 }
 EXPORT_SYMBOL(scsi_dma_unmap);
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -331,8 +331,8 @@ static void scsi_tgt_cmd_done(struct scs
 
 	scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag);
 
-	if (cmd->request_buffer)
-		scsi_free_sgtable(cmd);
+	if (cmd->sg)
+		scsi_free_sgring(cmd);
 
 	queue_work(scsi_tgtd, &tcmd->work);
 }
@@ -356,19 +356,15 @@ static int scsi_tgt_init_cmd(struct scsi
 static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 {
 	struct request *rq = cmd->request;
-	int count;
 
-	cmd->use_sg = rq->nr_phys_segments;
-	cmd->request_buffer = scsi_alloc_sgtable(cmd, gfp_mask);
-	if (!cmd->request_buffer)
+	cmd->sg = scsi_alloc_sgring(cmd, rq->nr_phys_segments, gfp_mask);
+	if (!cmd->sg)
 		return -ENOMEM;
-
+	cmd->request_buffer = NULL;
 	cmd->request_bufflen = rq->data_len;
 
-	dprintk("cmd %p cnt %d %lu\n", cmd, cmd->use_sg, rq_data_dir(rq));
-	count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer);
-	BUG_ON(count > cmd->use_sg);
-	cmd->use_sg = count;
+	dprintk("cmd %p cnt %d %lu\n", cmd, rq->nr_phys_segments, rq_data_dir(rq));
+	blk_rq_map_sg_ring(rq->q, rq, cmd->request_buffer);
 	return 0;
 }
 
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -5,7 +5,7 @@
 #include <linux/list.h>
 #include <linux/types.h>
 #include <linux/timer.h>
-#include <linux/scatterlist.h>
+#include <linux/sg_ring.h>
 
 struct request;
 struct scatterlist;
@@ -17,8 +17,12 @@ struct scsi_pointer {
 struct scsi_pointer {
 	char *ptr;		/* data pointer */
 	int this_residual;	/* left in this buffer */
+#ifdef CONFIG_SCSI_SG_CHAIN
 	struct scatterlist *buffer;	/* which buffer */
 	int buffers_residual;	/* how many buffers left */
+#endif
+	struct sg_ring *sg;	/* which buffer ring */
+	int buffers_offset;	/* how many buffers of this sg already used */
 
         dma_addr_t dma_handle;
 
@@ -66,11 +70,8 @@ struct scsi_cmnd {
 	unsigned request_bufflen;	/* Actual request size */
 
 	struct timer_list eh_timeout;	/* Used to time out the command. */
-	void *request_buffer;		/* Actual requested buffer */
-
-	/* These elements define the operation we ultimately want to perform */
-	unsigned short use_sg;	/* Number of pieces of scatter-gather */
-	unsigned short __use_sg;
+	struct sg_ring *sg;	/* if it's a scatter-gather, otherwise... */
+	void *request_buffer;	/* Actual requested buffer */
 
 	unsigned underflow;	/* Return error if less than
 				   this amount is transferred */
@@ -130,14 +131,28 @@ extern void *scsi_kmap_atomic_sg(struct 
 				 size_t *offset, size_t *len);
 extern void scsi_kunmap_atomic_sg(void *virt);
 
-extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
-extern void scsi_free_sgtable(struct scsi_cmnd *);
+extern struct sg_ring *scsi_alloc_sgring(struct scsi_cmnd *, unsigned, gfp_t);
+extern void scsi_free_sgring(struct scsi_cmnd *);
 
 extern int scsi_dma_map(struct scsi_cmnd *cmd);
 extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
 
-#define scsi_sg_count(cmd) ((cmd)->use_sg)
-#define scsi_sglist(cmd) ((struct scatterlist *)(cmd)->request_buffer)
+#ifdef CONFIG_SCSI_SG_CHAIN
+/* Deprecated: use sg_ring_num(cmd->sg) */
+extern int scsi_sg_count(struct scsi_cmnd *cmd);
+
+/* Deprecated: this routine converts the sg_ring into an sg chain:
+ * modern drivers should use cmd->sg directly. */
+extern struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd);
+
+/* Deprecated: the modern way is to use sg_ring_for_each(cmd->sg,
+ * sgring, i): sgring->sg[i] is the current element.  Note that i does
+ * not always increase (it goes back to 0 when sgring is iterated). */
+#define scsi_for_each_sg(cmd, sg, nseg, __i)			\
+	for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
+
+#endif /* CONFIG_SCSI_SG_CHAIN */
+
 #define scsi_bufflen(cmd) ((cmd)->request_bufflen)
 
 static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid)
@@ -150,7 +165,4 @@ static inline int scsi_get_resid(struct 
 	return cmd->resid;
 }
 
-#define scsi_for_each_sg(cmd, sg, nseg, __i)			\
-	for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
-
 #endif /* _SCSI_SCSI_CMND_H */
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
--- a/include/scsi/scsi_eh.h
+++ b/include/scsi/scsi_eh.h
@@ -1,7 +1,7 @@
 #ifndef _SCSI_SCSI_EH_H
 #define _SCSI_SCSI_EH_H
 
-#include <linux/scatterlist.h>
+#include <linux/sg_ring.h>
 
 #include <scsi/scsi_cmnd.h>
 struct scsi_device;
@@ -75,10 +75,10 @@ struct scsi_eh_save {
 
 	void *buffer;
 	unsigned bufflen;
-	unsigned short use_sg;
+	struct sg_ring *sg;
 	int resid;
 
-	struct scatterlist sense_sgl;
+	DECLARE_SG_RING(sense_sg, 1);
 };
 
 extern void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd,

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

* Re: [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count
  2008-01-03  8:50 ` [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count Rusty Russell
  2008-01-03  8:54   ` [PATCH 2/3] usb_storage: usb_stor_bulk_transfer_sg cleanup Rusty Russell
@ 2008-01-03  9:26   ` Boaz Harrosh
  2008-01-04  3:28     ` Rusty Russell
  1 sibling, 1 reply; 7+ messages in thread
From: Boaz Harrosh @ 2008-01-03  9:26 UTC (permalink / raw)
  To: Rusty Russell; +Cc: Jens Axboe, linux-scsi

On Thu, Jan 03 2008 at 10:50 +0200, Rusty Russell <rusty@rustcorp.com.au> wrote:
> This patch simply converts direct uses of ->use_sg and ->request_buffer to
> use the wrapper macros.  This removes the assumption that the sg list is
> overloaded on request_buffer, and that there's an explicit use_sg field.
> 
> The ->request_buffer assumption is explicit in scsi_debug.c's paranoid
> checking, so that code had to be shuffled a little.
> 
> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
> ---
>  drivers/scsi/NCR5380.c       |    6 +++---
>  drivers/scsi/NCR53C9x.c      |    6 +++---
>  drivers/scsi/aha1542.c       |   14 +++++++-------
>  drivers/scsi/atari_NCR5380.c |    2 +-
>  drivers/scsi/atp870u.c       |   22 +++++++++++-----------
>  drivers/scsi/eata_pio.c      |    6 +++---
>  drivers/scsi/fd_mcs.c        |    6 +++---
>  drivers/scsi/imm.c           |    5 ++---
>  drivers/scsi/in2000.c        |    6 +++---
>  drivers/scsi/libsrp.c        |   12 ++++++------
>  drivers/scsi/pcmcia/nsp_cs.c |    8 ++++----
>  drivers/scsi/ppa.c           |    4 ++--
>  drivers/scsi/qlogicpti.c     |   12 ++++++------
>  drivers/scsi/scsi_debug.c    |   14 +++++++-------
>  drivers/scsi/seagate.c       |    4 ++--
>  drivers/scsi/sr.c            |    6 +++---
>  drivers/scsi/sun3_NCR5380.c  |    6 +++---
>  drivers/scsi/sun3x_esp.c     |    4 ++--
>  drivers/scsi/wd33c93.c       |    6 +++---
>  21 files changed, 77 insertions(+), 76 deletions(-)
> 

All of these drivers are properly converted in current scsi-misc + scsi-pending.
If you are really serious about changing scsi-layer you better work ontop of
scsi git trees.

Also you can inspect -mm tree it has the scsi_data_buffer patches that does
4/5 what you want.

Boaz


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

* Re: [PATCH 0/2] sg_ring: Gentler scsi merge
  2008-01-03  7:00 [PATCH 0/2] sg_ring: Gentler scsi merge Rusty Russell
  2008-01-03  8:50 ` [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count Rusty Russell
@ 2008-01-03  9:42 ` Boaz Harrosh
  1 sibling, 0 replies; 7+ messages in thread
From: Boaz Harrosh @ 2008-01-03  9:42 UTC (permalink / raw)
  To: Rusty Russell; +Cc: Jens Axboe, linux-scsi

On Thu, Jan 03 2008 at 9:00 +0200, Rusty Russell <rusty@rustcorp.com.au> wrote:
> OK, after wading through many scsi drivers, I decided to change tack and try 
> to provide a transition path.  This is in two stages:
> 
> 1) These two patches.  sg_ring used underneath, but if any driver asks for 
> scsi_sglist() they get a 2.6.24-style chained sg.  No other patches are 
> necessary.
> 
> 2) Once all chained-sg-needing scsi drivers change to use cmd->sg (ie. 
> sg_ring) directly, and the chained sg patches can be reverted.  scsi_sglist() 
> and scsi_sg_count() then become:
> 
> 	/* You should only use these if you never need chained sgs */
> 	static inline struct scatterlist *scsi_sglist(struct scsi_cmd *cmd)
> 	{
> 		BUG_ON(!list_empty(&cmd->sg->list));
> 		return &cmd->sg->sg[0];
> 	}
> 
> 	static unsigned int scsi_sg_count(struct scsi_cmd *cmd)
> 	{
> 		if (!cmd->sg)
> 			return 0;
> 		BUG_ON(!list_empty(&cmd->sg->list));
> 		return cmd->sg->num;
> 	}
> 
> Thanks,
> Rusty.

Look in the mailing list archives for the scsi_sgtable patches.
These did exactly what you do here. (OK 95% ;))
(only as a scsi subsystem not as a generic sg)

Boaz


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

* Re: [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count
  2008-01-03  9:26   ` [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count Boaz Harrosh
@ 2008-01-04  3:28     ` Rusty Russell
  0 siblings, 0 replies; 7+ messages in thread
From: Rusty Russell @ 2008-01-04  3:28 UTC (permalink / raw)
  To: Boaz Harrosh; +Cc: Jens Axboe, linux-scsi

On Thursday 03 January 2008 20:26:13 Boaz Harrosh wrote:
> On Thu, Jan 03 2008 at 10:50 +0200, Rusty Russell <rusty@rustcorp.com.au> 
wrote:
> > This patch simply converts direct uses of ->use_sg and ->request_buffer
> > to use the wrapper macros.  This removes the assumption that the sg list
> > is overloaded on request_buffer, and that there's an explicit use_sg
> > field.
>
> All of these drivers are properly converted in current scsi-misc +
> scsi-pending. If you are really serious about changing scsi-layer you
> better work ontop of scsi git trees.

Hi Boaz,

    Well, I wouldn't say I'm serious about SCSI 8) but I am delighted to see 
this being done.  Have grabbed scsi-pending from git.kernel.org, thanks for 
the hint.

> Also you can inspect -mm tree it has the scsi_data_buffer patches that does
> 4/5 what you want.

   Remember, these scsi patches are a side-effect of trying to get my own 
sg-using code sane.  So this is exactly what I *don't* want: another "works 
for scsi" solution :(

I'll see where we can go from here...
Thanks,
Rusty.

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

end of thread, other threads:[~2008-01-04  3:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-03  7:00 [PATCH 0/2] sg_ring: Gentler scsi merge Rusty Russell
2008-01-03  8:50 ` [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count Rusty Russell
2008-01-03  8:54   ` [PATCH 2/3] usb_storage: usb_stor_bulk_transfer_sg cleanup Rusty Russell
2008-01-03  8:55     ` [PATCH 3/3] scsi: convert core to sg_ring Rusty Russell
2008-01-03  9:26   ` [PATCH 1/3] scsi: Convert everyone to scsi_sglist and scsi_sg_count Boaz Harrosh
2008-01-04  3:28     ` Rusty Russell
2008-01-03  9:42 ` [PATCH 0/2] sg_ring: Gentler scsi merge Boaz Harrosh

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).