1 /* 2 * Copyright (c) 2010 Cisco Systems, Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program; if not, write to the Free Software Foundation, Inc., 15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 */ 17 18 /* XXX TBD some includes may be extraneous */ 19 20 #include <linux/module.h> 21 #include <linux/moduleparam.h> 22 #include <linux/version.h> 23 #include <generated/utsrelease.h> 24 #include <linux/utsname.h> 25 #include <linux/init.h> 26 #include <linux/slab.h> 27 #include <linux/kthread.h> 28 #include <linux/types.h> 29 #include <linux/string.h> 30 #include <linux/configfs.h> 31 #include <linux/ctype.h> 32 #include <linux/hash.h> 33 #include <linux/rcupdate.h> 34 #include <linux/rculist.h> 35 #include <linux/kref.h> 36 #include <asm/unaligned.h> 37 #include <scsi/scsi.h> 38 #include <scsi/scsi_host.h> 39 #include <scsi/scsi_device.h> 40 #include <scsi/scsi_cmnd.h> 41 #include <scsi/libfc.h> 42 43 #include <target/target_core_base.h> 44 #include <target/target_core_transport.h> 45 #include <target/target_core_fabric_ops.h> 46 #include <target/target_core_device.h> 47 #include <target/target_core_tpg.h> 48 #include <target/target_core_configfs.h> 49 #include <target/target_core_base.h> 50 #include <target/configfs_macros.h> 51 52 #include <scsi/libfc.h> 53 #include "tcm_fc.h" 54 55 static void ft_sess_delete_all(struct ft_tport *); 56 57 /* 58 * Lookup or allocate target local port. 59 * Caller holds ft_lport_lock. 60 */ 61 static struct ft_tport *ft_tport_create(struct fc_lport *lport) 62 { 63 struct ft_tpg *tpg; 64 struct ft_tport *tport; 65 int i; 66 67 tport = rcu_dereference(lport->prov[FC_TYPE_FCP]); 68 if (tport && tport->tpg) 69 return tport; 70 71 tpg = ft_lport_find_tpg(lport); 72 if (!tpg) 73 return NULL; 74 75 if (tport) { 76 tport->tpg = tpg; 77 return tport; 78 } 79 80 tport = kzalloc(sizeof(*tport), GFP_KERNEL); 81 if (!tport) 82 return NULL; 83 84 tport->lport = lport; 85 tport->tpg = tpg; 86 tpg->tport = tport; 87 for (i = 0; i < FT_SESS_HASH_SIZE; i++) 88 INIT_HLIST_HEAD(&tport->hash[i]); 89 90 rcu_assign_pointer(lport->prov[FC_TYPE_FCP], tport); 91 return tport; 92 } 93 94 /* 95 * Free tport via RCU. 96 */ 97 static void ft_tport_rcu_free(struct rcu_head *rcu) 98 { 99 struct ft_tport *tport = container_of(rcu, struct ft_tport, rcu); 100 101 kfree(tport); 102 } 103 104 /* 105 * Delete a target local port. 106 * Caller holds ft_lport_lock. 107 */ 108 static void ft_tport_delete(struct ft_tport *tport) 109 { 110 struct fc_lport *lport; 111 struct ft_tpg *tpg; 112 113 ft_sess_delete_all(tport); 114 lport = tport->lport; 115 BUG_ON(tport != lport->prov[FC_TYPE_FCP]); 116 rcu_assign_pointer(lport->prov[FC_TYPE_FCP], NULL); 117 118 tpg = tport->tpg; 119 if (tpg) { 120 tpg->tport = NULL; 121 tport->tpg = NULL; 122 } 123 call_rcu(&tport->rcu, ft_tport_rcu_free); 124 } 125 126 /* 127 * Add local port. 128 * Called thru fc_lport_iterate(). 129 */ 130 void ft_lport_add(struct fc_lport *lport, void *arg) 131 { 132 mutex_lock(&ft_lport_lock); 133 ft_tport_create(lport); 134 mutex_unlock(&ft_lport_lock); 135 } 136 137 /* 138 * Delete local port. 139 * Called thru fc_lport_iterate(). 140 */ 141 void ft_lport_del(struct fc_lport *lport, void *arg) 142 { 143 struct ft_tport *tport; 144 145 mutex_lock(&ft_lport_lock); 146 tport = lport->prov[FC_TYPE_FCP]; 147 if (tport) 148 ft_tport_delete(tport); 149 mutex_unlock(&ft_lport_lock); 150 } 151 152 /* 153 * Notification of local port change from libfc. 154 * Create or delete local port and associated tport. 155 */ 156 int ft_lport_notify(struct notifier_block *nb, unsigned long event, void *arg) 157 { 158 struct fc_lport *lport = arg; 159 160 switch (event) { 161 case FC_LPORT_EV_ADD: 162 ft_lport_add(lport, NULL); 163 break; 164 case FC_LPORT_EV_DEL: 165 ft_lport_del(lport, NULL); 166 break; 167 } 168 return NOTIFY_DONE; 169 } 170 171 /* 172 * Hash function for FC_IDs. 173 */ 174 static u32 ft_sess_hash(u32 port_id) 175 { 176 return hash_32(port_id, FT_SESS_HASH_BITS); 177 } 178 179 /* 180 * Find session in local port. 181 * Sessions and hash lists are RCU-protected. 182 * A reference is taken which must be eventually freed. 183 */ 184 static struct ft_sess *ft_sess_get(struct fc_lport *lport, u32 port_id) 185 { 186 struct ft_tport *tport; 187 struct hlist_head *head; 188 struct hlist_node *pos; 189 struct ft_sess *sess; 190 191 rcu_read_lock(); 192 tport = rcu_dereference(lport->prov[FC_TYPE_FCP]); 193 if (!tport) 194 goto out; 195 196 head = &tport->hash[ft_sess_hash(port_id)]; 197 hlist_for_each_entry_rcu(sess, pos, head, hash) { 198 if (sess->port_id == port_id) { 199 kref_get(&sess->kref); 200 rcu_read_unlock(); 201 pr_debug("port_id %x found %p\n", port_id, sess); 202 return sess; 203 } 204 } 205 out: 206 rcu_read_unlock(); 207 pr_debug("port_id %x not found\n", port_id); 208 return NULL; 209 } 210 211 /* 212 * Allocate session and enter it in the hash for the local port. 213 * Caller holds ft_lport_lock. 214 */ 215 static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id, 216 struct ft_node_acl *acl) 217 { 218 struct ft_sess *sess; 219 struct hlist_head *head; 220 struct hlist_node *pos; 221 222 head = &tport->hash[ft_sess_hash(port_id)]; 223 hlist_for_each_entry_rcu(sess, pos, head, hash) 224 if (sess->port_id == port_id) 225 return sess; 226 227 sess = kzalloc(sizeof(*sess), GFP_KERNEL); 228 if (!sess) 229 return NULL; 230 231 sess->se_sess = transport_init_session(); 232 if (IS_ERR(sess->se_sess)) { 233 kfree(sess); 234 return NULL; 235 } 236 sess->se_sess->se_node_acl = &acl->se_node_acl; 237 sess->tport = tport; 238 sess->port_id = port_id; 239 kref_init(&sess->kref); /* ref for table entry */ 240 hlist_add_head_rcu(&sess->hash, head); 241 tport->sess_count++; 242 243 pr_debug("port_id %x sess %p\n", port_id, sess); 244 245 transport_register_session(&tport->tpg->se_tpg, &acl->se_node_acl, 246 sess->se_sess, sess); 247 return sess; 248 } 249 250 /* 251 * Unhash the session. 252 * Caller holds ft_lport_lock. 253 */ 254 static void ft_sess_unhash(struct ft_sess *sess) 255 { 256 struct ft_tport *tport = sess->tport; 257 258 hlist_del_rcu(&sess->hash); 259 BUG_ON(!tport->sess_count); 260 tport->sess_count--; 261 sess->port_id = -1; 262 sess->params = 0; 263 } 264 265 /* 266 * Delete session from hash. 267 * Caller holds ft_lport_lock. 268 */ 269 static struct ft_sess *ft_sess_delete(struct ft_tport *tport, u32 port_id) 270 { 271 struct hlist_head *head; 272 struct hlist_node *pos; 273 struct ft_sess *sess; 274 275 head = &tport->hash[ft_sess_hash(port_id)]; 276 hlist_for_each_entry_rcu(sess, pos, head, hash) { 277 if (sess->port_id == port_id) { 278 ft_sess_unhash(sess); 279 return sess; 280 } 281 } 282 return NULL; 283 } 284 285 /* 286 * Delete all sessions from tport. 287 * Caller holds ft_lport_lock. 288 */ 289 static void ft_sess_delete_all(struct ft_tport *tport) 290 { 291 struct hlist_head *head; 292 struct hlist_node *pos; 293 struct ft_sess *sess; 294 295 for (head = tport->hash; 296 head < &tport->hash[FT_SESS_HASH_SIZE]; head++) { 297 hlist_for_each_entry_rcu(sess, pos, head, hash) { 298 ft_sess_unhash(sess); 299 transport_deregister_session_configfs(sess->se_sess); 300 ft_sess_put(sess); /* release from table */ 301 } 302 } 303 } 304 305 /* 306 * TCM ops for sessions. 307 */ 308 309 /* 310 * Determine whether session is allowed to be shutdown in the current context. 311 * Returns non-zero if the session should be shutdown. 312 */ 313 int ft_sess_shutdown(struct se_session *se_sess) 314 { 315 struct ft_sess *sess = se_sess->fabric_sess_ptr; 316 317 pr_debug("port_id %x\n", sess->port_id); 318 return 1; 319 } 320 321 /* 322 * Remove session and send PRLO. 323 * This is called when the ACL is being deleted or queue depth is changing. 324 */ 325 void ft_sess_close(struct se_session *se_sess) 326 { 327 struct ft_sess *sess = se_sess->fabric_sess_ptr; 328 struct fc_lport *lport; 329 u32 port_id; 330 331 mutex_lock(&ft_lport_lock); 332 lport = sess->tport->lport; 333 port_id = sess->port_id; 334 if (port_id == -1) { 335 mutex_unlock(&ft_lport_lock); 336 return; 337 } 338 pr_debug("port_id %x\n", port_id); 339 ft_sess_unhash(sess); 340 mutex_unlock(&ft_lport_lock); 341 transport_deregister_session_configfs(se_sess); 342 ft_sess_put(sess); 343 /* XXX Send LOGO or PRLO */ 344 synchronize_rcu(); /* let transport deregister happen */ 345 } 346 347 void ft_sess_stop(struct se_session *se_sess, int sess_sleep, int conn_sleep) 348 { 349 struct ft_sess *sess = se_sess->fabric_sess_ptr; 350 351 pr_debug("port_id %x\n", sess->port_id); 352 } 353 354 int ft_sess_logged_in(struct se_session *se_sess) 355 { 356 struct ft_sess *sess = se_sess->fabric_sess_ptr; 357 358 return sess->port_id != -1; 359 } 360 361 u32 ft_sess_get_index(struct se_session *se_sess) 362 { 363 struct ft_sess *sess = se_sess->fabric_sess_ptr; 364 365 return sess->port_id; /* XXX TBD probably not what is needed */ 366 } 367 368 u32 ft_sess_get_port_name(struct se_session *se_sess, 369 unsigned char *buf, u32 len) 370 { 371 struct ft_sess *sess = se_sess->fabric_sess_ptr; 372 373 return ft_format_wwn(buf, len, sess->port_name); 374 } 375 376 void ft_sess_set_erl0(struct se_session *se_sess) 377 { 378 /* XXX TBD called when out of memory */ 379 } 380 381 /* 382 * libfc ops involving sessions. 383 */ 384 385 static int ft_prli_locked(struct fc_rport_priv *rdata, u32 spp_len, 386 const struct fc_els_spp *rspp, struct fc_els_spp *spp) 387 { 388 struct ft_tport *tport; 389 struct ft_sess *sess; 390 struct ft_node_acl *acl; 391 u32 fcp_parm; 392 393 tport = ft_tport_create(rdata->local_port); 394 if (!tport) 395 return 0; /* not a target for this local port */ 396 397 acl = ft_acl_get(tport->tpg, rdata); 398 if (!acl) 399 return 0; 400 401 if (!rspp) 402 goto fill; 403 404 if (rspp->spp_flags & (FC_SPP_OPA_VAL | FC_SPP_RPA_VAL)) 405 return FC_SPP_RESP_NO_PA; 406 407 /* 408 * If both target and initiator bits are off, the SPP is invalid. 409 */ 410 fcp_parm = ntohl(rspp->spp_params); 411 if (!(fcp_parm & (FCP_SPPF_INIT_FCN | FCP_SPPF_TARG_FCN))) 412 return FC_SPP_RESP_INVL; 413 414 /* 415 * Create session (image pair) only if requested by 416 * EST_IMG_PAIR flag and if the requestor is an initiator. 417 */ 418 if (rspp->spp_flags & FC_SPP_EST_IMG_PAIR) { 419 spp->spp_flags |= FC_SPP_EST_IMG_PAIR; 420 if (!(fcp_parm & FCP_SPPF_INIT_FCN)) 421 return FC_SPP_RESP_CONF; 422 sess = ft_sess_create(tport, rdata->ids.port_id, acl); 423 if (!sess) 424 return FC_SPP_RESP_RES; 425 if (!sess->params) 426 rdata->prli_count++; 427 sess->params = fcp_parm; 428 sess->port_name = rdata->ids.port_name; 429 sess->max_frame = rdata->maxframe_size; 430 431 /* XXX TBD - clearing actions. unit attn, see 4.10 */ 432 } 433 434 /* 435 * OR in our service parameters with other provider (initiator), if any. 436 * TBD XXX - indicate RETRY capability? 437 */ 438 fill: 439 fcp_parm = ntohl(spp->spp_params); 440 spp->spp_params = htonl(fcp_parm | FCP_SPPF_TARG_FCN); 441 return FC_SPP_RESP_ACK; 442 } 443 444 /** 445 * tcm_fcp_prli() - Handle incoming or outgoing PRLI for the FCP target 446 * @rdata: remote port private 447 * @spp_len: service parameter page length 448 * @rspp: received service parameter page (NULL for outgoing PRLI) 449 * @spp: response service parameter page 450 * 451 * Returns spp response code. 452 */ 453 static int ft_prli(struct fc_rport_priv *rdata, u32 spp_len, 454 const struct fc_els_spp *rspp, struct fc_els_spp *spp) 455 { 456 int ret; 457 458 mutex_lock(&ft_lport_lock); 459 ret = ft_prli_locked(rdata, spp_len, rspp, spp); 460 mutex_unlock(&ft_lport_lock); 461 pr_debug("port_id %x flags %x ret %x\n", 462 rdata->ids.port_id, rspp ? rspp->spp_flags : 0, ret); 463 return ret; 464 } 465 466 static void ft_sess_rcu_free(struct rcu_head *rcu) 467 { 468 struct ft_sess *sess = container_of(rcu, struct ft_sess, rcu); 469 470 transport_deregister_session(sess->se_sess); 471 kfree(sess); 472 } 473 474 static void ft_sess_free(struct kref *kref) 475 { 476 struct ft_sess *sess = container_of(kref, struct ft_sess, kref); 477 478 call_rcu(&sess->rcu, ft_sess_rcu_free); 479 } 480 481 void ft_sess_put(struct ft_sess *sess) 482 { 483 int sess_held = atomic_read(&sess->kref.refcount); 484 485 BUG_ON(!sess_held); 486 kref_put(&sess->kref, ft_sess_free); 487 } 488 489 static void ft_prlo(struct fc_rport_priv *rdata) 490 { 491 struct ft_sess *sess; 492 struct ft_tport *tport; 493 494 mutex_lock(&ft_lport_lock); 495 tport = rcu_dereference(rdata->local_port->prov[FC_TYPE_FCP]); 496 if (!tport) { 497 mutex_unlock(&ft_lport_lock); 498 return; 499 } 500 sess = ft_sess_delete(tport, rdata->ids.port_id); 501 if (!sess) { 502 mutex_unlock(&ft_lport_lock); 503 return; 504 } 505 mutex_unlock(&ft_lport_lock); 506 transport_deregister_session_configfs(sess->se_sess); 507 ft_sess_put(sess); /* release from table */ 508 rdata->prli_count--; 509 /* XXX TBD - clearing actions. unit attn, see 4.10 */ 510 } 511 512 /* 513 * Handle incoming FCP request. 514 * Caller has verified that the frame is type FCP. 515 */ 516 static void ft_recv(struct fc_lport *lport, struct fc_frame *fp) 517 { 518 struct ft_sess *sess; 519 u32 sid = fc_frame_sid(fp); 520 521 pr_debug("sid %x\n", sid); 522 523 sess = ft_sess_get(lport, sid); 524 if (!sess) { 525 pr_debug("sid %x sess lookup failed\n", sid); 526 /* TBD XXX - if FCP_CMND, send PRLO */ 527 fc_frame_free(fp); 528 return; 529 } 530 ft_recv_req(sess, fp); /* must do ft_sess_put() */ 531 } 532 533 /* 534 * Provider ops for libfc. 535 */ 536 struct fc4_prov ft_prov = { 537 .prli = ft_prli, 538 .prlo = ft_prlo, 539 .recv = ft_recv, 540 .module = THIS_MODULE, 541 }; 542