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