1/* 2 * SCSI target lib functions 3 * 4 * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu> 5 * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 */ 22#include <linux/blkdev.h> 23#include <linux/hash.h> 24#include <linux/module.h> 25#include <linux/pagemap.h> 26#include <scsi/scsi.h> 27#include <scsi/scsi_cmnd.h> 28#include <scsi/scsi_device.h> 29#include <scsi/scsi_host.h> 30#include <scsi/scsi_tgt.h> 31 32#include "scsi_tgt_priv.h" 33 34static struct workqueue_struct *scsi_tgtd; 35static struct kmem_cache *scsi_tgt_cmd_cache; 36 37/* 38 * TODO: this struct will be killed when the block layer supports large bios 39 * and James's work struct code is in 40 */ 41struct scsi_tgt_cmd { 42 /* TODO replace work with James b's code */ 43 struct work_struct work; 44 /* TODO fix limits of some drivers */ 45 struct bio *bio; 46 47 struct list_head hash_list; 48 struct request *rq; 49 u64 tag; 50}; 51 52#define TGT_HASH_ORDER 4 53#define cmd_hashfn(tag) hash_long((unsigned long) (tag), TGT_HASH_ORDER) 54 55struct scsi_tgt_queuedata { 56 struct Scsi_Host *shost; 57 struct list_head cmd_hash[1 << TGT_HASH_ORDER]; 58 spinlock_t cmd_hash_lock; 59}; 60 61/* 62 * Function: scsi_host_get_command() 63 * 64 * Purpose: Allocate and setup a scsi command block and blk request 65 * 66 * Arguments: shost - scsi host 67 * data_dir - dma data dir 68 * gfp_mask- allocator flags 69 * 70 * Returns: The allocated scsi command structure. 71 * 72 * This should be called by target LLDs to get a command. 73 */ 74struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, 75 enum dma_data_direction data_dir, 76 gfp_t gfp_mask) 77{ 78 int write = (data_dir == DMA_TO_DEVICE); 79 struct request *rq; 80 struct scsi_cmnd *cmd; 81 struct scsi_tgt_cmd *tcmd; 82 83 /* Bail if we can't get a reference to the device */ 84 if (!get_device(&shost->shost_gendev)) 85 return NULL; 86 87 tcmd = kmem_cache_alloc(scsi_tgt_cmd_cache, GFP_ATOMIC); 88 if (!tcmd) 89 goto put_dev; 90 91 /* 92 * The blk helpers are used to the READ/WRITE requests 93 * transfering data from a initiator point of view. Since 94 * we are in target mode we want the opposite. 95 */ 96 rq = blk_get_request(shost->uspace_req_q, !write, gfp_mask); 97 if (!rq) 98 goto free_tcmd; 99 100 cmd = __scsi_get_command(shost, gfp_mask); 101 if (!cmd) 102 goto release_rq; 103 104 memset(cmd, 0, sizeof(*cmd)); 105 cmd->sc_data_direction = data_dir; 106 cmd->jiffies_at_alloc = jiffies; 107 cmd->request = rq; 108 109 rq->special = cmd; 110 rq->cmd_type = REQ_TYPE_SPECIAL; 111 rq->cmd_flags |= REQ_TYPE_BLOCK_PC; 112 rq->end_io_data = tcmd; 113 114 tcmd->rq = rq; 115 116 return cmd; 117 118release_rq: 119 blk_put_request(rq); 120free_tcmd: 121 kmem_cache_free(scsi_tgt_cmd_cache, tcmd); 122put_dev: 123 put_device(&shost->shost_gendev); 124 return NULL; 125 126} 127EXPORT_SYMBOL_GPL(scsi_host_get_command); 128 129/* 130 * Function: scsi_host_put_command() 131 * 132 * Purpose: Free a scsi command block 133 * 134 * Arguments: shost - scsi host 135 * cmd - command block to free 136 * 137 * Returns: Nothing. 138 * 139 * Notes: The command must not belong to any lists. 140 */ 141void scsi_host_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) 142{ 143 struct request_queue *q = shost->uspace_req_q; 144 struct request *rq = cmd->request; 145 struct scsi_tgt_cmd *tcmd = rq->end_io_data; 146 unsigned long flags; 147 148 kmem_cache_free(scsi_tgt_cmd_cache, tcmd); 149 150 spin_lock_irqsave(q->queue_lock, flags); 151 __blk_put_request(q, rq); 152 spin_unlock_irqrestore(q->queue_lock, flags); 153 154 __scsi_put_command(shost, cmd, &shost->shost_gendev); 155} 156EXPORT_SYMBOL_GPL(scsi_host_put_command); 157 158static void cmd_hashlist_del(struct scsi_cmnd *cmd) 159{ 160 struct request_queue *q = cmd->request->q; 161 struct scsi_tgt_queuedata *qdata = q->queuedata; 162 unsigned long flags; 163 struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; 164 165 spin_lock_irqsave(&qdata->cmd_hash_lock, flags); 166 list_del(&tcmd->hash_list); 167 spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); 168} 169 170static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd) 171{ 172 blk_rq_unmap_user(tcmd->bio); 173} 174 175static void scsi_tgt_cmd_destroy(struct work_struct *work) 176{ 177 struct scsi_tgt_cmd *tcmd = 178 container_of(work, struct scsi_tgt_cmd, work); 179 struct scsi_cmnd *cmd = tcmd->rq->special; 180 181 dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction, 182 rq_data_dir(cmd->request)); 183 scsi_unmap_user_pages(tcmd); 184 scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd); 185} 186 187static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, 188 u64 tag) 189{ 190 struct scsi_tgt_queuedata *qdata = rq->q->queuedata; 191 unsigned long flags; 192 struct list_head *head; 193 194 tcmd->tag = tag; 195 tcmd->bio = NULL; 196 INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); 197 spin_lock_irqsave(&qdata->cmd_hash_lock, flags); 198 head = &qdata->cmd_hash[cmd_hashfn(tag)]; 199 list_add(&tcmd->hash_list, head); 200 spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); 201} 202 203/* 204 * scsi_tgt_alloc_queue - setup queue used for message passing 205 * shost: scsi host 206 * 207 * This should be called by the LLD after host allocation. 208 * And will be released when the host is released. 209 */ 210int scsi_tgt_alloc_queue(struct Scsi_Host *shost) 211{ 212 struct scsi_tgt_queuedata *queuedata; 213 struct request_queue *q; 214 int err, i; 215 216 /* 217 * Do we need to send a netlink event or should uspace 218 * just respond to the hotplug event? 219 */ 220 q = __scsi_alloc_queue(shost, NULL); 221 if (!q) 222 return -ENOMEM; 223 224 queuedata = kzalloc(sizeof(*queuedata), GFP_KERNEL); 225 if (!queuedata) { 226 err = -ENOMEM; 227 goto cleanup_queue; 228 } 229 queuedata->shost = shost; 230 q->queuedata = queuedata; 231 232 /* 233 * this is a silly hack. We should probably just queue as many 234 * command as is recvd to userspace. uspace can then make 235 * sure we do not overload the HBA 236 */ 237 q->nr_requests = shost->hostt->can_queue; 238 /* 239 * We currently only support software LLDs so this does 240 * not matter for now. Do we need this for the cards we support? 241 * If so we should make it a host template value. 242 */ 243 blk_queue_dma_alignment(q, 0); 244 shost->uspace_req_q = q; 245 246 for (i = 0; i < ARRAY_SIZE(queuedata->cmd_hash); i++) 247 INIT_LIST_HEAD(&queuedata->cmd_hash[i]); 248 spin_lock_init(&queuedata->cmd_hash_lock); 249 250 return 0; 251 252cleanup_queue: 253 blk_cleanup_queue(q); 254 return err; 255} 256EXPORT_SYMBOL_GPL(scsi_tgt_alloc_queue); 257 258void scsi_tgt_free_queue(struct Scsi_Host *shost) 259{ 260 int i; 261 unsigned long flags; 262 struct request_queue *q = shost->uspace_req_q; 263 struct scsi_cmnd *cmd; 264 struct scsi_tgt_queuedata *qdata = q->queuedata; 265 struct scsi_tgt_cmd *tcmd, *n; 266 LIST_HEAD(cmds); 267 268 spin_lock_irqsave(&qdata->cmd_hash_lock, flags); 269 270 for (i = 0; i < ARRAY_SIZE(qdata->cmd_hash); i++) { 271 list_for_each_entry_safe(tcmd, n, &qdata->cmd_hash[i], 272 hash_list) { 273 list_del(&tcmd->hash_list); 274 list_add(&tcmd->hash_list, &cmds); 275 } 276 } 277 278 spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); 279 280 while (!list_empty(&cmds)) { 281 tcmd = list_entry(cmds.next, struct scsi_tgt_cmd, hash_list); 282 list_del(&tcmd->hash_list); 283 cmd = tcmd->rq->special; 284 285 shost->hostt->eh_abort_handler(cmd); 286 scsi_tgt_cmd_destroy(&tcmd->work); 287 } 288} 289EXPORT_SYMBOL_GPL(scsi_tgt_free_queue); 290 291struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *cmd) 292{ 293 struct scsi_tgt_queuedata *queue = cmd->request->q->queuedata; 294 return queue->shost; 295} 296EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host); 297 298/* 299 * scsi_tgt_queue_command - queue command for userspace processing 300 * @cmd: scsi command 301 * @scsilun: scsi lun 302 * @tag: unique value to identify this command for tmf 303 */ 304int scsi_tgt_queue_command(struct scsi_cmnd *cmd, struct scsi_lun *scsilun, 305 u64 tag) 306{ 307 struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; 308 int err; 309 310 init_scsi_tgt_cmd(cmd->request, tcmd, tag); 311 err = scsi_tgt_uspace_send_cmd(cmd, scsilun, tag); 312 if (err) 313 cmd_hashlist_del(cmd); 314 315 return err; 316} 317EXPORT_SYMBOL_GPL(scsi_tgt_queue_command); 318 319/* 320 * This is run from a interrpt handler normally and the unmap 321 * needs process context so we must queue 322 */ 323static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd) 324{ 325 struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; 326 327 dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); 328 329 scsi_tgt_uspace_send_status(cmd, tcmd->tag); 330 331 if (cmd->request_buffer) 332 scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); 333 334 queue_work(scsi_tgtd, &tcmd->work); 335} 336 337static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd) 338{ 339 struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); 340 int err; 341 342 dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); 343 344 err = shost->hostt->transfer_response(cmd, scsi_tgt_cmd_done); 345 switch (err) { 346 case SCSI_MLQUEUE_HOST_BUSY: 347 case SCSI_MLQUEUE_DEVICE_BUSY: 348 return -EAGAIN; 349 } 350 return 0; 351} 352 353static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask) 354{ 355 struct request *rq = cmd->request; 356 int count; 357 358 cmd->use_sg = rq->nr_phys_segments; 359 cmd->request_buffer = scsi_alloc_sgtable(cmd, gfp_mask); 360 if (!cmd->request_buffer) 361 return -ENOMEM; 362 363 cmd->request_bufflen = rq->data_len; 364 365 dprintk("cmd %p cnt %d %lu\n", cmd, cmd->use_sg, rq_data_dir(rq)); 366 count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer); 367 if (likely(count <= cmd->use_sg)) { 368 cmd->use_sg = count; 369 return 0; 370 } 371 372 eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg); 373 scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); 374 return -EINVAL; 375} 376 377/* TODO: test this crap and replace bio_map_user with new interface maybe */ 378static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd, 379 unsigned long uaddr, unsigned int len, int rw) 380{ 381 struct request_queue *q = cmd->request->q; 382 struct request *rq = cmd->request; 383 int err; 384 385 dprintk("%lx %u\n", uaddr, len); 386 err = blk_rq_map_user(q, rq, (void *)uaddr, len); 387 if (err) { 388 /* 389 * TODO: need to fixup sg_tablesize, max_segment_size, 390 * max_sectors, etc for modern HW and software drivers 391 * where this value is bogus. 392 * 393 * TODO2: we can alloc a reserve buffer of max size 394 * we can handle and do the slow copy path for really large 395 * IO. 396 */ 397 eprintk("Could not handle request of size %u.\n", len); 398 return err; 399 } 400 401 tcmd->bio = rq->bio; 402 err = scsi_tgt_init_cmd(cmd, GFP_KERNEL); 403 if (err) 404 goto unmap_rq; 405 406 return 0; 407 408unmap_rq: 409 scsi_unmap_user_pages(tcmd); 410 return err; 411} 412 413static int scsi_tgt_copy_sense(struct scsi_cmnd *cmd, unsigned long uaddr, 414 unsigned len) 415{ 416 char __user *p = (char __user *) uaddr; 417 418 if (copy_from_user(cmd->sense_buffer, p, 419 min_t(unsigned, SCSI_SENSE_BUFFERSIZE, len))) { 420 printk(KERN_ERR "Could not copy the sense buffer\n"); 421 return -EIO; 422 } 423 return 0; 424} 425 426static int scsi_tgt_abort_cmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) 427{ 428 struct scsi_tgt_cmd *tcmd; 429 int err; 430 431 err = shost->hostt->eh_abort_handler(cmd); 432 if (err) 433 eprintk("fail to abort %p\n", cmd); 434 435 tcmd = cmd->request->end_io_data; 436 scsi_tgt_cmd_destroy(&tcmd->work); 437 return err; 438} 439 440static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag) 441{ 442 struct scsi_tgt_queuedata *qdata = q->queuedata; 443 struct request *rq = NULL; 444 struct list_head *head; 445 struct scsi_tgt_cmd *tcmd; 446 unsigned long flags; 447 448 head = &qdata->cmd_hash[cmd_hashfn(tag)]; 449 spin_lock_irqsave(&qdata->cmd_hash_lock, flags); 450 list_for_each_entry(tcmd, head, hash_list) { 451 if (tcmd->tag == tag) { 452 rq = tcmd->rq; 453 list_del(&tcmd->hash_list); 454 break; 455 } 456 } 457 spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); 458 459 return rq; 460} 461 462int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, 463 unsigned long uaddr, u32 len, unsigned long sense_uaddr, 464 u32 sense_len, u8 rw) 465{ 466 struct Scsi_Host *shost; 467 struct scsi_cmnd *cmd; 468 struct request *rq; 469 struct scsi_tgt_cmd *tcmd; 470 int err = 0; 471 472 dprintk("%d %llu %d %u %lx %u\n", host_no, (unsigned long long) tag, 473 result, len, uaddr, rw); 474 475 /* TODO: replace with a O(1) alg */ 476 shost = scsi_host_lookup(host_no); 477 if (IS_ERR(shost)) { 478 printk(KERN_ERR "Could not find host no %d\n", host_no); 479 return -EINVAL; 480 } 481 482 if (!shost->uspace_req_q) { 483 printk(KERN_ERR "Not target scsi host %d\n", host_no); 484 goto done; 485 } 486 487 rq = tgt_cmd_hash_lookup(shost->uspace_req_q, tag); 488 if (!rq) { 489 printk(KERN_ERR "Could not find tag %llu\n", 490 (unsigned long long) tag); 491 err = -EINVAL; 492 goto done; 493 } 494 cmd = rq->special; 495 496 dprintk("cmd %p scb %x result %d len %d bufflen %u %lu %x\n", 497 cmd, cmd->cmnd[0], result, len, cmd->request_bufflen, 498 rq_data_dir(rq), cmd->cmnd[0]); 499 500 if (result == TASK_ABORTED) { 501 scsi_tgt_abort_cmd(shost, cmd); 502 goto done; 503 } 504 /* 505 * store the userspace values here, the working values are 506 * in the request_* values 507 */ 508 tcmd = cmd->request->end_io_data; 509 cmd->result = result; 510 511 if (cmd->result == SAM_STAT_CHECK_CONDITION) 512 scsi_tgt_copy_sense(cmd, sense_uaddr, sense_len); 513 514 if (len) { 515 err = scsi_map_user_pages(rq->end_io_data, cmd, uaddr, len, rw); 516 if (err) { 517 /* 518 * user-space daemon bugs or OOM 519 * TODO: we can do better for OOM. 520 */ 521 struct scsi_tgt_queuedata *qdata; 522 struct list_head *head; 523 unsigned long flags; 524 525 eprintk("cmd %p ret %d uaddr %lx len %d rw %d\n", 526 cmd, err, uaddr, len, rw); 527 528 qdata = shost->uspace_req_q->queuedata; 529 head = &qdata->cmd_hash[cmd_hashfn(tcmd->tag)]; 530 531 spin_lock_irqsave(&qdata->cmd_hash_lock, flags); 532 list_add(&tcmd->hash_list, head); 533 spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); 534 535 goto done; 536 } 537 } 538 err = scsi_tgt_transfer_response(cmd); 539done: 540 scsi_host_put(shost); 541 return err; 542} 543 544int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, int function, u64 tag, 545 struct scsi_lun *scsilun, void *data) 546{ 547 int err; 548 549 /* TODO: need to retry if this fails. */ 550 err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, function, 551 tag, scsilun, data); 552 if (err < 0) 553 eprintk("The task management request lost!\n"); 554 return err; 555} 556EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request); 557 558int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result) 559{ 560 struct Scsi_Host *shost; 561 int err = -EINVAL; 562 563 dprintk("%d %d %llx\n", host_no, result, (unsigned long long) mid); 564 565 shost = scsi_host_lookup(host_no); 566 if (IS_ERR(shost)) { 567 printk(KERN_ERR "Could not find host no %d\n", host_no); 568 return err; 569 } 570 571 if (!shost->uspace_req_q) { 572 printk(KERN_ERR "Not target scsi host %d\n", host_no); 573 goto done; 574 } 575 576 err = shost->hostt->tsk_mgmt_response(mid, result); 577done: 578 scsi_host_put(shost); 579 return err; 580} 581 582static int __init scsi_tgt_init(void) 583{ 584 int err; 585 586 scsi_tgt_cmd_cache = kmem_cache_create("scsi_tgt_cmd", 587 sizeof(struct scsi_tgt_cmd), 588 0, 0, NULL, NULL); 589 if (!scsi_tgt_cmd_cache) 590 return -ENOMEM; 591 592 scsi_tgtd = create_workqueue("scsi_tgtd"); 593 if (!scsi_tgtd) { 594 err = -ENOMEM; 595 goto free_kmemcache; 596 } 597 598 err = scsi_tgt_if_init(); 599 if (err) 600 goto destroy_wq; 601 602 return 0; 603 604destroy_wq: 605 destroy_workqueue(scsi_tgtd); 606free_kmemcache: 607 kmem_cache_destroy(scsi_tgt_cmd_cache); 608 return err; 609} 610 611static void __exit scsi_tgt_exit(void) 612{ 613 destroy_workqueue(scsi_tgtd); 614 scsi_tgt_if_exit(); 615 kmem_cache_destroy(scsi_tgt_cmd_cache); 616} 617 618module_init(scsi_tgt_init); 619module_exit(scsi_tgt_exit); 620 621MODULE_DESCRIPTION("SCSI target core"); 622MODULE_LICENSE("GPL"); 623