--- linux/drivers/scsi/scsi_debug.c 2004-08-14 21:12:43.000000000 +1000 +++ linux/drivers/scsi/scsi_debug.c2681dma1 2004-10-16 16:22:34.330229976 +1000 @@ -262,16 +262,6 @@ static struct device pseudo_primary; static struct bus_type pseudo_lld_bus; -static unsigned char * scatg2virt(const struct scatterlist * sclp) -{ - if (NULL == sclp) - return NULL; - else if (sclp->page) - return (unsigned char *)page_address(sclp->page) + - sclp->offset; - else - return NULL; -} static int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) @@ -286,6 +276,7 @@ struct sdebug_dev_info * devip = NULL; unsigned char * sbuff; int inj_recovered = 0; + int num_elems = 0; if (done == NULL) return 0; /* assume mid level reprocessing command */ @@ -294,8 +285,12 @@ struct scatterlist *sgpnt = (struct scatterlist *) SCpnt->request_buffer; - buff = scatg2virt(&sgpnt[0]); - bufflen = sgpnt[0].length; + num_elems = dma_map_sg(NULL, sgpnt, SCpnt->use_sg, + SCpnt->sc_data_direction); + buff = phys_to_virt(sg_dma_address(&sgpnt[0])); + bufflen = sg_dma_len(&sgpnt[0]); + dma_unmap_sg(NULL, sgpnt, SCpnt->use_sg, + SCpnt->sc_data_direction); /* READ and WRITE process scatterlist themselves */ } else @@ -778,6 +773,7 @@ struct scatterlist *sgpnt = NULL; int bufflen = SCpnt->request_bufflen; unsigned long iflags; + int num_elems = 0; if (upper_blk || (block + num > sdebug_capacity)) { mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, @@ -799,9 +795,11 @@ block, bufflen); */ if (SCpnt->use_sg) { sgcount = 0; - sgpnt = (struct scatterlist *) buff; - buff = scatg2virt(&sgpnt[sgcount]); - bufflen = sgpnt[sgcount].length; + sgpnt = (struct scatterlist *)buff; + num_elems = dma_map_sg(NULL, sgpnt, SCpnt->use_sg, + SCpnt->sc_data_direction); + buff = phys_to_virt(sg_dma_address(&sgpnt[0])); + bufflen = sg_dma_len(&sgpnt[0]); } do { memcpy(buff, fake_storep + (block * SECT_SIZE), bufflen); @@ -809,14 +807,18 @@ if (SCpnt->use_sg) { block += bufflen >> POW2_SECT_SIZE; sgcount++; - if (nbytes) { - buff = scatg2virt(&sgpnt[sgcount]); - bufflen = sgpnt[sgcount].length; + if (nbytes > 0) { + buff = phys_to_virt( + sg_dma_address(&sgpnt[sgcount])); + bufflen = sg_dma_len(&sgpnt[sgcount]); } } else if (nbytes > 0) printk(KERN_WARNING "scsi_debug:resp_read: unexpected " "nbytes=%d\n", nbytes); - } while (nbytes); + } while (nbytes > 0); + if (SCpnt->use_sg) + dma_unmap_sg(NULL, sgpnt, SCpnt->use_sg, + SCpnt->sc_data_direction); read_unlock_irqrestore(&atomic_rw, iflags); return 0; } @@ -829,6 +831,7 @@ struct scatterlist *sgpnt = NULL; int bufflen = SCpnt->request_bufflen; unsigned long iflags; + int num_elems = 0; if (upper_blk || (block + num > sdebug_capacity)) { mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, @@ -842,8 +845,10 @@ if (SCpnt->use_sg) { sgcount = 0; sgpnt = (struct scatterlist *) buff; - buff = scatg2virt(&sgpnt[sgcount]); - bufflen = sgpnt[sgcount].length; + num_elems = dma_map_sg(NULL, sgpnt, SCpnt->use_sg, + SCpnt->sc_data_direction); + buff = phys_to_virt(sg_dma_address(&sgpnt[0])); + bufflen = sg_dma_len(&sgpnt[0]); } do { memcpy(fake_storep + (block * SECT_SIZE), buff, bufflen); @@ -852,14 +857,18 @@ if (SCpnt->use_sg) { block += bufflen >> POW2_SECT_SIZE; sgcount++; - if (nbytes) { - buff = scatg2virt(&sgpnt[sgcount]); - bufflen = sgpnt[sgcount].length; + if (nbytes > 0) { + buff = phys_to_virt( + sg_dma_address(&sgpnt[sgcount])); + bufflen = sg_dma_len(&sgpnt[sgcount]); } } else if (nbytes > 0) printk(KERN_WARNING "scsi_debug:resp_write: " "unexpected nbytes=%d\n", nbytes); - } while (nbytes); + } while (nbytes > 0); + if (SCpnt->use_sg) + dma_unmap_sg(NULL, sgpnt, SCpnt->use_sg, + SCpnt->sc_data_direction); write_unlock_irqrestore(&atomic_rw, iflags); return 0; }