Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later 2 : : /* 3 : : * BSG helper library 4 : : * 5 : : * Copyright (C) 2008 James Smart, Emulex Corporation 6 : : * Copyright (C) 2011 Red Hat, Inc. All rights reserved. 7 : : * Copyright (C) 2011 Mike Christie 8 : : */ 9 : : #include <linux/slab.h> 10 : : #include <linux/blk-mq.h> 11 : : #include <linux/delay.h> 12 : : #include <linux/scatterlist.h> 13 : : #include <linux/bsg-lib.h> 14 : : #include <linux/export.h> 15 : : #include <scsi/scsi_cmnd.h> 16 : : #include <scsi/sg.h> 17 : : 18 : : #define uptr64(val) ((void __user *)(uintptr_t)(val)) 19 : : 20 : : struct bsg_set { 21 : : struct blk_mq_tag_set tag_set; 22 : : bsg_job_fn *job_fn; 23 : : bsg_timeout_fn *timeout_fn; 24 : : }; 25 : : 26 : 0 : static int bsg_transport_check_proto(struct sg_io_v4 *hdr) 27 : : { 28 : 0 : if (hdr->protocol != BSG_PROTOCOL_SCSI || 29 : 0 : hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_TRANSPORT) 30 : : return -EINVAL; 31 : 0 : if (!capable(CAP_SYS_RAWIO)) 32 : : return -EPERM; 33 : 0 : return 0; 34 : : } 35 : : 36 : 0 : static int bsg_transport_fill_hdr(struct request *rq, struct sg_io_v4 *hdr, 37 : : fmode_t mode) 38 : : { 39 : : struct bsg_job *job = blk_mq_rq_to_pdu(rq); 40 : : int ret; 41 : : 42 : 0 : job->request_len = hdr->request_len; 43 : 0 : job->request = memdup_user(uptr64(hdr->request), hdr->request_len); 44 : 0 : if (IS_ERR(job->request)) 45 : 0 : return PTR_ERR(job->request); 46 : : 47 : 0 : if (hdr->dout_xfer_len && hdr->din_xfer_len) { 48 : 0 : job->bidi_rq = blk_get_request(rq->q, REQ_OP_SCSI_IN, 0); 49 : 0 : if (IS_ERR(job->bidi_rq)) { 50 : : ret = PTR_ERR(job->bidi_rq); 51 : 0 : goto out; 52 : : } 53 : : 54 : 0 : ret = blk_rq_map_user(rq->q, job->bidi_rq, NULL, 55 : 0 : uptr64(hdr->din_xferp), hdr->din_xfer_len, 56 : : GFP_KERNEL); 57 : 0 : if (ret) 58 : : goto out_free_bidi_rq; 59 : : 60 : 0 : job->bidi_bio = job->bidi_rq->bio; 61 : : } else { 62 : 0 : job->bidi_rq = NULL; 63 : 0 : job->bidi_bio = NULL; 64 : : } 65 : : 66 : : return 0; 67 : : 68 : : out_free_bidi_rq: 69 : 0 : if (job->bidi_rq) 70 : 0 : blk_put_request(job->bidi_rq); 71 : : out: 72 : 0 : kfree(job->request); 73 : 0 : return ret; 74 : : } 75 : : 76 : 0 : static int bsg_transport_complete_rq(struct request *rq, struct sg_io_v4 *hdr) 77 : : { 78 : : struct bsg_job *job = blk_mq_rq_to_pdu(rq); 79 : : int ret = 0; 80 : : 81 : : /* 82 : : * The assignments below don't make much sense, but are kept for 83 : : * bug by bug backwards compatibility: 84 : : */ 85 : 0 : hdr->device_status = job->result & 0xff; 86 : 0 : hdr->transport_status = host_byte(job->result); 87 : 0 : hdr->driver_status = driver_byte(job->result); 88 : 0 : hdr->info = 0; 89 : 0 : if (hdr->device_status || hdr->transport_status || hdr->driver_status) 90 : 0 : hdr->info |= SG_INFO_CHECK; 91 : 0 : hdr->response_len = 0; 92 : : 93 : 0 : if (job->result < 0) { 94 : : /* we're only returning the result field in the reply */ 95 : 0 : job->reply_len = sizeof(u32); 96 : : ret = job->result; 97 : : } 98 : : 99 : 0 : if (job->reply_len && hdr->response) { 100 : 0 : int len = min(hdr->max_response_len, job->reply_len); 101 : : 102 : 0 : if (copy_to_user(uptr64(hdr->response), job->reply, len)) 103 : : ret = -EFAULT; 104 : : else 105 : 0 : hdr->response_len = len; 106 : : } 107 : : 108 : : /* we assume all request payload was transferred, residual == 0 */ 109 : 0 : hdr->dout_resid = 0; 110 : : 111 : 0 : if (job->bidi_rq) { 112 : 0 : unsigned int rsp_len = job->reply_payload.payload_len; 113 : : 114 : 0 : if (WARN_ON(job->reply_payload_rcv_len > rsp_len)) 115 : 0 : hdr->din_resid = 0; 116 : : else 117 : 0 : hdr->din_resid = rsp_len - job->reply_payload_rcv_len; 118 : : } else { 119 : 0 : hdr->din_resid = 0; 120 : : } 121 : : 122 : 0 : return ret; 123 : : } 124 : : 125 : 0 : static void bsg_transport_free_rq(struct request *rq) 126 : : { 127 : : struct bsg_job *job = blk_mq_rq_to_pdu(rq); 128 : : 129 : 0 : if (job->bidi_rq) { 130 : 0 : blk_rq_unmap_user(job->bidi_bio); 131 : 0 : blk_put_request(job->bidi_rq); 132 : : } 133 : : 134 : 0 : kfree(job->request); 135 : 0 : } 136 : : 137 : : static const struct bsg_ops bsg_transport_ops = { 138 : : .check_proto = bsg_transport_check_proto, 139 : : .fill_hdr = bsg_transport_fill_hdr, 140 : : .complete_rq = bsg_transport_complete_rq, 141 : : .free_rq = bsg_transport_free_rq, 142 : : }; 143 : : 144 : : /** 145 : : * bsg_teardown_job - routine to teardown a bsg job 146 : : * @kref: kref inside bsg_job that is to be torn down 147 : : */ 148 : 0 : static void bsg_teardown_job(struct kref *kref) 149 : : { 150 : : struct bsg_job *job = container_of(kref, struct bsg_job, kref); 151 : : struct request *rq = blk_mq_rq_from_pdu(job); 152 : : 153 : 0 : put_device(job->dev); /* release reference for the request */ 154 : : 155 : 0 : kfree(job->request_payload.sg_list); 156 : 0 : kfree(job->reply_payload.sg_list); 157 : : 158 : 0 : blk_mq_end_request(rq, BLK_STS_OK); 159 : 0 : } 160 : : 161 : 0 : void bsg_job_put(struct bsg_job *job) 162 : : { 163 : 0 : kref_put(&job->kref, bsg_teardown_job); 164 : 0 : } 165 : : EXPORT_SYMBOL_GPL(bsg_job_put); 166 : : 167 : 0 : int bsg_job_get(struct bsg_job *job) 168 : : { 169 : 0 : return kref_get_unless_zero(&job->kref); 170 : : } 171 : : EXPORT_SYMBOL_GPL(bsg_job_get); 172 : : 173 : : /** 174 : : * bsg_job_done - completion routine for bsg requests 175 : : * @job: bsg_job that is complete 176 : : * @result: job reply result 177 : : * @reply_payload_rcv_len: length of payload recvd 178 : : * 179 : : * The LLD should call this when the bsg job has completed. 180 : : */ 181 : 0 : void bsg_job_done(struct bsg_job *job, int result, 182 : : unsigned int reply_payload_rcv_len) 183 : : { 184 : 0 : job->result = result; 185 : 0 : job->reply_payload_rcv_len = reply_payload_rcv_len; 186 : 0 : blk_mq_complete_request(blk_mq_rq_from_pdu(job)); 187 : 0 : } 188 : : EXPORT_SYMBOL_GPL(bsg_job_done); 189 : : 190 : : /** 191 : : * bsg_complete - softirq done routine for destroying the bsg requests 192 : : * @rq: BSG request that holds the job to be destroyed 193 : : */ 194 : 0 : static void bsg_complete(struct request *rq) 195 : : { 196 : : struct bsg_job *job = blk_mq_rq_to_pdu(rq); 197 : : 198 : : bsg_job_put(job); 199 : 0 : } 200 : : 201 : 0 : static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req) 202 : : { 203 : 0 : size_t sz = (sizeof(struct scatterlist) * req->nr_phys_segments); 204 : : 205 : 0 : BUG_ON(!req->nr_phys_segments); 206 : : 207 : 0 : buf->sg_list = kzalloc(sz, GFP_KERNEL); 208 : 0 : if (!buf->sg_list) 209 : : return -ENOMEM; 210 : 0 : sg_init_table(buf->sg_list, req->nr_phys_segments); 211 : 0 : buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list); 212 : 0 : buf->payload_len = blk_rq_bytes(req); 213 : 0 : return 0; 214 : : } 215 : : 216 : : /** 217 : : * bsg_prepare_job - create the bsg_job structure for the bsg request 218 : : * @dev: device that is being sent the bsg request 219 : : * @req: BSG request that needs a job structure 220 : : */ 221 : 0 : static bool bsg_prepare_job(struct device *dev, struct request *req) 222 : : { 223 : : struct bsg_job *job = blk_mq_rq_to_pdu(req); 224 : : int ret; 225 : : 226 : 0 : job->timeout = req->timeout; 227 : : 228 : 0 : if (req->bio) { 229 : 0 : ret = bsg_map_buffer(&job->request_payload, req); 230 : 0 : if (ret) 231 : : goto failjob_rls_job; 232 : : } 233 : 0 : if (job->bidi_rq) { 234 : 0 : ret = bsg_map_buffer(&job->reply_payload, job->bidi_rq); 235 : 0 : if (ret) 236 : : goto failjob_rls_rqst_payload; 237 : : } 238 : 0 : job->dev = dev; 239 : : /* take a reference for the request */ 240 : 0 : get_device(job->dev); 241 : : kref_init(&job->kref); 242 : 0 : return true; 243 : : 244 : : failjob_rls_rqst_payload: 245 : 0 : kfree(job->request_payload.sg_list); 246 : : failjob_rls_job: 247 : 0 : job->result = -ENOMEM; 248 : 0 : return false; 249 : : } 250 : : 251 : : /** 252 : : * bsg_queue_rq - generic handler for bsg requests 253 : : * @hctx: hardware queue 254 : : * @bd: queue data 255 : : * 256 : : * On error the create_bsg_job function should return a -Exyz error value 257 : : * that will be set to ->result. 258 : : * 259 : : * Drivers/subsys should pass this to the queue init function. 260 : : */ 261 : 0 : static blk_status_t bsg_queue_rq(struct blk_mq_hw_ctx *hctx, 262 : : const struct blk_mq_queue_data *bd) 263 : : { 264 : 0 : struct request_queue *q = hctx->queue; 265 : 0 : struct device *dev = q->queuedata; 266 : 0 : struct request *req = bd->rq; 267 : : struct bsg_set *bset = 268 : 0 : container_of(q->tag_set, struct bsg_set, tag_set); 269 : : blk_status_t sts = BLK_STS_IOERR; 270 : : int ret; 271 : : 272 : 0 : blk_mq_start_request(req); 273 : : 274 : 0 : if (!get_device(dev)) 275 : : return BLK_STS_IOERR; 276 : : 277 : 0 : if (!bsg_prepare_job(dev, req)) 278 : : goto out; 279 : : 280 : 0 : ret = bset->job_fn(blk_mq_rq_to_pdu(req)); 281 : 0 : if (!ret) 282 : : sts = BLK_STS_OK; 283 : : 284 : : out: 285 : 0 : put_device(dev); 286 : 0 : return sts; 287 : : } 288 : : 289 : : /* called right after the request is allocated for the request_queue */ 290 : 0 : static int bsg_init_rq(struct blk_mq_tag_set *set, struct request *req, 291 : : unsigned int hctx_idx, unsigned int numa_node) 292 : : { 293 : : struct bsg_job *job = blk_mq_rq_to_pdu(req); 294 : : 295 : 0 : job->reply = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); 296 : 0 : if (!job->reply) 297 : : return -ENOMEM; 298 : 0 : return 0; 299 : : } 300 : : 301 : : /* called right before the request is given to the request_queue user */ 302 : 0 : static void bsg_initialize_rq(struct request *req) 303 : : { 304 : : struct bsg_job *job = blk_mq_rq_to_pdu(req); 305 : 0 : void *reply = job->reply; 306 : : 307 : 0 : memset(job, 0, sizeof(*job)); 308 : 0 : job->reply = reply; 309 : 0 : job->reply_len = SCSI_SENSE_BUFFERSIZE; 310 : 0 : job->dd_data = job + 1; 311 : 0 : } 312 : : 313 : 0 : static void bsg_exit_rq(struct blk_mq_tag_set *set, struct request *req, 314 : : unsigned int hctx_idx) 315 : : { 316 : : struct bsg_job *job = blk_mq_rq_to_pdu(req); 317 : : 318 : 0 : kfree(job->reply); 319 : 0 : } 320 : : 321 : 0 : void bsg_remove_queue(struct request_queue *q) 322 : : { 323 : 0 : if (q) { 324 : : struct bsg_set *bset = 325 : 0 : container_of(q->tag_set, struct bsg_set, tag_set); 326 : : 327 : 0 : bsg_unregister_queue(q); 328 : 0 : blk_cleanup_queue(q); 329 : 0 : blk_mq_free_tag_set(&bset->tag_set); 330 : 0 : kfree(bset); 331 : : } 332 : 0 : } 333 : : EXPORT_SYMBOL_GPL(bsg_remove_queue); 334 : : 335 : 0 : static enum blk_eh_timer_return bsg_timeout(struct request *rq, bool reserved) 336 : : { 337 : : struct bsg_set *bset = 338 : 0 : container_of(rq->q->tag_set, struct bsg_set, tag_set); 339 : : 340 : 0 : if (!bset->timeout_fn) 341 : : return BLK_EH_DONE; 342 : 0 : return bset->timeout_fn(rq); 343 : : } 344 : : 345 : : static const struct blk_mq_ops bsg_mq_ops = { 346 : : .queue_rq = bsg_queue_rq, 347 : : .init_request = bsg_init_rq, 348 : : .exit_request = bsg_exit_rq, 349 : : .initialize_rq_fn = bsg_initialize_rq, 350 : : .complete = bsg_complete, 351 : : .timeout = bsg_timeout, 352 : : }; 353 : : 354 : : /** 355 : : * bsg_setup_queue - Create and add the bsg hooks so we can receive requests 356 : : * @dev: device to attach bsg device to 357 : : * @name: device to give bsg device 358 : : * @job_fn: bsg job handler 359 : : * @timeout: timeout handler function pointer 360 : : * @dd_job_size: size of LLD data needed for each job 361 : : */ 362 : 0 : struct request_queue *bsg_setup_queue(struct device *dev, const char *name, 363 : : bsg_job_fn *job_fn, bsg_timeout_fn *timeout, int dd_job_size) 364 : : { 365 : : struct bsg_set *bset; 366 : : struct blk_mq_tag_set *set; 367 : : struct request_queue *q; 368 : : int ret = -ENOMEM; 369 : : 370 : 0 : bset = kzalloc(sizeof(*bset), GFP_KERNEL); 371 : 0 : if (!bset) 372 : : return ERR_PTR(-ENOMEM); 373 : : 374 : 0 : bset->job_fn = job_fn; 375 : 0 : bset->timeout_fn = timeout; 376 : : 377 : 0 : set = &bset->tag_set; 378 : 0 : set->ops = &bsg_mq_ops, 379 : 0 : set->nr_hw_queues = 1; 380 : 0 : set->queue_depth = 128; 381 : 0 : set->numa_node = NUMA_NO_NODE; 382 : 0 : set->cmd_size = sizeof(struct bsg_job) + dd_job_size; 383 : 0 : set->flags = BLK_MQ_F_NO_SCHED | BLK_MQ_F_BLOCKING; 384 : 0 : if (blk_mq_alloc_tag_set(set)) 385 : : goto out_tag_set; 386 : : 387 : 0 : q = blk_mq_init_queue(set); 388 : 0 : if (IS_ERR(q)) { 389 : : ret = PTR_ERR(q); 390 : 0 : goto out_queue; 391 : : } 392 : : 393 : 0 : q->queuedata = dev; 394 : 0 : blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT); 395 : : 396 : 0 : ret = bsg_register_queue(q, dev, name, &bsg_transport_ops); 397 : 0 : if (ret) { 398 : 0 : printk(KERN_ERR "%s: bsg interface failed to " 399 : : "initialize - register queue\n", dev->kobj.name); 400 : : goto out_cleanup_queue; 401 : : } 402 : : 403 : : return q; 404 : : out_cleanup_queue: 405 : 0 : blk_cleanup_queue(q); 406 : : out_queue: 407 : 0 : blk_mq_free_tag_set(set); 408 : : out_tag_set: 409 : 0 : kfree(bset); 410 : 0 : return ERR_PTR(ret); 411 : : } 412 : : EXPORT_SYMBOL_GPL(bsg_setup_queue);