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