[PATCH 5/7] sg_ring: Convert core scsi code to sg_ring.
If nothing else, the simplification of this logic shows why I prefer sg_ring over scatterlist chaining. Signed-off-by: Rusty Russell <[EMAIL PROTECTED]> diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -1191,28 +1191,28 @@ cciss_scatter_gather(struct pci_dev *pde struct scsi_cmnd *cmd) { unsigned int len; - struct scatterlist *sg; + struct sg_ring *sg; __u64 addr64; - int use_sg, i; + int count = 0, i; - BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES); - - use_sg = scsi_dma_map(cmd); - if (use_sg) { /* not too many addrs? */ - scsi_for_each_sg(cmd, sg, use_sg, i) { - addr64 = (__u64) sg_dma_address(sg); - len = sg_dma_len(sg); + if (scsi_dma_map(cmd) >= 0) { /* not too many addrs? */ + sg_ring_for_each(scsi_sgring(cmd), sg, i) { + addr64 = (__u64) sg_dma_address(>sg[i]); + len = sg_dma_len(>sg[i]); cp->SG[i].Addr.lower = (__u32) (addr64 & (__u64) 0x); cp->SG[i].Addr.upper = (__u32) ((addr64 >> 32) & (__u64) 0x); cp->SG[i].Len = len; cp->SG[i].Ext = 0; // we are not chaining + count++; } } - cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */ - cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */ + cp->Header.SGList = (__u8) count; /* no. SGs contig in this cmd */ + cp->Header.SGTotal = (__u16) count; /* total sgs in this cmd list */ + + BUG_ON(count > MAXSGENTRIES); return; } 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 @@ -619,18 +619,17 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd ses->data_direction = scmd->sc_data_direction; 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(>sense_sgl, scmd->sense_buffer, - scmd->request_bufflen); - scmd->request_buffer = >sense_sgl; + + sg_ring_single(>sense_sg.ring, scmd->sense_buffer, + scmd->request_bufflen); + scmd->request_buffer = >sense_sg; 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 +638,6 @@ 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; if (cmnd) { memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); memcpy(scmd->cmnd, cmnd, cmnd_size); @@ -678,7 +676,6 @@ 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->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 #include #include -#include +#include #include #include @@ -737,21 +737,31 @@ 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 *sg) { struct scsi_host_sg_pool *sgp; - struct scatterlist *sgl, *prev, *ret; + + sgp = scsi_sg_pools + scsi_sgtable_index(sg->max); + + mempool_free(sg, 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 =
[PATCH 5/7] sg_ring: Convert core scsi code to sg_ring.
If nothing else, the simplification of this logic shows why I prefer sg_ring over scatterlist chaining. Signed-off-by: Rusty Russell [EMAIL PROTECTED] diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -1191,28 +1191,28 @@ cciss_scatter_gather(struct pci_dev *pde struct scsi_cmnd *cmd) { unsigned int len; - struct scatterlist *sg; + struct sg_ring *sg; __u64 addr64; - int use_sg, i; + int count = 0, i; - BUG_ON(scsi_sg_count(cmd) MAXSGENTRIES); - - use_sg = scsi_dma_map(cmd); - if (use_sg) { /* not too many addrs? */ - scsi_for_each_sg(cmd, sg, use_sg, i) { - addr64 = (__u64) sg_dma_address(sg); - len = sg_dma_len(sg); + if (scsi_dma_map(cmd) = 0) { /* not too many addrs? */ + sg_ring_for_each(scsi_sgring(cmd), sg, i) { + addr64 = (__u64) sg_dma_address(sg-sg[i]); + len = sg_dma_len(sg-sg[i]); cp-SG[i].Addr.lower = (__u32) (addr64 (__u64) 0x); cp-SG[i].Addr.upper = (__u32) ((addr64 32) (__u64) 0x); cp-SG[i].Len = len; cp-SG[i].Ext = 0; // we are not chaining + count++; } } - cp-Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */ - cp-Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */ + cp-Header.SGList = (__u8) count; /* no. SGs contig in this cmd */ + cp-Header.SGTotal = (__u16) count; /* total sgs in this cmd list */ + + BUG_ON(count MAXSGENTRIES); return; } 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 @@ -619,18 +619,17 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd ses-data_direction = scmd-sc_data_direction; 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-request_buffer = ses-sense_sg; 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 +638,6 @@ 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; if (cmnd) { memset(scmd-cmnd, 0, sizeof(scmd-cmnd)); memcpy(scmd-cmnd, cmnd, cmnd_size); @@ -678,7 +676,6 @@ 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-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 @@ -737,21 +737,31 @@ 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 *sg) { struct scsi_host_sg_pool *sgp; - struct scatterlist *sgl, *prev, *ret; + + sgp = scsi_sg_pools + scsi_sgtable_index(sg-max); + + mempool_free(sg, 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