[SCSI] st: convert dio path to use st_scsi_execute
This patch converts the dio path (mmap) to use st_scsi_execute. IOW, it removes scsi_execute_async in the non dio path. scsi_execute_async has gone! This also remove unused st_sleep_done. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Acked-by: Kai Makisara <Kai.Makisara@kolumbus.fi> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
		
							parent
							
								
									6d4762678b
								
							
						
					
					
						commit
						6620742f72
					
				| @ -191,9 +191,9 @@ static int from_buffer(struct st_buffer *, char __user *, int); | ||||
| static void move_buffer_data(struct st_buffer *, int); | ||||
| static void buf_to_sg(struct st_buffer *, unsigned int); | ||||
| 
 | ||||
| static int sgl_map_user_pages(struct scatterlist *, const unsigned int,  | ||||
| static int sgl_map_user_pages(struct st_buffer *, const unsigned int, | ||||
| 			      unsigned long, size_t, int); | ||||
| static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int); | ||||
| static int sgl_unmap_user_pages(struct st_buffer *, const unsigned int, int); | ||||
| 
 | ||||
| static int st_probe(struct device *); | ||||
| static int st_remove(struct device *); | ||||
| @ -435,22 +435,6 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) | ||||
| 	return (-EIO); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Wakeup from interrupt */ | ||||
| static void st_sleep_done(void *data, char *sense, int result, int resid) | ||||
| { | ||||
| 	struct st_request *SRpnt = data; | ||||
| 	struct scsi_tape *STp = SRpnt->stp; | ||||
| 
 | ||||
| 	memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); | ||||
| 	(STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result; | ||||
| 	(STp->buffer)->cmdstat.residual = resid; | ||||
| 	DEB( STp->write_pending = 0; ) | ||||
| 
 | ||||
| 	if (SRpnt->waiting) | ||||
| 		complete(SRpnt->waiting); | ||||
| } | ||||
| 
 | ||||
| static struct st_request *st_allocate_request(struct scsi_tape *stp) | ||||
| { | ||||
| 	struct st_request *streq; | ||||
| @ -566,7 +550,10 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd | ||||
| 	init_completion(waiting); | ||||
| 	SRpnt->waiting = waiting; | ||||
| 
 | ||||
| 	if (!STp->buffer->do_dio) { | ||||
| 	if (STp->buffer->do_dio) { | ||||
| 		mdata->nr_entries = STp->buffer->sg_segs; | ||||
| 		mdata->pages = STp->buffer->mapped_pages; | ||||
| 	} else { | ||||
| 		buf_to_sg(STp->buffer, bytes); | ||||
| 
 | ||||
| 		mdata->nr_entries = | ||||
| @ -579,16 +566,8 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd | ||||
| 	STp->buffer->cmdstat.have_sense = 0; | ||||
| 	STp->buffer->syscall_result = 0; | ||||
| 
 | ||||
| 	if (STp->buffer->do_dio) | ||||
| 		ret = scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), | ||||
| 					 direction, &((STp->buffer)->sg[0]), | ||||
| 					 bytes, (STp->buffer)->sg_segs, timeout, | ||||
| 					 retries, SRpnt, st_sleep_done, | ||||
| 					 GFP_KERNEL); | ||||
| 	else | ||||
| 		ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, | ||||
| 				      timeout, retries); | ||||
| 
 | ||||
| 	ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout, | ||||
| 			      retries); | ||||
| 	if (ret) { | ||||
| 		/* could not allocate the buffer or request was too large */ | ||||
| 		(STp->buffer)->syscall_result = (-EBUSY); | ||||
| @ -1540,8 +1519,8 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, | ||||
| 
 | ||||
| 	if (i && ((unsigned long)buf & queue_dma_alignment( | ||||
| 					STp->device->request_queue)) == 0) { | ||||
| 		i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg, | ||||
| 				      (unsigned long)buf, count, (is_read ? READ : WRITE)); | ||||
| 		i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf, | ||||
| 				       count, (is_read ? READ : WRITE)); | ||||
| 		if (i > 0) { | ||||
| 			STbp->do_dio = i; | ||||
| 			STbp->buffer_bytes = 0;   /* can be used as transfer counter */ | ||||
| @ -1595,7 +1574,7 @@ static void release_buffering(struct scsi_tape *STp, int is_read) | ||||
| 
 | ||||
| 	STbp = STp->buffer; | ||||
| 	if (STbp->do_dio) { | ||||
| 		sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read); | ||||
| 		sgl_unmap_user_pages(STbp, STbp->do_dio, is_read); | ||||
| 		STbp->do_dio = 0; | ||||
| 		STbp->sg_segs = 0; | ||||
| 	} | ||||
| @ -4647,14 +4626,16 @@ out: | ||||
| } | ||||
| 
 | ||||
