summaryrefslogtreecommitdiffstats
path: root/block/bsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/bsg.c')
-rw-r--r--block/bsg.c47
1 files changed, 21 insertions, 26 deletions
diff --git a/block/bsg.c b/block/bsg.c
index a57046de2f07..e34c3320956c 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -85,7 +85,6 @@ struct bsg_command {
85 struct bio *bidi_bio; 85 struct bio *bidi_bio;
86 int err; 86 int err;
87 struct sg_io_v4 hdr; 87 struct sg_io_v4 hdr;
88 char sense[SCSI_SENSE_BUFFERSIZE];
89}; 88};
90 89
91static void bsg_free_command(struct bsg_command *bc) 90static void bsg_free_command(struct bsg_command *bc)
@@ -140,18 +139,20 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
140 struct sg_io_v4 *hdr, struct bsg_device *bd, 139 struct sg_io_v4 *hdr, struct bsg_device *bd,
141 fmode_t has_write_perm) 140 fmode_t has_write_perm)
142{ 141{
142 struct scsi_request *req = scsi_req(rq);
143
143 if (hdr->request_len > BLK_MAX_CDB) { 144 if (hdr->request_len > BLK_MAX_CDB) {
144 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); 145 req->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
145 if (!rq->cmd) 146 if (!req->cmd)
146 return -ENOMEM; 147 return -ENOMEM;
147 } 148 }
148 149
149 if (copy_from_user(rq->cmd, (void __user *)(unsigned long)hdr->request, 150 if (copy_from_user(req->cmd, (void __user *)(unsigned long)hdr->request,
150 hdr->request_len)) 151 hdr->request_len))
151 return -EFAULT; 152 return -EFAULT;
152 153
153 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { 154 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
154 if (blk_verify_command(rq->cmd, has_write_perm)) 155 if (blk_verify_command(req->cmd, has_write_perm))
155 return -EPERM; 156 return -EPERM;
156 } else if (!capable(CAP_SYS_RAWIO)) 157 } else if (!capable(CAP_SYS_RAWIO))
157 return -EPERM; 158 return -EPERM;
@@ -159,7 +160,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
159 /* 160 /*
160 * fill in request structure 161 * fill in request structure
161 */ 162 */
162 rq->cmd_len = hdr->request_len; 163 req->cmd_len = hdr->request_len;
163 164
164 rq->timeout = msecs_to_jiffies(hdr->timeout); 165 rq->timeout = msecs_to_jiffies(hdr->timeout);
165 if (!rq->timeout) 166 if (!rq->timeout)
@@ -205,8 +206,7 @@ bsg_validate_sgv4_hdr(struct sg_io_v4 *hdr, int *rw)
205 * map sg_io_v4 to a request. 206 * map sg_io_v4 to a request.
206 */ 207 */
207static struct request * 208static struct request *
208bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, 209bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
209 u8 *sense)
210{ 210{
211 struct request_queue *q = bd->queue; 211 struct request_queue *q = bd->queue;
212 struct request *rq, *next_rq = NULL; 212 struct request *rq, *next_rq = NULL;
@@ -236,7 +236,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
236 rq = blk_get_request(q, rw, GFP_KERNEL); 236 rq = blk_get_request(q, rw, GFP_KERNEL);
237 if (IS_ERR(rq)) 237 if (IS_ERR(rq))
238 return rq; 238 return rq;
239 blk_rq_set_block_pc(rq); 239 scsi_req_init(rq);
240 240
241 ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm); 241 ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm);
242 if (ret) 242 if (ret)
@@ -280,13 +280,9 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
280 goto out; 280 goto out;
281 } 281 }
282 282
283 rq->sense = sense;
284 rq->sense_len = 0;
285
286 return rq; 283 return rq;
287out: 284out:
288 if (rq->cmd != rq->__cmd) 285 scsi_req_free_cmd(scsi_req(rq));
289 kfree(rq->cmd);
290 blk_put_request(rq); 286 blk_put_request(rq);
291 if (next_rq) { 287 if (next_rq) {
292 blk_rq_unmap_user(next_rq->bio); 288 blk_rq_unmap_user(next_rq->bio);
@@ -393,6 +389,7 @@ static struct bsg_command *bsg_get_done_cmd(struct bsg_device *bd)
393static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, 389static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
394 struct bio *bio, struct bio *bidi_bio) 390 struct bio *bio, struct bio *bidi_bio)
395{ 391{
392 struct scsi_request *req = scsi_req(rq);
396 int ret = 0; 393 int ret = 0;
397 394
398 dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors); 395 dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors);
@@ -407,12 +404,12 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
407 hdr->info |= SG_INFO_CHECK; 404 hdr->info |= SG_INFO_CHECK;
408 hdr->response_len = 0; 405 hdr->response_len = 0;
409 406
410 if (rq->sense_len && hdr->response) { 407 if (req->sense_len && hdr->response) {
411 int len = min_t(unsigned int, hdr->max_response_len, 408 int len = min_t(unsigned int, hdr->max_response_len,
412 rq->sense_len); 409 req->sense_len);
413 410
414 ret = copy_to_user((void __user *)(unsigned long)hdr->response, 411 ret = copy_to_user((void __user *)(unsigned long)hdr->response,
415 rq->sense, len); 412 req->sense, len);
416 if (!ret) 413 if (!ret)
417 hdr->response_len = len; 414 hdr->response_len = len;
418 else 415 else
@@ -420,14 +417,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
420 } 417 }
421 418
422 if (rq->next_rq) { 419 if (rq->next_rq) {
423 hdr->dout_resid = rq->resid_len; 420 hdr->dout_resid = req->resid_len;
424 hdr->din_resid = rq->next_rq->resid_len; 421 hdr->din_resid = scsi_req(rq->next_rq)->resid_len;
425 blk_rq_unmap_user(bidi_bio); 422 blk_rq_unmap_user(bidi_bio);
426 blk_put_request(rq->next_rq); 423 blk_put_request(rq->next_rq);
427 } else if (rq_data_dir(rq) == READ) 424 } else if (rq_data_dir(rq) == READ)
428 hdr->din_resid = rq->resid_len; 425 hdr->din_resid = req->resid_len;
429 else 426 else
430 hdr->dout_resid = rq->resid_len; 427 hdr->dout_resid = req->resid_len;
431 428
432 /* 429 /*
433 * If the request generated a negative error number, return it 430 * If the request generated a negative error number, return it
@@ -439,8 +436,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
439 ret = rq->errors; 436 ret = rq->errors;
440 437
441 blk_rq_unmap_user(bio); 438 blk_rq_unmap_user(bio);
442 if (rq->cmd != rq->__cmd) 439 scsi_req_free_cmd(req);
443 kfree(rq->cmd);
444 blk_put_request(rq); 440 blk_put_request(rq);
445 441
446 return ret; 442 return ret;
@@ -625,7 +621,7 @@ static int __bsg_write(struct bsg_device *bd, const char __user *buf,
625 /* 621 /*
626 * get a request, fill in the blanks, and add to request queue 622 * get a request, fill in the blanks, and add to request queue
627 */ 623 */
628 rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm, bc->sense); 624 rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm);
629 if (IS_ERR(rq)) { 625 if (IS_ERR(rq)) {
630 ret = PTR_ERR(rq); 626 ret = PTR_ERR(rq);
631 rq = NULL; 627 rq = NULL;
@@ -911,12 +907,11 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
911 struct bio *bio, *bidi_bio = NULL; 907 struct bio *bio, *bidi_bio = NULL;
912 struct sg_io_v4 hdr; 908 struct sg_io_v4 hdr;
913 int at_head; 909 int at_head;
914 u8 sense[SCSI_SENSE_BUFFERSIZE];
915 910
916 if (copy_from_user(&hdr, uarg, sizeof(hdr))) 911 if (copy_from_user(&hdr, uarg, sizeof(hdr)))
917 return -EFAULT; 912 return -EFAULT;
918 913
919 rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE, sense); 914 rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE);
920 if (IS_ERR(rq)) 915 if (IS_ERR(rq))
921 return PTR_ERR(rq); 916 return PTR_ERR(rq);
922 917