aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/st.c54
-rw-r--r--drivers/scsi/st.h1
2 files changed, 55 insertions, 0 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 9d9e4b90f23b..084a967b2e78 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -475,6 +475,60 @@ static void st_release_request(struct st_request *streq)
475 kfree(streq); 475 kfree(streq);
476} 476}
477 477
478static void st_scsi_execute_end(struct request *req, int uptodate)
479{
480 struct st_request *SRpnt = req->end_io_data;
481 struct scsi_tape *STp = SRpnt->stp;
482
483 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
484 STp->buffer->cmdstat.residual = req->data_len;
485
486 if (SRpnt->waiting)
487 complete(SRpnt->waiting);
488
489 blk_rq_unmap_user(SRpnt->bio);
490 __blk_put_request(req->q, req);
491}
492
493static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
494 int data_direction, void *buffer, unsigned bufflen,
495 int timeout, int retries)
496{
497 struct request *req;
498 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
499 int err = 0;
500 int write = (data_direction == DMA_TO_DEVICE);
501
502 req = blk_get_request(SRpnt->stp->device->request_queue, write,
503 GFP_KERNEL);
504 if (!req)
505 return DRIVER_ERROR << 24;
506
507 req->cmd_type = REQ_TYPE_BLOCK_PC;
508 req->cmd_flags |= REQ_QUIET;
509
510 mdata->null_mapped = 1;
511
512 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
513 if (err) {
514 blk_put_request(req);
515 return DRIVER_ERROR << 24;
516 }
517
518 SRpnt->bio = req->bio;
519 req->cmd_len = COMMAND_SIZE(cmd[0]);
520 memset(req->cmd, 0, BLK_MAX_CDB);
521 memcpy(req->cmd, cmd, req->cmd_len);
522 req->sense = SRpnt->sense;
523 req->sense_len = 0;
524 req->timeout = timeout;
525 req->retries = retries;
526 req->end_io_data = SRpnt;
527
528 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
529 return 0;
530}
531
478/* Do the scsi command. Waits until command performed if do_wait is true. 532/* Do the scsi command. Waits until command performed if do_wait is true.
479 Otherwise write_behind_check() is used to check that the command 533 Otherwise write_behind_check() is used to check that the command
480 has finished. */ 534 has finished. */
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index 74748abe8246..77302fa8608a 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -29,6 +29,7 @@ struct st_request {
29 int result; 29 int result;
30 struct scsi_tape *stp; 30 struct scsi_tape *stp;
31 struct completion *waiting; 31 struct completion *waiting;
32 struct bio *bio;
32}; 33};
33 34
34/* The tape buffer descriptor. */ 35/* The tape buffer descriptor. */