* [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 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.