Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB: Add SCSI RDMA Protocol (SRP) initiator

Add an InfiniBand SCSI RDMA Protocol (SRP) initiator. This driver is
used to talk talk to InfiniBand SRP targets (storage devices).

Signed-off-by: Roland Dreier <rolandd@cisco.com>

+2091
+2
drivers/infiniband/Kconfig
··· 33 33 34 34 source "drivers/infiniband/ulp/ipoib/Kconfig" 35 35 36 + source "drivers/infiniband/ulp/srp/Kconfig" 37 + 36 38 endmenu
+1
drivers/infiniband/Makefile
··· 1 1 obj-$(CONFIG_INFINIBAND) += core/ 2 2 obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/ 3 3 obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ 4 + obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/
+1
drivers/infiniband/ulp/srp/Kbuild
··· 1 + obj-$(CONFIG_INFINIBAND_SRP) += ib_srp.o
+11
drivers/infiniband/ulp/srp/Kconfig
··· 1 + config INFINIBAND_SRP 2 + tristate "InfiniBand SCSI RDMA Protocol" 3 + depends on INFINIBAND && SCSI 4 + ---help--- 5 + Support for the SCSI RDMA Protocol over InfiniBand. This 6 + allows you to access storage devices that speak SRP over 7 + InfiniBand. 8 + 9 + The SRP protocol is defined by the INCITS T10 technical 10 + committee. See <http://www.t10.org/>. 11 +
+1700
drivers/infiniband/ulp/srp/ib_srp.c
··· 1 + /* 2 + * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + * 32 + * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $ 33 + */ 34 + 35 + #include <linux/version.h> 36 + #include <linux/module.h> 37 + #include <linux/init.h> 38 + #include <linux/slab.h> 39 + #include <linux/err.h> 40 + #include <linux/string.h> 41 + #include <linux/parser.h> 42 + #include <linux/random.h> 43 + 44 + #include <asm/atomic.h> 45 + 46 + #include <scsi/scsi.h> 47 + #include <scsi/scsi_device.h> 48 + #include <scsi/scsi_dbg.h> 49 + #include <scsi/srp.h> 50 + 51 + #include <rdma/ib_cache.h> 52 + 53 + #include "ib_srp.h" 54 + 55 + #define DRV_NAME "ib_srp" 56 + #define PFX DRV_NAME ": " 57 + #define DRV_VERSION "0.2" 58 + #define DRV_RELDATE "November 1, 2005" 59 + 60 + MODULE_AUTHOR("Roland Dreier"); 61 + MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator " 62 + "v" DRV_VERSION " (" DRV_RELDATE ")"); 63 + MODULE_LICENSE("Dual BSD/GPL"); 64 + 65 + static int topspin_workarounds = 1; 66 + 67 + module_param(topspin_workarounds, int, 0444); 68 + MODULE_PARM_DESC(topspin_workarounds, 69 + "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); 70 + 71 + static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; 72 + 73 + static void srp_add_one(struct ib_device *device); 74 + static void srp_remove_one(struct ib_device *device); 75 + static void srp_completion(struct ib_cq *cq, void *target_ptr); 76 + static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); 77 + 78 + static struct ib_client srp_client = { 79 + .name = "srp", 80 + .add = srp_add_one, 81 + .remove = srp_remove_one 82 + }; 83 + 84 + static inline struct srp_target_port *host_to_target(struct Scsi_Host *host) 85 + { 86 + return (struct srp_target_port *) host->hostdata; 87 + } 88 + 89 + static const char *srp_target_info(struct Scsi_Host *host) 90 + { 91 + return host_to_target(host)->target_name; 92 + } 93 + 94 + static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, 95 + gfp_t gfp_mask, 96 + enum dma_data_direction direction) 97 + { 98 + struct srp_iu *iu; 99 + 100 + iu = kmalloc(sizeof *iu, gfp_mask); 101 + if (!iu) 102 + goto out; 103 + 104 + iu->buf = kzalloc(size, gfp_mask); 105 + if (!iu->buf) 106 + goto out_free_iu; 107 + 108 + iu->dma = dma_map_single(host->dev->dma_device, iu->buf, size, direction); 109 + if (dma_mapping_error(iu->dma)) 110 + goto out_free_buf; 111 + 112 + iu->size = size; 113 + iu->direction = direction; 114 + 115 + return iu; 116 + 117 + out_free_buf: 118 + kfree(iu->buf); 119 + out_free_iu: 120 + kfree(iu); 121 + out: 122 + return NULL; 123 + } 124 + 125 + static void srp_free_iu(struct srp_host *host, struct srp_iu *iu) 126 + { 127 + if (!iu) 128 + return; 129 + 130 + dma_unmap_single(host->dev->dma_device, iu->dma, iu->size, iu->direction); 131 + kfree(iu->buf); 132 + kfree(iu); 133 + } 134 + 135 + static void srp_qp_event(struct ib_event *event, void *context) 136 + { 137 + printk(KERN_ERR PFX "QP event %d\n", event->event); 138 + } 139 + 140 + static int srp_init_qp(struct srp_target_port *target, 141 + struct ib_qp *qp) 142 + { 143 + struct ib_qp_attr *attr; 144 + int ret; 145 + 146 + attr = kmalloc(sizeof *attr, GFP_KERNEL); 147 + if (!attr) 148 + return -ENOMEM; 149 + 150 + ret = ib_find_cached_pkey(target->srp_host->dev, 151 + target->srp_host->port, 152 + be16_to_cpu(target->path.pkey), 153 + &attr->pkey_index); 154 + if (ret) 155 + goto out; 156 + 157 + attr->qp_state = IB_QPS_INIT; 158 + attr->qp_access_flags = (IB_ACCESS_REMOTE_READ | 159 + IB_ACCESS_REMOTE_WRITE); 160 + attr->port_num = target->srp_host->port; 161 + 162 + ret = ib_modify_qp(qp, attr, 163 + IB_QP_STATE | 164 + IB_QP_PKEY_INDEX | 165 + IB_QP_ACCESS_FLAGS | 166 + IB_QP_PORT); 167 + 168 + out: 169 + kfree(attr); 170 + return ret; 171 + } 172 + 173 + static int srp_create_target_ib(struct srp_target_port *target) 174 + { 175 + struct ib_qp_init_attr *init_attr; 176 + int ret; 177 + 178 + init_attr = kzalloc(sizeof *init_attr, GFP_KERNEL); 179 + if (!init_attr) 180 + return -ENOMEM; 181 + 182 + target->cq = ib_create_cq(target->srp_host->dev, srp_completion, 183 + NULL, target, SRP_CQ_SIZE); 184 + if (IS_ERR(target->cq)) { 185 + ret = PTR_ERR(target->cq); 186 + goto out; 187 + } 188 + 189 + ib_req_notify_cq(target->cq, IB_CQ_NEXT_COMP); 190 + 191 + init_attr->event_handler = srp_qp_event; 192 + init_attr->cap.max_send_wr = SRP_SQ_SIZE; 193 + init_attr->cap.max_recv_wr = SRP_RQ_SIZE; 194 + init_attr->cap.max_recv_sge = 1; 195 + init_attr->cap.max_send_sge = 1; 196 + init_attr->sq_sig_type = IB_SIGNAL_ALL_WR; 197 + init_attr->qp_type = IB_QPT_RC; 198 + init_attr->send_cq = target->cq; 199 + init_attr->recv_cq = target->cq; 200 + 201 + target->qp = ib_create_qp(target->srp_host->pd, init_attr); 202 + if (IS_ERR(target->qp)) { 203 + ret = PTR_ERR(target->qp); 204 + ib_destroy_cq(target->cq); 205 + goto out; 206 + } 207 + 208 + ret = srp_init_qp(target, target->qp); 209 + if (ret) { 210 + ib_destroy_qp(target->qp); 211 + ib_destroy_cq(target->cq); 212 + goto out; 213 + } 214 + 215 + out: 216 + kfree(init_attr); 217 + return ret; 218 + } 219 + 220 + static void srp_free_target_ib(struct srp_target_port *target) 221 + { 222 + int i; 223 + 224 + ib_destroy_qp(target->qp); 225 + ib_destroy_cq(target->cq); 226 + 227 + for (i = 0; i < SRP_RQ_SIZE; ++i) 228 + srp_free_iu(target->srp_host, target->rx_ring[i]); 229 + for (i = 0; i < SRP_SQ_SIZE + 1; ++i) 230 + srp_free_iu(target->srp_host, target->tx_ring[i]); 231 + } 232 + 233 + static void srp_path_rec_completion(int status, 234 + struct ib_sa_path_rec *pathrec, 235 + void *target_ptr) 236 + { 237 + struct srp_target_port *target = target_ptr; 238 + 239 + target->status = status; 240 + if (status) 241 + printk(KERN_ERR PFX "Got failed path rec status %d\n", status); 242 + else 243 + target->path = *pathrec; 244 + complete(&target->done); 245 + } 246 + 247 + static int srp_lookup_path(struct srp_target_port *target) 248 + { 249 + target->path.numb_path = 1; 250 + 251 + init_completion(&target->done); 252 + 253 + target->path_query_id = ib_sa_path_rec_get(target->srp_host->dev, 254 + target->srp_host->port, 255 + &target->path, 256 + IB_SA_PATH_REC_DGID | 257 + IB_SA_PATH_REC_SGID | 258 + IB_SA_PATH_REC_NUMB_PATH | 259 + IB_SA_PATH_REC_PKEY, 260 + SRP_PATH_REC_TIMEOUT_MS, 261 + GFP_KERNEL, 262 + srp_path_rec_completion, 263 + target, &target->path_query); 264 + if (target->path_query_id < 0) 265 + return target->path_query_id; 266 + 267 + wait_for_completion(&target->done); 268 + 269 + if (target->status < 0) 270 + printk(KERN_WARNING PFX "Path record query failed\n"); 271 + 272 + return target->status; 273 + } 274 + 275 + static int srp_send_req(struct srp_target_port *target) 276 + { 277 + struct { 278 + struct ib_cm_req_param param; 279 + struct srp_login_req priv; 280 + } *req = NULL; 281 + int status; 282 + 283 + req = kzalloc(sizeof *req, GFP_KERNEL); 284 + if (!req) 285 + return -ENOMEM; 286 + 287 + req->param.primary_path = &target->path; 288 + req->param.alternate_path = NULL; 289 + req->param.service_id = target->service_id; 290 + req->param.qp_num = target->qp->qp_num; 291 + req->param.qp_type = target->qp->qp_type; 292 + req->param.private_data = &req->priv; 293 + req->param.private_data_len = sizeof req->priv; 294 + req->param.flow_control = 1; 295 + 296 + get_random_bytes(&req->param.starting_psn, 4); 297 + req->param.starting_psn &= 0xffffff; 298 + 299 + /* 300 + * Pick some arbitrary defaults here; we could make these 301 + * module parameters if anyone cared about setting them. 302 + */ 303 + req->param.responder_resources = 4; 304 + req->param.remote_cm_response_timeout = 20; 305 + req->param.local_cm_response_timeout = 20; 306 + req->param.retry_count = 7; 307 + req->param.rnr_retry_count = 7; 308 + req->param.max_cm_retries = 15; 309 + 310 + req->priv.opcode = SRP_LOGIN_REQ; 311 + req->priv.tag = 0; 312 + req->priv.req_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN); 313 + req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | 314 + SRP_BUF_FORMAT_INDIRECT); 315 + memcpy(req->priv.initiator_port_id, target->srp_host->initiator_port_id, 16); 316 + /* 317 + * Topspin/Cisco SRP targets will reject our login unless we 318 + * zero out the first 8 bytes of our initiator port ID. The 319 + * second 8 bytes must be our local node GUID, but we always 320 + * use that anyway. 321 + */ 322 + if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) { 323 + printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " 324 + "activated for target GUID %016llx\n", 325 + (unsigned long long) be64_to_cpu(target->ioc_guid)); 326 + memset(req->priv.initiator_port_id, 0, 8); 327 + } 328 + memcpy(req->priv.target_port_id, &target->id_ext, 8); 329 + memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8); 330 + 331 + status = ib_send_cm_req(target->cm_id, &req->param); 332 + 333 + kfree(req); 334 + 335 + return status; 336 + } 337 + 338 + static void srp_disconnect_target(struct srp_target_port *target) 339 + { 340 + /* XXX should send SRP_I_LOGOUT request */ 341 + 342 + init_completion(&target->done); 343 + ib_send_cm_dreq(target->cm_id, NULL, 0); 344 + wait_for_completion(&target->done); 345 + } 346 + 347 + static void srp_remove_work(void *target_ptr) 348 + { 349 + struct srp_target_port *target = target_ptr; 350 + 351 + spin_lock_irq(target->scsi_host->host_lock); 352 + if (target->state != SRP_TARGET_DEAD) { 353 + spin_unlock_irq(target->scsi_host->host_lock); 354 + scsi_host_put(target->scsi_host); 355 + return; 356 + } 357 + target->state = SRP_TARGET_REMOVED; 358 + spin_unlock_irq(target->scsi_host->host_lock); 359 + 360 + down(&target->srp_host->target_mutex); 361 + list_del(&target->list); 362 + up(&target->srp_host->target_mutex); 363 + 364 + scsi_remove_host(target->scsi_host); 365 + ib_destroy_cm_id(target->cm_id); 366 + srp_free_target_ib(target); 367 + scsi_host_put(target->scsi_host); 368 + /* And another put to really free the target port... */ 369 + scsi_host_put(target->scsi_host); 370 + } 371 + 372 + static int srp_connect_target(struct srp_target_port *target) 373 + { 374 + int ret; 375 + 376 + ret = srp_lookup_path(target); 377 + if (ret) 378 + return ret; 379 + 380 + while (1) { 381 + init_completion(&target->done); 382 + ret = srp_send_req(target); 383 + if (ret) 384 + return ret; 385 + wait_for_completion(&target->done); 386 + 387 + /* 388 + * The CM event handling code will set status to 389 + * SRP_PORT_REDIRECT if we get a port redirect REJ 390 + * back, or SRP_DLID_REDIRECT if we get a lid/qp 391 + * redirect REJ back. 392 + */ 393 + switch (target->status) { 394 + case 0: 395 + return 0; 396 + 397 + case SRP_PORT_REDIRECT: 398 + ret = srp_lookup_path(target); 399 + if (ret) 400 + return ret; 401 + break; 402 + 403 + case SRP_DLID_REDIRECT: 404 + break; 405 + 406 + default: 407 + return target->status; 408 + } 409 + } 410 + } 411 + 412 + static int srp_reconnect_target(struct srp_target_port *target) 413 + { 414 + struct ib_cm_id *new_cm_id; 415 + struct ib_qp_attr qp_attr; 416 + struct srp_request *req; 417 + struct ib_wc wc; 418 + int ret; 419 + int i; 420 + 421 + spin_lock_irq(target->scsi_host->host_lock); 422 + if (target->state != SRP_TARGET_LIVE) { 423 + spin_unlock_irq(target->scsi_host->host_lock); 424 + return -EAGAIN; 425 + } 426 + target->state = SRP_TARGET_CONNECTING; 427 + spin_unlock_irq(target->scsi_host->host_lock); 428 + 429 + srp_disconnect_target(target); 430 + /* 431 + * Now get a new local CM ID so that we avoid confusing the 432 + * target in case things are really fouled up. 433 + */ 434 + new_cm_id = ib_create_cm_id(target->srp_host->dev, 435 + srp_cm_handler, target); 436 + if (IS_ERR(new_cm_id)) { 437 + ret = PTR_ERR(new_cm_id); 438 + goto err; 439 + } 440 + ib_destroy_cm_id(target->cm_id); 441 + target->cm_id = new_cm_id; 442 + 443 + qp_attr.qp_state = IB_QPS_RESET; 444 + ret = ib_modify_qp(target->qp, &qp_attr, IB_QP_STATE); 445 + if (ret) 446 + goto err; 447 + 448 + ret = srp_init_qp(target, target->qp); 449 + if (ret) 450 + goto err; 451 + 452 + while (ib_poll_cq(target->cq, 1, &wc) > 0) 453 + ; /* nothing */ 454 + 455 + list_for_each_entry(req, &target->req_queue, list) { 456 + req->scmnd->result = DID_RESET << 16; 457 + req->scmnd->scsi_done(req->scmnd); 458 + } 459 + 460 + target->rx_head = 0; 461 + target->tx_head = 0; 462 + target->tx_tail = 0; 463 + target->req_head = 0; 464 + for (i = 0; i < SRP_SQ_SIZE - 1; ++i) 465 + target->req_ring[i].next = i + 1; 466 + target->req_ring[SRP_SQ_SIZE - 1].next = -1; 467 + INIT_LIST_HEAD(&target->req_queue); 468 + 469 + ret = srp_connect_target(target); 470 + if (ret) 471 + goto err; 472 + 473 + spin_lock_irq(target->scsi_host->host_lock); 474 + if (target->state == SRP_TARGET_CONNECTING) { 475 + ret = 0; 476 + target->state = SRP_TARGET_LIVE; 477 + } else 478 + ret = -EAGAIN; 479 + spin_unlock_irq(target->scsi_host->host_lock); 480 + 481 + return ret; 482 + 483 + err: 484 + printk(KERN_ERR PFX "reconnect failed (%d), removing target port.\n", ret); 485 + 486 + /* 487 + * We couldn't reconnect, so kill our target port off. 488 + * However, we have to defer the real removal because we might 489 + * be in the context of the SCSI error handler now, which 490 + * would deadlock if we call scsi_remove_host(). 491 + */ 492 + spin_lock_irq(target->scsi_host->host_lock); 493 + if (target->state == SRP_TARGET_CONNECTING) { 494 + target->state = SRP_TARGET_DEAD; 495 + INIT_WORK(&target->work, srp_remove_work, target); 496 + schedule_work(&target->work); 497 + } 498 + spin_unlock_irq(target->scsi_host->host_lock); 499 + 500 + return ret; 501 + } 502 + 503 + static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, 504 + struct srp_request *req) 505 + { 506 + struct srp_cmd *cmd = req->cmd->buf; 507 + int len; 508 + u8 fmt; 509 + 510 + if (!scmnd->request_buffer || scmnd->sc_data_direction == DMA_NONE) 511 + return sizeof (struct srp_cmd); 512 + 513 + if (scmnd->sc_data_direction != DMA_FROM_DEVICE && 514 + scmnd->sc_data_direction != DMA_TO_DEVICE) { 515 + printk(KERN_WARNING PFX "Unhandled data direction %d\n", 516 + scmnd->sc_data_direction); 517 + return -EINVAL; 518 + } 519 + 520 + if (scmnd->use_sg) { 521 + struct scatterlist *scat = scmnd->request_buffer; 522 + int n; 523 + int i; 524 + 525 + n = dma_map_sg(target->srp_host->dev->dma_device, 526 + scat, scmnd->use_sg, scmnd->sc_data_direction); 527 + 528 + if (n == 1) { 529 + struct srp_direct_buf *buf = (void *) cmd->add_data; 530 + 531 + fmt = SRP_DATA_DESC_DIRECT; 532 + 533 + buf->va = cpu_to_be64(sg_dma_address(scat)); 534 + buf->key = cpu_to_be32(target->srp_host->mr->rkey); 535 + buf->len = cpu_to_be32(sg_dma_len(scat)); 536 + 537 + len = sizeof (struct srp_cmd) + 538 + sizeof (struct srp_direct_buf); 539 + } else { 540 + struct srp_indirect_buf *buf = (void *) cmd->add_data; 541 + u32 datalen = 0; 542 + 543 + fmt = SRP_DATA_DESC_INDIRECT; 544 + 545 + if (scmnd->sc_data_direction == DMA_TO_DEVICE) 546 + cmd->data_out_desc_cnt = n; 547 + else 548 + cmd->data_in_desc_cnt = n; 549 + 550 + buf->table_desc.va = cpu_to_be64(req->cmd->dma + 551 + sizeof *cmd + 552 + sizeof *buf); 553 + buf->table_desc.key = 554 + cpu_to_be32(target->srp_host->mr->rkey); 555 + buf->table_desc.len = 556 + cpu_to_be32(n * sizeof (struct srp_direct_buf)); 557 + 558 + for (i = 0; i < n; ++i) { 559 + buf->desc_list[i].va = cpu_to_be64(sg_dma_address(&scat[i])); 560 + buf->desc_list[i].key = 561 + cpu_to_be32(target->srp_host->mr->rkey); 562 + buf->desc_list[i].len = cpu_to_be32(sg_dma_len(&scat[i])); 563 + 564 + datalen += sg_dma_len(&scat[i]); 565 + } 566 + 567 + buf->len = cpu_to_be32(datalen); 568 + 569 + len = sizeof (struct srp_cmd) + 570 + sizeof (struct srp_indirect_buf) + 571 + n * sizeof (struct srp_direct_buf); 572 + } 573 + } else { 574 + struct srp_direct_buf *buf = (void *) cmd->add_data; 575 + dma_addr_t dma; 576 + 577 + dma = dma_map_single(target->srp_host->dev->dma_device, 578 + scmnd->request_buffer, scmnd->request_bufflen, 579 + scmnd->sc_data_direction); 580 + if (dma_mapping_error(dma)) { 581 + printk(KERN_WARNING PFX "unable to map %p/%d (dir %d)\n", 582 + scmnd->request_buffer, (int) scmnd->request_bufflen, 583 + scmnd->sc_data_direction); 584 + return -EINVAL; 585 + } 586 + 587 + pci_unmap_addr_set(req, direct_mapping, dma); 588 + 589 + buf->va = cpu_to_be64(dma); 590 + buf->key = cpu_to_be32(target->srp_host->mr->rkey); 591 + buf->len = cpu_to_be32(scmnd->request_bufflen); 592 + 593 + fmt = SRP_DATA_DESC_DIRECT; 594 + 595 + len = sizeof (struct srp_cmd) + sizeof (struct srp_direct_buf); 596 + } 597 + 598 + if (scmnd->sc_data_direction == DMA_TO_DEVICE) 599 + cmd->buf_fmt = fmt << 4; 600 + else 601 + cmd->buf_fmt = fmt; 602 + 603 + 604 + return len; 605 + } 606 + 607 + static void srp_unmap_data(struct scsi_cmnd *scmnd, 608 + struct srp_target_port *target, 609 + struct srp_request *req) 610 + { 611 + if (!scmnd->request_buffer || 612 + (scmnd->sc_data_direction != DMA_TO_DEVICE && 613 + scmnd->sc_data_direction != DMA_FROM_DEVICE)) 614 + return; 615 + 616 + if (scmnd->use_sg) 617 + dma_unmap_sg(target->srp_host->dev->dma_device, 618 + (struct scatterlist *) scmnd->request_buffer, 619 + scmnd->use_sg, scmnd->sc_data_direction); 620 + else 621 + dma_unmap_single(target->srp_host->dev->dma_device, 622 + pci_unmap_addr(req, direct_mapping), 623 + scmnd->request_bufflen, 624 + scmnd->sc_data_direction); 625 + } 626 + 627 + static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) 628 + { 629 + struct srp_request *req; 630 + struct scsi_cmnd *scmnd; 631 + unsigned long flags; 632 + s32 delta; 633 + 634 + delta = (s32) be32_to_cpu(rsp->req_lim_delta); 635 + 636 + spin_lock_irqsave(target->scsi_host->host_lock, flags); 637 + 638 + target->req_lim += delta; 639 + 640 + req = &target->req_ring[rsp->tag & ~SRP_TAG_TSK_MGMT]; 641 + 642 + if (unlikely(rsp->tag & SRP_TAG_TSK_MGMT)) { 643 + if (be32_to_cpu(rsp->resp_data_len) < 4) 644 + req->tsk_status = -1; 645 + else 646 + req->tsk_status = rsp->data[3]; 647 + complete(&req->done); 648 + } else { 649 + scmnd = req->scmnd; 650 + if (!scmnd) 651 + printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n", 652 + (unsigned long long) rsp->tag); 653 + scmnd->result = rsp->status; 654 + 655 + if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { 656 + memcpy(scmnd->sense_buffer, rsp->data + 657 + be32_to_cpu(rsp->resp_data_len), 658 + min_t(int, be32_to_cpu(rsp->sense_data_len), 659 + SCSI_SENSE_BUFFERSIZE)); 660 + } 661 + 662 + if (rsp->flags & (SRP_RSP_FLAG_DOOVER | SRP_RSP_FLAG_DOUNDER)) 663 + scmnd->resid = be32_to_cpu(rsp->data_out_res_cnt); 664 + else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) 665 + scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt); 666 + 667 + srp_unmap_data(scmnd, target, req); 668 + 669 + if (!req->tsk_mgmt) { 670 + req->scmnd = NULL; 671 + scmnd->host_scribble = (void *) -1L; 672 + scmnd->scsi_done(scmnd); 673 + 674 + list_del(&req->list); 675 + req->next = target->req_head; 676 + target->req_head = rsp->tag & ~SRP_TAG_TSK_MGMT; 677 + } else 678 + req->cmd_done = 1; 679 + } 680 + 681 + spin_unlock_irqrestore(target->scsi_host->host_lock, flags); 682 + } 683 + 684 + static void srp_reconnect_work(void *target_ptr) 685 + { 686 + struct srp_target_port *target = target_ptr; 687 + 688 + srp_reconnect_target(target); 689 + } 690 + 691 + static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) 692 + { 693 + struct srp_iu *iu; 694 + u8 opcode; 695 + 696 + iu = target->rx_ring[wc->wr_id & ~SRP_OP_RECV]; 697 + 698 + dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma, 699 + target->max_ti_iu_len, DMA_FROM_DEVICE); 700 + 701 + opcode = *(u8 *) iu->buf; 702 + 703 + if (0) { 704 + int i; 705 + 706 + printk(KERN_ERR PFX "recv completion, opcode 0x%02x\n", opcode); 707 + 708 + for (i = 0; i < wc->byte_len; ++i) { 709 + if (i % 8 == 0) 710 + printk(KERN_ERR " [%02x] ", i); 711 + printk(" %02x", ((u8 *) iu->buf)[i]); 712 + if ((i + 1) % 8 == 0) 713 + printk("\n"); 714 + } 715 + 716 + if (wc->byte_len % 8) 717 + printk("\n"); 718 + } 719 + 720 + switch (opcode) { 721 + case SRP_RSP: 722 + srp_process_rsp(target, iu->buf); 723 + break; 724 + 725 + case SRP_T_LOGOUT: 726 + /* XXX Handle target logout */ 727 + printk(KERN_WARNING PFX "Got target logout request\n"); 728 + break; 729 + 730 + default: 731 + printk(KERN_WARNING PFX "Unhandled SRP opcode 0x%02x\n", opcode); 732 + break; 733 + } 734 + 735 + dma_sync_single_for_device(target->srp_host->dev->dma_device, iu->dma, 736 + target->max_ti_iu_len, DMA_FROM_DEVICE); 737 + } 738 + 739 + static void srp_completion(struct ib_cq *cq, void *target_ptr) 740 + { 741 + struct srp_target_port *target = target_ptr; 742 + struct ib_wc wc; 743 + unsigned long flags; 744 + 745 + ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); 746 + while (ib_poll_cq(cq, 1, &wc) > 0) { 747 + if (wc.status) { 748 + printk(KERN_ERR PFX "failed %s status %d\n", 749 + wc.wr_id & SRP_OP_RECV ? "receive" : "send", 750 + wc.status); 751 + spin_lock_irqsave(target->scsi_host->host_lock, flags); 752 + if (target->state == SRP_TARGET_LIVE) 753 + schedule_work(&target->work); 754 + spin_unlock_irqrestore(target->scsi_host->host_lock, flags); 755 + break; 756 + } 757 + 758 + if (wc.wr_id & SRP_OP_RECV) 759 + srp_handle_recv(target, &wc); 760 + else 761 + ++target->tx_tail; 762 + } 763 + } 764 + 765 + static int __srp_post_recv(struct srp_target_port *target) 766 + { 767 + struct srp_iu *iu; 768 + struct ib_sge list; 769 + struct ib_recv_wr wr, *bad_wr; 770 + unsigned int next; 771 + int ret; 772 + 773 + next = target->rx_head & (SRP_RQ_SIZE - 1); 774 + wr.wr_id = next | SRP_OP_RECV; 775 + iu = target->rx_ring[next]; 776 + 777 + list.addr = iu->dma; 778 + list.length = iu->size; 779 + list.lkey = target->srp_host->mr->lkey; 780 + 781 + wr.next = NULL; 782 + wr.sg_list = &list; 783 + wr.num_sge = 1; 784 + 785 + ret = ib_post_recv(target->qp, &wr, &bad_wr); 786 + if (!ret) 787 + ++target->rx_head; 788 + 789 + return ret; 790 + } 791 + 792 + static int srp_post_recv(struct srp_target_port *target) 793 + { 794 + unsigned long flags; 795 + int ret; 796 + 797 + spin_lock_irqsave(target->scsi_host->host_lock, flags); 798 + ret = __srp_post_recv(target); 799 + spin_unlock_irqrestore(target->scsi_host->host_lock, flags); 800 + 801 + return ret; 802 + } 803 + 804 + /* 805 + * Must be called with target->scsi_host->host_lock held to protect 806 + * req_lim and tx_head. 807 + */ 808 + static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target) 809 + { 810 + if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) 811 + return NULL; 812 + 813 + return target->tx_ring[target->tx_head & SRP_SQ_SIZE]; 814 + } 815 + 816 + /* 817 + * Must be called with target->scsi_host->host_lock held to protect 818 + * req_lim and tx_head. 819 + */ 820 + static int __srp_post_send(struct srp_target_port *target, 821 + struct srp_iu *iu, int len) 822 + { 823 + struct ib_sge list; 824 + struct ib_send_wr wr, *bad_wr; 825 + int ret = 0; 826 + 827 + if (target->req_lim < 1) { 828 + printk(KERN_ERR PFX "Target has req_lim %d\n", target->req_lim); 829 + return -EAGAIN; 830 + } 831 + 832 + list.addr = iu->dma; 833 + list.length = len; 834 + list.lkey = target->srp_host->mr->lkey; 835 + 836 + wr.next = NULL; 837 + wr.wr_id = target->tx_head & SRP_SQ_SIZE; 838 + wr.sg_list = &list; 839 + wr.num_sge = 1; 840 + wr.opcode = IB_WR_SEND; 841 + wr.send_flags = IB_SEND_SIGNALED; 842 + 843 + ret = ib_post_send(target->qp, &wr, &bad_wr); 844 + 845 + if (!ret) { 846 + ++target->tx_head; 847 + --target->req_lim; 848 + } 849 + 850 + return ret; 851 + } 852 + 853 + static int srp_queuecommand(struct scsi_cmnd *scmnd, 854 + void (*done)(struct scsi_cmnd *)) 855 + { 856 + struct srp_target_port *target = host_to_target(scmnd->device->host); 857 + struct srp_request *req; 858 + struct srp_iu *iu; 859 + struct srp_cmd *cmd; 860 + long req_index; 861 + int len; 862 + 863 + if (target->state == SRP_TARGET_CONNECTING) 864 + goto err; 865 + 866 + if (target->state == SRP_TARGET_DEAD || 867 + target->state == SRP_TARGET_REMOVED) { 868 + scmnd->result = DID_BAD_TARGET << 16; 869 + done(scmnd); 870 + return 0; 871 + } 872 + 873 + iu = __srp_get_tx_iu(target); 874 + if (!iu) 875 + goto err; 876 + 877 + dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma, 878 + SRP_MAX_IU_LEN, DMA_TO_DEVICE); 879 + 880 + req_index = target->req_head; 881 + 882 + scmnd->scsi_done = done; 883 + scmnd->result = 0; 884 + scmnd->host_scribble = (void *) req_index; 885 + 886 + cmd = iu->buf; 887 + memset(cmd, 0, sizeof *cmd); 888 + 889 + cmd->opcode = SRP_CMD; 890 + cmd->lun = cpu_to_be64((u64) scmnd->device->lun << 48); 891 + cmd->tag = req_index; 892 + memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len); 893 + 894 + req = &target->req_ring[req_index]; 895 + 896 + req->scmnd = scmnd; 897 + req->cmd = iu; 898 + req->cmd_done = 0; 899 + req->tsk_mgmt = NULL; 900 + 901 + len = srp_map_data(scmnd, target, req); 902 + if (len < 0) { 903 + printk(KERN_ERR PFX "Failed to map data\n"); 904 + goto err; 905 + } 906 + 907 + if (__srp_post_recv(target)) { 908 + printk(KERN_ERR PFX "Recv failed\n"); 909 + goto err_unmap; 910 + } 911 + 912 + dma_sync_single_for_device(target->srp_host->dev->dma_device, iu->dma, 913 + SRP_MAX_IU_LEN, DMA_TO_DEVICE); 914 + 915 + if (__srp_post_send(target, iu, len)) { 916 + printk(KERN_ERR PFX "Send failed\n"); 917 + goto err_unmap; 918 + } 919 + 920 + target->req_head = req->next; 921 + list_add_tail(&req->list, &target->req_queue); 922 + 923 + return 0; 924 + 925 + err_unmap: 926 + srp_unmap_data(scmnd, target, req); 927 + 928 + err: 929 + return SCSI_MLQUEUE_HOST_BUSY; 930 + } 931 + 932 + static int srp_alloc_iu_bufs(struct srp_target_port *target) 933 + { 934 + int i; 935 + 936 + for (i = 0; i < SRP_RQ_SIZE; ++i) { 937 + target->rx_ring[i] = srp_alloc_iu(target->srp_host, 938 + target->max_ti_iu_len, 939 + GFP_KERNEL, DMA_FROM_DEVICE); 940 + if (!target->rx_ring[i]) 941 + goto err; 942 + } 943 + 944 + for (i = 0; i < SRP_SQ_SIZE + 1; ++i) { 945 + target->tx_ring[i] = srp_alloc_iu(target->srp_host, 946 + SRP_MAX_IU_LEN, 947 + GFP_KERNEL, DMA_TO_DEVICE); 948 + if (!target->tx_ring[i]) 949 + goto err; 950 + } 951 + 952 + return 0; 953 + 954 + err: 955 + for (i = 0; i < SRP_RQ_SIZE; ++i) { 956 + srp_free_iu(target->srp_host, target->rx_ring[i]); 957 + target->rx_ring[i] = NULL; 958 + } 959 + 960 + for (i = 0; i < SRP_SQ_SIZE + 1; ++i) { 961 + srp_free_iu(target->srp_host, target->tx_ring[i]); 962 + target->tx_ring[i] = NULL; 963 + } 964 + 965 + return -ENOMEM; 966 + } 967 + 968 + static void srp_cm_rej_handler(struct ib_cm_id *cm_id, 969 + struct ib_cm_event *event, 970 + struct srp_target_port *target) 971 + { 972 + struct ib_class_port_info *cpi; 973 + int opcode; 974 + 975 + switch (event->param.rej_rcvd.reason) { 976 + case IB_CM_REJ_PORT_CM_REDIRECT: 977 + cpi = event->param.rej_rcvd.ari; 978 + target->path.dlid = cpi->redirect_lid; 979 + target->path.pkey = cpi->redirect_pkey; 980 + cm_id->remote_cm_qpn = be32_to_cpu(cpi->redirect_qp) & 0x00ffffff; 981 + memcpy(target->path.dgid.raw, cpi->redirect_gid, 16); 982 + 983 + target->status = target->path.dlid ? 984 + SRP_DLID_REDIRECT : SRP_PORT_REDIRECT; 985 + break; 986 + 987 + case IB_CM_REJ_PORT_REDIRECT: 988 + if (topspin_workarounds && 989 + !memcmp(&target->ioc_guid, topspin_oui, 3)) { 990 + /* 991 + * Topspin/Cisco SRP gateways incorrectly send 992 + * reject reason code 25 when they mean 24 993 + * (port redirect). 994 + */ 995 + memcpy(target->path.dgid.raw, 996 + event->param.rej_rcvd.ari, 16); 997 + 998 + printk(KERN_DEBUG PFX "Topspin/Cisco redirect to target port GID %016llx%016llx\n", 999 + (unsigned long long) be64_to_cpu(target->path.dgid.global.subnet_prefix), 1000 + (unsigned long long) be64_to_cpu(target->path.dgid.global.interface_id)); 1001 + 1002 + target->status = SRP_PORT_REDIRECT; 1003 + } else { 1004 + printk(KERN_WARNING " REJ reason: IB_CM_REJ_PORT_REDIRECT\n"); 1005 + target->status = -ECONNRESET; 1006 + } 1007 + break; 1008 + 1009 + case IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID: 1010 + printk(KERN_WARNING " REJ reason: IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID\n"); 1011 + target->status = -ECONNRESET; 1012 + break; 1013 + 1014 + case IB_CM_REJ_CONSUMER_DEFINED: 1015 + opcode = *(u8 *) event->private_data; 1016 + if (opcode == SRP_LOGIN_REJ) { 1017 + struct srp_login_rej *rej = event->private_data; 1018 + u32 reason = be32_to_cpu(rej->reason); 1019 + 1020 + if (reason == SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE) 1021 + printk(KERN_WARNING PFX 1022 + "SRP_LOGIN_REJ: requested max_it_iu_len too large\n"); 1023 + else 1024 + printk(KERN_WARNING PFX 1025 + "SRP LOGIN REJECTED, reason 0x%08x\n", reason); 1026 + } else 1027 + printk(KERN_WARNING " REJ reason: IB_CM_REJ_CONSUMER_DEFINED," 1028 + " opcode 0x%02x\n", opcode); 1029 + target->status = -ECONNRESET; 1030 + break; 1031 + 1032 + default: 1033 + printk(KERN_WARNING " REJ reason 0x%x\n", 1034 + event->param.rej_rcvd.reason); 1035 + target->status = -ECONNRESET; 1036 + } 1037 + } 1038 + 1039 + static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) 1040 + { 1041 + struct srp_target_port *target = cm_id->context; 1042 + struct ib_qp_attr *qp_attr = NULL; 1043 + int attr_mask = 0; 1044 + int comp = 0; 1045 + int opcode = 0; 1046 + 1047 + switch (event->event) { 1048 + case IB_CM_REQ_ERROR: 1049 + printk(KERN_DEBUG PFX "Sending CM REQ failed\n"); 1050 + comp = 1; 1051 + target->status = -ECONNRESET; 1052 + break; 1053 + 1054 + case IB_CM_REP_RECEIVED: 1055 + comp = 1; 1056 + opcode = *(u8 *) event->private_data; 1057 + 1058 + if (opcode == SRP_LOGIN_RSP) { 1059 + struct srp_login_rsp *rsp = event->private_data; 1060 + 1061 + target->max_ti_iu_len = be32_to_cpu(rsp->max_ti_iu_len); 1062 + target->req_lim = be32_to_cpu(rsp->req_lim_delta); 1063 + 1064 + target->scsi_host->can_queue = min(target->req_lim, 1065 + target->scsi_host->can_queue); 1066 + } else { 1067 + printk(KERN_WARNING PFX "Unhandled RSP opcode %#x\n", opcode); 1068 + target->status = -ECONNRESET; 1069 + break; 1070 + } 1071 + 1072 + target->status = srp_alloc_iu_bufs(target); 1073 + if (target->status) 1074 + break; 1075 + 1076 + qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL); 1077 + if (!qp_attr) { 1078 + target->status = -ENOMEM; 1079 + break; 1080 + } 1081 + 1082 + qp_attr->qp_state = IB_QPS_RTR; 1083 + target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask); 1084 + if (target->status) 1085 + break; 1086 + 1087 + target->status = ib_modify_qp(target->qp, qp_attr, attr_mask); 1088 + if (target->status) 1089 + break; 1090 + 1091 + target->status = srp_post_recv(target); 1092 + if (target->status) 1093 + break; 1094 + 1095 + qp_attr->qp_state = IB_QPS_RTS; 1096 + target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask); 1097 + if (target->status) 1098 + break; 1099 + 1100 + target->status = ib_modify_qp(target->qp, qp_attr, attr_mask); 1101 + if (target->status) 1102 + break; 1103 + 1104 + target->status = ib_send_cm_rtu(cm_id, NULL, 0); 1105 + if (target->status) 1106 + break; 1107 + 1108 + break; 1109 + 1110 + case IB_CM_REJ_RECEIVED: 1111 + printk(KERN_DEBUG PFX "REJ received\n"); 1112 + comp = 1; 1113 + 1114 + srp_cm_rej_handler(cm_id, event, target); 1115 + break; 1116 + 1117 + case IB_CM_MRA_RECEIVED: 1118 + printk(KERN_ERR PFX "MRA received\n"); 1119 + break; 1120 + 1121 + case IB_CM_DREP_RECEIVED: 1122 + break; 1123 + 1124 + case IB_CM_TIMEWAIT_EXIT: 1125 + printk(KERN_ERR PFX "connection closed\n"); 1126 + 1127 + comp = 1; 1128 + target->status = 0; 1129 + break; 1130 + 1131 + default: 1132 + printk(KERN_WARNING PFX "Unhandled CM event %d\n", event->event); 1133 + break; 1134 + } 1135 + 1136 + if (comp) 1137 + complete(&target->done); 1138 + 1139 + kfree(qp_attr); 1140 + 1141 + return 0; 1142 + } 1143 + 1144 + static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) 1145 + { 1146 + struct srp_target_port *target = host_to_target(scmnd->device->host); 1147 + struct srp_request *req; 1148 + struct srp_iu *iu; 1149 + struct srp_tsk_mgmt *tsk_mgmt; 1150 + int req_index; 1151 + int ret = FAILED; 1152 + 1153 + spin_lock_irq(target->scsi_host->host_lock); 1154 + 1155 + if (scmnd->host_scribble == (void *) -1L) 1156 + goto out; 1157 + 1158 + req_index = (long) scmnd->host_scribble; 1159 + printk(KERN_ERR "Abort for req_index %d\n", req_index); 1160 + 1161 + req = &target->req_ring[req_index]; 1162 + init_completion(&req->done); 1163 + 1164 + iu = __srp_get_tx_iu(target); 1165 + if (!iu) 1166 + goto out; 1167 + 1168 + tsk_mgmt = iu->buf; 1169 + memset(tsk_mgmt, 0, sizeof *tsk_mgmt); 1170 + 1171 + tsk_mgmt->opcode = SRP_TSK_MGMT; 1172 + tsk_mgmt->lun = cpu_to_be64((u64) scmnd->device->lun << 48); 1173 + tsk_mgmt->tag = req_index | SRP_TAG_TSK_MGMT; 1174 + tsk_mgmt->tsk_mgmt_func = func; 1175 + tsk_mgmt->task_tag = req_index; 1176 + 1177 + if (__srp_post_send(target, iu, sizeof *tsk_mgmt)) 1178 + goto out; 1179 + 1180 + req->tsk_mgmt = iu; 1181 + 1182 + spin_unlock_irq(target->scsi_host->host_lock); 1183 + if (!wait_for_completion_timeout(&req->done, 1184 + msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS))) 1185 + return FAILED; 1186 + spin_lock_irq(target->scsi_host->host_lock); 1187 + 1188 + if (req->cmd_done) { 1189 + list_del(&req->list); 1190 + req->next = target->req_head; 1191 + target->req_head = req_index; 1192 + 1193 + scmnd->scsi_done(scmnd); 1194 + } else if (!req->tsk_status) { 1195 + scmnd->result = DID_ABORT << 16; 1196 + ret = SUCCESS; 1197 + } 1198 + 1199 + out: 1200 + spin_unlock_irq(target->scsi_host->host_lock); 1201 + return ret; 1202 + } 1203 + 1204 + static int srp_abort(struct scsi_cmnd *scmnd) 1205 + { 1206 + printk(KERN_ERR "SRP abort called\n"); 1207 + 1208 + return srp_send_tsk_mgmt(scmnd, SRP_TSK_ABORT_TASK); 1209 + } 1210 + 1211 + static int srp_reset_device(struct scsi_cmnd *scmnd) 1212 + { 1213 + printk(KERN_ERR "SRP reset_device called\n"); 1214 + 1215 + return srp_send_tsk_mgmt(scmnd, SRP_TSK_LUN_RESET); 1216 + } 1217 + 1218 + static int srp_reset_host(struct scsi_cmnd *scmnd) 1219 + { 1220 + struct srp_target_port *target = host_to_target(scmnd->device->host); 1221 + int ret = FAILED; 1222 + 1223 + printk(KERN_ERR PFX "SRP reset_host called\n"); 1224 + 1225 + if (!srp_reconnect_target(target)) 1226 + ret = SUCCESS; 1227 + 1228 + return ret; 1229 + } 1230 + 1231 + static struct scsi_host_template srp_template = { 1232 + .module = THIS_MODULE, 1233 + .name = DRV_NAME, 1234 + .info = srp_target_info, 1235 + .queuecommand = srp_queuecommand, 1236 + .eh_abort_handler = srp_abort, 1237 + .eh_device_reset_handler = srp_reset_device, 1238 + .eh_host_reset_handler = srp_reset_host, 1239 + .can_queue = SRP_SQ_SIZE, 1240 + .this_id = -1, 1241 + .sg_tablesize = SRP_MAX_INDIRECT, 1242 + .cmd_per_lun = SRP_SQ_SIZE, 1243 + .use_clustering = ENABLE_CLUSTERING 1244 + }; 1245 + 1246 + static int srp_add_target(struct srp_host *host, struct srp_target_port *target) 1247 + { 1248 + sprintf(target->target_name, "SRP.T10:%016llX", 1249 + (unsigned long long) be64_to_cpu(target->id_ext)); 1250 + 1251 + if (scsi_add_host(target->scsi_host, host->dev->dma_device)) 1252 + return -ENODEV; 1253 + 1254 + down(&host->target_mutex); 1255 + list_add_tail(&target->list, &host->target_list); 1256 + up(&host->target_mutex); 1257 + 1258 + target->state = SRP_TARGET_LIVE; 1259 + 1260 + /* XXX: are we supposed to have a definition of SCAN_WILD_CARD ?? */ 1261 + scsi_scan_target(&target->scsi_host->shost_gendev, 1262 + 0, target->scsi_id, ~0, 0); 1263 + 1264 + return 0; 1265 + } 1266 + 1267 + static void srp_release_class_dev(struct class_device *class_dev) 1268 + { 1269 + struct srp_host *host = 1270 + container_of(class_dev, struct srp_host, class_dev); 1271 + 1272 + complete(&host->released); 1273 + } 1274 + 1275 + static struct class srp_class = { 1276 + .name = "infiniband_srp", 1277 + .release = srp_release_class_dev 1278 + }; 1279 + 1280 + /* 1281 + * Target ports are added by writing 1282 + * 1283 + * id_ext=<SRP ID ext>,ioc_guid=<SRP IOC GUID>,dgid=<dest GID>, 1284 + * pkey=<P_Key>,service_id=<service ID> 1285 + * 1286 + * to the add_target sysfs attribute. 1287 + */ 1288 + enum { 1289 + SRP_OPT_ERR = 0, 1290 + SRP_OPT_ID_EXT = 1 << 0, 1291 + SRP_OPT_IOC_GUID = 1 << 1, 1292 + SRP_OPT_DGID = 1 << 2, 1293 + SRP_OPT_PKEY = 1 << 3, 1294 + SRP_OPT_SERVICE_ID = 1 << 4, 1295 + SRP_OPT_MAX_SECT = 1 << 5, 1296 + SRP_OPT_ALL = (SRP_OPT_ID_EXT | 1297 + SRP_OPT_IOC_GUID | 1298 + SRP_OPT_DGID | 1299 + SRP_OPT_PKEY | 1300 + SRP_OPT_SERVICE_ID), 1301 + }; 1302 + 1303 + static match_table_t srp_opt_tokens = { 1304 + { SRP_OPT_ID_EXT, "id_ext=%s" }, 1305 + { SRP_OPT_IOC_GUID, "ioc_guid=%s" }, 1306 + { SRP_OPT_DGID, "dgid=%s" }, 1307 + { SRP_OPT_PKEY, "pkey=%x" }, 1308 + { SRP_OPT_SERVICE_ID, "service_id=%s" }, 1309 + { SRP_OPT_MAX_SECT, "max_sect=%d" }, 1310 + { SRP_OPT_ERR, NULL } 1311 + }; 1312 + 1313 + static int srp_parse_options(const char *buf, struct srp_target_port *target) 1314 + { 1315 + char *options, *sep_opt; 1316 + char *p; 1317 + char dgid[3]; 1318 + substring_t args[MAX_OPT_ARGS]; 1319 + int opt_mask = 0; 1320 + int token; 1321 + int ret = -EINVAL; 1322 + int i; 1323 + 1324 + options = kstrdup(buf, GFP_KERNEL); 1325 + if (!options) 1326 + return -ENOMEM; 1327 + 1328 + sep_opt = options; 1329 + while ((p = strsep(&sep_opt, ",")) != NULL) { 1330 + if (!*p) 1331 + continue; 1332 + 1333 + token = match_token(p, srp_opt_tokens, args); 1334 + opt_mask |= token; 1335 + 1336 + switch (token) { 1337 + case SRP_OPT_ID_EXT: 1338 + p = match_strdup(args); 1339 + target->id_ext = cpu_to_be64(simple_strtoull(p, NULL, 16)); 1340 + kfree(p); 1341 + break; 1342 + 1343 + case SRP_OPT_IOC_GUID: 1344 + p = match_strdup(args); 1345 + target->ioc_guid = cpu_to_be64(simple_strtoull(p, NULL, 16)); 1346 + kfree(p); 1347 + break; 1348 + 1349 + case SRP_OPT_DGID: 1350 + p = match_strdup(args); 1351 + if (strlen(p) != 32) { 1352 + printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p); 1353 + goto out; 1354 + } 1355 + 1356 + for (i = 0; i < 16; ++i) { 1357 + strlcpy(dgid, p + i * 2, 3); 1358 + target->path.dgid.raw[i] = simple_strtoul(dgid, NULL, 16); 1359 + } 1360 + break; 1361 + 1362 + case SRP_OPT_PKEY: 1363 + if (match_hex(args, &token)) { 1364 + printk(KERN_WARNING PFX "bad P_Key parameter '%s'\n", p); 1365 + goto out; 1366 + } 1367 + target->path.pkey = cpu_to_be16(token); 1368 + break; 1369 + 1370 + case SRP_OPT_SERVICE_ID: 1371 + p = match_strdup(args); 1372 + target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16)); 1373 + kfree(p); 1374 + break; 1375 + 1376 + case SRP_OPT_MAX_SECT: 1377 + if (match_int(args, &token)) { 1378 + printk(KERN_WARNING PFX "bad max sect parameter '%s'\n", p); 1379 + goto out; 1380 + } 1381 + target->scsi_host->max_sectors = token; 1382 + break; 1383 + 1384 + default: 1385 + printk(KERN_WARNING PFX "unknown parameter or missing value " 1386 + "'%s' in target creation request\n", p); 1387 + goto out; 1388 + } 1389 + } 1390 + 1391 + if ((opt_mask & SRP_OPT_ALL) == SRP_OPT_ALL) 1392 + ret = 0; 1393 + else 1394 + for (i = 0; i < ARRAY_SIZE(srp_opt_tokens); ++i) 1395 + if ((srp_opt_tokens[i].token & SRP_OPT_ALL) && 1396 + !(srp_opt_tokens[i].token & opt_mask)) 1397 + printk(KERN_WARNING PFX "target creation request is " 1398 + "missing parameter '%s'\n", 1399 + srp_opt_tokens[i].pattern); 1400 + 1401 + out: 1402 + kfree(options); 1403 + return ret; 1404 + } 1405 + 1406 + static ssize_t srp_create_target(struct class_device *class_dev, 1407 + const char *buf, size_t count) 1408 + { 1409 + struct srp_host *host = 1410 + container_of(class_dev, struct srp_host, class_dev); 1411 + struct Scsi_Host *target_host; 1412 + struct srp_target_port *target; 1413 + int ret; 1414 + int i; 1415 + 1416 + target_host = scsi_host_alloc(&srp_template, 1417 + sizeof (struct srp_target_port)); 1418 + if (!target_host) 1419 + return -ENOMEM; 1420 + 1421 + target = host_to_target(target_host); 1422 + memset(target, 0, sizeof *target); 1423 + 1424 + target->scsi_host = target_host; 1425 + target->srp_host = host; 1426 + 1427 + INIT_WORK(&target->work, srp_reconnect_work, target); 1428 + 1429 + for (i = 0; i < SRP_SQ_SIZE - 1; ++i) 1430 + target->req_ring[i].next = i + 1; 1431 + target->req_ring[SRP_SQ_SIZE - 1].next = -1; 1432 + INIT_LIST_HEAD(&target->req_queue); 1433 + 1434 + ret = srp_parse_options(buf, target); 1435 + if (ret) 1436 + goto err; 1437 + 1438 + ib_get_cached_gid(host->dev, host->port, 0, &target->path.sgid); 1439 + 1440 + printk(KERN_DEBUG PFX "new target: id_ext %016llx ioc_guid %016llx pkey %04x " 1441 + "service_id %016llx dgid %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", 1442 + (unsigned long long) be64_to_cpu(target->id_ext), 1443 + (unsigned long long) be64_to_cpu(target->ioc_guid), 1444 + be16_to_cpu(target->path.pkey), 1445 + (unsigned long long) be64_to_cpu(target->service_id), 1446 + (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[0]), 1447 + (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[2]), 1448 + (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[4]), 1449 + (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[6]), 1450 + (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[8]), 1451 + (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[10]), 1452 + (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[12]), 1453 + (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[14])); 1454 + 1455 + ret = srp_create_target_ib(target); 1456 + if (ret) 1457 + goto err; 1458 + 1459 + target->cm_id = ib_create_cm_id(host->dev, srp_cm_handler, target); 1460 + if (IS_ERR(target->cm_id)) { 1461 + ret = PTR_ERR(target->cm_id); 1462 + goto err_free; 1463 + } 1464 + 1465 + ret = srp_connect_target(target); 1466 + if (ret) { 1467 + printk(KERN_ERR PFX "Connection failed\n"); 1468 + goto err_cm_id; 1469 + } 1470 + 1471 + ret = srp_add_target(host, target); 1472 + if (ret) 1473 + goto err_disconnect; 1474 + 1475 + return count; 1476 + 1477 + err_disconnect: 1478 + srp_disconnect_target(target); 1479 + 1480 + err_cm_id: 1481 + ib_destroy_cm_id(target->cm_id); 1482 + 1483 + err_free: 1484 + srp_free_target_ib(target); 1485 + 1486 + err: 1487 + scsi_host_put(target_host); 1488 + 1489 + return ret; 1490 + } 1491 + 1492 + static CLASS_DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target); 1493 + 1494 + static ssize_t show_ibdev(struct class_device *class_dev, char *buf) 1495 + { 1496 + struct srp_host *host = 1497 + container_of(class_dev, struct srp_host, class_dev); 1498 + 1499 + return sprintf(buf, "%s\n", host->dev->name); 1500 + } 1501 + 1502 + static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); 1503 + 1504 + static ssize_t show_port(struct class_device *class_dev, char *buf) 1505 + { 1506 + struct srp_host *host = 1507 + container_of(class_dev, struct srp_host, class_dev); 1508 + 1509 + return sprintf(buf, "%d\n", host->port); 1510 + } 1511 + 1512 + static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); 1513 + 1514 + static struct srp_host *srp_add_port(struct ib_device *device, 1515 + __be64 node_guid, u8 port) 1516 + { 1517 + struct srp_host *host; 1518 + 1519 + host = kzalloc(sizeof *host, GFP_KERNEL); 1520 + if (!host) 1521 + return NULL; 1522 + 1523 + INIT_LIST_HEAD(&host->target_list); 1524 + init_MUTEX(&host->target_mutex); 1525 + init_completion(&host->released); 1526 + host->dev = device; 1527 + host->port = port; 1528 + 1529 + host->initiator_port_id[7] = port; 1530 + memcpy(host->initiator_port_id + 8, &node_guid, 8); 1531 + 1532 + host->pd = ib_alloc_pd(device); 1533 + if (IS_ERR(host->pd)) 1534 + goto err_free; 1535 + 1536 + host->mr = ib_get_dma_mr(host->pd, 1537 + IB_ACCESS_LOCAL_WRITE | 1538 + IB_ACCESS_REMOTE_READ | 1539 + IB_ACCESS_REMOTE_WRITE); 1540 + if (IS_ERR(host->mr)) 1541 + goto err_pd; 1542 + 1543 + host->class_dev.class = &srp_class; 1544 + host->class_dev.dev = device->dma_device; 1545 + snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d", 1546 + device->name, port); 1547 + 1548 + if (class_device_register(&host->class_dev)) 1549 + goto err_mr; 1550 + if (class_device_create_file(&host->class_dev, &class_device_attr_add_target)) 1551 + goto err_class; 1552 + if (class_device_create_file(&host->class_dev, &class_device_attr_ibdev)) 1553 + goto err_class; 1554 + if (class_device_create_file(&host->class_dev, &class_device_attr_port)) 1555 + goto err_class; 1556 + 1557 + return host; 1558 + 1559 + err_class: 1560 + class_device_unregister(&host->class_dev); 1561 + 1562 + err_mr: 1563 + ib_dereg_mr(host->mr); 1564 + 1565 + err_pd: 1566 + ib_dealloc_pd(host->pd); 1567 + 1568 + err_free: 1569 + kfree(host); 1570 + 1571 + return NULL; 1572 + } 1573 + 1574 + static void srp_add_one(struct ib_device *device) 1575 + { 1576 + struct list_head *dev_list; 1577 + struct srp_host *host; 1578 + struct ib_device_attr *dev_attr; 1579 + int s, e, p; 1580 + 1581 + dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL); 1582 + if (!dev_attr) 1583 + return; 1584 + 1585 + if (ib_query_device(device, dev_attr)) { 1586 + printk(KERN_WARNING PFX "Couldn't query node GUID for %s.\n", 1587 + device->name); 1588 + goto out; 1589 + } 1590 + 1591 + dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL); 1592 + if (!dev_list) 1593 + goto out; 1594 + 1595 + INIT_LIST_HEAD(dev_list); 1596 + 1597 + if (device->node_type == IB_NODE_SWITCH) { 1598 + s = 0; 1599 + e = 0; 1600 + } else { 1601 + s = 1; 1602 + e = device->phys_port_cnt; 1603 + } 1604 + 1605 + for (p = s; p <= e; ++p) { 1606 + host = srp_add_port(device, dev_attr->node_guid, p); 1607 + if (host) 1608 + list_add_tail(&host->list, dev_list); 1609 + } 1610 + 1611 + ib_set_client_data(device, &srp_client, dev_list); 1612 + 1613 + out: 1614 + kfree(dev_attr); 1615 + } 1616 + 1617 + static void srp_remove_one(struct ib_device *device) 1618 + { 1619 + struct list_head *dev_list; 1620 + struct srp_host *host, *tmp_host; 1621 + LIST_HEAD(target_list); 1622 + struct srp_target_port *target, *tmp_target; 1623 + unsigned long flags; 1624 + 1625 + dev_list = ib_get_client_data(device, &srp_client); 1626 + 1627 + list_for_each_entry_safe(host, tmp_host, dev_list, list) { 1628 + class_device_unregister(&host->class_dev); 1629 + /* 1630 + * Wait for the sysfs entry to go away, so that no new 1631 + * target ports can be created. 1632 + */ 1633 + wait_for_completion(&host->released); 1634 + 1635 + /* 1636 + * Mark all target ports as removed, so we stop queueing 1637 + * commands and don't try to reconnect. 1638 + */ 1639 + down(&host->target_mutex); 1640 + list_for_each_entry_safe(target, tmp_target, 1641 + &host->target_list, list) { 1642 + spin_lock_irqsave(target->scsi_host->host_lock, flags); 1643 + if (target->state != SRP_TARGET_REMOVED) 1644 + target->state = SRP_TARGET_REMOVED; 1645 + spin_unlock_irqrestore(target->scsi_host->host_lock, flags); 1646 + } 1647 + up(&host->target_mutex); 1648 + 1649 + /* 1650 + * Wait for any reconnection tasks that may have 1651 + * started before we marked our target ports as 1652 + * removed, and any target port removal tasks. 1653 + */ 1654 + flush_scheduled_work(); 1655 + 1656 + list_for_each_entry_safe(target, tmp_target, 1657 + &host->target_list, list) { 1658 + scsi_remove_host(target->scsi_host); 1659 + srp_disconnect_target(target); 1660 + ib_destroy_cm_id(target->cm_id); 1661 + srp_free_target_ib(target); 1662 + scsi_host_put(target->scsi_host); 1663 + } 1664 + 1665 + ib_dereg_mr(host->mr); 1666 + ib_dealloc_pd(host->pd); 1667 + kfree(host); 1668 + } 1669 + 1670 + kfree(dev_list); 1671 + } 1672 + 1673 + static int __init srp_init_module(void) 1674 + { 1675 + int ret; 1676 + 1677 + ret = class_register(&srp_class); 1678 + if (ret) { 1679 + printk(KERN_ERR PFX "couldn't register class infiniband_srp\n"); 1680 + return ret; 1681 + } 1682 + 1683 + ret = ib_register_client(&srp_client); 1684 + if (ret) { 1685 + printk(KERN_ERR PFX "couldn't register IB client\n"); 1686 + class_unregister(&srp_class); 1687 + return ret; 1688 + } 1689 + 1690 + return 0; 1691 + } 1692 + 1693 + static void __exit srp_cleanup_module(void) 1694 + { 1695 + ib_unregister_client(&srp_client); 1696 + class_unregister(&srp_class); 1697 + } 1698 + 1699 + module_init(srp_init_module); 1700 + module_exit(srp_cleanup_module);
+150
drivers/infiniband/ulp/srp/ib_srp.h
··· 1 + /* 2 + * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + * 32 + * $Id: ib_srp.h 3932 2005-11-01 17:19:29Z roland $ 33 + */ 34 + 35 + #ifndef IB_SRP_H 36 + #define IB_SRP_H 37 + 38 + #include <linux/types.h> 39 + #include <linux/list.h> 40 + 41 + #include <asm/semaphore.h> 42 + 43 + #include <scsi/scsi_host.h> 44 + #include <scsi/scsi_cmnd.h> 45 + 46 + #include <rdma/ib_verbs.h> 47 + #include <rdma/ib_sa.h> 48 + #include <rdma/ib_cm.h> 49 + 50 + enum { 51 + SRP_PATH_REC_TIMEOUT_MS = 1000, 52 + SRP_ABORT_TIMEOUT_MS = 5000, 53 + 54 + SRP_PORT_REDIRECT = 1, 55 + SRP_DLID_REDIRECT = 2, 56 + 57 + SRP_MAX_IU_LEN = 256, 58 + 59 + SRP_RQ_SHIFT = 6, 60 + SRP_RQ_SIZE = 1 << SRP_RQ_SHIFT, 61 + SRP_SQ_SIZE = SRP_RQ_SIZE - 1, 62 + SRP_CQ_SIZE = SRP_SQ_SIZE + SRP_RQ_SIZE, 63 + 64 + SRP_TAG_TSK_MGMT = 1 << (SRP_RQ_SHIFT + 1) 65 + }; 66 + 67 + #define SRP_OP_RECV (1 << 31) 68 + #define SRP_MAX_INDIRECT ((SRP_MAX_IU_LEN - \ 69 + sizeof (struct srp_cmd) - \ 70 + sizeof (struct srp_indirect_buf)) / 16) 71 + 72 + enum srp_target_state { 73 + SRP_TARGET_LIVE, 74 + SRP_TARGET_CONNECTING, 75 + SRP_TARGET_DEAD, 76 + SRP_TARGET_REMOVED 77 + }; 78 + 79 + struct srp_host { 80 + u8 initiator_port_id[16]; 81 + struct ib_device *dev; 82 + u8 port; 83 + struct ib_pd *pd; 84 + struct ib_mr *mr; 85 + struct class_device class_dev; 86 + struct list_head target_list; 87 + struct semaphore target_mutex; 88 + struct completion released; 89 + struct list_head list; 90 + }; 91 + 92 + struct srp_request { 93 + struct list_head list; 94 + struct scsi_cmnd *scmnd; 95 + struct srp_iu *cmd; 96 + struct srp_iu *tsk_mgmt; 97 + DECLARE_PCI_UNMAP_ADDR(direct_mapping) 98 + struct completion done; 99 + short next; 100 + u8 cmd_done; 101 + u8 tsk_status; 102 + }; 103 + 104 + struct srp_target_port { 105 + __be64 id_ext; 106 + __be64 ioc_guid; 107 + __be64 service_id; 108 + struct srp_host *srp_host; 109 + struct Scsi_Host *scsi_host; 110 + char target_name[32]; 111 + unsigned int scsi_id; 112 + 113 + struct ib_sa_path_rec path; 114 + struct ib_sa_query *path_query; 115 + int path_query_id; 116 + 117 + struct ib_cm_id *cm_id; 118 + struct ib_cq *cq; 119 + struct ib_qp *qp; 120 + 121 + int max_ti_iu_len; 122 + s32 req_lim; 123 + 124 + unsigned rx_head; 125 + struct srp_iu *rx_ring[SRP_RQ_SIZE]; 126 + 127 + unsigned tx_head; 128 + unsigned tx_tail; 129 + struct srp_iu *tx_ring[SRP_SQ_SIZE + 1]; 130 + 131 + int req_head; 132 + struct list_head req_queue; 133 + struct srp_request req_ring[SRP_SQ_SIZE]; 134 + 135 + struct work_struct work; 136 + 137 + struct list_head list; 138 + struct completion done; 139 + int status; 140 + enum srp_target_state state; 141 + }; 142 + 143 + struct srp_iu { 144 + dma_addr_t dma; 145 + void *buf; 146 + size_t size; 147 + enum dma_data_direction direction; 148 + }; 149 + 150 + #endif /* IB_SRP_H */
+226
include/scsi/srp.h
··· 1 + /* 2 + * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + * 32 + * $Id$ 33 + */ 34 + 35 + #ifndef SCSI_SRP_H 36 + #define SCSI_SRP_H 37 + 38 + /* 39 + * Structures and constants for the SCSI RDMA Protocol (SRP) as 40 + * defined by the INCITS T10 committee. This file was written using 41 + * draft Revision 16a of the SRP standard. 42 + */ 43 + 44 + #include <linux/types.h> 45 + 46 + enum { 47 + SRP_LOGIN_REQ = 0x00, 48 + SRP_TSK_MGMT = 0x01, 49 + SRP_CMD = 0x02, 50 + SRP_I_LOGOUT = 0x03, 51 + SRP_LOGIN_RSP = 0xc0, 52 + SRP_RSP = 0xc1, 53 + SRP_LOGIN_REJ = 0xc2, 54 + SRP_T_LOGOUT = 0x80, 55 + SRP_CRED_REQ = 0x81, 56 + SRP_AER_REQ = 0x82, 57 + SRP_CRED_RSP = 0x41, 58 + SRP_AER_RSP = 0x42 59 + }; 60 + 61 + enum { 62 + SRP_BUF_FORMAT_DIRECT = 1 << 1, 63 + SRP_BUF_FORMAT_INDIRECT = 1 << 2 64 + }; 65 + 66 + enum { 67 + SRP_NO_DATA_DESC = 0, 68 + SRP_DATA_DESC_DIRECT = 1, 69 + SRP_DATA_DESC_INDIRECT = 2 70 + }; 71 + 72 + enum { 73 + SRP_TSK_ABORT_TASK = 0x01, 74 + SRP_TSK_ABORT_TASK_SET = 0x02, 75 + SRP_TSK_CLEAR_TASK_SET = 0x04, 76 + SRP_TSK_LUN_RESET = 0x08, 77 + SRP_TSK_CLEAR_ACA = 0x40 78 + }; 79 + 80 + enum srp_login_rej_reason { 81 + SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL = 0x00010000, 82 + SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES = 0x00010001, 83 + SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE = 0x00010002, 84 + SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL = 0x00010003, 85 + SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT = 0x00010004, 86 + SRP_LOGIN_REJ_MULTI_CHANNEL_UNSUPPORTED = 0x00010005, 87 + SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED = 0x00010006 88 + }; 89 + 90 + struct srp_direct_buf { 91 + __be64 va; 92 + __be32 key; 93 + __be32 len; 94 + }; 95 + 96 + /* 97 + * We need the packed attribute because the SRP spec puts the list of 98 + * descriptors at an offset of 20, which is not aligned to the size 99 + * of struct srp_direct_buf. 100 + */ 101 + struct srp_indirect_buf { 102 + struct srp_direct_buf table_desc; 103 + __be32 len; 104 + struct srp_direct_buf desc_list[0] __attribute__((packed)); 105 + }; 106 + 107 + enum { 108 + SRP_MULTICHAN_SINGLE = 0, 109 + SRP_MULTICHAN_MULTI = 1 110 + }; 111 + 112 + struct srp_login_req { 113 + u8 opcode; 114 + u8 reserved1[7]; 115 + u64 tag; 116 + __be32 req_it_iu_len; 117 + u8 reserved2[4]; 118 + __be16 req_buf_fmt; 119 + u8 req_flags; 120 + u8 reserved3[5]; 121 + u8 initiator_port_id[16]; 122 + u8 target_port_id[16]; 123 + }; 124 + 125 + struct srp_login_rsp { 126 + u8 opcode; 127 + u8 reserved1[3]; 128 + __be32 req_lim_delta; 129 + u64 tag; 130 + __be32 max_it_iu_len; 131 + __be32 max_ti_iu_len; 132 + __be16 buf_fmt; 133 + u8 rsp_flags; 134 + u8 reserved2[25]; 135 + }; 136 + 137 + struct srp_login_rej { 138 + u8 opcode; 139 + u8 reserved1[3]; 140 + __be32 reason; 141 + u64 tag; 142 + u8 reserved2[8]; 143 + __be16 buf_fmt; 144 + u8 reserved3[6]; 145 + }; 146 + 147 + struct srp_i_logout { 148 + u8 opcode; 149 + u8 reserved[7]; 150 + u64 tag; 151 + }; 152 + 153 + struct srp_t_logout { 154 + u8 opcode; 155 + u8 sol_not; 156 + u8 reserved[2]; 157 + __be32 reason; 158 + u64 tag; 159 + }; 160 + 161 + /* 162 + * We need the packed attribute because the SRP spec only aligns the 163 + * 8-byte LUN field to 4 bytes. 164 + */ 165 + struct srp_tsk_mgmt { 166 + u8 opcode; 167 + u8 sol_not; 168 + u8 reserved1[6]; 169 + u64 tag; 170 + u8 reserved2[4]; 171 + __be64 lun __attribute__((packed)); 172 + u8 reserved3[2]; 173 + u8 tsk_mgmt_func; 174 + u8 reserved4; 175 + u64 task_tag; 176 + u8 reserved5[8]; 177 + }; 178 + 179 + /* 180 + * We need the packed attribute because the SRP spec only aligns the 181 + * 8-byte LUN field to 4 bytes. 182 + */ 183 + struct srp_cmd { 184 + u8 opcode; 185 + u8 sol_not; 186 + u8 reserved1[3]; 187 + u8 buf_fmt; 188 + u8 data_out_desc_cnt; 189 + u8 data_in_desc_cnt; 190 + u64 tag; 191 + u8 reserved2[4]; 192 + __be64 lun __attribute__((packed)); 193 + u8 reserved3; 194 + u8 task_attr; 195 + u8 reserved4; 196 + u8 add_cdb_len; 197 + u8 cdb[16]; 198 + u8 add_data[0]; 199 + }; 200 + 201 + enum { 202 + SRP_RSP_FLAG_RSPVALID = 1 << 0, 203 + SRP_RSP_FLAG_SNSVALID = 1 << 1, 204 + SRP_RSP_FLAG_DOOVER = 1 << 2, 205 + SRP_RSP_FLAG_DOUNDER = 1 << 3, 206 + SRP_RSP_FLAG_DIOVER = 1 << 4, 207 + SRP_RSP_FLAG_DIUNDER = 1 << 5 208 + }; 209 + 210 + struct srp_rsp { 211 + u8 opcode; 212 + u8 sol_not; 213 + u8 reserved1[2]; 214 + __be32 req_lim_delta; 215 + u64 tag; 216 + u8 reserved2[2]; 217 + u8 flags; 218 + u8 status; 219 + __be32 data_out_res_cnt; 220 + __be32 data_in_res_cnt; 221 + __be32 sense_data_len; 222 + __be32 resp_data_len; 223 + u8 data[0]; 224 + }; 225 + 226 + #endif /* SCSI_SRP_H */