Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6620742f authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by James Bottomley
Browse files

[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: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: default avatarKai Makisara <Kai.Makisara@kolumbus.fi>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 6d476267
Loading
Loading
Loading
Loading
+23 −53
Original line number Diff line number Diff line
@@ -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;
}
+1 −0
Original line number Diff line number Diff line
@@ -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 */