Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 136253
b: refs/heads/master
c: 2624304
h: refs/heads/master
i:
  136251: e1c3f33
v: v3
  • Loading branch information
FUJITA Tomonori authored and James Bottomley committed Mar 12, 2009
1 parent 174a745 commit a62c845
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 78a42ce8fb2604c459e9ebb2a4f2d546b8250111
refs/heads/master: 26243043f207b3faa00594a33e10b2103205f27b
87 changes: 81 additions & 6 deletions trunk/drivers/scsi/osst.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,18 +317,25 @@ static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)


/* Wakeup from interrupt */
static void osst_sleep_done(void *data, char *sense, int result, int resid)
static void osst_end_async(struct request *req, int update)
{
struct osst_request *SRpnt = data;
struct osst_request *SRpnt = req->end_io_data;
struct osst_tape *STp = SRpnt->stp;
struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;

memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
STp->buffer->cmdstat.midlevel_result = SRpnt->result = result;
STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
#if DEBUG
STp->write_pending = 0;
#endif
if (SRpnt->waiting)
complete(SRpnt->waiting);

if (SRpnt->bio) {
kfree(mdata->pages);
blk_rq_unmap_user(SRpnt->bio);
}

__blk_put_request(req->q, req);
}

/* osst_request memory management */
Expand All @@ -342,6 +349,74 @@ static void osst_release_request(struct osst_request *streq)
kfree(streq);
}

static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
int cmd_len, int data_direction, void *buffer, unsigned bufflen,
int use_sg, int timeout, int retries)
{
struct request *req;
struct page **pages = NULL;
struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;

int err = 0;
int write = (data_direction == DMA_TO_DEVICE);

req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL);
if (!req)
return DRIVER_ERROR << 24;

req->cmd_type = REQ_TYPE_BLOCK_PC;
req->cmd_flags |= REQ_QUIET;

SRpnt->bio = NULL;

if (use_sg) {
struct scatterlist *sg, *sgl = (struct scatterlist *)buffer;
int i;

pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL);
if (!pages)
goto free_req;

for_each_sg(sgl, sg, use_sg, i)
pages[i] = sg_page(sg);

mdata->null_mapped = 1;

mdata->page_order = get_order(sgl[0].length);
mdata->nr_entries =
DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order);
mdata->offset = 0;

err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
if (err) {
kfree(pages);
goto free_req;
}
SRpnt->bio = req->bio;
mdata->pages = pages;

} else if (bufflen) {
err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL);
if (err)
goto free_req;
}

req->cmd_len = cmd_len;
memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
memcpy(req->cmd, cmd, req->cmd_len);
req->sense = SRpnt->sense;
req->sense_len = 0;
req->timeout = timeout;
req->retries = retries;
req->end_io_data = SRpnt;

blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async);
return 0;
free_req:
blk_put_request(req);
return DRIVER_ERROR << 24;
}

/* Do the scsi command. Waits until command performed if do_wait is true.
Otherwise osst_write_behind_check() is used to check that the command
has finished. */
Expand Down Expand Up @@ -403,8 +478,8 @@ static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct oss
STp->buffer->cmdstat.have_sense = 0;
STp->buffer->syscall_result = 0;

if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
use_sg, timeout, retries, SRpnt, osst_sleep_done, GFP_KERNEL))
if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
use_sg, timeout, retries))
/* could not allocate the buffer or request was too large */
(STp->buffer)->syscall_result = (-EBUSY);
else if (do_wait) {
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/scsi/osst.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ struct osst_buffer {
int syscall_result;
struct osst_request *last_SRpnt;
struct st_cmdstatus cmdstat;
struct rq_map_data map_data;
unsigned char *b_data;
os_aux_t *aux; /* onstream AUX structure at end of each block */
unsigned short use_sg; /* zero or number of s/g segments for this adapter */
Expand Down Expand Up @@ -634,6 +635,7 @@ struct osst_request {
int result;
struct osst_tape *stp;
struct completion *waiting;
struct bio *bio;
};

/* Values of write_type */
Expand Down

0 comments on commit a62c845

Please sign in to comment.