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> 42de25968cSTim Schmielau #include <linux/jiffies.h> 43aef9ec39SRoland Dreier 44aef9ec39SRoland Dreier #include <asm/atomic.h> 45aef9ec39SRoland Dreier 46aef9ec39SRoland Dreier #include <scsi/scsi.h> 47aef9ec39SRoland Dreier #include <scsi/scsi_device.h> 48aef9ec39SRoland Dreier #include <scsi/scsi_dbg.h> 49aef9ec39SRoland Dreier #include <scsi/srp.h> 50aef9ec39SRoland Dreier 51aef9ec39SRoland Dreier #include <rdma/ib_cache.h> 52aef9ec39SRoland Dreier 53aef9ec39SRoland Dreier #include "ib_srp.h" 54aef9ec39SRoland Dreier 55aef9ec39SRoland Dreier #define DRV_NAME "ib_srp" 56aef9ec39SRoland Dreier #define PFX DRV_NAME ": " 57aef9ec39SRoland Dreier #define DRV_VERSION "0.2" 58aef9ec39SRoland Dreier #define DRV_RELDATE "November 1, 2005" 59aef9ec39SRoland Dreier 60aef9ec39SRoland Dreier MODULE_AUTHOR("Roland Dreier"); 61aef9ec39SRoland Dreier MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator " 62aef9ec39SRoland Dreier "v" DRV_VERSION " (" DRV_RELDATE ")"); 63aef9ec39SRoland Dreier MODULE_LICENSE("Dual BSD/GPL"); 64aef9ec39SRoland Dreier 6574b0a15bSVu Pham static int srp_sg_tablesize = SRP_DEF_SG_TABLESIZE; 6674b0a15bSVu Pham static int srp_max_iu_len; 6774b0a15bSVu Pham 6874b0a15bSVu Pham module_param(srp_sg_tablesize, int, 0444); 6974b0a15bSVu Pham MODULE_PARM_DESC(srp_sg_tablesize, 7074b0a15bSVu Pham "Max number of gather/scatter entries per I/O (default is 12)"); 7174b0a15bSVu Pham 72aef9ec39SRoland Dreier static int topspin_workarounds = 1; 73aef9ec39SRoland Dreier 74aef9ec39SRoland Dreier module_param(topspin_workarounds, int, 0444); 75aef9ec39SRoland Dreier MODULE_PARM_DESC(topspin_workarounds, 76aef9ec39SRoland Dreier "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); 77aef9ec39SRoland Dreier 78aef9ec39SRoland Dreier static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; 79aef9ec39SRoland Dreier 80559ce8f1SIshai Rabinovitz static int mellanox_workarounds = 1; 81559ce8f1SIshai Rabinovitz 82559ce8f1SIshai Rabinovitz module_param(mellanox_workarounds, int, 0444); 83559ce8f1SIshai Rabinovitz MODULE_PARM_DESC(mellanox_workarounds, 84559ce8f1SIshai Rabinovitz "Enable workarounds for Mellanox SRP target bugs if != 0"); 85559ce8f1SIshai Rabinovitz 86559ce8f1SIshai Rabinovitz static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; 87559ce8f1SIshai Rabinovitz 88aef9ec39SRoland Dreier static void srp_add_one(struct ib_device *device); 89aef9ec39SRoland Dreier static void srp_remove_one(struct ib_device *device); 90aef9ec39SRoland Dreier static void srp_completion(struct ib_cq *cq, void *target_ptr); 91aef9ec39SRoland Dreier static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); 92aef9ec39SRoland Dreier 93aef9ec39SRoland Dreier static struct ib_client srp_client = { 94aef9ec39SRoland Dreier .name = "srp", 95aef9ec39SRoland Dreier .add = srp_add_one, 96aef9ec39SRoland Dreier .remove = srp_remove_one 97aef9ec39SRoland Dreier }; 98aef9ec39SRoland Dreier 99aef9ec39SRoland Dreier static inline struct srp_target_port *host_to_target(struct Scsi_Host *host) 100aef9ec39SRoland Dreier { 101aef9ec39SRoland Dreier return (struct srp_target_port *) host->hostdata; 102aef9ec39SRoland Dreier } 103aef9ec39SRoland Dreier 104aef9ec39SRoland Dreier static const char *srp_target_info(struct Scsi_Host *host) 105aef9ec39SRoland Dreier { 106aef9ec39SRoland Dreier return host_to_target(host)->target_name; 107aef9ec39SRoland Dreier } 108aef9ec39SRoland Dreier 109aef9ec39SRoland Dreier static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, 110aef9ec39SRoland Dreier gfp_t gfp_mask, 111aef9ec39SRoland Dreier enum dma_data_direction direction) 112aef9ec39SRoland Dreier { 113aef9ec39SRoland Dreier struct srp_iu *iu; 114aef9ec39SRoland Dreier 115aef9ec39SRoland Dreier iu = kmalloc(sizeof *iu, gfp_mask); 116aef9ec39SRoland Dreier if (!iu) 117aef9ec39SRoland Dreier goto out; 118aef9ec39SRoland Dreier 119aef9ec39SRoland Dreier iu->buf = kzalloc(size, gfp_mask); 120aef9ec39SRoland Dreier if (!iu->buf) 121aef9ec39SRoland Dreier goto out_free_iu; 122aef9ec39SRoland Dreier 123f5358a17SRoland Dreier iu->dma = dma_map_single(host->dev->dev->dma_device, 124f5358a17SRoland Dreier iu->buf, size, direction); 125aef9ec39SRoland Dreier if (dma_mapping_error(iu->dma)) 126aef9ec39SRoland Dreier goto out_free_buf; 127aef9ec39SRoland Dreier 128aef9ec39SRoland Dreier iu->size = size; 129aef9ec39SRoland Dreier iu->direction = direction; 130aef9ec39SRoland Dreier 131aef9ec39SRoland Dreier return iu; 132aef9ec39SRoland Dreier 133aef9ec39SRoland Dreier out_free_buf: 134aef9ec39SRoland Dreier kfree(iu->buf); 135aef9ec39SRoland Dreier out_free_iu: 136aef9ec39SRoland Dreier kfree(iu); 137aef9ec39SRoland Dreier out: 138aef9ec39SRoland Dreier return NULL; 139aef9ec39SRoland Dreier } 140aef9ec39SRoland Dreier 141aef9ec39SRoland Dreier static void srp_free_iu(struct srp_host *host, struct srp_iu *iu) 142aef9ec39SRoland Dreier { 143aef9ec39SRoland Dreier if (!iu) 144aef9ec39SRoland Dreier return; 145aef9ec39SRoland Dreier 146f5358a17SRoland Dreier dma_unmap_single(host->dev->dev->dma_device, 147f5358a17SRoland Dreier iu->dma, iu->size, iu->direction); 148aef9ec39SRoland Dreier kfree(iu->buf); 149aef9ec39SRoland Dreier kfree(iu); 150aef9ec39SRoland Dreier } 151aef9ec39SRoland Dreier 152aef9ec39SRoland Dreier static void srp_qp_event(struct ib_event *event, void *context) 153aef9ec39SRoland Dreier { 154aef9ec39SRoland Dreier printk(KERN_ERR PFX "QP event %d\n", event->event); 155aef9ec39SRoland Dreier } 156aef9ec39SRoland Dreier 157aef9ec39SRoland Dreier static int srp_init_qp(struct srp_target_port *target, 158aef9ec39SRoland Dreier struct ib_qp *qp) 159aef9ec39SRoland Dreier { 160aef9ec39SRoland Dreier struct ib_qp_attr *attr; 161aef9ec39SRoland Dreier int ret; 162aef9ec39SRoland Dreier 163aef9ec39SRoland Dreier attr = kmalloc(sizeof *attr, GFP_KERNEL); 164aef9ec39SRoland Dreier if (!attr) 165aef9ec39SRoland Dreier return -ENOMEM; 166aef9ec39SRoland Dreier 167f5358a17SRoland Dreier ret = ib_find_cached_pkey(target->srp_host->dev->dev, 168aef9ec39SRoland Dreier target->srp_host->port, 169aef9ec39SRoland Dreier be16_to_cpu(target->path.pkey), 170aef9ec39SRoland Dreier &attr->pkey_index); 171aef9ec39SRoland Dreier if (ret) 172aef9ec39SRoland Dreier goto out; 173aef9ec39SRoland Dreier 174aef9ec39SRoland Dreier attr->qp_state = IB_QPS_INIT; 175aef9ec39SRoland Dreier attr->qp_access_flags = (IB_ACCESS_REMOTE_READ | 176aef9ec39SRoland Dreier IB_ACCESS_REMOTE_WRITE); 177aef9ec39SRoland Dreier attr->port_num = target->srp_host->port; 178aef9ec39SRoland Dreier 179aef9ec39SRoland Dreier ret = ib_modify_qp(qp, attr, 180aef9ec39SRoland Dreier IB_QP_STATE | 181aef9ec39SRoland Dreier IB_QP_PKEY_INDEX | 182aef9ec39SRoland Dreier IB_QP_ACCESS_FLAGS | 183aef9ec39SRoland Dreier IB_QP_PORT); 184aef9ec39SRoland Dreier 185aef9ec39SRoland Dreier out: 186aef9ec39SRoland Dreier kfree(attr); 187aef9ec39SRoland Dreier return ret; 188aef9ec39SRoland Dreier } 189aef9ec39SRoland Dreier 190aef9ec39SRoland Dreier static int srp_create_target_ib(struct srp_target_port *target) 191aef9ec39SRoland Dreier { 192aef9ec39SRoland Dreier struct ib_qp_init_attr *init_attr; 193aef9ec39SRoland Dreier int ret; 194aef9ec39SRoland Dreier 195aef9ec39SRoland Dreier init_attr = kzalloc(sizeof *init_attr, GFP_KERNEL); 196aef9ec39SRoland Dreier if (!init_attr) 197aef9ec39SRoland Dreier return -ENOMEM; 198aef9ec39SRoland Dreier 199f5358a17SRoland Dreier target->cq = ib_create_cq(target->srp_host->dev->dev, srp_completion, 200aef9ec39SRoland Dreier NULL, target, SRP_CQ_SIZE); 201aef9ec39SRoland Dreier if (IS_ERR(target->cq)) { 202aef9ec39SRoland Dreier ret = PTR_ERR(target->cq); 203aef9ec39SRoland Dreier goto out; 204aef9ec39SRoland Dreier } 205aef9ec39SRoland Dreier 206aef9ec39SRoland Dreier ib_req_notify_cq(target->cq, IB_CQ_NEXT_COMP); 207aef9ec39SRoland Dreier 208aef9ec39SRoland Dreier init_attr->event_handler = srp_qp_event; 209aef9ec39SRoland Dreier init_attr->cap.max_send_wr = SRP_SQ_SIZE; 210aef9ec39SRoland Dreier init_attr->cap.max_recv_wr = SRP_RQ_SIZE; 211aef9ec39SRoland Dreier init_attr->cap.max_recv_sge = 1; 212aef9ec39SRoland Dreier init_attr->cap.max_send_sge = 1; 213aef9ec39SRoland Dreier init_attr->sq_sig_type = IB_SIGNAL_ALL_WR; 214aef9ec39SRoland Dreier init_attr->qp_type = IB_QPT_RC; 215aef9ec39SRoland Dreier init_attr->send_cq = target->cq; 216aef9ec39SRoland Dreier init_attr->recv_cq = target->cq; 217aef9ec39SRoland Dreier 218f5358a17SRoland Dreier target->qp = ib_create_qp(target->srp_host->dev->pd, init_attr); 219aef9ec39SRoland Dreier if (IS_ERR(target->qp)) { 220aef9ec39SRoland Dreier ret = PTR_ERR(target->qp); 221aef9ec39SRoland Dreier ib_destroy_cq(target->cq); 222aef9ec39SRoland Dreier goto out; 223aef9ec39SRoland Dreier } 224aef9ec39SRoland Dreier 225aef9ec39SRoland Dreier ret = srp_init_qp(target, target->qp); 226aef9ec39SRoland Dreier if (ret) { 227aef9ec39SRoland Dreier ib_destroy_qp(target->qp); 228aef9ec39SRoland Dreier ib_destroy_cq(target->cq); 229aef9ec39SRoland Dreier goto out; 230aef9ec39SRoland Dreier } 231aef9ec39SRoland Dreier 232aef9ec39SRoland Dreier out: 233aef9ec39SRoland Dreier kfree(init_attr); 234aef9ec39SRoland Dreier return ret; 235aef9ec39SRoland Dreier } 236aef9ec39SRoland Dreier 237aef9ec39SRoland Dreier static void srp_free_target_ib(struct srp_target_port *target) 238aef9ec39SRoland Dreier { 239aef9ec39SRoland Dreier int i; 240aef9ec39SRoland Dreier 241aef9ec39SRoland Dreier ib_destroy_qp(target->qp); 242aef9ec39SRoland Dreier ib_destroy_cq(target->cq); 243aef9ec39SRoland Dreier 244aef9ec39SRoland Dreier for (i = 0; i < SRP_RQ_SIZE; ++i) 245aef9ec39SRoland Dreier srp_free_iu(target->srp_host, target->rx_ring[i]); 246aef9ec39SRoland Dreier for (i = 0; i < SRP_SQ_SIZE + 1; ++i) 247aef9ec39SRoland Dreier srp_free_iu(target->srp_host, target->tx_ring[i]); 248aef9ec39SRoland Dreier } 249aef9ec39SRoland Dreier 250aef9ec39SRoland Dreier static void srp_path_rec_completion(int status, 251aef9ec39SRoland Dreier struct ib_sa_path_rec *pathrec, 252aef9ec39SRoland Dreier void *target_ptr) 253aef9ec39SRoland Dreier { 254aef9ec39SRoland Dreier struct srp_target_port *target = target_ptr; 255aef9ec39SRoland Dreier 256aef9ec39SRoland Dreier target->status = status; 257aef9ec39SRoland Dreier if (status) 258aef9ec39SRoland Dreier printk(KERN_ERR PFX "Got failed path rec status %d\n", status); 259aef9ec39SRoland Dreier else 260aef9ec39SRoland Dreier target->path = *pathrec; 261aef9ec39SRoland Dreier complete(&target->done); 262aef9ec39SRoland Dreier } 263aef9ec39SRoland Dreier 264aef9ec39SRoland Dreier static int srp_lookup_path(struct srp_target_port *target) 265aef9ec39SRoland Dreier { 266aef9ec39SRoland Dreier target->path.numb_path = 1; 267aef9ec39SRoland Dreier 268aef9ec39SRoland Dreier init_completion(&target->done); 269aef9ec39SRoland Dreier 270f5358a17SRoland Dreier target->path_query_id = ib_sa_path_rec_get(target->srp_host->dev->dev, 271aef9ec39SRoland Dreier target->srp_host->port, 272aef9ec39SRoland Dreier &target->path, 273aef9ec39SRoland Dreier IB_SA_PATH_REC_DGID | 274aef9ec39SRoland Dreier IB_SA_PATH_REC_SGID | 275aef9ec39SRoland Dreier IB_SA_PATH_REC_NUMB_PATH | 276aef9ec39SRoland Dreier IB_SA_PATH_REC_PKEY, 277aef9ec39SRoland Dreier SRP_PATH_REC_TIMEOUT_MS, 278aef9ec39SRoland Dreier GFP_KERNEL, 279aef9ec39SRoland Dreier srp_path_rec_completion, 280aef9ec39SRoland Dreier target, &target->path_query); 281aef9ec39SRoland Dreier if (target->path_query_id < 0) 282aef9ec39SRoland Dreier return target->path_query_id; 283aef9ec39SRoland Dreier 284aef9ec39SRoland Dreier wait_for_completion(&target->done); 285aef9ec39SRoland Dreier 286aef9ec39SRoland Dreier if (target->status < 0) 287aef9ec39SRoland Dreier printk(KERN_WARNING PFX "Path record query failed\n"); 288aef9ec39SRoland Dreier 289aef9ec39SRoland Dreier return target->status; 290aef9ec39SRoland Dreier } 291aef9ec39SRoland Dreier 292aef9ec39SRoland Dreier static int srp_send_req(struct srp_target_port *target) 293aef9ec39SRoland Dreier { 294aef9ec39SRoland Dreier struct { 295aef9ec39SRoland Dreier struct ib_cm_req_param param; 296aef9ec39SRoland Dreier struct srp_login_req priv; 297aef9ec39SRoland Dreier } *req = NULL; 298aef9ec39SRoland Dreier int status; 299aef9ec39SRoland Dreier 300aef9ec39SRoland Dreier req = kzalloc(sizeof *req, GFP_KERNEL); 301aef9ec39SRoland Dreier if (!req) 302aef9ec39SRoland Dreier return -ENOMEM; 303aef9ec39SRoland Dreier 304aef9ec39SRoland Dreier req->param.primary_path = &target->path; 305aef9ec39SRoland Dreier req->param.alternate_path = NULL; 306aef9ec39SRoland Dreier req->param.service_id = target->service_id; 307aef9ec39SRoland Dreier req->param.qp_num = target->qp->qp_num; 308aef9ec39SRoland Dreier req->param.qp_type = target->qp->qp_type; 309aef9ec39SRoland Dreier req->param.private_data = &req->priv; 310aef9ec39SRoland Dreier req->param.private_data_len = sizeof req->priv; 311aef9ec39SRoland Dreier req->param.flow_control = 1; 312aef9ec39SRoland Dreier 313aef9ec39SRoland Dreier get_random_bytes(&req->param.starting_psn, 4); 314aef9ec39SRoland Dreier req->param.starting_psn &= 0xffffff; 315aef9ec39SRoland Dreier 316aef9ec39SRoland Dreier /* 317aef9ec39SRoland Dreier * Pick some arbitrary defaults here; we could make these 318aef9ec39SRoland Dreier * module parameters if anyone cared about setting them. 319aef9ec39SRoland Dreier */ 320aef9ec39SRoland Dreier req->param.responder_resources = 4; 321aef9ec39SRoland Dreier req->param.remote_cm_response_timeout = 20; 322aef9ec39SRoland Dreier req->param.local_cm_response_timeout = 20; 323aef9ec39SRoland Dreier req->param.retry_count = 7; 324aef9ec39SRoland Dreier req->param.rnr_retry_count = 7; 325aef9ec39SRoland Dreier req->param.max_cm_retries = 15; 326aef9ec39SRoland Dreier 327aef9ec39SRoland Dreier req->priv.opcode = SRP_LOGIN_REQ; 328aef9ec39SRoland Dreier req->priv.tag = 0; 32974b0a15bSVu Pham req->priv.req_it_iu_len = cpu_to_be32(srp_max_iu_len); 330aef9ec39SRoland Dreier req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | 331aef9ec39SRoland Dreier SRP_BUF_FORMAT_INDIRECT); 3320c0450dbSRamachandra K /* 3330c0450dbSRamachandra K * In the published SRP specification (draft rev. 16a), the 3340c0450dbSRamachandra K * port identifier format is 8 bytes of ID extension followed 3350c0450dbSRamachandra K * by 8 bytes of GUID. Older drafts put the two halves in the 3360c0450dbSRamachandra K * opposite order, so that the GUID comes first. 3370c0450dbSRamachandra K * 3380c0450dbSRamachandra K * Targets conforming to these obsolete drafts can be 3390c0450dbSRamachandra K * recognized by the I/O Class they report. 3400c0450dbSRamachandra K */ 3410c0450dbSRamachandra K if (target->io_class == SRP_REV10_IB_IO_CLASS) { 3420c0450dbSRamachandra K memcpy(req->priv.initiator_port_id, 3430c0450dbSRamachandra K target->srp_host->initiator_port_id + 8, 8); 3440c0450dbSRamachandra K memcpy(req->priv.initiator_port_id + 8, 3450c0450dbSRamachandra K target->srp_host->initiator_port_id, 8); 3460c0450dbSRamachandra K memcpy(req->priv.target_port_id, &target->ioc_guid, 8); 3470c0450dbSRamachandra K memcpy(req->priv.target_port_id + 8, &target->id_ext, 8); 3480c0450dbSRamachandra K } else { 3490c0450dbSRamachandra K memcpy(req->priv.initiator_port_id, 3500c0450dbSRamachandra K target->srp_host->initiator_port_id, 16); 3510c0450dbSRamachandra K memcpy(req->priv.target_port_id, &target->id_ext, 8); 3520c0450dbSRamachandra K memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8); 3530c0450dbSRamachandra K } 3540c0450dbSRamachandra K 355aef9ec39SRoland Dreier /* 356aef9ec39SRoland Dreier * Topspin/Cisco SRP targets will reject our login unless we 357aef9ec39SRoland Dreier * zero out the first 8 bytes of our initiator port ID. The 358aef9ec39SRoland Dreier * second 8 bytes must be our local node GUID, but we always 359aef9ec39SRoland Dreier * use that anyway. 360aef9ec39SRoland Dreier */ 361aef9ec39SRoland Dreier if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) { 362aef9ec39SRoland Dreier printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " 363aef9ec39SRoland Dreier "activated for target GUID %016llx\n", 364aef9ec39SRoland Dreier (unsigned long long) be64_to_cpu(target->ioc_guid)); 365aef9ec39SRoland Dreier memset(req->priv.initiator_port_id, 0, 8); 366aef9ec39SRoland Dreier } 367aef9ec39SRoland Dreier 368aef9ec39SRoland Dreier status = ib_send_cm_req(target->cm_id, &req->param); 369aef9ec39SRoland Dreier 370aef9ec39SRoland Dreier kfree(req); 371aef9ec39SRoland Dreier 372aef9ec39SRoland Dreier return status; 373aef9ec39SRoland Dreier } 374aef9ec39SRoland Dreier 375aef9ec39SRoland Dreier static void srp_disconnect_target(struct srp_target_port *target) 376aef9ec39SRoland Dreier { 377aef9ec39SRoland Dreier /* XXX should send SRP_I_LOGOUT request */ 378aef9ec39SRoland Dreier 379aef9ec39SRoland Dreier init_completion(&target->done); 380e6581056SRoland Dreier if (ib_send_cm_dreq(target->cm_id, NULL, 0)) { 381e6581056SRoland Dreier printk(KERN_DEBUG PFX "Sending CM DREQ failed\n"); 382e6581056SRoland Dreier return; 383e6581056SRoland Dreier } 384aef9ec39SRoland Dreier wait_for_completion(&target->done); 385aef9ec39SRoland Dreier } 386aef9ec39SRoland Dreier 387aef9ec39SRoland Dreier static void srp_remove_work(void *target_ptr) 388aef9ec39SRoland Dreier { 389aef9ec39SRoland Dreier struct srp_target_port *target = target_ptr; 390aef9ec39SRoland Dreier 391aef9ec39SRoland Dreier spin_lock_irq(target->scsi_host->host_lock); 392aef9ec39SRoland Dreier if (target->state != SRP_TARGET_DEAD) { 393aef9ec39SRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 394aef9ec39SRoland Dreier return; 395aef9ec39SRoland Dreier } 396aef9ec39SRoland Dreier target->state = SRP_TARGET_REMOVED; 397aef9ec39SRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 398aef9ec39SRoland Dreier 399b3589fd4SMatthew Wilcox spin_lock(&target->srp_host->target_lock); 400aef9ec39SRoland Dreier list_del(&target->list); 401b3589fd4SMatthew Wilcox spin_unlock(&target->srp_host->target_lock); 402aef9ec39SRoland Dreier 403aef9ec39SRoland Dreier scsi_remove_host(target->scsi_host); 404aef9ec39SRoland Dreier ib_destroy_cm_id(target->cm_id); 405aef9ec39SRoland Dreier srp_free_target_ib(target); 406aef9ec39SRoland Dreier scsi_host_put(target->scsi_host); 407aef9ec39SRoland Dreier } 408aef9ec39SRoland Dreier 409aef9ec39SRoland Dreier static int srp_connect_target(struct srp_target_port *target) 410aef9ec39SRoland Dreier { 411aef9ec39SRoland Dreier int ret; 412aef9ec39SRoland Dreier 413aef9ec39SRoland Dreier ret = srp_lookup_path(target); 414aef9ec39SRoland Dreier if (ret) 415aef9ec39SRoland Dreier return ret; 416aef9ec39SRoland Dreier 417aef9ec39SRoland Dreier while (1) { 418aef9ec39SRoland Dreier init_completion(&target->done); 419aef9ec39SRoland Dreier ret = srp_send_req(target); 420aef9ec39SRoland Dreier if (ret) 421aef9ec39SRoland Dreier return ret; 422aef9ec39SRoland Dreier wait_for_completion(&target->done); 423aef9ec39SRoland Dreier 424aef9ec39SRoland Dreier /* 425aef9ec39SRoland Dreier * The CM event handling code will set status to 426aef9ec39SRoland Dreier * SRP_PORT_REDIRECT if we get a port redirect REJ 427aef9ec39SRoland Dreier * back, or SRP_DLID_REDIRECT if we get a lid/qp 428aef9ec39SRoland Dreier * redirect REJ back. 429aef9ec39SRoland Dreier */ 430aef9ec39SRoland Dreier switch (target->status) { 431aef9ec39SRoland Dreier case 0: 432aef9ec39SRoland Dreier return 0; 433aef9ec39SRoland Dreier 434aef9ec39SRoland Dreier case SRP_PORT_REDIRECT: 435aef9ec39SRoland Dreier ret = srp_lookup_path(target); 436aef9ec39SRoland Dreier if (ret) 437aef9ec39SRoland Dreier return ret; 438aef9ec39SRoland Dreier break; 439aef9ec39SRoland Dreier 440aef9ec39SRoland Dreier case SRP_DLID_REDIRECT: 441aef9ec39SRoland Dreier break; 442aef9ec39SRoland Dreier 443aef9ec39SRoland Dreier default: 444aef9ec39SRoland Dreier return target->status; 445aef9ec39SRoland Dreier } 446aef9ec39SRoland Dreier } 447aef9ec39SRoland Dreier } 448aef9ec39SRoland Dreier 449d945e1dfSRoland Dreier static void srp_unmap_data(struct scsi_cmnd *scmnd, 450d945e1dfSRoland Dreier struct srp_target_port *target, 451d945e1dfSRoland Dreier struct srp_request *req) 452d945e1dfSRoland Dreier { 453d945e1dfSRoland Dreier struct scatterlist *scat; 454d945e1dfSRoland Dreier int nents; 455d945e1dfSRoland Dreier 456d945e1dfSRoland Dreier if (!scmnd->request_buffer || 457d945e1dfSRoland Dreier (scmnd->sc_data_direction != DMA_TO_DEVICE && 458d945e1dfSRoland Dreier scmnd->sc_data_direction != DMA_FROM_DEVICE)) 459d945e1dfSRoland Dreier return; 460d945e1dfSRoland Dreier 461f5358a17SRoland Dreier if (req->fmr) { 462f5358a17SRoland Dreier ib_fmr_pool_unmap(req->fmr); 463f5358a17SRoland Dreier req->fmr = NULL; 464f5358a17SRoland Dreier } 465f5358a17SRoland Dreier 466d945e1dfSRoland Dreier /* 467d945e1dfSRoland Dreier * This handling of non-SG commands can be killed when the 468d945e1dfSRoland Dreier * SCSI midlayer no longer generates non-SG commands. 469d945e1dfSRoland Dreier */ 470d945e1dfSRoland Dreier if (likely(scmnd->use_sg)) { 471d945e1dfSRoland Dreier nents = scmnd->use_sg; 472d945e1dfSRoland Dreier scat = scmnd->request_buffer; 473d945e1dfSRoland Dreier } else { 474d945e1dfSRoland Dreier nents = 1; 475d945e1dfSRoland Dreier scat = &req->fake_sg; 476d945e1dfSRoland Dreier } 477d945e1dfSRoland Dreier 478f5358a17SRoland Dreier dma_unmap_sg(target->srp_host->dev->dev->dma_device, scat, nents, 479d945e1dfSRoland Dreier scmnd->sc_data_direction); 480d945e1dfSRoland Dreier } 481d945e1dfSRoland Dreier 482526b4caaSIshai Rabinovitz static void srp_remove_req(struct srp_target_port *target, struct srp_request *req) 483526b4caaSIshai Rabinovitz { 484526b4caaSIshai Rabinovitz srp_unmap_data(req->scmnd, target, req); 485526b4caaSIshai Rabinovitz list_move_tail(&req->list, &target->free_reqs); 486526b4caaSIshai Rabinovitz } 487526b4caaSIshai Rabinovitz 488526b4caaSIshai Rabinovitz static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) 489526b4caaSIshai Rabinovitz { 490526b4caaSIshai Rabinovitz req->scmnd->result = DID_RESET << 16; 491526b4caaSIshai Rabinovitz req->scmnd->scsi_done(req->scmnd); 492526b4caaSIshai Rabinovitz srp_remove_req(target, req); 493526b4caaSIshai Rabinovitz } 494526b4caaSIshai Rabinovitz 495aef9ec39SRoland Dreier static int srp_reconnect_target(struct srp_target_port *target) 496aef9ec39SRoland Dreier { 497aef9ec39SRoland Dreier struct ib_cm_id *new_cm_id; 498aef9ec39SRoland Dreier struct ib_qp_attr qp_attr; 499526b4caaSIshai Rabinovitz struct srp_request *req, *tmp; 500aef9ec39SRoland Dreier struct ib_wc wc; 501aef9ec39SRoland Dreier int ret; 502aef9ec39SRoland Dreier 503aef9ec39SRoland Dreier spin_lock_irq(target->scsi_host->host_lock); 504aef9ec39SRoland Dreier if (target->state != SRP_TARGET_LIVE) { 505aef9ec39SRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 506aef9ec39SRoland Dreier return -EAGAIN; 507aef9ec39SRoland Dreier } 508aef9ec39SRoland Dreier target->state = SRP_TARGET_CONNECTING; 509aef9ec39SRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 510aef9ec39SRoland Dreier 511aef9ec39SRoland Dreier srp_disconnect_target(target); 512aef9ec39SRoland Dreier /* 513aef9ec39SRoland Dreier * Now get a new local CM ID so that we avoid confusing the 514aef9ec39SRoland Dreier * target in case things are really fouled up. 515aef9ec39SRoland Dreier */ 516f5358a17SRoland Dreier new_cm_id = ib_create_cm_id(target->srp_host->dev->dev, 517aef9ec39SRoland Dreier srp_cm_handler, target); 518aef9ec39SRoland Dreier if (IS_ERR(new_cm_id)) { 519aef9ec39SRoland Dreier ret = PTR_ERR(new_cm_id); 520aef9ec39SRoland Dreier goto err; 521aef9ec39SRoland Dreier } 522aef9ec39SRoland Dreier ib_destroy_cm_id(target->cm_id); 523aef9ec39SRoland Dreier target->cm_id = new_cm_id; 524aef9ec39SRoland Dreier 525aef9ec39SRoland Dreier qp_attr.qp_state = IB_QPS_RESET; 526aef9ec39SRoland Dreier ret = ib_modify_qp(target->qp, &qp_attr, IB_QP_STATE); 527aef9ec39SRoland Dreier if (ret) 528aef9ec39SRoland Dreier goto err; 529aef9ec39SRoland Dreier 530aef9ec39SRoland Dreier ret = srp_init_qp(target, target->qp); 531aef9ec39SRoland Dreier if (ret) 532aef9ec39SRoland Dreier goto err; 533aef9ec39SRoland Dreier 534aef9ec39SRoland Dreier while (ib_poll_cq(target->cq, 1, &wc) > 0) 535aef9ec39SRoland Dreier ; /* nothing */ 536aef9ec39SRoland Dreier 537d916a8f1SIshai Rabinovitz spin_lock_irq(target->scsi_host->host_lock); 538526b4caaSIshai Rabinovitz list_for_each_entry_safe(req, tmp, &target->req_queue, list) 539526b4caaSIshai Rabinovitz srp_reset_req(target, req); 540d916a8f1SIshai Rabinovitz spin_unlock_irq(target->scsi_host->host_lock); 541aef9ec39SRoland Dreier 542aef9ec39SRoland Dreier target->rx_head = 0; 543aef9ec39SRoland Dreier target->tx_head = 0; 544aef9ec39SRoland Dreier target->tx_tail = 0; 545aef9ec39SRoland Dreier 546aef9ec39SRoland Dreier ret = srp_connect_target(target); 547aef9ec39SRoland Dreier if (ret) 548aef9ec39SRoland Dreier goto err; 549aef9ec39SRoland Dreier 550aef9ec39SRoland Dreier spin_lock_irq(target->scsi_host->host_lock); 551aef9ec39SRoland Dreier if (target->state == SRP_TARGET_CONNECTING) { 552aef9ec39SRoland Dreier ret = 0; 553aef9ec39SRoland Dreier target->state = SRP_TARGET_LIVE; 554aef9ec39SRoland Dreier } else 555aef9ec39SRoland Dreier ret = -EAGAIN; 556aef9ec39SRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 557aef9ec39SRoland Dreier 558aef9ec39SRoland Dreier return ret; 559aef9ec39SRoland Dreier 560aef9ec39SRoland Dreier err: 561aef9ec39SRoland Dreier printk(KERN_ERR PFX "reconnect failed (%d), removing target port.\n", ret); 562aef9ec39SRoland Dreier 563aef9ec39SRoland Dreier /* 564aef9ec39SRoland Dreier * We couldn't reconnect, so kill our target port off. 565aef9ec39SRoland Dreier * However, we have to defer the real removal because we might 566aef9ec39SRoland Dreier * be in the context of the SCSI error handler now, which 567aef9ec39SRoland Dreier * would deadlock if we call scsi_remove_host(). 568aef9ec39SRoland Dreier */ 569aef9ec39SRoland Dreier spin_lock_irq(target->scsi_host->host_lock); 570aef9ec39SRoland Dreier if (target->state == SRP_TARGET_CONNECTING) { 571aef9ec39SRoland Dreier target->state = SRP_TARGET_DEAD; 572aef9ec39SRoland Dreier INIT_WORK(&target->work, srp_remove_work, target); 573aef9ec39SRoland Dreier schedule_work(&target->work); 574aef9ec39SRoland Dreier } 575aef9ec39SRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 576aef9ec39SRoland Dreier 577aef9ec39SRoland Dreier return ret; 578aef9ec39SRoland Dreier } 579aef9ec39SRoland Dreier 580559ce8f1SIshai Rabinovitz static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat, 581f5358a17SRoland Dreier int sg_cnt, struct srp_request *req, 582f5358a17SRoland Dreier struct srp_direct_buf *buf) 583f5358a17SRoland Dreier { 584f5358a17SRoland Dreier u64 io_addr = 0; 585f5358a17SRoland Dreier u64 *dma_pages; 586f5358a17SRoland Dreier u32 len; 587f5358a17SRoland Dreier int page_cnt; 588f5358a17SRoland Dreier int i, j; 589f5358a17SRoland Dreier int ret; 590559ce8f1SIshai Rabinovitz struct srp_device *dev = target->srp_host->dev; 591f5358a17SRoland Dreier 592f5358a17SRoland Dreier if (!dev->fmr_pool) 593f5358a17SRoland Dreier return -ENODEV; 594f5358a17SRoland Dreier 595559ce8f1SIshai Rabinovitz if ((sg_dma_address(&scat[0]) & ~dev->fmr_page_mask) && 596559ce8f1SIshai Rabinovitz mellanox_workarounds && !memcmp(&target->ioc_guid, mellanox_oui, 3)) 597559ce8f1SIshai Rabinovitz return -EINVAL; 598559ce8f1SIshai Rabinovitz 599f5358a17SRoland Dreier len = page_cnt = 0; 600f5358a17SRoland Dreier for (i = 0; i < sg_cnt; ++i) { 601f5358a17SRoland Dreier if (sg_dma_address(&scat[i]) & ~dev->fmr_page_mask) { 602f5358a17SRoland Dreier if (i > 0) 603f5358a17SRoland Dreier return -EINVAL; 604f5358a17SRoland Dreier else 605f5358a17SRoland Dreier ++page_cnt; 606f5358a17SRoland Dreier } 607f5358a17SRoland Dreier if ((sg_dma_address(&scat[i]) + sg_dma_len(&scat[i])) & 608f5358a17SRoland Dreier ~dev->fmr_page_mask) { 609f5358a17SRoland Dreier if (i < sg_cnt - 1) 610f5358a17SRoland Dreier return -EINVAL; 611f5358a17SRoland Dreier else 612f5358a17SRoland Dreier ++page_cnt; 613f5358a17SRoland Dreier } 614f5358a17SRoland Dreier 615f5358a17SRoland Dreier len += sg_dma_len(&scat[i]); 616f5358a17SRoland Dreier } 617f5358a17SRoland Dreier 618f5358a17SRoland Dreier page_cnt += len >> dev->fmr_page_shift; 619f5358a17SRoland Dreier if (page_cnt > SRP_FMR_SIZE) 620f5358a17SRoland Dreier return -ENOMEM; 621f5358a17SRoland Dreier 622f5358a17SRoland Dreier dma_pages = kmalloc(sizeof (u64) * page_cnt, GFP_ATOMIC); 623f5358a17SRoland Dreier if (!dma_pages) 624f5358a17SRoland Dreier return -ENOMEM; 625f5358a17SRoland Dreier 626f5358a17SRoland Dreier page_cnt = 0; 627f5358a17SRoland Dreier for (i = 0; i < sg_cnt; ++i) 628f5358a17SRoland Dreier for (j = 0; j < sg_dma_len(&scat[i]); j += dev->fmr_page_size) 629f5358a17SRoland Dreier dma_pages[page_cnt++] = 630f5358a17SRoland Dreier (sg_dma_address(&scat[i]) & dev->fmr_page_mask) + j; 631f5358a17SRoland Dreier 632f5358a17SRoland Dreier req->fmr = ib_fmr_pool_map_phys(dev->fmr_pool, 633adfaa888SMichael S. Tsirkin dma_pages, page_cnt, io_addr); 634f5358a17SRoland Dreier if (IS_ERR(req->fmr)) { 635f5358a17SRoland Dreier ret = PTR_ERR(req->fmr); 6366583eb3dSVu Pham req->fmr = NULL; 637f5358a17SRoland Dreier goto out; 638f5358a17SRoland Dreier } 639f5358a17SRoland Dreier 640f5358a17SRoland Dreier buf->va = cpu_to_be64(sg_dma_address(&scat[0]) & ~dev->fmr_page_mask); 641f5358a17SRoland Dreier buf->key = cpu_to_be32(req->fmr->fmr->rkey); 642f5358a17SRoland Dreier buf->len = cpu_to_be32(len); 643f5358a17SRoland Dreier 644f5358a17SRoland Dreier ret = 0; 645f5358a17SRoland Dreier 646f5358a17SRoland Dreier out: 647f5358a17SRoland Dreier kfree(dma_pages); 648f5358a17SRoland Dreier 649f5358a17SRoland Dreier return ret; 650f5358a17SRoland Dreier } 651f5358a17SRoland Dreier 652aef9ec39SRoland Dreier static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, 653aef9ec39SRoland Dreier struct srp_request *req) 654aef9ec39SRoland Dreier { 655cf368713SRoland Dreier struct scatterlist *scat; 656aef9ec39SRoland Dreier struct srp_cmd *cmd = req->cmd->buf; 657cf368713SRoland Dreier int len, nents, count; 658f5358a17SRoland Dreier u8 fmt = SRP_DATA_DESC_DIRECT; 659aef9ec39SRoland Dreier 660aef9ec39SRoland Dreier if (!scmnd->request_buffer || scmnd->sc_data_direction == DMA_NONE) 661aef9ec39SRoland Dreier return sizeof (struct srp_cmd); 662aef9ec39SRoland Dreier 663aef9ec39SRoland Dreier if (scmnd->sc_data_direction != DMA_FROM_DEVICE && 664aef9ec39SRoland Dreier scmnd->sc_data_direction != DMA_TO_DEVICE) { 665aef9ec39SRoland Dreier printk(KERN_WARNING PFX "Unhandled data direction %d\n", 666aef9ec39SRoland Dreier scmnd->sc_data_direction); 667aef9ec39SRoland Dreier return -EINVAL; 668aef9ec39SRoland Dreier } 669aef9ec39SRoland Dreier 670cf368713SRoland Dreier /* 671cf368713SRoland Dreier * This handling of non-SG commands can be killed when the 672cf368713SRoland Dreier * SCSI midlayer no longer generates non-SG commands. 673cf368713SRoland Dreier */ 674cf368713SRoland Dreier if (likely(scmnd->use_sg)) { 675cf368713SRoland Dreier nents = scmnd->use_sg; 676cf368713SRoland Dreier scat = scmnd->request_buffer; 677cf368713SRoland Dreier } else { 678cf368713SRoland Dreier nents = 1; 679cf368713SRoland Dreier scat = &req->fake_sg; 680cf368713SRoland Dreier sg_init_one(scat, scmnd->request_buffer, scmnd->request_bufflen); 681cf368713SRoland Dreier } 682aef9ec39SRoland Dreier 683f5358a17SRoland Dreier count = dma_map_sg(target->srp_host->dev->dev->dma_device, 684f5358a17SRoland Dreier scat, nents, scmnd->sc_data_direction); 685aef9ec39SRoland Dreier 686aef9ec39SRoland Dreier fmt = SRP_DATA_DESC_DIRECT; 687f5358a17SRoland Dreier len = sizeof (struct srp_cmd) + sizeof (struct srp_direct_buf); 688f5358a17SRoland Dreier 689f5358a17SRoland Dreier if (count == 1) { 690f5358a17SRoland Dreier /* 691f5358a17SRoland Dreier * The midlayer only generated a single gather/scatter 692f5358a17SRoland Dreier * entry, or DMA mapping coalesced everything to a 693f5358a17SRoland Dreier * single entry. So a direct descriptor along with 694f5358a17SRoland Dreier * the DMA MR suffices. 695f5358a17SRoland Dreier */ 696f5358a17SRoland Dreier struct srp_direct_buf *buf = (void *) cmd->add_data; 697aef9ec39SRoland Dreier 698aef9ec39SRoland Dreier buf->va = cpu_to_be64(sg_dma_address(scat)); 699f5358a17SRoland Dreier buf->key = cpu_to_be32(target->srp_host->dev->mr->rkey); 700aef9ec39SRoland Dreier buf->len = cpu_to_be32(sg_dma_len(scat)); 701559ce8f1SIshai Rabinovitz } else if (srp_map_fmr(target, scat, count, req, 702f5358a17SRoland Dreier (void *) cmd->add_data)) { 703f5358a17SRoland Dreier /* 704f5358a17SRoland Dreier * FMR mapping failed, and the scatterlist has more 705f5358a17SRoland Dreier * than one entry. Generate an indirect memory 706f5358a17SRoland Dreier * descriptor. 707f5358a17SRoland Dreier */ 708aef9ec39SRoland Dreier struct srp_indirect_buf *buf = (void *) cmd->add_data; 709aef9ec39SRoland Dreier u32 datalen = 0; 710f5358a17SRoland Dreier int i; 711aef9ec39SRoland Dreier 712aef9ec39SRoland Dreier fmt = SRP_DATA_DESC_INDIRECT; 713f5358a17SRoland Dreier len = sizeof (struct srp_cmd) + 714f5358a17SRoland Dreier sizeof (struct srp_indirect_buf) + 715f5358a17SRoland Dreier count * sizeof (struct srp_direct_buf); 716f5358a17SRoland Dreier 717f5358a17SRoland Dreier for (i = 0; i < count; ++i) { 718f5358a17SRoland Dreier buf->desc_list[i].va = 719f5358a17SRoland Dreier cpu_to_be64(sg_dma_address(&scat[i])); 720f5358a17SRoland Dreier buf->desc_list[i].key = 721f5358a17SRoland Dreier cpu_to_be32(target->srp_host->dev->mr->rkey); 722f5358a17SRoland Dreier buf->desc_list[i].len = 723f5358a17SRoland Dreier cpu_to_be32(sg_dma_len(&scat[i])); 724f5358a17SRoland Dreier datalen += sg_dma_len(&scat[i]); 725f5358a17SRoland Dreier } 726aef9ec39SRoland Dreier 727aef9ec39SRoland Dreier if (scmnd->sc_data_direction == DMA_TO_DEVICE) 728cf368713SRoland Dreier cmd->data_out_desc_cnt = count; 729aef9ec39SRoland Dreier else 730cf368713SRoland Dreier cmd->data_in_desc_cnt = count; 731aef9ec39SRoland Dreier 732f5358a17SRoland Dreier buf->table_desc.va = 733f5358a17SRoland Dreier cpu_to_be64(req->cmd->dma + sizeof *cmd + sizeof *buf); 734aef9ec39SRoland Dreier buf->table_desc.key = 735f5358a17SRoland Dreier cpu_to_be32(target->srp_host->dev->mr->rkey); 736aef9ec39SRoland Dreier buf->table_desc.len = 737cf368713SRoland Dreier cpu_to_be32(count * sizeof (struct srp_direct_buf)); 738aef9ec39SRoland Dreier 739aef9ec39SRoland Dreier buf->len = cpu_to_be32(datalen); 740aef9ec39SRoland Dreier } 741aef9ec39SRoland Dreier 742aef9ec39SRoland Dreier if (scmnd->sc_data_direction == DMA_TO_DEVICE) 743aef9ec39SRoland Dreier cmd->buf_fmt = fmt << 4; 744aef9ec39SRoland Dreier else 745aef9ec39SRoland Dreier cmd->buf_fmt = fmt; 746aef9ec39SRoland Dreier 747aef9ec39SRoland Dreier return len; 748aef9ec39SRoland Dreier } 749aef9ec39SRoland Dreier 750aef9ec39SRoland Dreier static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) 751aef9ec39SRoland Dreier { 752aef9ec39SRoland Dreier struct srp_request *req; 753aef9ec39SRoland Dreier struct scsi_cmnd *scmnd; 754aef9ec39SRoland Dreier unsigned long flags; 755aef9ec39SRoland Dreier s32 delta; 756aef9ec39SRoland Dreier 757aef9ec39SRoland Dreier delta = (s32) be32_to_cpu(rsp->req_lim_delta); 758aef9ec39SRoland Dreier 759aef9ec39SRoland Dreier spin_lock_irqsave(target->scsi_host->host_lock, flags); 760aef9ec39SRoland Dreier 761aef9ec39SRoland Dreier target->req_lim += delta; 762aef9ec39SRoland Dreier 763aef9ec39SRoland Dreier req = &target->req_ring[rsp->tag & ~SRP_TAG_TSK_MGMT]; 764aef9ec39SRoland Dreier 765aef9ec39SRoland Dreier if (unlikely(rsp->tag & SRP_TAG_TSK_MGMT)) { 766aef9ec39SRoland Dreier if (be32_to_cpu(rsp->resp_data_len) < 4) 767aef9ec39SRoland Dreier req->tsk_status = -1; 768aef9ec39SRoland Dreier else 769aef9ec39SRoland Dreier req->tsk_status = rsp->data[3]; 770aef9ec39SRoland Dreier complete(&req->done); 771aef9ec39SRoland Dreier } else { 772aef9ec39SRoland Dreier scmnd = req->scmnd; 773aef9ec39SRoland Dreier if (!scmnd) 774aef9ec39SRoland Dreier printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n", 775aef9ec39SRoland Dreier (unsigned long long) rsp->tag); 776aef9ec39SRoland Dreier scmnd->result = rsp->status; 777aef9ec39SRoland Dreier 778aef9ec39SRoland Dreier if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { 779aef9ec39SRoland Dreier memcpy(scmnd->sense_buffer, rsp->data + 780aef9ec39SRoland Dreier be32_to_cpu(rsp->resp_data_len), 781aef9ec39SRoland Dreier min_t(int, be32_to_cpu(rsp->sense_data_len), 782aef9ec39SRoland Dreier SCSI_SENSE_BUFFERSIZE)); 783aef9ec39SRoland Dreier } 784aef9ec39SRoland Dreier 785aef9ec39SRoland Dreier if (rsp->flags & (SRP_RSP_FLAG_DOOVER | SRP_RSP_FLAG_DOUNDER)) 786aef9ec39SRoland Dreier scmnd->resid = be32_to_cpu(rsp->data_out_res_cnt); 787aef9ec39SRoland Dreier else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) 788aef9ec39SRoland Dreier scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt); 789aef9ec39SRoland Dreier 790aef9ec39SRoland Dreier if (!req->tsk_mgmt) { 791aef9ec39SRoland Dreier scmnd->host_scribble = (void *) -1L; 792aef9ec39SRoland Dreier scmnd->scsi_done(scmnd); 793aef9ec39SRoland Dreier 794d945e1dfSRoland Dreier srp_remove_req(target, req); 795aef9ec39SRoland Dreier } else 796aef9ec39SRoland Dreier req->cmd_done = 1; 797aef9ec39SRoland Dreier } 798aef9ec39SRoland Dreier 799aef9ec39SRoland Dreier spin_unlock_irqrestore(target->scsi_host->host_lock, flags); 800aef9ec39SRoland Dreier } 801aef9ec39SRoland Dreier 802aef9ec39SRoland Dreier static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) 803aef9ec39SRoland Dreier { 804aef9ec39SRoland Dreier struct srp_iu *iu; 805aef9ec39SRoland Dreier u8 opcode; 806aef9ec39SRoland Dreier 807aef9ec39SRoland Dreier iu = target->rx_ring[wc->wr_id & ~SRP_OP_RECV]; 808aef9ec39SRoland Dreier 809f5358a17SRoland Dreier dma_sync_single_for_cpu(target->srp_host->dev->dev->dma_device, iu->dma, 810aef9ec39SRoland Dreier target->max_ti_iu_len, DMA_FROM_DEVICE); 811aef9ec39SRoland Dreier 812aef9ec39SRoland Dreier opcode = *(u8 *) iu->buf; 813aef9ec39SRoland Dreier 814aef9ec39SRoland Dreier if (0) { 815aef9ec39SRoland Dreier int i; 816aef9ec39SRoland Dreier 817aef9ec39SRoland Dreier printk(KERN_ERR PFX "recv completion, opcode 0x%02x\n", opcode); 818aef9ec39SRoland Dreier 819aef9ec39SRoland Dreier for (i = 0; i < wc->byte_len; ++i) { 820aef9ec39SRoland Dreier if (i % 8 == 0) 821aef9ec39SRoland Dreier printk(KERN_ERR " [%02x] ", i); 822aef9ec39SRoland Dreier printk(" %02x", ((u8 *) iu->buf)[i]); 823aef9ec39SRoland Dreier if ((i + 1) % 8 == 0) 824aef9ec39SRoland Dreier printk("\n"); 825aef9ec39SRoland Dreier } 826aef9ec39SRoland Dreier 827aef9ec39SRoland Dreier if (wc->byte_len % 8) 828aef9ec39SRoland Dreier printk("\n"); 829aef9ec39SRoland Dreier } 830aef9ec39SRoland Dreier 831aef9ec39SRoland Dreier switch (opcode) { 832aef9ec39SRoland Dreier case SRP_RSP: 833aef9ec39SRoland Dreier srp_process_rsp(target, iu->buf); 834aef9ec39SRoland Dreier break; 835aef9ec39SRoland Dreier 836aef9ec39SRoland Dreier case SRP_T_LOGOUT: 837aef9ec39SRoland Dreier /* XXX Handle target logout */ 838aef9ec39SRoland Dreier printk(KERN_WARNING PFX "Got target logout request\n"); 839aef9ec39SRoland Dreier break; 840aef9ec39SRoland Dreier 841aef9ec39SRoland Dreier default: 842aef9ec39SRoland Dreier printk(KERN_WARNING PFX "Unhandled SRP opcode 0x%02x\n", opcode); 843aef9ec39SRoland Dreier break; 844aef9ec39SRoland Dreier } 845aef9ec39SRoland Dreier 846f5358a17SRoland Dreier dma_sync_single_for_device(target->srp_host->dev->dev->dma_device, iu->dma, 847aef9ec39SRoland Dreier target->max_ti_iu_len, DMA_FROM_DEVICE); 848aef9ec39SRoland Dreier } 849aef9ec39SRoland Dreier 850aef9ec39SRoland Dreier static void srp_completion(struct ib_cq *cq, void *target_ptr) 851aef9ec39SRoland Dreier { 852aef9ec39SRoland Dreier struct srp_target_port *target = target_ptr; 853aef9ec39SRoland Dreier struct ib_wc wc; 854aef9ec39SRoland Dreier 855aef9ec39SRoland Dreier ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); 856aef9ec39SRoland Dreier while (ib_poll_cq(cq, 1, &wc) > 0) { 857aef9ec39SRoland Dreier if (wc.status) { 858aef9ec39SRoland Dreier printk(KERN_ERR PFX "failed %s status %d\n", 859aef9ec39SRoland Dreier wc.wr_id & SRP_OP_RECV ? "receive" : "send", 860aef9ec39SRoland Dreier wc.status); 861aef9ec39SRoland Dreier break; 862aef9ec39SRoland Dreier } 863aef9ec39SRoland Dreier 864aef9ec39SRoland Dreier if (wc.wr_id & SRP_OP_RECV) 865aef9ec39SRoland Dreier srp_handle_recv(target, &wc); 866aef9ec39SRoland Dreier else 867aef9ec39SRoland Dreier ++target->tx_tail; 868aef9ec39SRoland Dreier } 869aef9ec39SRoland Dreier } 870aef9ec39SRoland Dreier 871aef9ec39SRoland Dreier static int __srp_post_recv(struct srp_target_port *target) 872aef9ec39SRoland Dreier { 873aef9ec39SRoland Dreier struct srp_iu *iu; 874aef9ec39SRoland Dreier struct ib_sge list; 875aef9ec39SRoland Dreier struct ib_recv_wr wr, *bad_wr; 876aef9ec39SRoland Dreier unsigned int next; 877aef9ec39SRoland Dreier int ret; 878aef9ec39SRoland Dreier 879aef9ec39SRoland Dreier next = target->rx_head & (SRP_RQ_SIZE - 1); 880aef9ec39SRoland Dreier wr.wr_id = next | SRP_OP_RECV; 881aef9ec39SRoland Dreier iu = target->rx_ring[next]; 882aef9ec39SRoland Dreier 883aef9ec39SRoland Dreier list.addr = iu->dma; 884aef9ec39SRoland Dreier list.length = iu->size; 885f5358a17SRoland Dreier list.lkey = target->srp_host->dev->mr->lkey; 886aef9ec39SRoland Dreier 887aef9ec39SRoland Dreier wr.next = NULL; 888aef9ec39SRoland Dreier wr.sg_list = &list; 889aef9ec39SRoland Dreier wr.num_sge = 1; 890aef9ec39SRoland Dreier 891aef9ec39SRoland Dreier ret = ib_post_recv(target->qp, &wr, &bad_wr); 892aef9ec39SRoland Dreier if (!ret) 893aef9ec39SRoland Dreier ++target->rx_head; 894aef9ec39SRoland Dreier 895aef9ec39SRoland Dreier return ret; 896aef9ec39SRoland Dreier } 897aef9ec39SRoland Dreier 898aef9ec39SRoland Dreier static int srp_post_recv(struct srp_target_port *target) 899aef9ec39SRoland Dreier { 900aef9ec39SRoland Dreier unsigned long flags; 901aef9ec39SRoland Dreier int ret; 902aef9ec39SRoland Dreier 903aef9ec39SRoland Dreier spin_lock_irqsave(target->scsi_host->host_lock, flags); 904aef9ec39SRoland Dreier ret = __srp_post_recv(target); 905aef9ec39SRoland Dreier spin_unlock_irqrestore(target->scsi_host->host_lock, flags); 906aef9ec39SRoland Dreier 907aef9ec39SRoland Dreier return ret; 908aef9ec39SRoland Dreier } 909aef9ec39SRoland Dreier 910aef9ec39SRoland Dreier /* 911aef9ec39SRoland Dreier * Must be called with target->scsi_host->host_lock held to protect 91247f2bce9SRoland Dreier * req_lim and tx_head. Lock cannot be dropped between call here and 91347f2bce9SRoland Dreier * call to __srp_post_send(). 914aef9ec39SRoland Dreier */ 915aef9ec39SRoland Dreier static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target) 916aef9ec39SRoland Dreier { 917aef9ec39SRoland Dreier if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) 918aef9ec39SRoland Dreier return NULL; 919aef9ec39SRoland Dreier 9206bfa24faSRoland Dreier if (unlikely(target->req_lim < 1)) 9216bfa24faSRoland Dreier ++target->zero_req_lim; 92247f2bce9SRoland Dreier 923aef9ec39SRoland Dreier return target->tx_ring[target->tx_head & SRP_SQ_SIZE]; 924aef9ec39SRoland Dreier } 925aef9ec39SRoland Dreier 926aef9ec39SRoland Dreier /* 927aef9ec39SRoland Dreier * Must be called with target->scsi_host->host_lock held to protect 928aef9ec39SRoland Dreier * req_lim and tx_head. 929aef9ec39SRoland Dreier */ 930aef9ec39SRoland Dreier static int __srp_post_send(struct srp_target_port *target, 931aef9ec39SRoland Dreier struct srp_iu *iu, int len) 932aef9ec39SRoland Dreier { 933aef9ec39SRoland Dreier struct ib_sge list; 934aef9ec39SRoland Dreier struct ib_send_wr wr, *bad_wr; 935aef9ec39SRoland Dreier int ret = 0; 936aef9ec39SRoland Dreier 937aef9ec39SRoland Dreier list.addr = iu->dma; 938aef9ec39SRoland Dreier list.length = len; 939f5358a17SRoland Dreier list.lkey = target->srp_host->dev->mr->lkey; 940aef9ec39SRoland Dreier 941aef9ec39SRoland Dreier wr.next = NULL; 942aef9ec39SRoland Dreier wr.wr_id = target->tx_head & SRP_SQ_SIZE; 943aef9ec39SRoland Dreier wr.sg_list = &list; 944aef9ec39SRoland Dreier wr.num_sge = 1; 945aef9ec39SRoland Dreier wr.opcode = IB_WR_SEND; 946aef9ec39SRoland Dreier wr.send_flags = IB_SEND_SIGNALED; 947aef9ec39SRoland Dreier 948aef9ec39SRoland Dreier ret = ib_post_send(target->qp, &wr, &bad_wr); 949aef9ec39SRoland Dreier 950aef9ec39SRoland Dreier if (!ret) { 951aef9ec39SRoland Dreier ++target->tx_head; 952aef9ec39SRoland Dreier --target->req_lim; 953aef9ec39SRoland Dreier } 954aef9ec39SRoland Dreier 955aef9ec39SRoland Dreier return ret; 956aef9ec39SRoland Dreier } 957aef9ec39SRoland Dreier 958aef9ec39SRoland Dreier static int srp_queuecommand(struct scsi_cmnd *scmnd, 959aef9ec39SRoland Dreier void (*done)(struct scsi_cmnd *)) 960aef9ec39SRoland Dreier { 961aef9ec39SRoland Dreier struct srp_target_port *target = host_to_target(scmnd->device->host); 962aef9ec39SRoland Dreier struct srp_request *req; 963aef9ec39SRoland Dreier struct srp_iu *iu; 964aef9ec39SRoland Dreier struct srp_cmd *cmd; 965aef9ec39SRoland Dreier int len; 966aef9ec39SRoland Dreier 967aef9ec39SRoland Dreier if (target->state == SRP_TARGET_CONNECTING) 968aef9ec39SRoland Dreier goto err; 969aef9ec39SRoland Dreier 970aef9ec39SRoland Dreier if (target->state == SRP_TARGET_DEAD || 971aef9ec39SRoland Dreier target->state == SRP_TARGET_REMOVED) { 972aef9ec39SRoland Dreier scmnd->result = DID_BAD_TARGET << 16; 973aef9ec39SRoland Dreier done(scmnd); 974aef9ec39SRoland Dreier return 0; 975aef9ec39SRoland Dreier } 976aef9ec39SRoland Dreier 977aef9ec39SRoland Dreier iu = __srp_get_tx_iu(target); 978aef9ec39SRoland Dreier if (!iu) 979aef9ec39SRoland Dreier goto err; 980aef9ec39SRoland Dreier 981f5358a17SRoland Dreier dma_sync_single_for_cpu(target->srp_host->dev->dev->dma_device, iu->dma, 98274b0a15bSVu Pham srp_max_iu_len, DMA_TO_DEVICE); 983aef9ec39SRoland Dreier 984d945e1dfSRoland Dreier req = list_entry(target->free_reqs.next, struct srp_request, list); 985aef9ec39SRoland Dreier 986aef9ec39SRoland Dreier scmnd->scsi_done = done; 987aef9ec39SRoland Dreier scmnd->result = 0; 988d945e1dfSRoland Dreier scmnd->host_scribble = (void *) (long) req->index; 989aef9ec39SRoland Dreier 990aef9ec39SRoland Dreier cmd = iu->buf; 991aef9ec39SRoland Dreier memset(cmd, 0, sizeof *cmd); 992aef9ec39SRoland Dreier 993aef9ec39SRoland Dreier cmd->opcode = SRP_CMD; 994aef9ec39SRoland Dreier cmd->lun = cpu_to_be64((u64) scmnd->device->lun << 48); 995d945e1dfSRoland Dreier cmd->tag = req->index; 996aef9ec39SRoland Dreier memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len); 997aef9ec39SRoland Dreier 998aef9ec39SRoland Dreier req->scmnd = scmnd; 999aef9ec39SRoland Dreier req->cmd = iu; 1000aef9ec39SRoland Dreier req->cmd_done = 0; 1001aef9ec39SRoland Dreier req->tsk_mgmt = NULL; 1002aef9ec39SRoland Dreier 1003aef9ec39SRoland Dreier len = srp_map_data(scmnd, target, req); 1004aef9ec39SRoland Dreier if (len < 0) { 1005aef9ec39SRoland Dreier printk(KERN_ERR PFX "Failed to map data\n"); 1006aef9ec39SRoland Dreier goto err; 1007aef9ec39SRoland Dreier } 1008aef9ec39SRoland Dreier 1009aef9ec39SRoland Dreier if (__srp_post_recv(target)) { 1010aef9ec39SRoland Dreier printk(KERN_ERR PFX "Recv failed\n"); 1011aef9ec39SRoland Dreier goto err_unmap; 1012aef9ec39SRoland Dreier } 1013aef9ec39SRoland Dreier 1014f5358a17SRoland Dreier dma_sync_single_for_device(target->srp_host->dev->dev->dma_device, iu->dma, 101574b0a15bSVu Pham srp_max_iu_len, DMA_TO_DEVICE); 1016aef9ec39SRoland Dreier 1017aef9ec39SRoland Dreier if (__srp_post_send(target, iu, len)) { 1018aef9ec39SRoland Dreier printk(KERN_ERR PFX "Send failed\n"); 1019aef9ec39SRoland Dreier goto err_unmap; 1020aef9ec39SRoland Dreier } 1021aef9ec39SRoland Dreier 1022d945e1dfSRoland Dreier list_move_tail(&req->list, &target->req_queue); 1023aef9ec39SRoland Dreier 1024aef9ec39SRoland Dreier return 0; 1025aef9ec39SRoland Dreier 1026aef9ec39SRoland Dreier err_unmap: 1027aef9ec39SRoland Dreier srp_unmap_data(scmnd, target, req); 1028aef9ec39SRoland Dreier 1029aef9ec39SRoland Dreier err: 1030aef9ec39SRoland Dreier return SCSI_MLQUEUE_HOST_BUSY; 1031aef9ec39SRoland Dreier } 1032aef9ec39SRoland Dreier 1033aef9ec39SRoland Dreier static int srp_alloc_iu_bufs(struct srp_target_port *target) 1034aef9ec39SRoland Dreier { 1035aef9ec39SRoland Dreier int i; 1036aef9ec39SRoland Dreier 1037aef9ec39SRoland Dreier for (i = 0; i < SRP_RQ_SIZE; ++i) { 1038aef9ec39SRoland Dreier target->rx_ring[i] = srp_alloc_iu(target->srp_host, 1039aef9ec39SRoland Dreier target->max_ti_iu_len, 1040aef9ec39SRoland Dreier GFP_KERNEL, DMA_FROM_DEVICE); 1041aef9ec39SRoland Dreier if (!target->rx_ring[i]) 1042aef9ec39SRoland Dreier goto err; 1043aef9ec39SRoland Dreier } 1044aef9ec39SRoland Dreier 1045aef9ec39SRoland Dreier for (i = 0; i < SRP_SQ_SIZE + 1; ++i) { 1046aef9ec39SRoland Dreier target->tx_ring[i] = srp_alloc_iu(target->srp_host, 104774b0a15bSVu Pham srp_max_iu_len, 1048aef9ec39SRoland Dreier GFP_KERNEL, DMA_TO_DEVICE); 1049aef9ec39SRoland Dreier if (!target->tx_ring[i]) 1050aef9ec39SRoland Dreier goto err; 1051aef9ec39SRoland Dreier } 1052aef9ec39SRoland Dreier 1053aef9ec39SRoland Dreier return 0; 1054aef9ec39SRoland Dreier 1055aef9ec39SRoland Dreier err: 1056aef9ec39SRoland Dreier for (i = 0; i < SRP_RQ_SIZE; ++i) { 1057aef9ec39SRoland Dreier srp_free_iu(target->srp_host, target->rx_ring[i]); 1058aef9ec39SRoland Dreier target->rx_ring[i] = NULL; 1059aef9ec39SRoland Dreier } 1060aef9ec39SRoland Dreier 1061aef9ec39SRoland Dreier for (i = 0; i < SRP_SQ_SIZE + 1; ++i) { 1062aef9ec39SRoland Dreier srp_free_iu(target->srp_host, target->tx_ring[i]); 1063aef9ec39SRoland Dreier target->tx_ring[i] = NULL; 1064aef9ec39SRoland Dreier } 1065aef9ec39SRoland Dreier 1066aef9ec39SRoland Dreier return -ENOMEM; 1067aef9ec39SRoland Dreier } 1068aef9ec39SRoland Dreier 1069aef9ec39SRoland Dreier static void srp_cm_rej_handler(struct ib_cm_id *cm_id, 1070aef9ec39SRoland Dreier struct ib_cm_event *event, 1071aef9ec39SRoland Dreier struct srp_target_port *target) 1072aef9ec39SRoland Dreier { 1073aef9ec39SRoland Dreier struct ib_class_port_info *cpi; 1074aef9ec39SRoland Dreier int opcode; 1075aef9ec39SRoland Dreier 1076aef9ec39SRoland Dreier switch (event->param.rej_rcvd.reason) { 1077aef9ec39SRoland Dreier case IB_CM_REJ_PORT_CM_REDIRECT: 1078aef9ec39SRoland Dreier cpi = event->param.rej_rcvd.ari; 1079aef9ec39SRoland Dreier target->path.dlid = cpi->redirect_lid; 1080aef9ec39SRoland Dreier target->path.pkey = cpi->redirect_pkey; 1081aef9ec39SRoland Dreier cm_id->remote_cm_qpn = be32_to_cpu(cpi->redirect_qp) & 0x00ffffff; 1082aef9ec39SRoland Dreier memcpy(target->path.dgid.raw, cpi->redirect_gid, 16); 1083aef9ec39SRoland Dreier 1084aef9ec39SRoland Dreier target->status = target->path.dlid ? 1085aef9ec39SRoland Dreier SRP_DLID_REDIRECT : SRP_PORT_REDIRECT; 1086aef9ec39SRoland Dreier break; 1087aef9ec39SRoland Dreier 1088aef9ec39SRoland Dreier case IB_CM_REJ_PORT_REDIRECT: 1089aef9ec39SRoland Dreier if (topspin_workarounds && 1090aef9ec39SRoland Dreier !memcmp(&target->ioc_guid, topspin_oui, 3)) { 1091aef9ec39SRoland Dreier /* 1092aef9ec39SRoland Dreier * Topspin/Cisco SRP gateways incorrectly send 1093aef9ec39SRoland Dreier * reject reason code 25 when they mean 24 1094aef9ec39SRoland Dreier * (port redirect). 1095aef9ec39SRoland Dreier */ 1096aef9ec39SRoland Dreier memcpy(target->path.dgid.raw, 1097aef9ec39SRoland Dreier event->param.rej_rcvd.ari, 16); 1098aef9ec39SRoland Dreier 1099aef9ec39SRoland Dreier printk(KERN_DEBUG PFX "Topspin/Cisco redirect to target port GID %016llx%016llx\n", 1100aef9ec39SRoland Dreier (unsigned long long) be64_to_cpu(target->path.dgid.global.subnet_prefix), 1101aef9ec39SRoland Dreier (unsigned long long) be64_to_cpu(target->path.dgid.global.interface_id)); 1102aef9ec39SRoland Dreier 1103aef9ec39SRoland Dreier target->status = SRP_PORT_REDIRECT; 1104aef9ec39SRoland Dreier } else { 1105aef9ec39SRoland Dreier printk(KERN_WARNING " REJ reason: IB_CM_REJ_PORT_REDIRECT\n"); 1106aef9ec39SRoland Dreier target->status = -ECONNRESET; 1107aef9ec39SRoland Dreier } 1108aef9ec39SRoland Dreier break; 1109aef9ec39SRoland Dreier 1110aef9ec39SRoland Dreier case IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID: 1111aef9ec39SRoland Dreier printk(KERN_WARNING " REJ reason: IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID\n"); 1112aef9ec39SRoland Dreier target->status = -ECONNRESET; 1113aef9ec39SRoland Dreier break; 1114aef9ec39SRoland Dreier 1115aef9ec39SRoland Dreier case IB_CM_REJ_CONSUMER_DEFINED: 1116aef9ec39SRoland Dreier opcode = *(u8 *) event->private_data; 1117aef9ec39SRoland Dreier if (opcode == SRP_LOGIN_REJ) { 1118aef9ec39SRoland Dreier struct srp_login_rej *rej = event->private_data; 1119aef9ec39SRoland Dreier u32 reason = be32_to_cpu(rej->reason); 1120aef9ec39SRoland Dreier 1121aef9ec39SRoland Dreier if (reason == SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE) 1122aef9ec39SRoland Dreier printk(KERN_WARNING PFX 1123aef9ec39SRoland Dreier "SRP_LOGIN_REJ: requested max_it_iu_len too large\n"); 1124aef9ec39SRoland Dreier else 1125aef9ec39SRoland Dreier printk(KERN_WARNING PFX 1126aef9ec39SRoland Dreier "SRP LOGIN REJECTED, reason 0x%08x\n", reason); 1127aef9ec39SRoland Dreier } else 1128aef9ec39SRoland Dreier printk(KERN_WARNING " REJ reason: IB_CM_REJ_CONSUMER_DEFINED," 1129aef9ec39SRoland Dreier " opcode 0x%02x\n", opcode); 1130aef9ec39SRoland Dreier target->status = -ECONNRESET; 1131aef9ec39SRoland Dreier break; 1132aef9ec39SRoland Dreier 1133aef9ec39SRoland Dreier default: 1134aef9ec39SRoland Dreier printk(KERN_WARNING " REJ reason 0x%x\n", 1135aef9ec39SRoland Dreier event->param.rej_rcvd.reason); 1136aef9ec39SRoland Dreier target->status = -ECONNRESET; 1137aef9ec39SRoland Dreier } 1138aef9ec39SRoland Dreier } 1139aef9ec39SRoland Dreier 1140aef9ec39SRoland Dreier static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) 1141aef9ec39SRoland Dreier { 1142aef9ec39SRoland Dreier struct srp_target_port *target = cm_id->context; 1143aef9ec39SRoland Dreier struct ib_qp_attr *qp_attr = NULL; 1144aef9ec39SRoland Dreier int attr_mask = 0; 1145aef9ec39SRoland Dreier int comp = 0; 1146aef9ec39SRoland Dreier int opcode = 0; 1147aef9ec39SRoland Dreier 1148aef9ec39SRoland Dreier switch (event->event) { 1149aef9ec39SRoland Dreier case IB_CM_REQ_ERROR: 1150aef9ec39SRoland Dreier printk(KERN_DEBUG PFX "Sending CM REQ failed\n"); 1151aef9ec39SRoland Dreier comp = 1; 1152aef9ec39SRoland Dreier target->status = -ECONNRESET; 1153aef9ec39SRoland Dreier break; 1154aef9ec39SRoland Dreier 1155aef9ec39SRoland Dreier case IB_CM_REP_RECEIVED: 1156aef9ec39SRoland Dreier comp = 1; 1157aef9ec39SRoland Dreier opcode = *(u8 *) event->private_data; 1158aef9ec39SRoland Dreier 1159aef9ec39SRoland Dreier if (opcode == SRP_LOGIN_RSP) { 1160aef9ec39SRoland Dreier struct srp_login_rsp *rsp = event->private_data; 1161aef9ec39SRoland Dreier 1162aef9ec39SRoland Dreier target->max_ti_iu_len = be32_to_cpu(rsp->max_ti_iu_len); 1163aef9ec39SRoland Dreier target->req_lim = be32_to_cpu(rsp->req_lim_delta); 1164aef9ec39SRoland Dreier 1165aef9ec39SRoland Dreier target->scsi_host->can_queue = min(target->req_lim, 1166aef9ec39SRoland Dreier target->scsi_host->can_queue); 1167aef9ec39SRoland Dreier } else { 1168aef9ec39SRoland Dreier printk(KERN_WARNING PFX "Unhandled RSP opcode %#x\n", opcode); 1169aef9ec39SRoland Dreier target->status = -ECONNRESET; 1170aef9ec39SRoland Dreier break; 1171aef9ec39SRoland Dreier } 1172aef9ec39SRoland Dreier 1173aef9ec39SRoland Dreier target->status = srp_alloc_iu_bufs(target); 1174aef9ec39SRoland Dreier if (target->status) 1175aef9ec39SRoland Dreier break; 1176aef9ec39SRoland Dreier 1177aef9ec39SRoland Dreier qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL); 1178aef9ec39SRoland Dreier if (!qp_attr) { 1179aef9ec39SRoland Dreier target->status = -ENOMEM; 1180aef9ec39SRoland Dreier break; 1181aef9ec39SRoland Dreier } 1182aef9ec39SRoland Dreier 1183aef9ec39SRoland Dreier qp_attr->qp_state = IB_QPS_RTR; 1184aef9ec39SRoland Dreier target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask); 1185aef9ec39SRoland Dreier if (target->status) 1186aef9ec39SRoland Dreier break; 1187aef9ec39SRoland Dreier 1188aef9ec39SRoland Dreier target->status = ib_modify_qp(target->qp, qp_attr, attr_mask); 1189aef9ec39SRoland Dreier if (target->status) 1190aef9ec39SRoland Dreier break; 1191aef9ec39SRoland Dreier 1192aef9ec39SRoland Dreier target->status = srp_post_recv(target); 1193aef9ec39SRoland Dreier if (target->status) 1194aef9ec39SRoland Dreier break; 1195aef9ec39SRoland Dreier 1196aef9ec39SRoland Dreier qp_attr->qp_state = IB_QPS_RTS; 1197aef9ec39SRoland Dreier target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask); 1198aef9ec39SRoland Dreier if (target->status) 1199aef9ec39SRoland Dreier break; 1200aef9ec39SRoland Dreier 1201aef9ec39SRoland Dreier target->status = ib_modify_qp(target->qp, qp_attr, attr_mask); 1202aef9ec39SRoland Dreier if (target->status) 1203aef9ec39SRoland Dreier break; 1204aef9ec39SRoland Dreier 1205aef9ec39SRoland Dreier target->status = ib_send_cm_rtu(cm_id, NULL, 0); 1206aef9ec39SRoland Dreier if (target->status) 1207aef9ec39SRoland Dreier break; 1208aef9ec39SRoland Dreier 1209aef9ec39SRoland Dreier break; 1210aef9ec39SRoland Dreier 1211aef9ec39SRoland Dreier case IB_CM_REJ_RECEIVED: 1212aef9ec39SRoland Dreier printk(KERN_DEBUG PFX "REJ received\n"); 1213aef9ec39SRoland Dreier comp = 1; 1214aef9ec39SRoland Dreier 1215aef9ec39SRoland Dreier srp_cm_rej_handler(cm_id, event, target); 1216aef9ec39SRoland Dreier break; 1217aef9ec39SRoland Dreier 1218b7ac4ab4SIshai Rabinovitz case IB_CM_DREQ_RECEIVED: 1219b7ac4ab4SIshai Rabinovitz printk(KERN_WARNING PFX "DREQ received - connection closed\n"); 1220b7ac4ab4SIshai Rabinovitz if (ib_send_cm_drep(cm_id, NULL, 0)) 1221b7ac4ab4SIshai Rabinovitz printk(KERN_ERR PFX "Sending CM DREP failed\n"); 1222aef9ec39SRoland Dreier break; 1223aef9ec39SRoland Dreier 1224aef9ec39SRoland Dreier case IB_CM_TIMEWAIT_EXIT: 1225aef9ec39SRoland Dreier printk(KERN_ERR PFX "connection closed\n"); 1226aef9ec39SRoland Dreier 1227aef9ec39SRoland Dreier comp = 1; 1228aef9ec39SRoland Dreier target->status = 0; 1229aef9ec39SRoland Dreier break; 1230aef9ec39SRoland Dreier 1231b7ac4ab4SIshai Rabinovitz case IB_CM_MRA_RECEIVED: 1232b7ac4ab4SIshai Rabinovitz case IB_CM_DREQ_ERROR: 1233b7ac4ab4SIshai Rabinovitz case IB_CM_DREP_RECEIVED: 1234b7ac4ab4SIshai Rabinovitz break; 1235b7ac4ab4SIshai Rabinovitz 1236aef9ec39SRoland Dreier default: 1237aef9ec39SRoland Dreier printk(KERN_WARNING PFX "Unhandled CM event %d\n", event->event); 1238aef9ec39SRoland Dreier break; 1239aef9ec39SRoland Dreier } 1240aef9ec39SRoland Dreier 1241aef9ec39SRoland Dreier if (comp) 1242aef9ec39SRoland Dreier complete(&target->done); 1243aef9ec39SRoland Dreier 1244aef9ec39SRoland Dreier kfree(qp_attr); 1245aef9ec39SRoland Dreier 1246aef9ec39SRoland Dreier return 0; 1247aef9ec39SRoland Dreier } 1248aef9ec39SRoland Dreier 1249d945e1dfSRoland Dreier static int srp_send_tsk_mgmt(struct srp_target_port *target, 1250d945e1dfSRoland Dreier struct srp_request *req, u8 func) 1251aef9ec39SRoland Dreier { 1252aef9ec39SRoland Dreier struct srp_iu *iu; 1253aef9ec39SRoland Dreier struct srp_tsk_mgmt *tsk_mgmt; 1254aef9ec39SRoland Dreier 1255aef9ec39SRoland Dreier spin_lock_irq(target->scsi_host->host_lock); 1256aef9ec39SRoland Dreier 12571285b3a0SRoland Dreier if (target->state == SRP_TARGET_DEAD || 12581285b3a0SRoland Dreier target->state == SRP_TARGET_REMOVED) { 1259d945e1dfSRoland Dreier req->scmnd->result = DID_BAD_TARGET << 16; 12601285b3a0SRoland Dreier goto out; 12611285b3a0SRoland Dreier } 12621285b3a0SRoland Dreier 1263aef9ec39SRoland Dreier init_completion(&req->done); 1264aef9ec39SRoland Dreier 1265aef9ec39SRoland Dreier iu = __srp_get_tx_iu(target); 1266aef9ec39SRoland Dreier if (!iu) 1267aef9ec39SRoland Dreier goto out; 1268aef9ec39SRoland Dreier 1269aef9ec39SRoland Dreier tsk_mgmt = iu->buf; 1270aef9ec39SRoland Dreier memset(tsk_mgmt, 0, sizeof *tsk_mgmt); 1271aef9ec39SRoland Dreier 1272aef9ec39SRoland Dreier tsk_mgmt->opcode = SRP_TSK_MGMT; 1273d945e1dfSRoland Dreier tsk_mgmt->lun = cpu_to_be64((u64) req->scmnd->device->lun << 48); 1274d945e1dfSRoland Dreier tsk_mgmt->tag = req->index | SRP_TAG_TSK_MGMT; 1275aef9ec39SRoland Dreier tsk_mgmt->tsk_mgmt_func = func; 1276d945e1dfSRoland Dreier tsk_mgmt->task_tag = req->index; 1277aef9ec39SRoland Dreier 1278aef9ec39SRoland Dreier if (__srp_post_send(target, iu, sizeof *tsk_mgmt)) 1279aef9ec39SRoland Dreier goto out; 1280aef9ec39SRoland Dreier 1281aef9ec39SRoland Dreier req->tsk_mgmt = iu; 1282aef9ec39SRoland Dreier 1283aef9ec39SRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 1284d945e1dfSRoland Dreier 1285aef9ec39SRoland Dreier if (!wait_for_completion_timeout(&req->done, 1286aef9ec39SRoland Dreier msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS))) 1287d945e1dfSRoland Dreier return -1; 1288aef9ec39SRoland Dreier 1289d945e1dfSRoland Dreier return 0; 1290aef9ec39SRoland Dreier 1291aef9ec39SRoland Dreier out: 1292aef9ec39SRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 1293d945e1dfSRoland Dreier return -1; 1294d945e1dfSRoland Dreier } 1295d945e1dfSRoland Dreier 1296d945e1dfSRoland Dreier static int srp_find_req(struct srp_target_port *target, 1297d945e1dfSRoland Dreier struct scsi_cmnd *scmnd, 1298d945e1dfSRoland Dreier struct srp_request **req) 1299d945e1dfSRoland Dreier { 1300d945e1dfSRoland Dreier if (scmnd->host_scribble == (void *) -1L) 1301d945e1dfSRoland Dreier return -1; 1302d945e1dfSRoland Dreier 1303d945e1dfSRoland Dreier *req = &target->req_ring[(long) scmnd->host_scribble]; 1304d945e1dfSRoland Dreier 1305d945e1dfSRoland Dreier return 0; 1306aef9ec39SRoland Dreier } 1307aef9ec39SRoland Dreier 1308aef9ec39SRoland Dreier static int srp_abort(struct scsi_cmnd *scmnd) 1309aef9ec39SRoland Dreier { 1310d945e1dfSRoland Dreier struct srp_target_port *target = host_to_target(scmnd->device->host); 1311d945e1dfSRoland Dreier struct srp_request *req; 1312d945e1dfSRoland Dreier int ret = SUCCESS; 1313d945e1dfSRoland Dreier 1314aef9ec39SRoland Dreier printk(KERN_ERR "SRP abort called\n"); 1315aef9ec39SRoland Dreier 1316d945e1dfSRoland Dreier if (srp_find_req(target, scmnd, &req)) 1317d945e1dfSRoland Dreier return FAILED; 1318d945e1dfSRoland Dreier if (srp_send_tsk_mgmt(target, req, SRP_TSK_ABORT_TASK)) 1319d945e1dfSRoland Dreier return FAILED; 1320d945e1dfSRoland Dreier 1321d945e1dfSRoland Dreier spin_lock_irq(target->scsi_host->host_lock); 1322d945e1dfSRoland Dreier 1323d945e1dfSRoland Dreier if (req->cmd_done) { 1324d945e1dfSRoland Dreier srp_remove_req(target, req); 1325d945e1dfSRoland Dreier scmnd->scsi_done(scmnd); 1326d945e1dfSRoland Dreier } else if (!req->tsk_status) { 1327d945e1dfSRoland Dreier srp_remove_req(target, req); 1328d945e1dfSRoland Dreier scmnd->result = DID_ABORT << 16; 1329d945e1dfSRoland Dreier } else 1330d945e1dfSRoland Dreier ret = FAILED; 1331d945e1dfSRoland Dreier 1332d945e1dfSRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 1333d945e1dfSRoland Dreier 1334d945e1dfSRoland Dreier return ret; 1335aef9ec39SRoland Dreier } 1336aef9ec39SRoland Dreier 1337aef9ec39SRoland Dreier static int srp_reset_device(struct scsi_cmnd *scmnd) 1338aef9ec39SRoland Dreier { 1339d945e1dfSRoland Dreier struct srp_target_port *target = host_to_target(scmnd->device->host); 1340d945e1dfSRoland Dreier struct srp_request *req, *tmp; 1341d945e1dfSRoland Dreier 1342aef9ec39SRoland Dreier printk(KERN_ERR "SRP reset_device called\n"); 1343aef9ec39SRoland Dreier 1344d945e1dfSRoland Dreier if (srp_find_req(target, scmnd, &req)) 1345d945e1dfSRoland Dreier return FAILED; 1346d945e1dfSRoland Dreier if (srp_send_tsk_mgmt(target, req, SRP_TSK_LUN_RESET)) 1347d945e1dfSRoland Dreier return FAILED; 1348d945e1dfSRoland Dreier if (req->tsk_status) 1349d945e1dfSRoland Dreier return FAILED; 1350d945e1dfSRoland Dreier 1351d945e1dfSRoland Dreier spin_lock_irq(target->scsi_host->host_lock); 1352d945e1dfSRoland Dreier 1353d945e1dfSRoland Dreier list_for_each_entry_safe(req, tmp, &target->req_queue, list) 1354526b4caaSIshai Rabinovitz if (req->scmnd->device == scmnd->device) 1355526b4caaSIshai Rabinovitz srp_reset_req(target, req); 1356d945e1dfSRoland Dreier 1357d945e1dfSRoland Dreier spin_unlock_irq(target->scsi_host->host_lock); 1358d945e1dfSRoland Dreier 1359d945e1dfSRoland Dreier return SUCCESS; 1360aef9ec39SRoland Dreier } 1361aef9ec39SRoland Dreier 1362aef9ec39SRoland Dreier static int srp_reset_host(struct scsi_cmnd *scmnd) 1363aef9ec39SRoland Dreier { 1364aef9ec39SRoland Dreier struct srp_target_port *target = host_to_target(scmnd->device->host); 1365aef9ec39SRoland Dreier int ret = FAILED; 1366aef9ec39SRoland Dreier 1367aef9ec39SRoland Dreier printk(KERN_ERR PFX "SRP reset_host called\n"); 1368aef9ec39SRoland Dreier 1369aef9ec39SRoland Dreier if (!srp_reconnect_target(target)) 1370aef9ec39SRoland Dreier ret = SUCCESS; 1371aef9ec39SRoland Dreier 1372aef9ec39SRoland Dreier return ret; 1373aef9ec39SRoland Dreier } 1374aef9ec39SRoland Dreier 13756ecb0c84SRoland Dreier static ssize_t show_id_ext(struct class_device *cdev, char *buf) 13766ecb0c84SRoland Dreier { 13776ecb0c84SRoland Dreier struct srp_target_port *target = host_to_target(class_to_shost(cdev)); 13786ecb0c84SRoland Dreier 13796ecb0c84SRoland Dreier if (target->state == SRP_TARGET_DEAD || 13806ecb0c84SRoland Dreier target->state == SRP_TARGET_REMOVED) 13816ecb0c84SRoland Dreier return -ENODEV; 13826ecb0c84SRoland Dreier 13836ecb0c84SRoland Dreier return sprintf(buf, "0x%016llx\n", 13846ecb0c84SRoland Dreier (unsigned long long) be64_to_cpu(target->id_ext)); 13856ecb0c84SRoland Dreier } 13866ecb0c84SRoland Dreier 13876ecb0c84SRoland Dreier static ssize_t show_ioc_guid(struct class_device *cdev, char *buf) 13886ecb0c84SRoland Dreier { 13896ecb0c84SRoland Dreier struct srp_target_port *target = host_to_target(class_to_shost(cdev)); 13906ecb0c84SRoland Dreier 13916ecb0c84SRoland Dreier if (target->state == SRP_TARGET_DEAD || 13926ecb0c84SRoland Dreier target->state == SRP_TARGET_REMOVED) 13936ecb0c84SRoland Dreier return -ENODEV; 13946ecb0c84SRoland Dreier 13956ecb0c84SRoland Dreier return sprintf(buf, "0x%016llx\n", 13966ecb0c84SRoland Dreier (unsigned long long) be64_to_cpu(target->ioc_guid)); 13976ecb0c84SRoland Dreier } 13986ecb0c84SRoland Dreier 13996ecb0c84SRoland Dreier static ssize_t show_service_id(struct class_device *cdev, char *buf) 14006ecb0c84SRoland Dreier { 14016ecb0c84SRoland Dreier struct srp_target_port *target = host_to_target(class_to_shost(cdev)); 14026ecb0c84SRoland Dreier 14036ecb0c84SRoland Dreier if (target->state == SRP_TARGET_DEAD || 14046ecb0c84SRoland Dreier target->state == SRP_TARGET_REMOVED) 14056ecb0c84SRoland Dreier return -ENODEV; 14066ecb0c84SRoland Dreier 14076ecb0c84SRoland Dreier return sprintf(buf, "0x%016llx\n", 14086ecb0c84SRoland Dreier (unsigned long long) be64_to_cpu(target->service_id)); 14096ecb0c84SRoland Dreier } 14106ecb0c84SRoland Dreier 14116ecb0c84SRoland Dreier static ssize_t show_pkey(struct class_device *cdev, char *buf) 14126ecb0c84SRoland Dreier { 14136ecb0c84SRoland Dreier struct srp_target_port *target = host_to_target(class_to_shost(cdev)); 14146ecb0c84SRoland Dreier 14156ecb0c84SRoland Dreier if (target->state == SRP_TARGET_DEAD || 14166ecb0c84SRoland Dreier target->state == SRP_TARGET_REMOVED) 14176ecb0c84SRoland Dreier return -ENODEV; 14186ecb0c84SRoland Dreier 14196ecb0c84SRoland Dreier return sprintf(buf, "0x%04x\n", be16_to_cpu(target->path.pkey)); 14206ecb0c84SRoland Dreier } 14216ecb0c84SRoland Dreier 14226ecb0c84SRoland Dreier static ssize_t show_dgid(struct class_device *cdev, char *buf) 14236ecb0c84SRoland Dreier { 14246ecb0c84SRoland Dreier struct srp_target_port *target = host_to_target(class_to_shost(cdev)); 14256ecb0c84SRoland Dreier 14266ecb0c84SRoland Dreier if (target->state == SRP_TARGET_DEAD || 14276ecb0c84SRoland Dreier target->state == SRP_TARGET_REMOVED) 14286ecb0c84SRoland Dreier return -ENODEV; 14296ecb0c84SRoland Dreier 14306ecb0c84SRoland Dreier return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", 14316ecb0c84SRoland Dreier be16_to_cpu(((__be16 *) target->path.dgid.raw)[0]), 14326ecb0c84SRoland Dreier be16_to_cpu(((__be16 *) target->path.dgid.raw)[1]), 14336ecb0c84SRoland Dreier be16_to_cpu(((__be16 *) target->path.dgid.raw)[2]), 14346ecb0c84SRoland Dreier be16_to_cpu(((__be16 *) target->path.dgid.raw)[3]), 14356ecb0c84SRoland Dreier be16_to_cpu(((__be16 *) target->path.dgid.raw)[4]), 14366ecb0c84SRoland Dreier be16_to_cpu(((__be16 *) target->path.dgid.raw)[5]), 14376ecb0c84SRoland Dreier be16_to_cpu(((__be16 *) target->path.dgid.raw)[6]), 14386ecb0c84SRoland Dreier be16_to_cpu(((__be16 *) target->path.dgid.raw)[7])); 14396ecb0c84SRoland Dreier } 14406ecb0c84SRoland Dreier 14416bfa24faSRoland Dreier static ssize_t show_zero_req_lim(struct class_device *cdev, char *buf) 14426bfa24faSRoland Dreier { 14436bfa24faSRoland Dreier struct srp_target_port *target = host_to_target(class_to_shost(cdev)); 14446bfa24faSRoland Dreier 14456bfa24faSRoland Dreier if (target->state == SRP_TARGET_DEAD || 14466bfa24faSRoland Dreier target->state == SRP_TARGET_REMOVED) 14476bfa24faSRoland Dreier return -ENODEV; 14486bfa24faSRoland Dreier 14496bfa24faSRoland Dreier return sprintf(buf, "%d\n", target->zero_req_lim); 14506bfa24faSRoland Dreier } 14516bfa24faSRoland Dreier 1452ded7f1a1SIshai Rabinovitz static ssize_t show_local_ib_port(struct class_device *cdev, char *buf) 1453ded7f1a1SIshai Rabinovitz { 1454ded7f1a1SIshai Rabinovitz struct srp_target_port *target = host_to_target(class_to_shost(cdev)); 1455ded7f1a1SIshai Rabinovitz 1456ded7f1a1SIshai Rabinovitz return sprintf(buf, "%d\n", target->srp_host->port); 1457ded7f1a1SIshai Rabinovitz } 1458ded7f1a1SIshai Rabinovitz 1459ded7f1a1SIshai Rabinovitz static ssize_t show_local_ib_device(struct class_device *cdev, char *buf) 1460ded7f1a1SIshai Rabinovitz { 1461ded7f1a1SIshai Rabinovitz struct srp_target_port *target = host_to_target(class_to_shost(cdev)); 1462ded7f1a1SIshai Rabinovitz 1463ded7f1a1SIshai Rabinovitz return sprintf(buf, "%s\n", target->srp_host->dev->dev->name); 1464ded7f1a1SIshai Rabinovitz } 1465ded7f1a1SIshai Rabinovitz 14666ecb0c84SRoland Dreier static CLASS_DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL); 14676ecb0c84SRoland Dreier static CLASS_DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); 14686ecb0c84SRoland Dreier static CLASS_DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); 14696ecb0c84SRoland Dreier static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); 14706ecb0c84SRoland Dreier static CLASS_DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL); 14716bfa24faSRoland Dreier static CLASS_DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); 1472ded7f1a1SIshai Rabinovitz static CLASS_DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); 1473ded7f1a1SIshai Rabinovitz static CLASS_DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); 14746ecb0c84SRoland Dreier 14756ecb0c84SRoland Dreier static struct class_device_attribute *srp_host_attrs[] = { 14766ecb0c84SRoland Dreier &class_device_attr_id_ext, 14776ecb0c84SRoland Dreier &class_device_attr_ioc_guid, 14786ecb0c84SRoland Dreier &class_device_attr_service_id, 14796ecb0c84SRoland Dreier &class_device_attr_pkey, 14806ecb0c84SRoland Dreier &class_device_attr_dgid, 14816bfa24faSRoland Dreier &class_device_attr_zero_req_lim, 1482ded7f1a1SIshai Rabinovitz &class_device_attr_local_ib_port, 1483ded7f1a1SIshai Rabinovitz &class_device_attr_local_ib_device, 14846ecb0c84SRoland Dreier NULL 14856ecb0c84SRoland Dreier }; 14866ecb0c84SRoland Dreier 1487aef9ec39SRoland Dreier static struct scsi_host_template srp_template = { 1488aef9ec39SRoland Dreier .module = THIS_MODULE, 1489aef9ec39SRoland Dreier .name = DRV_NAME, 1490aef9ec39SRoland Dreier .info = srp_target_info, 1491aef9ec39SRoland Dreier .queuecommand = srp_queuecommand, 1492aef9ec39SRoland Dreier .eh_abort_handler = srp_abort, 1493aef9ec39SRoland Dreier .eh_device_reset_handler = srp_reset_device, 1494aef9ec39SRoland Dreier .eh_host_reset_handler = srp_reset_host, 1495aef9ec39SRoland Dreier .can_queue = SRP_SQ_SIZE, 1496aef9ec39SRoland Dreier .this_id = -1, 1497aef9ec39SRoland Dreier .cmd_per_lun = SRP_SQ_SIZE, 14986ecb0c84SRoland Dreier .use_clustering = ENABLE_CLUSTERING, 14996ecb0c84SRoland Dreier .shost_attrs = srp_host_attrs 1500aef9ec39SRoland Dreier }; 1501aef9ec39SRoland Dreier 1502aef9ec39SRoland Dreier static int srp_add_target(struct srp_host *host, struct srp_target_port *target) 1503aef9ec39SRoland Dreier { 1504aef9ec39SRoland Dreier sprintf(target->target_name, "SRP.T10:%016llX", 1505aef9ec39SRoland Dreier (unsigned long long) be64_to_cpu(target->id_ext)); 1506aef9ec39SRoland Dreier 1507f5358a17SRoland Dreier if (scsi_add_host(target->scsi_host, host->dev->dev->dma_device)) 1508aef9ec39SRoland Dreier return -ENODEV; 1509aef9ec39SRoland Dreier 1510b3589fd4SMatthew Wilcox spin_lock(&host->target_lock); 1511aef9ec39SRoland Dreier list_add_tail(&target->list, &host->target_list); 1512b3589fd4SMatthew Wilcox spin_unlock(&host->target_lock); 1513aef9ec39SRoland Dreier 1514aef9ec39SRoland Dreier target->state = SRP_TARGET_LIVE; 1515aef9ec39SRoland Dreier 1516aef9ec39SRoland Dreier scsi_scan_target(&target->scsi_host->shost_gendev, 15171962a4a1SMatthew Wilcox 0, target->scsi_id, SCAN_WILD_CARD, 0); 1518aef9ec39SRoland Dreier 1519aef9ec39SRoland Dreier return 0; 1520aef9ec39SRoland Dreier } 1521aef9ec39SRoland Dreier 1522aef9ec39SRoland Dreier static void srp_release_class_dev(struct class_device *class_dev) 1523aef9ec39SRoland Dreier { 1524aef9ec39SRoland Dreier struct srp_host *host = 1525aef9ec39SRoland Dreier container_of(class_dev, struct srp_host, class_dev); 1526aef9ec39SRoland Dreier 1527aef9ec39SRoland Dreier complete(&host->released); 1528aef9ec39SRoland Dreier } 1529aef9ec39SRoland Dreier 1530aef9ec39SRoland Dreier static struct class srp_class = { 1531aef9ec39SRoland Dreier .name = "infiniband_srp", 1532aef9ec39SRoland Dreier .release = srp_release_class_dev 1533aef9ec39SRoland Dreier }; 1534aef9ec39SRoland Dreier 1535aef9ec39SRoland Dreier /* 1536aef9ec39SRoland Dreier * Target ports are added by writing 1537aef9ec39SRoland Dreier * 1538aef9ec39SRoland Dreier * id_ext=<SRP ID ext>,ioc_guid=<SRP IOC GUID>,dgid=<dest GID>, 1539aef9ec39SRoland Dreier * pkey=<P_Key>,service_id=<service ID> 1540aef9ec39SRoland Dreier * 1541aef9ec39SRoland Dreier * to the add_target sysfs attribute. 1542aef9ec39SRoland Dreier */ 1543aef9ec39SRoland Dreier enum { 1544aef9ec39SRoland Dreier SRP_OPT_ERR = 0, 1545aef9ec39SRoland Dreier SRP_OPT_ID_EXT = 1 << 0, 1546aef9ec39SRoland Dreier SRP_OPT_IOC_GUID = 1 << 1, 1547aef9ec39SRoland Dreier SRP_OPT_DGID = 1 << 2, 1548aef9ec39SRoland Dreier SRP_OPT_PKEY = 1 << 3, 1549aef9ec39SRoland Dreier SRP_OPT_SERVICE_ID = 1 << 4, 1550aef9ec39SRoland Dreier SRP_OPT_MAX_SECT = 1 << 5, 155152fb2b50SVu Pham SRP_OPT_MAX_CMD_PER_LUN = 1 << 6, 15520c0450dbSRamachandra K SRP_OPT_IO_CLASS = 1 << 7, 1553aef9ec39SRoland Dreier SRP_OPT_ALL = (SRP_OPT_ID_EXT | 1554aef9ec39SRoland Dreier SRP_OPT_IOC_GUID | 1555aef9ec39SRoland Dreier SRP_OPT_DGID | 1556aef9ec39SRoland Dreier SRP_OPT_PKEY | 1557aef9ec39SRoland Dreier SRP_OPT_SERVICE_ID), 1558aef9ec39SRoland Dreier }; 1559aef9ec39SRoland Dreier 1560aef9ec39SRoland Dreier static match_table_t srp_opt_tokens = { 1561aef9ec39SRoland Dreier { SRP_OPT_ID_EXT, "id_ext=%s" }, 1562aef9ec39SRoland Dreier { SRP_OPT_IOC_GUID, "ioc_guid=%s" }, 1563aef9ec39SRoland Dreier { SRP_OPT_DGID, "dgid=%s" }, 1564aef9ec39SRoland Dreier { SRP_OPT_PKEY, "pkey=%x" }, 1565aef9ec39SRoland Dreier { SRP_OPT_SERVICE_ID, "service_id=%s" }, 1566aef9ec39SRoland Dreier { SRP_OPT_MAX_SECT, "max_sect=%d" }, 156752fb2b50SVu Pham { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" }, 15680c0450dbSRamachandra K { SRP_OPT_IO_CLASS, "io_class=%x" }, 1569aef9ec39SRoland Dreier { SRP_OPT_ERR, NULL } 1570aef9ec39SRoland Dreier }; 1571aef9ec39SRoland Dreier 1572aef9ec39SRoland Dreier static int srp_parse_options(const char *buf, struct srp_target_port *target) 1573aef9ec39SRoland Dreier { 1574aef9ec39SRoland Dreier char *options, *sep_opt; 1575aef9ec39SRoland Dreier char *p; 1576aef9ec39SRoland Dreier char dgid[3]; 1577aef9ec39SRoland Dreier substring_t args[MAX_OPT_ARGS]; 1578aef9ec39SRoland Dreier int opt_mask = 0; 1579aef9ec39SRoland Dreier int token; 1580aef9ec39SRoland Dreier int ret = -EINVAL; 1581aef9ec39SRoland Dreier int i; 1582aef9ec39SRoland Dreier 1583aef9ec39SRoland Dreier options = kstrdup(buf, GFP_KERNEL); 1584aef9ec39SRoland Dreier if (!options) 1585aef9ec39SRoland Dreier return -ENOMEM; 1586aef9ec39SRoland Dreier 1587aef9ec39SRoland Dreier sep_opt = options; 1588aef9ec39SRoland Dreier while ((p = strsep(&sep_opt, ",")) != NULL) { 1589aef9ec39SRoland Dreier if (!*p) 1590aef9ec39SRoland Dreier continue; 1591aef9ec39SRoland Dreier 1592aef9ec39SRoland Dreier token = match_token(p, srp_opt_tokens, args); 1593aef9ec39SRoland Dreier opt_mask |= token; 1594aef9ec39SRoland Dreier 1595aef9ec39SRoland Dreier switch (token) { 1596aef9ec39SRoland Dreier case SRP_OPT_ID_EXT: 1597aef9ec39SRoland Dreier p = match_strdup(args); 1598aef9ec39SRoland Dreier target->id_ext = cpu_to_be64(simple_strtoull(p, NULL, 16)); 1599aef9ec39SRoland Dreier kfree(p); 1600aef9ec39SRoland Dreier break; 1601aef9ec39SRoland Dreier 1602aef9ec39SRoland Dreier case SRP_OPT_IOC_GUID: 1603aef9ec39SRoland Dreier p = match_strdup(args); 1604aef9ec39SRoland Dreier target->ioc_guid = cpu_to_be64(simple_strtoull(p, NULL, 16)); 1605aef9ec39SRoland Dreier kfree(p); 1606aef9ec39SRoland Dreier break; 1607aef9ec39SRoland Dreier 1608aef9ec39SRoland Dreier case SRP_OPT_DGID: 1609aef9ec39SRoland Dreier p = match_strdup(args); 1610aef9ec39SRoland Dreier if (strlen(p) != 32) { 1611aef9ec39SRoland Dreier printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p); 1612ce1823f0SRoland Dreier kfree(p); 1613aef9ec39SRoland Dreier goto out; 1614aef9ec39SRoland Dreier } 1615aef9ec39SRoland Dreier 1616aef9ec39SRoland Dreier for (i = 0; i < 16; ++i) { 1617aef9ec39SRoland Dreier strlcpy(dgid, p + i * 2, 3); 1618aef9ec39SRoland Dreier target->path.dgid.raw[i] = simple_strtoul(dgid, NULL, 16); 1619aef9ec39SRoland Dreier } 1620bf17c1c7SRoland Dreier kfree(p); 1621aef9ec39SRoland Dreier break; 1622aef9ec39SRoland Dreier 1623aef9ec39SRoland Dreier case SRP_OPT_PKEY: 1624aef9ec39SRoland Dreier if (match_hex(args, &token)) { 1625aef9ec39SRoland Dreier printk(KERN_WARNING PFX "bad P_Key parameter '%s'\n", p); 1626aef9ec39SRoland Dreier goto out; 1627aef9ec39SRoland Dreier } 1628aef9ec39SRoland Dreier target->path.pkey = cpu_to_be16(token); 1629aef9ec39SRoland Dreier break; 1630aef9ec39SRoland Dreier 1631aef9ec39SRoland Dreier case SRP_OPT_SERVICE_ID: 1632aef9ec39SRoland Dreier p = match_strdup(args); 1633aef9ec39SRoland Dreier target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16)); 1634aef9ec39SRoland Dreier kfree(p); 1635aef9ec39SRoland Dreier break; 1636aef9ec39SRoland Dreier 1637aef9ec39SRoland Dreier case SRP_OPT_MAX_SECT: 1638aef9ec39SRoland Dreier if (match_int(args, &token)) { 1639aef9ec39SRoland Dreier printk(KERN_WARNING PFX "bad max sect parameter '%s'\n", p); 1640aef9ec39SRoland Dreier goto out; 1641aef9ec39SRoland Dreier } 1642aef9ec39SRoland Dreier target->scsi_host->max_sectors = token; 1643aef9ec39SRoland Dreier break; 1644aef9ec39SRoland Dreier 164552fb2b50SVu Pham case SRP_OPT_MAX_CMD_PER_LUN: 164652fb2b50SVu Pham if (match_int(args, &token)) { 164752fb2b50SVu Pham printk(KERN_WARNING PFX "bad max cmd_per_lun parameter '%s'\n", p); 164852fb2b50SVu Pham goto out; 164952fb2b50SVu Pham } 165052fb2b50SVu Pham target->scsi_host->cmd_per_lun = min(token, SRP_SQ_SIZE); 165152fb2b50SVu Pham break; 165252fb2b50SVu Pham 16530c0450dbSRamachandra K case SRP_OPT_IO_CLASS: 16540c0450dbSRamachandra K if (match_hex(args, &token)) { 16550c0450dbSRamachandra K printk(KERN_WARNING PFX "bad IO class parameter '%s' \n", p); 16560c0450dbSRamachandra K goto out; 16570c0450dbSRamachandra K } 16580c0450dbSRamachandra K if (token != SRP_REV10_IB_IO_CLASS && 16590c0450dbSRamachandra K token != SRP_REV16A_IB_IO_CLASS) { 16600c0450dbSRamachandra K printk(KERN_WARNING PFX "unknown IO class parameter value" 16610c0450dbSRamachandra K " %x specified (use %x or %x).\n", 16620c0450dbSRamachandra K token, SRP_REV10_IB_IO_CLASS, SRP_REV16A_IB_IO_CLASS); 16630c0450dbSRamachandra K goto out; 16640c0450dbSRamachandra K } 16650c0450dbSRamachandra K target->io_class = token; 16660c0450dbSRamachandra K break; 16670c0450dbSRamachandra K 1668aef9ec39SRoland Dreier default: 1669aef9ec39SRoland Dreier printk(KERN_WARNING PFX "unknown parameter or missing value " 1670aef9ec39SRoland Dreier "'%s' in target creation request\n", p); 1671aef9ec39SRoland Dreier goto out; 1672aef9ec39SRoland Dreier } 1673aef9ec39SRoland Dreier } 1674aef9ec39SRoland Dreier 1675aef9ec39SRoland Dreier if ((opt_mask & SRP_OPT_ALL) == SRP_OPT_ALL) 1676aef9ec39SRoland Dreier ret = 0; 1677aef9ec39SRoland Dreier else 1678aef9ec39SRoland Dreier for (i = 0; i < ARRAY_SIZE(srp_opt_tokens); ++i) 1679aef9ec39SRoland Dreier if ((srp_opt_tokens[i].token & SRP_OPT_ALL) && 1680aef9ec39SRoland Dreier !(srp_opt_tokens[i].token & opt_mask)) 1681aef9ec39SRoland Dreier printk(KERN_WARNING PFX "target creation request is " 1682aef9ec39SRoland Dreier "missing parameter '%s'\n", 1683aef9ec39SRoland Dreier srp_opt_tokens[i].pattern); 1684aef9ec39SRoland Dreier 1685aef9ec39SRoland Dreier out: 1686aef9ec39SRoland Dreier kfree(options); 1687aef9ec39SRoland Dreier return ret; 1688aef9ec39SRoland Dreier } 1689aef9ec39SRoland Dreier 1690aef9ec39SRoland Dreier static ssize_t srp_create_target(struct class_device *class_dev, 1691aef9ec39SRoland Dreier const char *buf, size_t count) 1692aef9ec39SRoland Dreier { 1693aef9ec39SRoland Dreier struct srp_host *host = 1694aef9ec39SRoland Dreier container_of(class_dev, struct srp_host, class_dev); 1695aef9ec39SRoland Dreier struct Scsi_Host *target_host; 1696aef9ec39SRoland Dreier struct srp_target_port *target; 1697aef9ec39SRoland Dreier int ret; 1698aef9ec39SRoland Dreier int i; 1699aef9ec39SRoland Dreier 1700aef9ec39SRoland Dreier target_host = scsi_host_alloc(&srp_template, 1701aef9ec39SRoland Dreier sizeof (struct srp_target_port)); 1702aef9ec39SRoland Dreier if (!target_host) 1703aef9ec39SRoland Dreier return -ENOMEM; 1704aef9ec39SRoland Dreier 17055f068992SRoland Dreier target_host->max_lun = SRP_MAX_LUN; 17065f068992SRoland Dreier 1707aef9ec39SRoland Dreier target = host_to_target(target_host); 1708aef9ec39SRoland Dreier memset(target, 0, sizeof *target); 1709aef9ec39SRoland Dreier 17100c0450dbSRamachandra K target->io_class = SRP_REV16A_IB_IO_CLASS; 1711aef9ec39SRoland Dreier target->scsi_host = target_host; 1712aef9ec39SRoland Dreier target->srp_host = host; 1713aef9ec39SRoland Dreier 1714d945e1dfSRoland Dreier INIT_LIST_HEAD(&target->free_reqs); 1715aef9ec39SRoland Dreier INIT_LIST_HEAD(&target->req_queue); 1716d945e1dfSRoland Dreier for (i = 0; i < SRP_SQ_SIZE; ++i) { 1717d945e1dfSRoland Dreier target->req_ring[i].index = i; 1718d945e1dfSRoland Dreier list_add_tail(&target->req_ring[i].list, &target->free_reqs); 1719d945e1dfSRoland Dreier } 1720aef9ec39SRoland Dreier 1721aef9ec39SRoland Dreier ret = srp_parse_options(buf, target); 1722aef9ec39SRoland Dreier if (ret) 1723aef9ec39SRoland Dreier goto err; 1724aef9ec39SRoland Dreier 1725f5358a17SRoland Dreier ib_get_cached_gid(host->dev->dev, host->port, 0, &target->path.sgid); 1726aef9ec39SRoland Dreier 1727aef9ec39SRoland Dreier printk(KERN_DEBUG PFX "new target: id_ext %016llx ioc_guid %016llx pkey %04x " 1728aef9ec39SRoland Dreier "service_id %016llx dgid %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", 1729aef9ec39SRoland Dreier (unsigned long long) be64_to_cpu(target->id_ext), 1730aef9ec39SRoland Dreier (unsigned long long) be64_to_cpu(target->ioc_guid), 1731aef9ec39SRoland Dreier be16_to_cpu(target->path.pkey), 1732aef9ec39SRoland Dreier (unsigned long long) be64_to_cpu(target->service_id), 1733aef9ec39SRoland Dreier (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[0]), 1734aef9ec39SRoland Dreier (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[2]), 1735aef9ec39SRoland Dreier (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[4]), 1736aef9ec39SRoland Dreier (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[6]), 1737aef9ec39SRoland Dreier (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[8]), 1738aef9ec39SRoland Dreier (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[10]), 1739aef9ec39SRoland Dreier (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[12]), 1740aef9ec39SRoland Dreier (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[14])); 1741aef9ec39SRoland Dreier 1742aef9ec39SRoland Dreier ret = srp_create_target_ib(target); 1743aef9ec39SRoland Dreier if (ret) 1744aef9ec39SRoland Dreier goto err; 1745aef9ec39SRoland Dreier 1746f5358a17SRoland Dreier target->cm_id = ib_create_cm_id(host->dev->dev, srp_cm_handler, target); 1747aef9ec39SRoland Dreier if (IS_ERR(target->cm_id)) { 1748aef9ec39SRoland Dreier ret = PTR_ERR(target->cm_id); 1749aef9ec39SRoland Dreier goto err_free; 1750aef9ec39SRoland Dreier } 1751aef9ec39SRoland Dreier 1752aef9ec39SRoland Dreier ret = srp_connect_target(target); 1753aef9ec39SRoland Dreier if (ret) { 1754aef9ec39SRoland Dreier printk(KERN_ERR PFX "Connection failed\n"); 1755aef9ec39SRoland Dreier goto err_cm_id; 1756aef9ec39SRoland Dreier } 1757aef9ec39SRoland Dreier 1758aef9ec39SRoland Dreier ret = srp_add_target(host, target); 1759aef9ec39SRoland Dreier if (ret) 1760aef9ec39SRoland Dreier goto err_disconnect; 1761aef9ec39SRoland Dreier 1762aef9ec39SRoland Dreier return count; 1763aef9ec39SRoland Dreier 1764aef9ec39SRoland Dreier err_disconnect: 1765aef9ec39SRoland Dreier srp_disconnect_target(target); 1766aef9ec39SRoland Dreier 1767aef9ec39SRoland Dreier err_cm_id: 1768aef9ec39SRoland Dreier ib_destroy_cm_id(target->cm_id); 1769aef9ec39SRoland Dreier 1770aef9ec39SRoland Dreier err_free: 1771aef9ec39SRoland Dreier srp_free_target_ib(target); 1772aef9ec39SRoland Dreier 1773aef9ec39SRoland Dreier err: 1774aef9ec39SRoland Dreier scsi_host_put(target_host); 1775aef9ec39SRoland Dreier 1776aef9ec39SRoland Dreier return ret; 1777aef9ec39SRoland Dreier } 1778aef9ec39SRoland Dreier 1779aef9ec39SRoland Dreier static CLASS_DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target); 1780aef9ec39SRoland Dreier 1781aef9ec39SRoland Dreier static ssize_t show_ibdev(struct class_device *class_dev, char *buf) 1782aef9ec39SRoland Dreier { 1783aef9ec39SRoland Dreier struct srp_host *host = 1784aef9ec39SRoland Dreier container_of(class_dev, struct srp_host, class_dev); 1785aef9ec39SRoland Dreier 1786f5358a17SRoland Dreier return sprintf(buf, "%s\n", host->dev->dev->name); 1787aef9ec39SRoland Dreier } 1788aef9ec39SRoland Dreier 1789aef9ec39SRoland Dreier static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); 1790aef9ec39SRoland Dreier 1791aef9ec39SRoland Dreier static ssize_t show_port(struct class_device *class_dev, char *buf) 1792aef9ec39SRoland Dreier { 1793aef9ec39SRoland Dreier struct srp_host *host = 1794aef9ec39SRoland Dreier container_of(class_dev, struct srp_host, class_dev); 1795aef9ec39SRoland Dreier 1796aef9ec39SRoland Dreier return sprintf(buf, "%d\n", host->port); 1797aef9ec39SRoland Dreier } 1798aef9ec39SRoland Dreier 1799aef9ec39SRoland Dreier static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); 1800aef9ec39SRoland Dreier 1801f5358a17SRoland Dreier static struct srp_host *srp_add_port(struct srp_device *device, u8 port) 1802aef9ec39SRoland Dreier { 1803aef9ec39SRoland Dreier struct srp_host *host; 1804aef9ec39SRoland Dreier 1805aef9ec39SRoland Dreier host = kzalloc(sizeof *host, GFP_KERNEL); 1806aef9ec39SRoland Dreier if (!host) 1807aef9ec39SRoland Dreier return NULL; 1808aef9ec39SRoland Dreier 1809aef9ec39SRoland Dreier INIT_LIST_HEAD(&host->target_list); 1810b3589fd4SMatthew Wilcox spin_lock_init(&host->target_lock); 1811aef9ec39SRoland Dreier init_completion(&host->released); 1812aef9ec39SRoland Dreier host->dev = device; 1813aef9ec39SRoland Dreier host->port = port; 1814aef9ec39SRoland Dreier 1815aef9ec39SRoland Dreier host->initiator_port_id[7] = port; 1816f5358a17SRoland Dreier memcpy(host->initiator_port_id + 8, &device->dev->node_guid, 8); 1817aef9ec39SRoland Dreier 1818aef9ec39SRoland Dreier host->class_dev.class = &srp_class; 1819f5358a17SRoland Dreier host->class_dev.dev = device->dev->dma_device; 1820aef9ec39SRoland Dreier snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d", 1821f5358a17SRoland Dreier device->dev->name, port); 1822aef9ec39SRoland Dreier 1823aef9ec39SRoland Dreier if (class_device_register(&host->class_dev)) 1824f5358a17SRoland Dreier goto free_host; 1825aef9ec39SRoland Dreier if (class_device_create_file(&host->class_dev, &class_device_attr_add_target)) 1826aef9ec39SRoland Dreier goto err_class; 1827aef9ec39SRoland Dreier if (class_device_create_file(&host->class_dev, &class_device_attr_ibdev)) 1828aef9ec39SRoland Dreier goto err_class; 1829aef9ec39SRoland Dreier if (class_device_create_file(&host->class_dev, &class_device_attr_port)) 1830aef9ec39SRoland Dreier goto err_class; 1831aef9ec39SRoland Dreier 1832aef9ec39SRoland Dreier return host; 1833aef9ec39SRoland Dreier 1834aef9ec39SRoland Dreier err_class: 1835aef9ec39SRoland Dreier class_device_unregister(&host->class_dev); 1836aef9ec39SRoland Dreier 1837f5358a17SRoland Dreier free_host: 1838aef9ec39SRoland Dreier kfree(host); 1839aef9ec39SRoland Dreier 1840aef9ec39SRoland Dreier return NULL; 1841aef9ec39SRoland Dreier } 1842aef9ec39SRoland Dreier 1843aef9ec39SRoland Dreier static void srp_add_one(struct ib_device *device) 1844aef9ec39SRoland Dreier { 1845f5358a17SRoland Dreier struct srp_device *srp_dev; 1846f5358a17SRoland Dreier struct ib_device_attr *dev_attr; 1847f5358a17SRoland Dreier struct ib_fmr_pool_param fmr_param; 1848aef9ec39SRoland Dreier struct srp_host *host; 1849aef9ec39SRoland Dreier int s, e, p; 1850aef9ec39SRoland Dreier 1851f5358a17SRoland Dreier dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL); 1852f5358a17SRoland Dreier if (!dev_attr) 1853cf311cd4SSean Hefty return; 1854aef9ec39SRoland Dreier 1855f5358a17SRoland Dreier if (ib_query_device(device, dev_attr)) { 1856f5358a17SRoland Dreier printk(KERN_WARNING PFX "Query device failed for %s\n", 1857f5358a17SRoland Dreier device->name); 1858f5358a17SRoland Dreier goto free_attr; 1859f5358a17SRoland Dreier } 1860f5358a17SRoland Dreier 1861f5358a17SRoland Dreier srp_dev = kmalloc(sizeof *srp_dev, GFP_KERNEL); 1862f5358a17SRoland Dreier if (!srp_dev) 1863f5358a17SRoland Dreier goto free_attr; 1864f5358a17SRoland Dreier 1865f5358a17SRoland Dreier /* 1866f5358a17SRoland Dreier * Use the smallest page size supported by the HCA, down to a 1867f5358a17SRoland Dreier * minimum of 512 bytes (which is the smallest sector that a 1868f5358a17SRoland Dreier * SCSI command will ever carry). 1869f5358a17SRoland Dreier */ 1870f5358a17SRoland Dreier srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1); 1871f5358a17SRoland Dreier srp_dev->fmr_page_size = 1 << srp_dev->fmr_page_shift; 1872f5358a17SRoland Dreier srp_dev->fmr_page_mask = ~((unsigned long) srp_dev->fmr_page_size - 1); 1873f5358a17SRoland Dreier 1874f5358a17SRoland Dreier INIT_LIST_HEAD(&srp_dev->dev_list); 1875f5358a17SRoland Dreier 1876f5358a17SRoland Dreier srp_dev->dev = device; 1877f5358a17SRoland Dreier srp_dev->pd = ib_alloc_pd(device); 1878f5358a17SRoland Dreier if (IS_ERR(srp_dev->pd)) 1879f5358a17SRoland Dreier goto free_dev; 1880f5358a17SRoland Dreier 1881f5358a17SRoland Dreier srp_dev->mr = ib_get_dma_mr(srp_dev->pd, 1882f5358a17SRoland Dreier IB_ACCESS_LOCAL_WRITE | 1883f5358a17SRoland Dreier IB_ACCESS_REMOTE_READ | 1884f5358a17SRoland Dreier IB_ACCESS_REMOTE_WRITE); 1885f5358a17SRoland Dreier if (IS_ERR(srp_dev->mr)) 1886f5358a17SRoland Dreier goto err_pd; 1887f5358a17SRoland Dreier 1888f5358a17SRoland Dreier memset(&fmr_param, 0, sizeof fmr_param); 1889f5358a17SRoland Dreier fmr_param.pool_size = SRP_FMR_POOL_SIZE; 1890f5358a17SRoland Dreier fmr_param.dirty_watermark = SRP_FMR_DIRTY_SIZE; 1891f5358a17SRoland Dreier fmr_param.cache = 1; 1892f5358a17SRoland Dreier fmr_param.max_pages_per_fmr = SRP_FMR_SIZE; 1893f5358a17SRoland Dreier fmr_param.page_shift = srp_dev->fmr_page_shift; 1894f5358a17SRoland Dreier fmr_param.access = (IB_ACCESS_LOCAL_WRITE | 1895f5358a17SRoland Dreier IB_ACCESS_REMOTE_WRITE | 1896f5358a17SRoland Dreier IB_ACCESS_REMOTE_READ); 1897f5358a17SRoland Dreier 1898f5358a17SRoland Dreier srp_dev->fmr_pool = ib_create_fmr_pool(srp_dev->pd, &fmr_param); 1899f5358a17SRoland Dreier if (IS_ERR(srp_dev->fmr_pool)) 1900f5358a17SRoland Dreier srp_dev->fmr_pool = NULL; 1901aef9ec39SRoland Dreier 1902*07ebafbaSTom Tucker if (device->node_type == RDMA_NODE_IB_SWITCH) { 1903aef9ec39SRoland Dreier s = 0; 1904aef9ec39SRoland Dreier e = 0; 1905aef9ec39SRoland Dreier } else { 1906aef9ec39SRoland Dreier s = 1; 1907aef9ec39SRoland Dreier e = device->phys_port_cnt; 1908aef9ec39SRoland Dreier } 1909aef9ec39SRoland Dreier 1910aef9ec39SRoland Dreier for (p = s; p <= e; ++p) { 1911f5358a17SRoland Dreier host = srp_add_port(srp_dev, p); 1912aef9ec39SRoland Dreier if (host) 1913f5358a17SRoland Dreier list_add_tail(&host->list, &srp_dev->dev_list); 1914aef9ec39SRoland Dreier } 1915aef9ec39SRoland Dreier 1916f5358a17SRoland Dreier ib_set_client_data(device, &srp_client, srp_dev); 1917f5358a17SRoland Dreier 1918f5358a17SRoland Dreier goto free_attr; 1919f5358a17SRoland Dreier 1920f5358a17SRoland Dreier err_pd: 1921f5358a17SRoland Dreier ib_dealloc_pd(srp_dev->pd); 1922f5358a17SRoland Dreier 1923f5358a17SRoland Dreier free_dev: 1924f5358a17SRoland Dreier kfree(srp_dev); 1925f5358a17SRoland Dreier 1926f5358a17SRoland Dreier free_attr: 1927f5358a17SRoland Dreier kfree(dev_attr); 1928aef9ec39SRoland Dreier } 1929aef9ec39SRoland Dreier 1930aef9ec39SRoland Dreier static void srp_remove_one(struct ib_device *device) 1931aef9ec39SRoland Dreier { 1932f5358a17SRoland Dreier struct srp_device *srp_dev; 1933aef9ec39SRoland Dreier struct srp_host *host, *tmp_host; 1934aef9ec39SRoland Dreier LIST_HEAD(target_list); 1935aef9ec39SRoland Dreier struct srp_target_port *target, *tmp_target; 1936aef9ec39SRoland Dreier 1937f5358a17SRoland Dreier srp_dev = ib_get_client_data(device, &srp_client); 1938aef9ec39SRoland Dreier 1939f5358a17SRoland Dreier list_for_each_entry_safe(host, tmp_host, &srp_dev->dev_list, list) { 1940aef9ec39SRoland Dreier class_device_unregister(&host->class_dev); 1941aef9ec39SRoland Dreier /* 1942aef9ec39SRoland Dreier * Wait for the sysfs entry to go away, so that no new 1943aef9ec39SRoland Dreier * target ports can be created. 1944aef9ec39SRoland Dreier */ 1945aef9ec39SRoland Dreier wait_for_completion(&host->released); 1946aef9ec39SRoland Dreier 1947aef9ec39SRoland Dreier /* 1948aef9ec39SRoland Dreier * Mark all target ports as removed, so we stop queueing 1949aef9ec39SRoland Dreier * commands and don't try to reconnect. 1950aef9ec39SRoland Dreier */ 1951b3589fd4SMatthew Wilcox spin_lock(&host->target_lock); 1952549c5fc2SMatthew Wilcox list_for_each_entry(target, &host->target_list, list) { 19530c5b3952SIshai Rabinovitz spin_lock_irq(target->scsi_host->host_lock); 1954aef9ec39SRoland Dreier target->state = SRP_TARGET_REMOVED; 19550c5b3952SIshai Rabinovitz spin_unlock_irq(target->scsi_host->host_lock); 1956aef9ec39SRoland Dreier } 1957b3589fd4SMatthew Wilcox spin_unlock(&host->target_lock); 1958aef9ec39SRoland Dreier 1959aef9ec39SRoland Dreier /* 1960aef9ec39SRoland Dreier * Wait for any reconnection tasks that may have 1961aef9ec39SRoland Dreier * started before we marked our target ports as 1962aef9ec39SRoland Dreier * removed, and any target port removal tasks. 1963aef9ec39SRoland Dreier */ 1964aef9ec39SRoland Dreier flush_scheduled_work(); 1965aef9ec39SRoland Dreier 1966aef9ec39SRoland Dreier list_for_each_entry_safe(target, tmp_target, 1967aef9ec39SRoland Dreier &host->target_list, list) { 1968aef9ec39SRoland Dreier scsi_remove_host(target->scsi_host); 1969aef9ec39SRoland Dreier srp_disconnect_target(target); 1970aef9ec39SRoland Dreier ib_destroy_cm_id(target->cm_id); 1971aef9ec39SRoland Dreier srp_free_target_ib(target); 1972aef9ec39SRoland Dreier scsi_host_put(target->scsi_host); 1973aef9ec39SRoland Dreier } 1974aef9ec39SRoland Dreier 1975aef9ec39SRoland Dreier kfree(host); 1976aef9ec39SRoland Dreier } 1977aef9ec39SRoland Dreier 1978f5358a17SRoland Dreier if (srp_dev->fmr_pool) 1979f5358a17SRoland Dreier ib_destroy_fmr_pool(srp_dev->fmr_pool); 1980f5358a17SRoland Dreier ib_dereg_mr(srp_dev->mr); 1981f5358a17SRoland Dreier ib_dealloc_pd(srp_dev->pd); 1982f5358a17SRoland Dreier 1983f5358a17SRoland Dreier kfree(srp_dev); 1984aef9ec39SRoland Dreier } 1985aef9ec39SRoland Dreier 1986aef9ec39SRoland Dreier static int __init srp_init_module(void) 1987aef9ec39SRoland Dreier { 1988aef9ec39SRoland Dreier int ret; 1989aef9ec39SRoland Dreier 199074b0a15bSVu Pham srp_template.sg_tablesize = srp_sg_tablesize; 199174b0a15bSVu Pham srp_max_iu_len = (sizeof (struct srp_cmd) + 199274b0a15bSVu Pham sizeof (struct srp_indirect_buf) + 199374b0a15bSVu Pham srp_sg_tablesize * 16); 199474b0a15bSVu Pham 1995aef9ec39SRoland Dreier ret = class_register(&srp_class); 1996aef9ec39SRoland Dreier if (ret) { 1997aef9ec39SRoland Dreier printk(KERN_ERR PFX "couldn't register class infiniband_srp\n"); 1998aef9ec39SRoland Dreier return ret; 1999aef9ec39SRoland Dreier } 2000aef9ec39SRoland Dreier 2001aef9ec39SRoland Dreier ret = ib_register_client(&srp_client); 2002aef9ec39SRoland Dreier if (ret) { 2003aef9ec39SRoland Dreier printk(KERN_ERR PFX "couldn't register IB client\n"); 2004aef9ec39SRoland Dreier class_unregister(&srp_class); 2005aef9ec39SRoland Dreier return ret; 2006aef9ec39SRoland Dreier } 2007aef9ec39SRoland Dreier 2008aef9ec39SRoland Dreier return 0; 2009aef9ec39SRoland Dreier } 2010aef9ec39SRoland Dreier 2011aef9ec39SRoland Dreier static void __exit srp_cleanup_module(void) 2012aef9ec39SRoland Dreier { 2013aef9ec39SRoland Dreier ib_unregister_client(&srp_client); 2014aef9ec39SRoland Dreier class_unregister(&srp_class); 2015aef9ec39SRoland Dreier } 2016aef9ec39SRoland Dreier 2017aef9ec39SRoland Dreier module_init(srp_init_module); 2018aef9ec39SRoland Dreier module_exit(srp_cleanup_module); 2019