提交 6620742f 编写于 作者: F FUJITA Tomonori 提交者: James Bottomley

[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: NFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: NKai Makisara <Kai.Makisara@kolumbus.fi>
Signed-off-by: NJames Bottomley <James.Bottomley@HansenPartnership.com>
上级 6d476267
...@@ -191,9 +191,9 @@ static int from_buffer(struct st_buffer *, char __user *, int); ...@@ -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 move_buffer_data(struct st_buffer *, int);
static void buf_to_sg(struct st_buffer *, unsigned 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); 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_probe(struct device *);
static int st_remove(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) ...@@ -435,22 +435,6 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
return (-EIO); 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) static struct st_request *st_allocate_request(struct scsi_tape *stp)
{ {
struct st_request *streq; struct st_request *streq;
...@@ -566,7 +550,10 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd ...@@ -566,7 +550,10 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd
init_completion(waiting); init_completion(waiting);
SRpnt->waiting = 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); buf_to_sg(STp->buffer, bytes);
mdata->nr_entries = mdata->nr_entries =
...@@ -579,16 +566,8 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd ...@@ -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->cmdstat.have_sense = 0;
STp->buffer->syscall_result = 0; STp->buffer->syscall_result = 0;
if (STp->buffer->do_dio) ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
ret = scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), retries);
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);
if (ret) { if (ret) {
/* could not allocate the buffer or request was too large */ /* could not allocate the buffer or request was too large */
(STp->buffer)->syscall_result = (-EBUSY); (STp->buffer)->syscall_result = (-EBUSY);
...@@ -1540,8 +1519,8 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, ...@@ -1540,8 +1519,8 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
if (i && ((unsigned long)buf & queue_dma_alignment( if (i && ((unsigned long)buf & queue_dma_alignment(
STp->device->request_queue)) == 0) { STp->device->request_queue)) == 0) {
i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg, i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
(unsigned long)buf, count, (is_read ? READ : WRITE)); count, (is_read ? READ : WRITE));
if (i > 0) { if (i > 0) {
STbp->do_dio = i; STbp->do_dio = i;
STbp->buffer_bytes = 0; /* can be used as transfer counter */ 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) ...@@ -1595,7 +1574,7 @@ static void release_buffering(struct scsi_tape *STp, int is_read)
STbp = STp->buffer; STbp = STp->buffer;
if (STbp->do_dio) { 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->do_dio = 0;
STbp->sg_segs = 0; STbp->sg_segs = 0;
} }
...@@ -4647,14 +4626,16 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) ...@@ -4647,14 +4626,16 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
} }
/* The following functions may be useful for a larger audience. */ /* The following functions may be useful for a larger audience. */
static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, static int sgl_map_user_pages(struct st_buffer *STbp,
unsigned long uaddr, size_t count, int rw) 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 end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
unsigned long start = uaddr >> PAGE_SHIFT; unsigned long start = uaddr >> PAGE_SHIFT;
const int nr_pages = end - start; const int nr_pages = end - start;
int res, i, j; int res, i, j;
struct page **pages; struct page **pages;
struct rq_map_data *mdata = &STbp->map_data;
/* User attempted Overflow! */ /* User attempted Overflow! */
if ((uaddr + count) < uaddr) if ((uaddr + count) < uaddr)
...@@ -4696,24 +4677,11 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa ...@@ -4696,24 +4677,11 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
flush_dcache_page(pages[i]); flush_dcache_page(pages[i]);
} }
/* Populate the scatter/gather list */ mdata->offset = uaddr & ~PAGE_MASK;
sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK); mdata->page_order = 0;
if (nr_pages > 1) { STbp->mapped_pages = pages;
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;
}
kfree(pages);
return nr_pages; return nr_pages;
out_unmap: out_unmap:
if (res > 0) { if (res > 0) {
for (j=0; j < res; j++) for (j=0; j < res; j++)
...@@ -4726,13 +4694,13 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa ...@@ -4726,13 +4694,13 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
/* And unmap them... */ /* And unmap them... */
static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages, static int sgl_unmap_user_pages(struct st_buffer *STbp,
int dirtied) const unsigned int nr_pages, int dirtied)
{ {
int i; int i;
for (i=0; i < nr_pages; i++) { for (i=0; i < nr_pages; i++) {
struct page *page = sg_page(&sgl[i]); struct page *page = STbp->mapped_pages[i];
if (dirtied) if (dirtied)
SetPageDirty(page); SetPageDirty(page);
...@@ -4741,6 +4709,8 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p ...@@ -4741,6 +4709,8 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
*/ */
page_cache_release(page); page_cache_release(page);
} }
kfree(STbp->mapped_pages);
STbp->mapped_pages = NULL;
return 0; return 0;
} }
...@@ -46,6 +46,7 @@ struct st_buffer { ...@@ -46,6 +46,7 @@ struct st_buffer {
struct st_request *last_SRpnt; struct st_request *last_SRpnt;
struct st_cmdstatus cmdstat; struct st_cmdstatus cmdstat;
struct page **reserved_pages; struct page **reserved_pages;
struct page **mapped_pages;
struct rq_map_data map_data; struct rq_map_data map_data;
unsigned char *b_data; unsigned char *b_data;
unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ unsigned short use_sg; /* zero or max number of s/g segments for this adapter */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册