1892 lines · c
1/*2 * Xen SCSI backend driver3 *4 * Copyright (c) 2008, FUJITSU Limited5 *6 * Based on the blkback driver code.7 * Adaption to kernel taget core infrastructure taken from vhost/scsi.c8 *9 * This program is free software; you can redistribute it and/or10 * modify it under the terms of the GNU General Public License version 211 * as published by the Free Software Foundation; or, when distributed12 * separately from the Linux kernel or incorporated into other13 * software packages, subject to the following license:14 *15 * Permission is hereby granted, free of charge, to any person obtaining a copy16 * of this source file (the "Software"), to deal in the Software without17 * restriction, including without limitation the rights to use, copy, modify,18 * merge, publish, distribute, sublicense, and/or sell copies of the Software,19 * and to permit persons to whom the Software is furnished to do so, subject to20 * the following conditions:21 *22 * The above copyright notice and this permission notice shall be included in23 * all copies or substantial portions of the Software.24 *25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS31 * IN THE SOFTWARE.32 */33 34#define pr_fmt(fmt) "xen-pvscsi: " fmt35 36#include <linux/module.h>37#include <linux/utsname.h>38#include <linux/interrupt.h>39#include <linux/slab.h>40#include <linux/wait.h>41#include <linux/sched.h>42#include <linux/list.h>43#include <linux/gfp.h>44#include <linux/delay.h>45#include <linux/spinlock.h>46#include <linux/configfs.h>47 48#include <generated/utsrelease.h>49 50#include <scsi/scsi_host.h> /* SG_ALL */51 52#include <target/target_core_base.h>53#include <target/target_core_fabric.h>54 55#include <asm/hypervisor.h>56 57#include <xen/xen.h>58#include <xen/balloon.h>59#include <xen/events.h>60#include <xen/xenbus.h>61#include <xen/grant_table.h>62#include <xen/page.h>63 64#include <xen/interface/grant_table.h>65#include <xen/interface/io/vscsiif.h>66 67#define VSCSI_VERSION "v0.1"68#define VSCSI_NAMELEN 3269 70struct ids_tuple {71 unsigned int hst; /* host */72 unsigned int chn; /* channel */73 unsigned int tgt; /* target */74 unsigned int lun; /* LUN */75};76 77struct v2p_entry {78 struct ids_tuple v; /* translate from */79 struct scsiback_tpg *tpg; /* translate to */80 unsigned int lun;81 struct kref kref;82 struct list_head l;83};84 85struct vscsibk_info {86 struct xenbus_device *dev;87 88 domid_t domid;89 unsigned int irq;90 91 struct vscsiif_back_ring ring;92 93 spinlock_t ring_lock;94 atomic_t nr_unreplied_reqs;95 96 spinlock_t v2p_lock;97 struct list_head v2p_entry_lists;98 99 wait_queue_head_t waiting_to_free;100 101 struct gnttab_page_cache free_pages;102};103 104/* theoretical maximum of grants for one request */105#define VSCSI_MAX_GRANTS (SG_ALL + VSCSIIF_SG_TABLESIZE)106 107/*108 * VSCSI_GRANT_BATCH is the maximum number of grants to be processed in one109 * call to map/unmap grants. Don't choose it too large, as there are arrays110 * with VSCSI_GRANT_BATCH elements allocated on the stack.111 */112#define VSCSI_GRANT_BATCH 16113 114struct vscsibk_pend {115 uint16_t rqid;116 117 uint8_t cmnd[VSCSIIF_MAX_COMMAND_SIZE];118 uint8_t cmd_len;119 120 uint8_t sc_data_direction;121 uint16_t n_sg; /* real length of SG list */122 uint16_t n_grants; /* SG pages and potentially SG list */123 uint32_t data_len;124 uint32_t result;125 126 struct vscsibk_info *info;127 struct v2p_entry *v2p;128 struct scatterlist *sgl;129 130 uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE];131 132 grant_handle_t grant_handles[VSCSI_MAX_GRANTS];133 struct page *pages[VSCSI_MAX_GRANTS];134 135 struct se_cmd se_cmd;136 137 struct completion tmr_done;138};139 140#define VSCSI_DEFAULT_SESSION_TAGS 128141 142struct scsiback_nexus {143 /* Pointer to TCM session for I_T Nexus */144 struct se_session *tvn_se_sess;145};146 147struct scsiback_tport {148 /* SCSI protocol the tport is providing */149 u8 tport_proto_id;150 /* Binary World Wide unique Port Name for pvscsi Target port */151 u64 tport_wwpn;152 /* ASCII formatted WWPN for pvscsi Target port */153 char tport_name[VSCSI_NAMELEN];154 /* Returned by scsiback_make_tport() */155 struct se_wwn tport_wwn;156};157 158struct scsiback_tpg {159 /* scsiback port target portal group tag for TCM */160 u16 tport_tpgt;161 /* track number of TPG Port/Lun Links wrt explicit I_T Nexus shutdown */162 int tv_tpg_port_count;163 /* xen-pvscsi references to tpg_nexus, protected by tv_tpg_mutex */164 int tv_tpg_fe_count;165 /* list for scsiback_list */166 struct list_head tv_tpg_list;167 /* Used to protect access for tpg_nexus */168 struct mutex tv_tpg_mutex;169 /* Pointer to the TCM pvscsi I_T Nexus for this TPG endpoint */170 struct scsiback_nexus *tpg_nexus;171 /* Pointer back to scsiback_tport */172 struct scsiback_tport *tport;173 /* Returned by scsiback_make_tpg() */174 struct se_portal_group se_tpg;175 /* alias used in xenstore */176 char param_alias[VSCSI_NAMELEN];177 /* list of info structures related to this target portal group */178 struct list_head info_list;179};180 181#define SCSIBACK_INVALID_HANDLE (~0)182 183static bool log_print_stat;184module_param(log_print_stat, bool, 0644);185 186static int scsiback_max_buffer_pages = 1024;187module_param_named(max_buffer_pages, scsiback_max_buffer_pages, int, 0644);188MODULE_PARM_DESC(max_buffer_pages,189"Maximum number of free pages to keep in backend buffer");190 191/* Global spinlock to protect scsiback TPG list */192static DEFINE_MUTEX(scsiback_mutex);193static LIST_HEAD(scsiback_list);194 195static void scsiback_get(struct vscsibk_info *info)196{197 atomic_inc(&info->nr_unreplied_reqs);198}199 200static void scsiback_put(struct vscsibk_info *info)201{202 if (atomic_dec_and_test(&info->nr_unreplied_reqs))203 wake_up(&info->waiting_to_free);204}205 206static unsigned long vaddr_page(struct page *page)207{208 unsigned long pfn = page_to_pfn(page);209 210 return (unsigned long)pfn_to_kaddr(pfn);211}212 213static unsigned long vaddr(struct vscsibk_pend *req, int seg)214{215 return vaddr_page(req->pages[seg]);216}217 218static void scsiback_print_status(char *sense_buffer, int errors,219 struct vscsibk_pend *pending_req)220{221 struct scsiback_tpg *tpg = pending_req->v2p->tpg;222 223 pr_err("[%s:%d] cmnd[0]=%02x -> st=%02x msg=%02x host=%02x\n",224 tpg->tport->tport_name, pending_req->v2p->lun,225 pending_req->cmnd[0], errors & 0xff, COMMAND_COMPLETE,226 host_byte(errors));227}228 229static void scsiback_fast_flush_area(struct vscsibk_pend *req)230{231 struct gnttab_unmap_grant_ref unmap[VSCSI_GRANT_BATCH];232 struct page *pages[VSCSI_GRANT_BATCH];233 unsigned int i, invcount = 0;234 grant_handle_t handle;235 int err;236 237 kfree(req->sgl);238 req->sgl = NULL;239 req->n_sg = 0;240 241 if (!req->n_grants)242 return;243 244 for (i = 0; i < req->n_grants; i++) {245 handle = req->grant_handles[i];246 if (handle == SCSIBACK_INVALID_HANDLE)247 continue;248 gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),249 GNTMAP_host_map, handle);250 req->grant_handles[i] = SCSIBACK_INVALID_HANDLE;251 pages[invcount] = req->pages[i];252 put_page(pages[invcount]);253 invcount++;254 if (invcount < VSCSI_GRANT_BATCH)255 continue;256 err = gnttab_unmap_refs(unmap, NULL, pages, invcount);257 BUG_ON(err);258 invcount = 0;259 }260 261 if (invcount) {262 err = gnttab_unmap_refs(unmap, NULL, pages, invcount);263 BUG_ON(err);264 }265 266 gnttab_page_cache_put(&req->info->free_pages, req->pages,267 req->n_grants);268 req->n_grants = 0;269}270 271static void scsiback_free_translation_entry(struct kref *kref)272{273 struct v2p_entry *entry = container_of(kref, struct v2p_entry, kref);274 struct scsiback_tpg *tpg = entry->tpg;275 276 mutex_lock(&tpg->tv_tpg_mutex);277 tpg->tv_tpg_fe_count--;278 mutex_unlock(&tpg->tv_tpg_mutex);279 280 kfree(entry);281}282 283static int32_t scsiback_result(int32_t result)284{285 int32_t host_status;286 287 switch (XEN_VSCSIIF_RSLT_HOST(result)) {288 case DID_OK:289 host_status = XEN_VSCSIIF_RSLT_HOST_OK;290 break;291 case DID_NO_CONNECT:292 host_status = XEN_VSCSIIF_RSLT_HOST_NO_CONNECT;293 break;294 case DID_BUS_BUSY:295 host_status = XEN_VSCSIIF_RSLT_HOST_BUS_BUSY;296 break;297 case DID_TIME_OUT:298 host_status = XEN_VSCSIIF_RSLT_HOST_TIME_OUT;299 break;300 case DID_BAD_TARGET:301 host_status = XEN_VSCSIIF_RSLT_HOST_BAD_TARGET;302 break;303 case DID_ABORT:304 host_status = XEN_VSCSIIF_RSLT_HOST_ABORT;305 break;306 case DID_PARITY:307 host_status = XEN_VSCSIIF_RSLT_HOST_PARITY;308 break;309 case DID_ERROR:310 host_status = XEN_VSCSIIF_RSLT_HOST_ERROR;311 break;312 case DID_RESET:313 host_status = XEN_VSCSIIF_RSLT_HOST_RESET;314 break;315 case DID_BAD_INTR:316 host_status = XEN_VSCSIIF_RSLT_HOST_BAD_INTR;317 break;318 case DID_PASSTHROUGH:319 host_status = XEN_VSCSIIF_RSLT_HOST_PASSTHROUGH;320 break;321 case DID_SOFT_ERROR:322 host_status = XEN_VSCSIIF_RSLT_HOST_SOFT_ERROR;323 break;324 case DID_IMM_RETRY:325 host_status = XEN_VSCSIIF_RSLT_HOST_IMM_RETRY;326 break;327 case DID_REQUEUE:328 host_status = XEN_VSCSIIF_RSLT_HOST_REQUEUE;329 break;330 case DID_TRANSPORT_DISRUPTED:331 host_status = XEN_VSCSIIF_RSLT_HOST_TRANSPORT_DISRUPTED;332 break;333 case DID_TRANSPORT_FAILFAST:334 host_status = XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST;335 break;336 case DID_TRANSPORT_MARGINAL:337 host_status = XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL;338 break;339 default:340 host_status = XEN_VSCSIIF_RSLT_HOST_ERROR;341 break;342 }343 344 return (host_status << 16) | (result & 0x00ffff);345}346 347static void scsiback_send_response(struct vscsibk_info *info,348 char *sense_buffer, int32_t result, uint32_t resid,349 uint16_t rqid)350{351 struct vscsiif_response *ring_res;352 int notify;353 struct scsi_sense_hdr sshdr;354 unsigned long flags;355 unsigned len;356 357 spin_lock_irqsave(&info->ring_lock, flags);358 359 ring_res = RING_GET_RESPONSE(&info->ring, info->ring.rsp_prod_pvt);360 info->ring.rsp_prod_pvt++;361 362 ring_res->rslt = scsiback_result(result);363 ring_res->rqid = rqid;364 365 if (sense_buffer != NULL &&366 scsi_normalize_sense(sense_buffer, VSCSIIF_SENSE_BUFFERSIZE,367 &sshdr)) {368 len = min_t(unsigned, 8 + sense_buffer[7],369 VSCSIIF_SENSE_BUFFERSIZE);370 memcpy(ring_res->sense_buffer, sense_buffer, len);371 ring_res->sense_len = len;372 } else {373 ring_res->sense_len = 0;374 }375 376 ring_res->residual_len = resid;377 378 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&info->ring, notify);379 spin_unlock_irqrestore(&info->ring_lock, flags);380 381 if (notify)382 notify_remote_via_irq(info->irq);383}384 385static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,386 uint32_t resid, struct vscsibk_pend *pending_req)387{388 scsiback_send_response(pending_req->info, sense_buffer, result,389 resid, pending_req->rqid);390 391 if (pending_req->v2p)392 kref_put(&pending_req->v2p->kref,393 scsiback_free_translation_entry);394}395 396static void scsiback_cmd_done(struct vscsibk_pend *pending_req)397{398 struct vscsibk_info *info = pending_req->info;399 unsigned char *sense_buffer;400 unsigned int resid;401 int errors;402 403 sense_buffer = pending_req->sense_buffer;404 resid = pending_req->se_cmd.residual_count;405 errors = pending_req->result;406 407 if (errors && log_print_stat)408 scsiback_print_status(sense_buffer, errors, pending_req);409 410 scsiback_fast_flush_area(pending_req);411 scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req);412 scsiback_put(info);413 /*414 * Drop the extra KREF_ACK reference taken by target_submit_cmd_map_sgls()415 * ahead of scsiback_check_stop_free() -> transport_generic_free_cmd()416 * final se_cmd->cmd_kref put.417 */418 target_put_sess_cmd(&pending_req->se_cmd);419}420 421static void scsiback_cmd_exec(struct vscsibk_pend *pending_req)422{423 struct se_cmd *se_cmd = &pending_req->se_cmd;424 struct se_session *sess = pending_req->v2p->tpg->tpg_nexus->tvn_se_sess;425 426 scsiback_get(pending_req->info);427 se_cmd->tag = pending_req->rqid;428 target_init_cmd(se_cmd, sess, pending_req->sense_buffer,429 pending_req->v2p->lun, pending_req->data_len, 0,430 pending_req->sc_data_direction, TARGET_SCF_ACK_KREF);431 432 if (target_submit_prep(se_cmd, pending_req->cmnd, pending_req->sgl,433 pending_req->n_sg, NULL, 0, NULL, 0, GFP_KERNEL))434 return;435 436 target_submit(se_cmd);437}438 439static int scsiback_gnttab_data_map_batch(struct gnttab_map_grant_ref *map,440 struct page **pg, grant_handle_t *grant, int cnt)441{442 int err, i;443 444 if (!cnt)445 return 0;446 447 err = gnttab_map_refs(map, NULL, pg, cnt);448 for (i = 0; i < cnt; i++) {449 if (unlikely(map[i].status != GNTST_okay)) {450 pr_err("invalid buffer -- could not remap it\n");451 map[i].handle = SCSIBACK_INVALID_HANDLE;452 if (!err)453 err = -ENOMEM;454 } else {455 get_page(pg[i]);456 }457 grant[i] = map[i].handle;458 }459 return err;460}461 462static int scsiback_gnttab_data_map_list(struct vscsibk_pend *pending_req,463 struct scsiif_request_segment *seg, struct page **pg,464 grant_handle_t *grant, int cnt, u32 flags)465{466 int mapcount = 0, i, err = 0;467 struct gnttab_map_grant_ref map[VSCSI_GRANT_BATCH];468 struct vscsibk_info *info = pending_req->info;469 470 for (i = 0; i < cnt; i++) {471 if (gnttab_page_cache_get(&info->free_pages, pg + mapcount)) {472 gnttab_page_cache_put(&info->free_pages, pg, mapcount);473 pr_err("no grant page\n");474 return -ENOMEM;475 }476 gnttab_set_map_op(&map[mapcount], vaddr_page(pg[mapcount]),477 flags, seg[i].gref, info->domid);478 mapcount++;479 if (mapcount < VSCSI_GRANT_BATCH)480 continue;481 err = scsiback_gnttab_data_map_batch(map, pg, grant, mapcount);482 pg += mapcount;483 grant += mapcount;484 pending_req->n_grants += mapcount;485 if (err)486 return err;487 mapcount = 0;488 }489 err = scsiback_gnttab_data_map_batch(map, pg, grant, mapcount);490 pending_req->n_grants += mapcount;491 return err;492}493 494static int scsiback_gnttab_data_map(struct vscsiif_request *ring_req,495 struct vscsibk_pend *pending_req)496{497 u32 flags;498 int i, err, n_segs, i_seg = 0;499 struct page **pg;500 struct scsiif_request_segment *seg;501 unsigned long end_seg = 0;502 unsigned int nr_segments = (unsigned int)ring_req->nr_segments;503 unsigned int nr_sgl = 0;504 struct scatterlist *sg;505 grant_handle_t *grant;506 507 pending_req->n_sg = 0;508 pending_req->n_grants = 0;509 pending_req->data_len = 0;510 511 nr_segments &= ~VSCSIIF_SG_GRANT;512 if (!nr_segments)513 return 0;514 515 if (nr_segments > VSCSIIF_SG_TABLESIZE) {516 pr_debug("invalid parameter nr_seg = %d\n",517 ring_req->nr_segments);518 return -EINVAL;519 }520 521 if (ring_req->nr_segments & VSCSIIF_SG_GRANT) {522 err = scsiback_gnttab_data_map_list(pending_req, ring_req->seg,523 pending_req->pages, pending_req->grant_handles,524 nr_segments, GNTMAP_host_map | GNTMAP_readonly);525 if (err)526 return err;527 nr_sgl = nr_segments;528 nr_segments = 0;529 for (i = 0; i < nr_sgl; i++) {530 n_segs = ring_req->seg[i].length /531 sizeof(struct scsiif_request_segment);532 if ((unsigned)ring_req->seg[i].offset +533 (unsigned)ring_req->seg[i].length > PAGE_SIZE ||534 n_segs * sizeof(struct scsiif_request_segment) !=535 ring_req->seg[i].length)536 return -EINVAL;537 nr_segments += n_segs;538 }539 if (nr_segments > SG_ALL) {540 pr_debug("invalid nr_seg = %d\n", nr_segments);541 return -EINVAL;542 }543 }544 545 /* free of (sgl) in fast_flush_area() */546 pending_req->sgl = kmalloc_array(nr_segments,547 sizeof(struct scatterlist), GFP_KERNEL);548 if (!pending_req->sgl)549 return -ENOMEM;550 551 sg_init_table(pending_req->sgl, nr_segments);552 pending_req->n_sg = nr_segments;553 554 flags = GNTMAP_host_map;555 if (pending_req->sc_data_direction == DMA_TO_DEVICE)556 flags |= GNTMAP_readonly;557 558 pg = pending_req->pages + nr_sgl;559 grant = pending_req->grant_handles + nr_sgl;560 if (!nr_sgl) {561 seg = ring_req->seg;562 err = scsiback_gnttab_data_map_list(pending_req, seg,563 pg, grant, nr_segments, flags);564 if (err)565 return err;566 } else {567 for (i = 0; i < nr_sgl; i++) {568 seg = (struct scsiif_request_segment *)(569 vaddr(pending_req, i) + ring_req->seg[i].offset);570 n_segs = ring_req->seg[i].length /571 sizeof(struct scsiif_request_segment);572 err = scsiback_gnttab_data_map_list(pending_req, seg,573 pg, grant, n_segs, flags);574 if (err)575 return err;576 pg += n_segs;577 grant += n_segs;578 }579 end_seg = vaddr(pending_req, 0) + ring_req->seg[0].offset;580 seg = (struct scsiif_request_segment *)end_seg;581 end_seg += ring_req->seg[0].length;582 pg = pending_req->pages + nr_sgl;583 }584 585 for_each_sg(pending_req->sgl, sg, nr_segments, i) {586 sg_set_page(sg, pg[i], seg->length, seg->offset);587 pending_req->data_len += seg->length;588 seg++;589 if (nr_sgl && (unsigned long)seg >= end_seg) {590 i_seg++;591 end_seg = vaddr(pending_req, i_seg) +592 ring_req->seg[i_seg].offset;593 seg = (struct scsiif_request_segment *)end_seg;594 end_seg += ring_req->seg[i_seg].length;595 }596 if (sg->offset >= PAGE_SIZE ||597 sg->length > PAGE_SIZE ||598 sg->offset + sg->length > PAGE_SIZE)599 return -EINVAL;600 }601 602 return 0;603}604 605static void scsiback_disconnect(struct vscsibk_info *info)606{607 wait_event(info->waiting_to_free,608 atomic_read(&info->nr_unreplied_reqs) == 0);609 610 unbind_from_irqhandler(info->irq, info);611 info->irq = 0;612 xenbus_unmap_ring_vfree(info->dev, info->ring.sring);613}614 615static void scsiback_device_action(struct vscsibk_pend *pending_req,616 enum tcm_tmreq_table act, int tag)617{618 struct scsiback_tpg *tpg = pending_req->v2p->tpg;619 struct scsiback_nexus *nexus = tpg->tpg_nexus;620 struct se_cmd *se_cmd = &pending_req->se_cmd;621 u64 unpacked_lun = pending_req->v2p->lun;622 int rc, err = XEN_VSCSIIF_RSLT_RESET_FAILED;623 624 init_completion(&pending_req->tmr_done);625 626 rc = target_submit_tmr(&pending_req->se_cmd, nexus->tvn_se_sess,627 &pending_req->sense_buffer[0],628 unpacked_lun, NULL, act, GFP_KERNEL,629 tag, TARGET_SCF_ACK_KREF);630 if (rc)631 goto err;632 633 wait_for_completion(&pending_req->tmr_done);634 635 err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?636 XEN_VSCSIIF_RSLT_RESET_SUCCESS : XEN_VSCSIIF_RSLT_RESET_FAILED;637 638 scsiback_do_resp_with_sense(NULL, err, 0, pending_req);639 transport_generic_free_cmd(&pending_req->se_cmd, 0);640 return;641 642err:643 scsiback_do_resp_with_sense(NULL, err, 0, pending_req);644}645 646/*647 Perform virtual to physical translation648*/649static struct v2p_entry *scsiback_do_translation(struct vscsibk_info *info,650 struct ids_tuple *v)651{652 struct v2p_entry *entry;653 struct list_head *head = &(info->v2p_entry_lists);654 unsigned long flags;655 656 spin_lock_irqsave(&info->v2p_lock, flags);657 list_for_each_entry(entry, head, l) {658 if ((entry->v.chn == v->chn) &&659 (entry->v.tgt == v->tgt) &&660 (entry->v.lun == v->lun)) {661 kref_get(&entry->kref);662 goto out;663 }664 }665 entry = NULL;666 667out:668 spin_unlock_irqrestore(&info->v2p_lock, flags);669 return entry;670}671 672static struct vscsibk_pend *scsiback_get_pend_req(struct vscsiif_back_ring *ring,673 struct v2p_entry *v2p)674{675 struct scsiback_tpg *tpg = v2p->tpg;676 struct scsiback_nexus *nexus = tpg->tpg_nexus;677 struct se_session *se_sess = nexus->tvn_se_sess;678 struct vscsibk_pend *req;679 int tag, cpu, i;680 681 tag = sbitmap_queue_get(&se_sess->sess_tag_pool, &cpu);682 if (tag < 0) {683 pr_err("Unable to obtain tag for vscsiif_request\n");684 return ERR_PTR(-ENOMEM);685 }686 687 req = &((struct vscsibk_pend *)se_sess->sess_cmd_map)[tag];688 memset(req, 0, sizeof(*req));689 req->se_cmd.map_tag = tag;690 req->se_cmd.map_cpu = cpu;691 692 for (i = 0; i < VSCSI_MAX_GRANTS; i++)693 req->grant_handles[i] = SCSIBACK_INVALID_HANDLE;694 695 return req;696}697 698static struct vscsibk_pend *prepare_pending_reqs(struct vscsibk_info *info,699 struct vscsiif_back_ring *ring,700 struct vscsiif_request *ring_req)701{702 struct vscsibk_pend *pending_req;703 struct v2p_entry *v2p;704 struct ids_tuple vir;705 706 /* request range check from frontend */707 if ((ring_req->sc_data_direction != DMA_BIDIRECTIONAL) &&708 (ring_req->sc_data_direction != DMA_TO_DEVICE) &&709 (ring_req->sc_data_direction != DMA_FROM_DEVICE) &&710 (ring_req->sc_data_direction != DMA_NONE)) {711 pr_debug("invalid parameter data_dir = %d\n",712 ring_req->sc_data_direction);713 return ERR_PTR(-EINVAL);714 }715 if (ring_req->cmd_len > VSCSIIF_MAX_COMMAND_SIZE) {716 pr_debug("invalid parameter cmd_len = %d\n",717 ring_req->cmd_len);718 return ERR_PTR(-EINVAL);719 }720 721 vir.chn = ring_req->channel;722 vir.tgt = ring_req->id;723 vir.lun = ring_req->lun;724 725 v2p = scsiback_do_translation(info, &vir);726 if (!v2p) {727 pr_debug("the v2p of (chn:%d, tgt:%d, lun:%d) doesn't exist.\n",728 vir.chn, vir.tgt, vir.lun);729 return ERR_PTR(-ENODEV);730 }731 732 pending_req = scsiback_get_pend_req(ring, v2p);733 if (IS_ERR(pending_req)) {734 kref_put(&v2p->kref, scsiback_free_translation_entry);735 return ERR_PTR(-ENOMEM);736 }737 pending_req->rqid = ring_req->rqid;738 pending_req->info = info;739 pending_req->v2p = v2p;740 pending_req->sc_data_direction = ring_req->sc_data_direction;741 pending_req->cmd_len = ring_req->cmd_len;742 memcpy(pending_req->cmnd, ring_req->cmnd, pending_req->cmd_len);743 744 return pending_req;745}746 747static int scsiback_do_cmd_fn(struct vscsibk_info *info,748 unsigned int *eoi_flags)749{750 struct vscsiif_back_ring *ring = &info->ring;751 struct vscsiif_request ring_req;752 struct vscsibk_pend *pending_req;753 RING_IDX rc, rp;754 int more_to_do;755 uint32_t result;756 757 rc = ring->req_cons;758 rp = ring->sring->req_prod;759 rmb(); /* guest system is accessing ring, too */760 761 if (RING_REQUEST_PROD_OVERFLOW(ring, rp)) {762 rc = ring->rsp_prod_pvt;763 pr_warn("Dom%d provided bogus ring requests (%#x - %#x = %u). Halting ring processing\n",764 info->domid, rp, rc, rp - rc);765 return -EINVAL;766 }767 768 while ((rc != rp)) {769 *eoi_flags &= ~XEN_EOI_FLAG_SPURIOUS;770 771 if (RING_REQUEST_CONS_OVERFLOW(ring, rc))772 break;773 774 RING_COPY_REQUEST(ring, rc, &ring_req);775 ring->req_cons = ++rc;776 777 pending_req = prepare_pending_reqs(info, ring, &ring_req);778 if (IS_ERR(pending_req)) {779 switch (PTR_ERR(pending_req)) {780 case -ENODEV:781 result = DID_NO_CONNECT;782 break;783 default:784 result = DID_ERROR;785 break;786 }787 scsiback_send_response(info, NULL, result << 16, 0,788 ring_req.rqid);789 return 1;790 }791 792 switch (ring_req.act) {793 case VSCSIIF_ACT_SCSI_CDB:794 if (scsiback_gnttab_data_map(&ring_req, pending_req)) {795 scsiback_fast_flush_area(pending_req);796 scsiback_do_resp_with_sense(NULL,797 DID_ERROR << 16, 0, pending_req);798 transport_generic_free_cmd(&pending_req->se_cmd, 0);799 } else {800 scsiback_cmd_exec(pending_req);801 }802 break;803 case VSCSIIF_ACT_SCSI_ABORT:804 scsiback_device_action(pending_req, TMR_ABORT_TASK,805 ring_req.ref_rqid);806 break;807 case VSCSIIF_ACT_SCSI_RESET:808 scsiback_device_action(pending_req, TMR_LUN_RESET, 0);809 break;810 default:811 pr_err_ratelimited("invalid request\n");812 scsiback_do_resp_with_sense(NULL, DID_ERROR << 16, 0,813 pending_req);814 transport_generic_free_cmd(&pending_req->se_cmd, 0);815 break;816 }817 818 /* Yield point for this unbounded loop. */819 cond_resched();820 }821 822 gnttab_page_cache_shrink(&info->free_pages, scsiback_max_buffer_pages);823 824 RING_FINAL_CHECK_FOR_REQUESTS(&info->ring, more_to_do);825 return more_to_do;826}827 828static irqreturn_t scsiback_irq_fn(int irq, void *dev_id)829{830 struct vscsibk_info *info = dev_id;831 int rc;832 unsigned int eoi_flags = XEN_EOI_FLAG_SPURIOUS;833 834 while ((rc = scsiback_do_cmd_fn(info, &eoi_flags)) > 0)835 cond_resched();836 837 /* In case of a ring error we keep the event channel masked. */838 if (!rc)839 xen_irq_lateeoi(irq, eoi_flags);840 841 return IRQ_HANDLED;842}843 844static int scsiback_init_sring(struct vscsibk_info *info, grant_ref_t ring_ref,845 evtchn_port_t evtchn)846{847 void *area;848 struct vscsiif_sring *sring;849 int err;850 851 if (info->irq)852 return -1;853 854 err = xenbus_map_ring_valloc(info->dev, &ring_ref, 1, &area);855 if (err)856 return err;857 858 sring = (struct vscsiif_sring *)area;859 BACK_RING_INIT(&info->ring, sring, PAGE_SIZE);860 861 err = bind_interdomain_evtchn_to_irq_lateeoi(info->dev, evtchn);862 if (err < 0)863 goto unmap_page;864 865 info->irq = err;866 867 err = request_threaded_irq(info->irq, NULL, scsiback_irq_fn,868 IRQF_ONESHOT, "vscsiif-backend", info);869 if (err)870 goto free_irq;871 872 return 0;873 874free_irq:875 unbind_from_irqhandler(info->irq, info);876 info->irq = 0;877unmap_page:878 xenbus_unmap_ring_vfree(info->dev, area);879 880 return err;881}882 883static int scsiback_map(struct vscsibk_info *info)884{885 struct xenbus_device *dev = info->dev;886 unsigned int ring_ref;887 evtchn_port_t evtchn;888 int err;889 890 err = xenbus_gather(XBT_NIL, dev->otherend,891 "ring-ref", "%u", &ring_ref,892 "event-channel", "%u", &evtchn, NULL);893 if (err) {894 xenbus_dev_fatal(dev, err, "reading %s ring", dev->otherend);895 return err;896 }897 898 return scsiback_init_sring(info, ring_ref, evtchn);899}900 901/*902 Check for a translation entry being present903*/904static struct v2p_entry *scsiback_chk_translation_entry(905 struct vscsibk_info *info, struct ids_tuple *v)906{907 struct list_head *head = &(info->v2p_entry_lists);908 struct v2p_entry *entry;909 910 list_for_each_entry(entry, head, l)911 if ((entry->v.chn == v->chn) &&912 (entry->v.tgt == v->tgt) &&913 (entry->v.lun == v->lun))914 return entry;915 916 return NULL;917}918 919/*920 Add a new translation entry921*/922static int scsiback_add_translation_entry(struct vscsibk_info *info,923 char *phy, struct ids_tuple *v)924{925 int err = 0;926 struct v2p_entry *new;927 unsigned long flags;928 char *lunp;929 unsigned long long unpacked_lun;930 struct se_lun *se_lun;931 struct scsiback_tpg *tpg_entry, *tpg = NULL;932 char *error = "doesn't exist";933 934 lunp = strrchr(phy, ':');935 if (!lunp) {936 pr_err("illegal format of physical device %s\n", phy);937 return -EINVAL;938 }939 *lunp = 0;940 lunp++;941 err = kstrtoull(lunp, 10, &unpacked_lun);942 if (err < 0) {943 pr_err("lun number not valid: %s\n", lunp);944 return err;945 }946 947 mutex_lock(&scsiback_mutex);948 list_for_each_entry(tpg_entry, &scsiback_list, tv_tpg_list) {949 if (!strcmp(phy, tpg_entry->tport->tport_name) ||950 !strcmp(phy, tpg_entry->param_alias)) {951 mutex_lock(&tpg_entry->se_tpg.tpg_lun_mutex);952 hlist_for_each_entry(se_lun, &tpg_entry->se_tpg.tpg_lun_hlist, link) {953 if (se_lun->unpacked_lun == unpacked_lun) {954 if (!tpg_entry->tpg_nexus)955 error = "nexus undefined";956 else957 tpg = tpg_entry;958 break;959 }960 }961 mutex_unlock(&tpg_entry->se_tpg.tpg_lun_mutex);962 break;963 }964 }965 if (tpg) {966 mutex_lock(&tpg->tv_tpg_mutex);967 tpg->tv_tpg_fe_count++;968 mutex_unlock(&tpg->tv_tpg_mutex);969 }970 mutex_unlock(&scsiback_mutex);971 972 if (!tpg) {973 pr_err("%s:%llu %s\n", phy, unpacked_lun, error);974 return -ENODEV;975 }976 977 new = kmalloc(sizeof(struct v2p_entry), GFP_KERNEL);978 if (new == NULL) {979 err = -ENOMEM;980 goto out_free;981 }982 983 spin_lock_irqsave(&info->v2p_lock, flags);984 985 /* Check double assignment to identical virtual ID */986 if (scsiback_chk_translation_entry(info, v)) {987 pr_warn("Virtual ID is already used. Assignment was not performed.\n");988 err = -EEXIST;989 goto out;990 }991 992 /* Create a new translation entry and add to the list */993 kref_init(&new->kref);994 new->v = *v;995 new->tpg = tpg;996 new->lun = unpacked_lun;997 list_add_tail(&new->l, &info->v2p_entry_lists);998 999out:1000 spin_unlock_irqrestore(&info->v2p_lock, flags);1001 1002out_free:1003 if (err) {1004 mutex_lock(&tpg->tv_tpg_mutex);1005 tpg->tv_tpg_fe_count--;1006 mutex_unlock(&tpg->tv_tpg_mutex);1007 kfree(new);1008 }1009 1010 return err;1011}1012 1013/*1014 Delete the translation entry specified1015*/1016static int scsiback_del_translation_entry(struct vscsibk_info *info,1017 struct ids_tuple *v)1018{1019 struct v2p_entry *entry;1020 unsigned long flags;1021 1022 spin_lock_irqsave(&info->v2p_lock, flags);1023 /* Find out the translation entry specified */1024 entry = scsiback_chk_translation_entry(info, v);1025 if (entry)1026 list_del(&entry->l);1027 1028 spin_unlock_irqrestore(&info->v2p_lock, flags);1029 1030 if (!entry)1031 return -ENOENT;1032 1033 kref_put(&entry->kref, scsiback_free_translation_entry);1034 return 0;1035}1036 1037static void scsiback_do_add_lun(struct vscsibk_info *info, const char *state,1038 char *phy, struct ids_tuple *vir, int try)1039{1040 struct v2p_entry *entry;1041 unsigned long flags;1042 int err;1043 1044 if (try) {1045 spin_lock_irqsave(&info->v2p_lock, flags);1046 entry = scsiback_chk_translation_entry(info, vir);1047 spin_unlock_irqrestore(&info->v2p_lock, flags);1048 if (entry)1049 return;1050 }1051 if (!scsiback_add_translation_entry(info, phy, vir)) {1052 if (xenbus_printf(XBT_NIL, info->dev->nodename, state,1053 "%d", XenbusStateInitialised)) {1054 pr_err("xenbus_printf error %s\n", state);1055 scsiback_del_translation_entry(info, vir);1056 }1057 } else if (!try) {1058 err = xenbus_printf(XBT_NIL, info->dev->nodename, state,1059 "%d", XenbusStateClosed);1060 if (err)1061 xenbus_dev_error(info->dev, err,1062 "%s: writing %s", __func__, state);1063 }1064}1065 1066static void scsiback_do_del_lun(struct vscsibk_info *info, const char *state,1067 struct ids_tuple *vir)1068{1069 if (!scsiback_del_translation_entry(info, vir)) {1070 if (xenbus_printf(XBT_NIL, info->dev->nodename, state,1071 "%d", XenbusStateClosed))1072 pr_err("xenbus_printf error %s\n", state);1073 }1074}1075 1076#define VSCSIBACK_OP_ADD_OR_DEL_LUN 11077#define VSCSIBACK_OP_UPDATEDEV_STATE 21078 1079static void scsiback_do_1lun_hotplug(struct vscsibk_info *info, int op,1080 char *ent)1081{1082 int err;1083 struct ids_tuple vir;1084 char *val;1085 int device_state;1086 char phy[VSCSI_NAMELEN];1087 char str[64];1088 char state[64];1089 struct xenbus_device *dev = info->dev;1090 1091 /* read status */1092 snprintf(state, sizeof(state), "vscsi-devs/%s/state", ent);1093 err = xenbus_scanf(XBT_NIL, dev->nodename, state, "%u", &device_state);1094 if (XENBUS_EXIST_ERR(err))1095 return;1096 1097 /* physical SCSI device */1098 snprintf(str, sizeof(str), "vscsi-devs/%s/p-dev", ent);1099 val = xenbus_read(XBT_NIL, dev->nodename, str, NULL);1100 if (IS_ERR(val)) {1101 err = xenbus_printf(XBT_NIL, dev->nodename, state,1102 "%d", XenbusStateClosed);1103 if (err)1104 xenbus_dev_error(info->dev, err,1105 "%s: writing %s", __func__, state);1106 return;1107 }1108 strscpy(phy, val, VSCSI_NAMELEN);1109 kfree(val);1110 1111 /* virtual SCSI device */1112 snprintf(str, sizeof(str), "vscsi-devs/%s/v-dev", ent);1113 err = xenbus_scanf(XBT_NIL, dev->nodename, str, "%u:%u:%u:%u",1114 &vir.hst, &vir.chn, &vir.tgt, &vir.lun);1115 if (XENBUS_EXIST_ERR(err)) {1116 err = xenbus_printf(XBT_NIL, dev->nodename, state,1117 "%d", XenbusStateClosed);1118 if (err)1119 xenbus_dev_error(info->dev, err,1120 "%s: writing %s", __func__, state);1121 return;1122 }1123 1124 switch (op) {1125 case VSCSIBACK_OP_ADD_OR_DEL_LUN:1126 switch (device_state) {1127 case XenbusStateInitialising:1128 scsiback_do_add_lun(info, state, phy, &vir, 0);1129 break;1130 case XenbusStateConnected:1131 scsiback_do_add_lun(info, state, phy, &vir, 1);1132 break;1133 case XenbusStateClosing:1134 scsiback_do_del_lun(info, state, &vir);1135 break;1136 default:1137 break;1138 }1139 break;1140 1141 case VSCSIBACK_OP_UPDATEDEV_STATE:1142 if (device_state == XenbusStateInitialised) {1143 /* modify vscsi-devs/dev-x/state */1144 if (xenbus_printf(XBT_NIL, dev->nodename, state,1145 "%d", XenbusStateConnected)) {1146 pr_err("xenbus_printf error %s\n", str);1147 scsiback_del_translation_entry(info, &vir);1148 xenbus_printf(XBT_NIL, dev->nodename, state,1149 "%d", XenbusStateClosed);1150 }1151 }1152 break;1153 /* When it is necessary, processing is added here. */1154 default:1155 break;1156 }1157}1158 1159static void scsiback_do_lun_hotplug(struct vscsibk_info *info, int op)1160{1161 int i;1162 char **dir;1163 unsigned int ndir = 0;1164 1165 dir = xenbus_directory(XBT_NIL, info->dev->nodename, "vscsi-devs",1166 &ndir);1167 if (IS_ERR(dir))1168 return;1169 1170 for (i = 0; i < ndir; i++)1171 scsiback_do_1lun_hotplug(info, op, dir[i]);1172 1173 kfree(dir);1174}1175 1176static void scsiback_frontend_changed(struct xenbus_device *dev,1177 enum xenbus_state frontend_state)1178{1179 struct vscsibk_info *info = dev_get_drvdata(&dev->dev);1180 1181 switch (frontend_state) {1182 case XenbusStateInitialising:1183 break;1184 1185 case XenbusStateInitialised:1186 if (scsiback_map(info))1187 break;1188 1189 scsiback_do_lun_hotplug(info, VSCSIBACK_OP_ADD_OR_DEL_LUN);1190 xenbus_switch_state(dev, XenbusStateConnected);1191 break;1192 1193 case XenbusStateConnected:1194 scsiback_do_lun_hotplug(info, VSCSIBACK_OP_UPDATEDEV_STATE);1195 1196 if (dev->state == XenbusStateConnected)1197 break;1198 1199 xenbus_switch_state(dev, XenbusStateConnected);1200 break;1201 1202 case XenbusStateClosing:1203 if (info->irq)1204 scsiback_disconnect(info);1205 1206 xenbus_switch_state(dev, XenbusStateClosing);1207 break;1208 1209 case XenbusStateClosed:1210 xenbus_switch_state(dev, XenbusStateClosed);1211 if (xenbus_dev_is_online(dev))1212 break;1213 fallthrough; /* if not online */1214 case XenbusStateUnknown:1215 device_unregister(&dev->dev);1216 break;1217 1218 case XenbusStateReconfiguring:1219 scsiback_do_lun_hotplug(info, VSCSIBACK_OP_ADD_OR_DEL_LUN);1220 xenbus_switch_state(dev, XenbusStateReconfigured);1221 1222 break;1223 1224 default:1225 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",1226 frontend_state);1227 break;1228 }1229}1230 1231/*1232 Release the translation entry specfied1233*/1234static void scsiback_release_translation_entry(struct vscsibk_info *info)1235{1236 struct v2p_entry *entry, *tmp;1237 struct list_head *head = &(info->v2p_entry_lists);1238 struct list_head tmp_list;1239 unsigned long flags;1240 1241 spin_lock_irqsave(&info->v2p_lock, flags);1242 1243 list_cut_before(&tmp_list, head, head);1244 1245 spin_unlock_irqrestore(&info->v2p_lock, flags);1246 1247 list_for_each_entry_safe(entry, tmp, &tmp_list, l) {1248 list_del(&entry->l);1249 kref_put(&entry->kref, scsiback_free_translation_entry);1250 }1251}1252 1253static void scsiback_remove(struct xenbus_device *dev)1254{1255 struct vscsibk_info *info = dev_get_drvdata(&dev->dev);1256 1257 if (info->irq)1258 scsiback_disconnect(info);1259 1260 scsiback_release_translation_entry(info);1261 1262 gnttab_page_cache_shrink(&info->free_pages, 0);1263 1264 dev_set_drvdata(&dev->dev, NULL);1265}1266 1267static int scsiback_probe(struct xenbus_device *dev,1268 const struct xenbus_device_id *id)1269{1270 int err;1271 1272 struct vscsibk_info *info = kzalloc(sizeof(struct vscsibk_info),1273 GFP_KERNEL);1274 1275 pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id);1276 1277 if (!info) {1278 xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure");1279 return -ENOMEM;1280 }1281 info->dev = dev;1282 dev_set_drvdata(&dev->dev, info);1283 1284 info->domid = dev->otherend_id;1285 spin_lock_init(&info->ring_lock);1286 atomic_set(&info->nr_unreplied_reqs, 0);1287 init_waitqueue_head(&info->waiting_to_free);1288 info->dev = dev;1289 info->irq = 0;1290 INIT_LIST_HEAD(&info->v2p_entry_lists);1291 spin_lock_init(&info->v2p_lock);1292 gnttab_page_cache_init(&info->free_pages);1293 1294 err = xenbus_printf(XBT_NIL, dev->nodename, "feature-sg-grant", "%u",1295 SG_ALL);1296 if (err)1297 xenbus_dev_error(dev, err, "writing feature-sg-grant");1298 1299 err = xenbus_switch_state(dev, XenbusStateInitWait);1300 if (err)1301 goto fail;1302 1303 return 0;1304 1305fail:1306 pr_warn("%s failed\n", __func__);1307 scsiback_remove(dev);1308 1309 return err;1310}1311 1312static char *scsiback_dump_proto_id(struct scsiback_tport *tport)1313{1314 switch (tport->tport_proto_id) {1315 case SCSI_PROTOCOL_SAS:1316 return "SAS";1317 case SCSI_PROTOCOL_FCP:1318 return "FCP";1319 case SCSI_PROTOCOL_ISCSI:1320 return "iSCSI";1321 default:1322 break;1323 }1324 1325 return "Unknown";1326}1327 1328static char *scsiback_get_fabric_wwn(struct se_portal_group *se_tpg)1329{1330 struct scsiback_tpg *tpg = container_of(se_tpg,1331 struct scsiback_tpg, se_tpg);1332 struct scsiback_tport *tport = tpg->tport;1333 1334 return &tport->tport_name[0];1335}1336 1337static u16 scsiback_get_tag(struct se_portal_group *se_tpg)1338{1339 struct scsiback_tpg *tpg = container_of(se_tpg,1340 struct scsiback_tpg, se_tpg);1341 return tpg->tport_tpgt;1342}1343 1344static struct se_wwn *1345scsiback_make_tport(struct target_fabric_configfs *tf,1346 struct config_group *group,1347 const char *name)1348{1349 struct scsiback_tport *tport;1350 char *ptr;1351 u64 wwpn = 0;1352 int off = 0;1353 1354 tport = kzalloc(sizeof(struct scsiback_tport), GFP_KERNEL);1355 if (!tport)1356 return ERR_PTR(-ENOMEM);1357 1358 tport->tport_wwpn = wwpn;1359 /*1360 * Determine the emulated Protocol Identifier and Target Port Name1361 * based on the incoming configfs directory name.1362 */1363 ptr = strstr(name, "naa.");1364 if (ptr) {1365 tport->tport_proto_id = SCSI_PROTOCOL_SAS;1366 goto check_len;1367 }1368 ptr = strstr(name, "fc.");1369 if (ptr) {1370 tport->tport_proto_id = SCSI_PROTOCOL_FCP;1371 off = 3; /* Skip over "fc." */1372 goto check_len;1373 }1374 ptr = strstr(name, "iqn.");1375 if (ptr) {1376 tport->tport_proto_id = SCSI_PROTOCOL_ISCSI;1377 goto check_len;1378 }1379 1380 pr_err("Unable to locate prefix for emulated Target Port: %s\n", name);1381 kfree(tport);1382 return ERR_PTR(-EINVAL);1383 1384check_len:1385 if (strlen(name) >= VSCSI_NAMELEN) {1386 pr_err("Emulated %s Address: %s, exceeds max: %d\n", name,1387 scsiback_dump_proto_id(tport), VSCSI_NAMELEN);1388 kfree(tport);1389 return ERR_PTR(-EINVAL);1390 }1391 snprintf(&tport->tport_name[0], VSCSI_NAMELEN, "%s", &name[off]);1392 1393 pr_debug("Allocated emulated Target %s Address: %s\n",1394 scsiback_dump_proto_id(tport), name);1395 1396 return &tport->tport_wwn;1397}1398 1399static void scsiback_drop_tport(struct se_wwn *wwn)1400{1401 struct scsiback_tport *tport = container_of(wwn,1402 struct scsiback_tport, tport_wwn);1403 1404 pr_debug("Deallocating emulated Target %s Address: %s\n",1405 scsiback_dump_proto_id(tport), tport->tport_name);1406 1407 kfree(tport);1408}1409 1410static int scsiback_check_stop_free(struct se_cmd *se_cmd)1411{1412 return transport_generic_free_cmd(se_cmd, 0);1413}1414 1415static void scsiback_release_cmd(struct se_cmd *se_cmd)1416{1417 target_free_tag(se_cmd->se_sess, se_cmd);1418}1419 1420static int scsiback_write_pending(struct se_cmd *se_cmd)1421{1422 /* Go ahead and process the write immediately */1423 target_execute_cmd(se_cmd);1424 1425 return 0;1426}1427 1428static int scsiback_queue_data_in(struct se_cmd *se_cmd)1429{1430 struct vscsibk_pend *pending_req = container_of(se_cmd,1431 struct vscsibk_pend, se_cmd);1432 1433 pending_req->result = SAM_STAT_GOOD;1434 scsiback_cmd_done(pending_req);1435 return 0;1436}1437 1438static int scsiback_queue_status(struct se_cmd *se_cmd)1439{1440 struct vscsibk_pend *pending_req = container_of(se_cmd,1441 struct vscsibk_pend, se_cmd);1442 1443 if (se_cmd->sense_buffer &&1444 ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||1445 (se_cmd->se_cmd_flags & SCF_EMULATED_TASK_SENSE)))1446 pending_req->result = SAM_STAT_CHECK_CONDITION;1447 else1448 pending_req->result = se_cmd->scsi_status;1449 1450 scsiback_cmd_done(pending_req);1451 return 0;1452}1453 1454static void scsiback_queue_tm_rsp(struct se_cmd *se_cmd)1455{1456 struct vscsibk_pend *pending_req = container_of(se_cmd,1457 struct vscsibk_pend, se_cmd);1458 1459 complete(&pending_req->tmr_done);1460}1461 1462static void scsiback_aborted_task(struct se_cmd *se_cmd)1463{1464}1465 1466static ssize_t scsiback_tpg_param_alias_show(struct config_item *item,1467 char *page)1468{1469 struct se_portal_group *se_tpg = param_to_tpg(item);1470 struct scsiback_tpg *tpg = container_of(se_tpg, struct scsiback_tpg,1471 se_tpg);1472 ssize_t rb;1473 1474 mutex_lock(&tpg->tv_tpg_mutex);1475 rb = snprintf(page, PAGE_SIZE, "%s\n", tpg->param_alias);1476 mutex_unlock(&tpg->tv_tpg_mutex);1477 1478 return rb;1479}1480 1481static ssize_t scsiback_tpg_param_alias_store(struct config_item *item,1482 const char *page, size_t count)1483{1484 struct se_portal_group *se_tpg = param_to_tpg(item);1485 struct scsiback_tpg *tpg = container_of(se_tpg, struct scsiback_tpg,1486 se_tpg);1487 int len;1488 1489 if (strlen(page) >= VSCSI_NAMELEN) {1490 pr_err("param alias: %s, exceeds max: %d\n", page,1491 VSCSI_NAMELEN);1492 return -EINVAL;1493 }1494 1495 mutex_lock(&tpg->tv_tpg_mutex);1496 len = snprintf(tpg->param_alias, VSCSI_NAMELEN, "%s", page);1497 if (tpg->param_alias[len - 1] == '\n')1498 tpg->param_alias[len - 1] = '\0';1499 mutex_unlock(&tpg->tv_tpg_mutex);1500 1501 return count;1502}1503 1504CONFIGFS_ATTR(scsiback_tpg_param_, alias);1505 1506static struct configfs_attribute *scsiback_param_attrs[] = {1507 &scsiback_tpg_param_attr_alias,1508 NULL,1509};1510 1511static int scsiback_alloc_sess_cb(struct se_portal_group *se_tpg,1512 struct se_session *se_sess, void *p)1513{1514 struct scsiback_tpg *tpg = container_of(se_tpg,1515 struct scsiback_tpg, se_tpg);1516 1517 tpg->tpg_nexus = p;1518 return 0;1519}1520 1521static int scsiback_make_nexus(struct scsiback_tpg *tpg,1522 const char *name)1523{1524 struct scsiback_nexus *tv_nexus;1525 int ret = 0;1526 1527 mutex_lock(&tpg->tv_tpg_mutex);1528 if (tpg->tpg_nexus) {1529 pr_debug("tpg->tpg_nexus already exists\n");1530 ret = -EEXIST;1531 goto out_unlock;1532 }1533 1534 tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL);1535 if (!tv_nexus) {1536 ret = -ENOMEM;1537 goto out_unlock;1538 }1539 1540 tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,1541 VSCSI_DEFAULT_SESSION_TAGS,1542 sizeof(struct vscsibk_pend),1543 TARGET_PROT_NORMAL, name,1544 tv_nexus, scsiback_alloc_sess_cb);1545 if (IS_ERR(tv_nexus->tvn_se_sess)) {1546 kfree(tv_nexus);1547 ret = -ENOMEM;1548 goto out_unlock;1549 }1550 1551out_unlock:1552 mutex_unlock(&tpg->tv_tpg_mutex);1553 return ret;1554}1555 1556static int scsiback_drop_nexus(struct scsiback_tpg *tpg)1557{1558 struct se_session *se_sess;1559 struct scsiback_nexus *tv_nexus;1560 1561 mutex_lock(&tpg->tv_tpg_mutex);1562 tv_nexus = tpg->tpg_nexus;1563 if (!tv_nexus) {1564 mutex_unlock(&tpg->tv_tpg_mutex);1565 return -ENODEV;1566 }1567 1568 se_sess = tv_nexus->tvn_se_sess;1569 if (!se_sess) {1570 mutex_unlock(&tpg->tv_tpg_mutex);1571 return -ENODEV;1572 }1573 1574 if (tpg->tv_tpg_port_count != 0) {1575 mutex_unlock(&tpg->tv_tpg_mutex);1576 pr_err("Unable to remove xen-pvscsi I_T Nexus with active TPG port count: %d\n",1577 tpg->tv_tpg_port_count);1578 return -EBUSY;1579 }1580 1581 if (tpg->tv_tpg_fe_count != 0) {1582 mutex_unlock(&tpg->tv_tpg_mutex);1583 pr_err("Unable to remove xen-pvscsi I_T Nexus with active TPG frontend count: %d\n",1584 tpg->tv_tpg_fe_count);1585 return -EBUSY;1586 }1587 1588 pr_debug("Removing I_T Nexus to emulated %s Initiator Port: %s\n",1589 scsiback_dump_proto_id(tpg->tport),1590 tv_nexus->tvn_se_sess->se_node_acl->initiatorname);1591 1592 /*1593 * Release the SCSI I_T Nexus to the emulated xen-pvscsi Target Port1594 */1595 target_remove_session(se_sess);1596 tpg->tpg_nexus = NULL;1597 mutex_unlock(&tpg->tv_tpg_mutex);1598 1599 kfree(tv_nexus);1600 return 0;1601}1602 1603static ssize_t scsiback_tpg_nexus_show(struct config_item *item, char *page)1604{1605 struct se_portal_group *se_tpg = to_tpg(item);1606 struct scsiback_tpg *tpg = container_of(se_tpg,1607 struct scsiback_tpg, se_tpg);1608 struct scsiback_nexus *tv_nexus;1609 ssize_t ret;1610 1611 mutex_lock(&tpg->tv_tpg_mutex);1612 tv_nexus = tpg->tpg_nexus;1613 if (!tv_nexus) {1614 mutex_unlock(&tpg->tv_tpg_mutex);1615 return -ENODEV;1616 }1617 ret = snprintf(page, PAGE_SIZE, "%s\n",1618 tv_nexus->tvn_se_sess->se_node_acl->initiatorname);1619 mutex_unlock(&tpg->tv_tpg_mutex);1620 1621 return ret;1622}1623 1624static ssize_t scsiback_tpg_nexus_store(struct config_item *item,1625 const char *page, size_t count)1626{1627 struct se_portal_group *se_tpg = to_tpg(item);1628 struct scsiback_tpg *tpg = container_of(se_tpg,1629 struct scsiback_tpg, se_tpg);1630 struct scsiback_tport *tport_wwn = tpg->tport;1631 unsigned char i_port[VSCSI_NAMELEN], *ptr, *port_ptr;1632 int ret;1633 /*1634 * Shutdown the active I_T nexus if 'NULL' is passed.1635 */1636 if (!strncmp(page, "NULL", 4)) {1637 ret = scsiback_drop_nexus(tpg);1638 return (!ret) ? count : ret;1639 }1640 /*1641 * Otherwise make sure the passed virtual Initiator port WWN matches1642 * the fabric protocol_id set in scsiback_make_tport(), and call1643 * scsiback_make_nexus().1644 */1645 if (strlen(page) >= VSCSI_NAMELEN) {1646 pr_err("Emulated NAA Sas Address: %s, exceeds max: %d\n",1647 page, VSCSI_NAMELEN);1648 return -EINVAL;1649 }1650 snprintf(&i_port[0], VSCSI_NAMELEN, "%s", page);1651 1652 ptr = strstr(i_port, "naa.");1653 if (ptr) {1654 if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_SAS) {1655 pr_err("Passed SAS Initiator Port %s does not match target port protoid: %s\n",1656 i_port, scsiback_dump_proto_id(tport_wwn));1657 return -EINVAL;1658 }1659 port_ptr = &i_port[0];1660 goto check_newline;1661 }1662 ptr = strstr(i_port, "fc.");1663 if (ptr) {1664 if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_FCP) {1665 pr_err("Passed FCP Initiator Port %s does not match target port protoid: %s\n",1666 i_port, scsiback_dump_proto_id(tport_wwn));1667 return -EINVAL;1668 }1669 port_ptr = &i_port[3]; /* Skip over "fc." */1670 goto check_newline;1671 }1672 ptr = strstr(i_port, "iqn.");1673 if (ptr) {1674 if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_ISCSI) {1675 pr_err("Passed iSCSI Initiator Port %s does not match target port protoid: %s\n",1676 i_port, scsiback_dump_proto_id(tport_wwn));1677 return -EINVAL;1678 }1679 port_ptr = &i_port[0];1680 goto check_newline;1681 }1682 pr_err("Unable to locate prefix for emulated Initiator Port: %s\n",1683 i_port);1684 return -EINVAL;1685 /*1686 * Clear any trailing newline for the NAA WWN1687 */1688check_newline:1689 if (i_port[strlen(i_port) - 1] == '\n')1690 i_port[strlen(i_port) - 1] = '\0';1691 1692 ret = scsiback_make_nexus(tpg, port_ptr);1693 if (ret < 0)1694 return ret;1695 1696 return count;1697}1698 1699CONFIGFS_ATTR(scsiback_tpg_, nexus);1700 1701static struct configfs_attribute *scsiback_tpg_attrs[] = {1702 &scsiback_tpg_attr_nexus,1703 NULL,1704};1705 1706static ssize_t1707scsiback_wwn_version_show(struct config_item *item, char *page)1708{1709 return sprintf(page, "xen-pvscsi fabric module %s on %s/%s on "1710 UTS_RELEASE"\n",1711 VSCSI_VERSION, utsname()->sysname, utsname()->machine);1712}1713 1714CONFIGFS_ATTR_RO(scsiback_wwn_, version);1715 1716static struct configfs_attribute *scsiback_wwn_attrs[] = {1717 &scsiback_wwn_attr_version,1718 NULL,1719};1720 1721static int scsiback_port_link(struct se_portal_group *se_tpg,1722 struct se_lun *lun)1723{1724 struct scsiback_tpg *tpg = container_of(se_tpg,1725 struct scsiback_tpg, se_tpg);1726 1727 mutex_lock(&tpg->tv_tpg_mutex);1728 tpg->tv_tpg_port_count++;1729 mutex_unlock(&tpg->tv_tpg_mutex);1730 1731 return 0;1732}1733 1734static void scsiback_port_unlink(struct se_portal_group *se_tpg,1735 struct se_lun *lun)1736{1737 struct scsiback_tpg *tpg = container_of(se_tpg,1738 struct scsiback_tpg, se_tpg);1739 1740 mutex_lock(&tpg->tv_tpg_mutex);1741 tpg->tv_tpg_port_count--;1742 mutex_unlock(&tpg->tv_tpg_mutex);1743}1744 1745static struct se_portal_group *1746scsiback_make_tpg(struct se_wwn *wwn, const char *name)1747{1748 struct scsiback_tport *tport = container_of(wwn,1749 struct scsiback_tport, tport_wwn);1750 1751 struct scsiback_tpg *tpg;1752 u16 tpgt;1753 int ret;1754 1755 if (strstr(name, "tpgt_") != name)1756 return ERR_PTR(-EINVAL);1757 ret = kstrtou16(name + 5, 10, &tpgt);1758 if (ret)1759 return ERR_PTR(ret);1760 1761 tpg = kzalloc(sizeof(struct scsiback_tpg), GFP_KERNEL);1762 if (!tpg)1763 return ERR_PTR(-ENOMEM);1764 1765 mutex_init(&tpg->tv_tpg_mutex);1766 INIT_LIST_HEAD(&tpg->tv_tpg_list);1767 INIT_LIST_HEAD(&tpg->info_list);1768 tpg->tport = tport;1769 tpg->tport_tpgt = tpgt;1770 1771 ret = core_tpg_register(wwn, &tpg->se_tpg, tport->tport_proto_id);1772 if (ret < 0) {1773 kfree(tpg);1774 return NULL;1775 }1776 mutex_lock(&scsiback_mutex);1777 list_add_tail(&tpg->tv_tpg_list, &scsiback_list);1778 mutex_unlock(&scsiback_mutex);1779 1780 return &tpg->se_tpg;1781}1782 1783static void scsiback_drop_tpg(struct se_portal_group *se_tpg)1784{1785 struct scsiback_tpg *tpg = container_of(se_tpg,1786 struct scsiback_tpg, se_tpg);1787 1788 mutex_lock(&scsiback_mutex);1789 list_del(&tpg->tv_tpg_list);1790 mutex_unlock(&scsiback_mutex);1791 /*1792 * Release the virtual I_T Nexus for this xen-pvscsi TPG1793 */1794 scsiback_drop_nexus(tpg);1795 /*1796 * Deregister the se_tpg from TCM.1797 */1798 core_tpg_deregister(se_tpg);1799 kfree(tpg);1800}1801 1802static int scsiback_check_true(struct se_portal_group *se_tpg)1803{1804 return 1;1805}1806 1807static const struct target_core_fabric_ops scsiback_ops = {1808 .module = THIS_MODULE,1809 .fabric_name = "xen-pvscsi",1810 .tpg_get_wwn = scsiback_get_fabric_wwn,1811 .tpg_get_tag = scsiback_get_tag,1812 .tpg_check_demo_mode = scsiback_check_true,1813 .tpg_check_demo_mode_cache = scsiback_check_true,1814 .check_stop_free = scsiback_check_stop_free,1815 .release_cmd = scsiback_release_cmd,1816 .sess_get_initiator_sid = NULL,1817 .write_pending = scsiback_write_pending,1818 .queue_data_in = scsiback_queue_data_in,1819 .queue_status = scsiback_queue_status,1820 .queue_tm_rsp = scsiback_queue_tm_rsp,1821 .aborted_task = scsiback_aborted_task,1822 /*1823 * Setup callers for generic logic in target_core_fabric_configfs.c1824 */1825 .fabric_make_wwn = scsiback_make_tport,1826 .fabric_drop_wwn = scsiback_drop_tport,1827 .fabric_make_tpg = scsiback_make_tpg,1828 .fabric_drop_tpg = scsiback_drop_tpg,1829 .fabric_post_link = scsiback_port_link,1830 .fabric_pre_unlink = scsiback_port_unlink,1831 1832 .tfc_wwn_attrs = scsiback_wwn_attrs,1833 .tfc_tpg_base_attrs = scsiback_tpg_attrs,1834 .tfc_tpg_param_attrs = scsiback_param_attrs,1835 1836 .default_submit_type = TARGET_DIRECT_SUBMIT,1837 .direct_submit_supp = 1,1838};1839 1840static const struct xenbus_device_id scsiback_ids[] = {1841 { "vscsi" },1842 { "" }1843};1844 1845static struct xenbus_driver scsiback_driver = {1846 .ids = scsiback_ids,1847 .probe = scsiback_probe,1848 .remove = scsiback_remove,1849 .otherend_changed = scsiback_frontend_changed1850};1851 1852static int __init scsiback_init(void)1853{1854 int ret;1855 1856 if (!xen_domain())1857 return -ENODEV;1858 1859 pr_debug("xen-pvscsi: fabric module %s on %s/%s on "UTS_RELEASE"\n",1860 VSCSI_VERSION, utsname()->sysname, utsname()->machine);1861 1862 ret = xenbus_register_backend(&scsiback_driver);1863 if (ret)1864 goto out;1865 1866 ret = target_register_template(&scsiback_ops);1867 if (ret)1868 goto out_unregister_xenbus;1869 1870 return 0;1871 1872out_unregister_xenbus:1873 xenbus_unregister_driver(&scsiback_driver);1874out:1875 pr_err("%s: error %d\n", __func__, ret);1876 return ret;1877}1878 1879static void __exit scsiback_exit(void)1880{1881 target_unregister_template(&scsiback_ops);1882 xenbus_unregister_driver(&scsiback_driver);1883}1884 1885module_init(scsiback_init);1886module_exit(scsiback_exit);1887 1888MODULE_DESCRIPTION("Xen SCSI backend driver");1889MODULE_LICENSE("Dual BSD/GPL");1890MODULE_ALIAS("xen-backend:vscsi");1891MODULE_AUTHOR("Juergen Gross <jgross@suse.com>");1892