| /* The following functions may be useful for a larger audience. */ | ||||
| static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,  | ||||
| 			      unsigned long uaddr, size_t count, int rw) | ||||
| static int sgl_map_user_pages(struct st_buffer *STbp, | ||||
| 			      const unsigned int max_pages, unsigned long uaddr, | ||||
| 			      size_t count, int rw) | ||||
| { | ||||
| 	unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||||
| 	unsigned long start = uaddr >> PAGE_SHIFT; | ||||
| 	const int nr_pages = end - start; | ||||
| 	int res, i, j; | ||||
| 	struct page **pages; | ||||
| 	struct rq_map_data *mdata = &STbp->map_data; | ||||
| 
 | ||||
| 	/* User attempted Overflow! */ | ||||
| 	if ((uaddr + count) < uaddr) | ||||
| @ -4696,24 +4677,11 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa | ||||
| 		flush_dcache_page(pages[i]); | ||||
|         } | ||||
| 
 | ||||
| 	/* Populate the scatter/gather list */ | ||||
| 	sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK); | ||||
| 	if (nr_pages > 1) { | ||||
| 		sgl[0].length = PAGE_SIZE - sgl[0].offset; | ||||
| 		count -= sgl[0].length; | ||||
| 		for (i=1; i < nr_pages ; i++) { | ||||
| 			sg_set_page(&sgl[i], pages[i], | ||||
| 				    count < PAGE_SIZE ? count : PAGE_SIZE, 0);; | ||||
| 			count -= PAGE_SIZE; | ||||
| 		} | ||||
| 	} | ||||
| 	else { | ||||
| 		sgl[0].length = count; | ||||
| 	} | ||||
| 	mdata->offset = uaddr & ~PAGE_MASK; | ||||
| 	mdata->page_order = 0; | ||||
| 	STbp->mapped_pages = pages; | ||||
| 
 | ||||
| 	kfree(pages); | ||||
| 	return nr_pages; | ||||
| 
 | ||||
|  out_unmap: | ||||
| 	if (res > 0) { | ||||
| 		for (j=0; j < res; j++) | ||||
| @ -4726,13 +4694,13 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa | ||||
| 
 | ||||
| 
 | ||||
| /* And unmap them... */ | ||||
| static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages, | ||||
| 				int dirtied) | ||||
| static int sgl_unmap_user_pages(struct st_buffer *STbp, | ||||
| 				const unsigned int nr_pages, int dirtied) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i=0; i < nr_pages; i++) { | ||||
| 		struct page *page = sg_page(&sgl[i]); | ||||
| 		struct page *page = STbp->mapped_pages[i]; | ||||
| 
 | ||||
| 		if (dirtied) | ||||
| 			SetPageDirty(page); | ||||
| @ -4741,6 +4709,8 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p | ||||
| 		 */ | ||||
| 		page_cache_release(page); | ||||
| 	} | ||||
| 	kfree(STbp->mapped_pages); | ||||
| 	STbp->mapped_pages = NULL; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -46,6 +46,7 @@ struct st_buffer { | ||||
| 	struct st_request *last_SRpnt; | ||||
| 	struct st_cmdstatus cmdstat; | ||||
| 	struct page **reserved_pages; | ||||
| 	struct page **mapped_pages; | ||||
| 	struct rq_map_data map_data; | ||||
| 	unsigned char *b_data; | ||||
| 	unsigned short use_sg;	/* zero or max number of s/g segments for this adapter */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user