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

[SCSI] libfc: A modular Fibre Channel library

libFC is composed of 4 blocks supported by an exchange manager
and a framing library. The upper 4 layers are fc_lport, fc_disc,
fc_rport and fc_fcp. A LLD that uses libfc could choose to
either use libfc's block, or using the transport template
defined in libfc.h, override one or more blocks with its own
implementation.

The EM (Exchange Manager) manages exhcanges/sequences for all
commands- ELS, CT and FCP.

The framing library frames ELS and CT commands.

The fc_lport block manages the library's representation of the
host's FC enabled ports.

The fc_disc block manages discovery of targets as well as
handling changes that occur in the FC fabric (via. RSCN events).

The fc_rport block manages the library's representation of other
entities in the FC fabric. Currently the library uses this block
for targets, its peer when in point-to-point mode and the
directory server, but can be extended for other entities if
needed.

The fc_fcp block interacts with the scsi-ml and handles all
I/O.

Signed-off-by: Robert Love <robert.w.love@intel.com>
[jejb: added include of delay.h to fix ppc64 compile prob spotted by sfr]
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

authored by

Robert Love and committed by
James Bottomley
42e9a92f f032c2f7

+9509
+6
drivers/scsi/Kconfig
··· 603 603 substantial, so users of MultiMaster Host Adapters may not 604 604 wish to include it. 605 605 606 + config LIBFC 607 + tristate "LibFC module" 608 + depends on SCSI && SCSI_FC_ATTRS 609 + ---help--- 610 + Fibre Channel library module 611 + 606 612 config SCSI_DMX3191D 607 613 tristate "DMX3191D SCSI support" 608 614 depends on PCI && SCSI
+1
drivers/scsi/Makefile
··· 36 36 obj-$(CONFIG_SCSI_SRP_ATTRS) += scsi_transport_srp.o 37 37 obj-$(CONFIG_SCSI_DH) += device_handler/ 38 38 39 + obj-$(CONFIG_LIBFC) += libfc/ 39 40 obj-$(CONFIG_ISCSI_TCP) += libiscsi.o libiscsi_tcp.o iscsi_tcp.o 40 41 obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o 41 42 obj-$(CONFIG_SCSI_A4000T) += 53c700.o a4000t.o
+12
drivers/scsi/libfc/Makefile
··· 1 + # $Id: Makefile 2 + 3 + obj-$(CONFIG_LIBFC) += libfc.o 4 + 5 + libfc-objs := \ 6 + fc_disc.o \ 7 + fc_exch.o \ 8 + fc_elsct.o \ 9 + fc_frame.o \ 10 + fc_lport.o \ 11 + fc_rport.o \ 12 + fc_fcp.o
+845
drivers/scsi/libfc/fc_disc.c
··· 1 + /* 2 + * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. 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 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + /* 21 + * Target Discovery 22 + * 23 + * This block discovers all FC-4 remote ports, including FCP initiators. It 24 + * also handles RSCN events and re-discovery if necessary. 25 + */ 26 + 27 + /* 28 + * DISC LOCKING 29 + * 30 + * The disc mutex is can be locked when acquiring rport locks, but may not 31 + * be held when acquiring the lport lock. Refer to fc_lport.c for more 32 + * details. 33 + */ 34 + 35 + #include <linux/timer.h> 36 + #include <linux/err.h> 37 + #include <asm/unaligned.h> 38 + 39 + #include <scsi/fc/fc_gs.h> 40 + 41 + #include <scsi/libfc.h> 42 + 43 + #define FC_DISC_RETRY_LIMIT 3 /* max retries */ 44 + #define FC_DISC_RETRY_DELAY 500UL /* (msecs) delay */ 45 + 46 + #define FC_DISC_DELAY 3 47 + 48 + static int fc_disc_debug; 49 + 50 + #define FC_DEBUG_DISC(fmt...) \ 51 + do { \ 52 + if (fc_disc_debug) \ 53 + FC_DBG(fmt); \ 54 + } while (0) 55 + 56 + static void fc_disc_gpn_ft_req(struct fc_disc *); 57 + static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); 58 + static int fc_disc_new_target(struct fc_disc *, struct fc_rport *, 59 + struct fc_rport_identifiers *); 60 + static void fc_disc_del_target(struct fc_disc *, struct fc_rport *); 61 + static void fc_disc_done(struct fc_disc *); 62 + static void fc_disc_timeout(struct work_struct *); 63 + static void fc_disc_single(struct fc_disc *, struct fc_disc_port *); 64 + static void fc_disc_restart(struct fc_disc *); 65 + 66 + /** 67 + * fc_disc_lookup_rport - lookup a remote port by port_id 68 + * @lport: Fibre Channel host port instance 69 + * @port_id: remote port port_id to match 70 + */ 71 + struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport, 72 + u32 port_id) 73 + { 74 + const struct fc_disc *disc = &lport->disc; 75 + struct fc_rport *rport, *found = NULL; 76 + struct fc_rport_libfc_priv *rdata; 77 + int disc_found = 0; 78 + 79 + list_for_each_entry(rdata, &disc->rports, peers) { 80 + rport = PRIV_TO_RPORT(rdata); 81 + if (rport->port_id == port_id) { 82 + disc_found = 1; 83 + found = rport; 84 + break; 85 + } 86 + } 87 + 88 + if (!disc_found) 89 + found = NULL; 90 + 91 + return found; 92 + } 93 + 94 + /** 95 + * fc_disc_stop_rports - delete all the remote ports associated with the lport 96 + * @disc: The discovery job to stop rports on 97 + * 98 + * Locking Note: This function expects that the lport mutex is locked before 99 + * calling it. 100 + */ 101 + void fc_disc_stop_rports(struct fc_disc *disc) 102 + { 103 + struct fc_lport *lport; 104 + struct fc_rport *rport; 105 + struct fc_rport_libfc_priv *rdata, *next; 106 + 107 + lport = disc->lport; 108 + 109 + mutex_lock(&disc->disc_mutex); 110 + list_for_each_entry_safe(rdata, next, &disc->rports, peers) { 111 + rport = PRIV_TO_RPORT(rdata); 112 + list_del(&rdata->peers); 113 + lport->tt.rport_logoff(rport); 114 + } 115 + 116 + mutex_unlock(&disc->disc_mutex); 117 + } 118 + 119 + /** 120 + * fc_disc_rport_callback - Event handler for rport events 121 + * @lport: The lport which is receiving the event 122 + * @rport: The rport which the event has occured on 123 + * @event: The event that occured 124 + * 125 + * Locking Note: The rport lock should not be held when calling 126 + * this function. 127 + */ 128 + static void fc_disc_rport_callback(struct fc_lport *lport, 129 + struct fc_rport *rport, 130 + enum fc_rport_event event) 131 + { 132 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 133 + struct fc_disc *disc = &lport->disc; 134 + int found = 0; 135 + 136 + FC_DEBUG_DISC("Received a %d event for port (%6x)\n", event, 137 + rport->port_id); 138 + 139 + if (event == RPORT_EV_CREATED) { 140 + if (disc) { 141 + found = 1; 142 + mutex_lock(&disc->disc_mutex); 143 + list_add_tail(&rdata->peers, &disc->rports); 144 + mutex_unlock(&disc->disc_mutex); 145 + } 146 + } 147 + 148 + if (!found) 149 + FC_DEBUG_DISC("The rport (%6x) is not maintained " 150 + "by the discovery layer\n", rport->port_id); 151 + } 152 + 153 + /** 154 + * fc_disc_recv_rscn_req - Handle Registered State Change Notification (RSCN) 155 + * @sp: Current sequence of the RSCN exchange 156 + * @fp: RSCN Frame 157 + * @lport: Fibre Channel host port instance 158 + * 159 + * Locking Note: This function expects that the disc_mutex is locked 160 + * before it is called. 161 + */ 162 + static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, 163 + struct fc_disc *disc) 164 + { 165 + struct fc_lport *lport; 166 + struct fc_rport *rport; 167 + struct fc_rport_libfc_priv *rdata; 168 + struct fc_els_rscn *rp; 169 + struct fc_els_rscn_page *pp; 170 + struct fc_seq_els_data rjt_data; 171 + unsigned int len; 172 + int redisc = 0; 173 + enum fc_els_rscn_ev_qual ev_qual; 174 + enum fc_els_rscn_addr_fmt fmt; 175 + LIST_HEAD(disc_ports); 176 + struct fc_disc_port *dp, *next; 177 + 178 + lport = disc->lport; 179 + 180 + FC_DEBUG_DISC("Received an RSCN event on port (%6x)\n", 181 + fc_host_port_id(lport->host)); 182 + 183 + /* make sure the frame contains an RSCN message */ 184 + rp = fc_frame_payload_get(fp, sizeof(*rp)); 185 + if (!rp) 186 + goto reject; 187 + /* make sure the page length is as expected (4 bytes) */ 188 + if (rp->rscn_page_len != sizeof(*pp)) 189 + goto reject; 190 + /* get the RSCN payload length */ 191 + len = ntohs(rp->rscn_plen); 192 + if (len < sizeof(*rp)) 193 + goto reject; 194 + /* make sure the frame contains the expected payload */ 195 + rp = fc_frame_payload_get(fp, len); 196 + if (!rp) 197 + goto reject; 198 + /* payload must be a multiple of the RSCN page size */ 199 + len -= sizeof(*rp); 200 + if (len % sizeof(*pp)) 201 + goto reject; 202 + 203 + for (pp = (void *)(rp + 1); len > 0; len -= sizeof(*pp), pp++) { 204 + ev_qual = pp->rscn_page_flags >> ELS_RSCN_EV_QUAL_BIT; 205 + ev_qual &= ELS_RSCN_EV_QUAL_MASK; 206 + fmt = pp->rscn_page_flags >> ELS_RSCN_ADDR_FMT_BIT; 207 + fmt &= ELS_RSCN_ADDR_FMT_MASK; 208 + /* 209 + * if we get an address format other than port 210 + * (area, domain, fabric), then do a full discovery 211 + */ 212 + switch (fmt) { 213 + case ELS_ADDR_FMT_PORT: 214 + FC_DEBUG_DISC("Port address format for port (%6x)\n", 215 + ntoh24(pp->rscn_fid)); 216 + dp = kzalloc(sizeof(*dp), GFP_KERNEL); 217 + if (!dp) { 218 + redisc = 1; 219 + break; 220 + } 221 + dp->lp = lport; 222 + dp->ids.port_id = ntoh24(pp->rscn_fid); 223 + dp->ids.port_name = -1; 224 + dp->ids.node_name = -1; 225 + dp->ids.roles = FC_RPORT_ROLE_UNKNOWN; 226 + list_add_tail(&dp->peers, &disc_ports); 227 + break; 228 + case ELS_ADDR_FMT_AREA: 229 + case ELS_ADDR_FMT_DOM: 230 + case ELS_ADDR_FMT_FAB: 231 + default: 232 + FC_DEBUG_DISC("Address format is (%d)\n", fmt); 233 + redisc = 1; 234 + break; 235 + } 236 + } 237 + lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); 238 + if (redisc) { 239 + FC_DEBUG_DISC("RSCN received: rediscovering\n"); 240 + fc_disc_restart(disc); 241 + } else { 242 + FC_DEBUG_DISC("RSCN received: not rediscovering. " 243 + "redisc %d state %d in_prog %d\n", 244 + redisc, lport->state, disc->pending); 245 + list_for_each_entry_safe(dp, next, &disc_ports, peers) { 246 + list_del(&dp->peers); 247 + rport = lport->tt.rport_lookup(lport, dp->ids.port_id); 248 + if (rport) { 249 + rdata = RPORT_TO_PRIV(rport); 250 + list_del(&rdata->peers); 251 + lport->tt.rport_logoff(rport); 252 + } 253 + fc_disc_single(disc, dp); 254 + } 255 + } 256 + fc_frame_free(fp); 257 + return; 258 + reject: 259 + FC_DEBUG_DISC("Received a bad RSCN frame\n"); 260 + rjt_data.fp = NULL; 261 + rjt_data.reason = ELS_RJT_LOGIC; 262 + rjt_data.explan = ELS_EXPL_NONE; 263 + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 264 + fc_frame_free(fp); 265 + } 266 + 267 + /** 268 + * fc_disc_recv_req - Handle incoming requests 269 + * @sp: Current sequence of the request exchange 270 + * @fp: The frame 271 + * @lport: The FC local port 272 + * 273 + * Locking Note: This function is called from the EM and will lock 274 + * the disc_mutex before calling the handler for the 275 + * request. 276 + */ 277 + static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp, 278 + struct fc_lport *lport) 279 + { 280 + u8 op; 281 + struct fc_disc *disc = &lport->disc; 282 + 283 + op = fc_frame_payload_op(fp); 284 + switch (op) { 285 + case ELS_RSCN: 286 + mutex_lock(&disc->disc_mutex); 287 + fc_disc_recv_rscn_req(sp, fp, disc); 288 + mutex_unlock(&disc->disc_mutex); 289 + break; 290 + default: 291 + FC_DBG("Received an unsupported request. opcode (%x)\n", op); 292 + break; 293 + } 294 + } 295 + 296 + /** 297 + * fc_disc_restart - Restart discovery 298 + * @lport: FC discovery context 299 + * 300 + * Locking Note: This function expects that the disc mutex 301 + * is already locked. 302 + */ 303 + static void fc_disc_restart(struct fc_disc *disc) 304 + { 305 + struct fc_rport *rport; 306 + struct fc_rport_libfc_priv *rdata, *next; 307 + struct fc_lport *lport = disc->lport; 308 + 309 + FC_DEBUG_DISC("Restarting discovery for port (%6x)\n", 310 + fc_host_port_id(lport->host)); 311 + 312 + list_for_each_entry_safe(rdata, next, &disc->rports, peers) { 313 + rport = PRIV_TO_RPORT(rdata); 314 + FC_DEBUG_DISC("list_del(%6x)\n", rport->port_id); 315 + list_del(&rdata->peers); 316 + lport->tt.rport_logoff(rport); 317 + } 318 + 319 + disc->requested = 1; 320 + if (!disc->pending) 321 + fc_disc_gpn_ft_req(disc); 322 + } 323 + 324 + /** 325 + * fc_disc_start - Fibre Channel Target discovery 326 + * @lport: FC local port 327 + * 328 + * Returns non-zero if discovery cannot be started. 329 + */ 330 + static void fc_disc_start(void (*disc_callback)(struct fc_lport *, 331 + enum fc_disc_event), 332 + struct fc_lport *lport) 333 + { 334 + struct fc_rport *rport; 335 + struct fc_rport_identifiers ids; 336 + struct fc_disc *disc = &lport->disc; 337 + 338 + /* 339 + * At this point we may have a new disc job or an existing 340 + * one. Either way, let's lock when we make changes to it 341 + * and send the GPN_FT request. 342 + */ 343 + mutex_lock(&disc->disc_mutex); 344 + 345 + disc->disc_callback = disc_callback; 346 + 347 + /* 348 + * If not ready, or already running discovery, just set request flag. 349 + */ 350 + disc->requested = 1; 351 + 352 + if (disc->pending) { 353 + mutex_unlock(&disc->disc_mutex); 354 + return; 355 + } 356 + 357 + /* 358 + * Handle point-to-point mode as a simple discovery 359 + * of the remote port. Yucky, yucky, yuck, yuck! 360 + */ 361 + rport = disc->lport->ptp_rp; 362 + if (rport) { 363 + ids.port_id = rport->port_id; 364 + ids.port_name = rport->port_name; 365 + ids.node_name = rport->node_name; 366 + ids.roles = FC_RPORT_ROLE_UNKNOWN; 367 + get_device(&rport->dev); 368 + 369 + if (!fc_disc_new_target(disc, rport, &ids)) { 370 + disc->event = DISC_EV_SUCCESS; 371 + fc_disc_done(disc); 372 + } 373 + put_device(&rport->dev); 374 + } else { 375 + fc_disc_gpn_ft_req(disc); /* get ports by FC-4 type */ 376 + } 377 + 378 + mutex_unlock(&disc->disc_mutex); 379 + } 380 + 381 + static struct fc_rport_operations fc_disc_rport_ops = { 382 + .event_callback = fc_disc_rport_callback, 383 + }; 384 + 385 + /** 386 + * fc_disc_new_target - Handle new target found by discovery 387 + * @lport: FC local port 388 + * @rport: The previous FC remote port (NULL if new remote port) 389 + * @ids: Identifiers for the new FC remote port 390 + * 391 + * Locking Note: This function expects that the disc_mutex is locked 392 + * before it is called. 393 + */ 394 + static int fc_disc_new_target(struct fc_disc *disc, 395 + struct fc_rport *rport, 396 + struct fc_rport_identifiers *ids) 397 + { 398 + struct fc_lport *lport = disc->lport; 399 + struct fc_rport_libfc_priv *rp; 400 + int error = 0; 401 + 402 + if (rport && ids->port_name) { 403 + if (rport->port_name == -1) { 404 + /* 405 + * Set WWN and fall through to notify of create. 406 + */ 407 + fc_rport_set_name(rport, ids->port_name, 408 + rport->node_name); 409 + } else if (rport->port_name != ids->port_name) { 410 + /* 411 + * This is a new port with the same FCID as 412 + * a previously-discovered port. Presumably the old 413 + * port logged out and a new port logged in and was 414 + * assigned the same FCID. This should be rare. 415 + * Delete the old one and fall thru to re-create. 416 + */ 417 + fc_disc_del_target(disc, rport); 418 + rport = NULL; 419 + } 420 + } 421 + if (((ids->port_name != -1) || (ids->port_id != -1)) && 422 + ids->port_id != fc_host_port_id(lport->host) && 423 + ids->port_name != lport->wwpn) { 424 + if (!rport) { 425 + rport = lport->tt.rport_lookup(lport, ids->port_id); 426 + if (!rport) { 427 + struct fc_disc_port dp; 428 + dp.lp = lport; 429 + dp.ids.port_id = ids->port_id; 430 + dp.ids.port_name = ids->port_name; 431 + dp.ids.node_name = ids->node_name; 432 + dp.ids.roles = ids->roles; 433 + rport = fc_rport_rogue_create(&dp); 434 + } 435 + if (!rport) 436 + error = -ENOMEM; 437 + } 438 + if (rport) { 439 + rp = rport->dd_data; 440 + rp->ops = &fc_disc_rport_ops; 441 + rp->rp_state = RPORT_ST_INIT; 442 + lport->tt.rport_login(rport); 443 + } 444 + } 445 + return error; 446 + } 447 + 448 + /** 449 + * fc_disc_del_target - Delete a target 450 + * @disc: FC discovery context 451 + * @rport: The remote port to be removed 452 + */ 453 + static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport) 454 + { 455 + struct fc_lport *lport = disc->lport; 456 + struct fc_rport_libfc_priv *rdata = RPORT_TO_PRIV(rport); 457 + list_del(&rdata->peers); 458 + lport->tt.rport_logoff(rport); 459 + } 460 + 461 + /** 462 + * fc_disc_done - Discovery has been completed 463 + * @disc: FC discovery context 464 + */ 465 + static void fc_disc_done(struct fc_disc *disc) 466 + { 467 + struct fc_lport *lport = disc->lport; 468 + 469 + FC_DEBUG_DISC("Discovery complete for port (%6x)\n", 470 + fc_host_port_id(lport->host)); 471 + 472 + disc->disc_callback(lport, disc->event); 473 + disc->event = DISC_EV_NONE; 474 + 475 + if (disc->requested) 476 + fc_disc_gpn_ft_req(disc); 477 + else 478 + disc->pending = 0; 479 + } 480 + 481 + /** 482 + * fc_disc_error - Handle error on dNS request 483 + * @disc: FC discovery context 484 + * @fp: The frame pointer 485 + */ 486 + static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp) 487 + { 488 + struct fc_lport *lport = disc->lport; 489 + unsigned long delay = 0; 490 + if (fc_disc_debug) 491 + FC_DBG("Error %ld, retries %d/%d\n", 492 + PTR_ERR(fp), disc->retry_count, 493 + FC_DISC_RETRY_LIMIT); 494 + 495 + if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { 496 + /* 497 + * Memory allocation failure, or the exchange timed out, 498 + * retry after delay. 499 + */ 500 + if (disc->retry_count < FC_DISC_RETRY_LIMIT) { 501 + /* go ahead and retry */ 502 + if (!fp) 503 + delay = msecs_to_jiffies(FC_DISC_RETRY_DELAY); 504 + else { 505 + delay = msecs_to_jiffies(lport->e_d_tov); 506 + 507 + /* timeout faster first time */ 508 + if (!disc->retry_count) 509 + delay /= 4; 510 + } 511 + disc->retry_count++; 512 + schedule_delayed_work(&disc->disc_work, delay); 513 + } else { 514 + /* exceeded retries */ 515 + disc->event = DISC_EV_FAILED; 516 + fc_disc_done(disc); 517 + } 518 + } 519 + } 520 + 521 + /** 522 + * fc_disc_gpn_ft_req - Send Get Port Names by FC-4 type (GPN_FT) request 523 + * @lport: FC discovery context 524 + * 525 + * Locking Note: This function expects that the disc_mutex is locked 526 + * before it is called. 527 + */ 528 + static void fc_disc_gpn_ft_req(struct fc_disc *disc) 529 + { 530 + struct fc_frame *fp; 531 + struct fc_lport *lport = disc->lport; 532 + 533 + WARN_ON(!fc_lport_test_ready(lport)); 534 + 535 + disc->pending = 1; 536 + disc->requested = 0; 537 + 538 + disc->buf_len = 0; 539 + disc->seq_count = 0; 540 + fp = fc_frame_alloc(lport, 541 + sizeof(struct fc_ct_hdr) + 542 + sizeof(struct fc_ns_gid_ft)); 543 + if (!fp) 544 + goto err; 545 + 546 + if (lport->tt.elsct_send(lport, NULL, fp, 547 + FC_NS_GPN_FT, 548 + fc_disc_gpn_ft_resp, 549 + disc, lport->e_d_tov)) 550 + return; 551 + err: 552 + fc_disc_error(disc, fp); 553 + } 554 + 555 + /** 556 + * fc_disc_gpn_ft_parse - Parse the list of IDs and names resulting from a request 557 + * @lport: Fibre Channel host port instance 558 + * @buf: GPN_FT response buffer 559 + * @len: size of response buffer 560 + */ 561 + static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) 562 + { 563 + struct fc_lport *lport; 564 + struct fc_gpn_ft_resp *np; 565 + char *bp; 566 + size_t plen; 567 + size_t tlen; 568 + int error = 0; 569 + struct fc_disc_port dp; 570 + struct fc_rport *rport; 571 + struct fc_rport_libfc_priv *rdata; 572 + 573 + lport = disc->lport; 574 + 575 + /* 576 + * Handle partial name record left over from previous call. 577 + */ 578 + bp = buf; 579 + plen = len; 580 + np = (struct fc_gpn_ft_resp *)bp; 581 + tlen = disc->buf_len; 582 + if (tlen) { 583 + WARN_ON(tlen >= sizeof(*np)); 584 + plen = sizeof(*np) - tlen; 585 + WARN_ON(plen <= 0); 586 + WARN_ON(plen >= sizeof(*np)); 587 + if (plen > len) 588 + plen = len; 589 + np = &disc->partial_buf; 590 + memcpy((char *)np + tlen, bp, plen); 591 + 592 + /* 593 + * Set bp so that the loop below will advance it to the 594 + * first valid full name element. 595 + */ 596 + bp -= tlen; 597 + len += tlen; 598 + plen += tlen; 599 + disc->buf_len = (unsigned char) plen; 600 + if (plen == sizeof(*np)) 601 + disc->buf_len = 0; 602 + } 603 + 604 + /* 605 + * Handle full name records, including the one filled from above. 606 + * Normally, np == bp and plen == len, but from the partial case above, 607 + * bp, len describe the overall buffer, and np, plen describe the 608 + * partial buffer, which if would usually be full now. 609 + * After the first time through the loop, things return to "normal". 610 + */ 611 + while (plen >= sizeof(*np)) { 612 + dp.lp = lport; 613 + dp.ids.port_id = ntoh24(np->fp_fid); 614 + dp.ids.port_name = ntohll(np->fp_wwpn); 615 + dp.ids.node_name = -1; 616 + dp.ids.roles = FC_RPORT_ROLE_UNKNOWN; 617 + 618 + if ((dp.ids.port_id != fc_host_port_id(lport->host)) && 619 + (dp.ids.port_name != lport->wwpn)) { 620 + rport = fc_rport_rogue_create(&dp); 621 + if (rport) { 622 + rdata = rport->dd_data; 623 + rdata->ops = &fc_disc_rport_ops; 624 + rdata->local_port = lport; 625 + lport->tt.rport_login(rport); 626 + } else 627 + FC_DBG("Failed to allocate memory for " 628 + "the newly discovered port (%6x)\n", 629 + dp.ids.port_id); 630 + } 631 + 632 + if (np->fp_flags & FC_NS_FID_LAST) { 633 + disc->event = DISC_EV_SUCCESS; 634 + fc_disc_done(disc); 635 + len = 0; 636 + break; 637 + } 638 + len -= sizeof(*np); 639 + bp += sizeof(*np); 640 + np = (struct fc_gpn_ft_resp *)bp; 641 + plen = len; 642 + } 643 + 644 + /* 645 + * Save any partial record at the end of the buffer for next time. 646 + */ 647 + if (error == 0 && len > 0 && len < sizeof(*np)) { 648 + if (np != &disc->partial_buf) { 649 + FC_DEBUG_DISC("Partial buffer remains " 650 + "for discovery by (%6x)\n", 651 + fc_host_port_id(lport->host)); 652 + memcpy(&disc->partial_buf, np, len); 653 + } 654 + disc->buf_len = (unsigned char) len; 655 + } else { 656 + disc->buf_len = 0; 657 + } 658 + return error; 659 + } 660 + 661 + /* 662 + * Handle retry of memory allocation for remote ports. 663 + */ 664 + static void fc_disc_timeout(struct work_struct *work) 665 + { 666 + struct fc_disc *disc = container_of(work, 667 + struct fc_disc, 668 + disc_work.work); 669 + mutex_lock(&disc->disc_mutex); 670 + if (disc->requested && !disc->pending) 671 + fc_disc_gpn_ft_req(disc); 672 + mutex_unlock(&disc->disc_mutex); 673 + } 674 + 675 + /** 676 + * fc_disc_gpn_ft_resp - Handle a response frame from Get Port Names (GPN_FT) 677 + * @sp: Current sequence of GPN_FT exchange 678 + * @fp: response frame 679 + * @lp_arg: Fibre Channel host port instance 680 + * 681 + * Locking Note: This function expects that the disc_mutex is locked 682 + * before it is called. 683 + */ 684 + static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, 685 + void *disc_arg) 686 + { 687 + struct fc_disc *disc = disc_arg; 688 + struct fc_ct_hdr *cp; 689 + struct fc_frame_header *fh; 690 + unsigned int seq_cnt; 691 + void *buf = NULL; 692 + unsigned int len; 693 + int error; 694 + 695 + FC_DEBUG_DISC("Received a GPN_FT response on port (%6x)\n", 696 + fc_host_port_id(disc->lport->host)); 697 + 698 + if (IS_ERR(fp)) { 699 + fc_disc_error(disc, fp); 700 + return; 701 + } 702 + 703 + WARN_ON(!fc_frame_is_linear(fp)); /* buffer must be contiguous */ 704 + fh = fc_frame_header_get(fp); 705 + len = fr_len(fp) - sizeof(*fh); 706 + seq_cnt = ntohs(fh->fh_seq_cnt); 707 + if (fr_sof(fp) == FC_SOF_I3 && seq_cnt == 0 && 708 + disc->seq_count == 0) { 709 + cp = fc_frame_payload_get(fp, sizeof(*cp)); 710 + if (!cp) { 711 + FC_DBG("GPN_FT response too short, len %d\n", 712 + fr_len(fp)); 713 + } else if (ntohs(cp->ct_cmd) == FC_FS_ACC) { 714 + 715 + /* 716 + * Accepted. Parse response. 717 + */ 718 + buf = cp + 1; 719 + len -= sizeof(*cp); 720 + } else if (ntohs(cp->ct_cmd) == FC_FS_RJT) { 721 + FC_DBG("GPN_FT rejected reason %x exp %x " 722 + "(check zoning)\n", cp->ct_reason, 723 + cp->ct_explan); 724 + disc->event = DISC_EV_FAILED; 725 + fc_disc_done(disc); 726 + } else { 727 + FC_DBG("GPN_FT unexpected response code %x\n", 728 + ntohs(cp->ct_cmd)); 729 + } 730 + } else if (fr_sof(fp) == FC_SOF_N3 && 731 + seq_cnt == disc->seq_count) { 732 + buf = fh + 1; 733 + } else { 734 + FC_DBG("GPN_FT unexpected frame - out of sequence? " 735 + "seq_cnt %x expected %x sof %x eof %x\n", 736 + seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp)); 737 + } 738 + if (buf) { 739 + error = fc_disc_gpn_ft_parse(disc, buf, len); 740 + if (error) 741 + fc_disc_error(disc, fp); 742 + else 743 + disc->seq_count++; 744 + } 745 + fc_frame_free(fp); 746 + } 747 + 748 + /** 749 + * fc_disc_single - Discover the directory information for a single target 750 + * @lport: FC local port 751 + * @dp: The port to rediscover 752 + * 753 + * Locking Note: This function expects that the disc_mutex is locked 754 + * before it is called. 755 + */ 756 + static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) 757 + { 758 + struct fc_lport *lport; 759 + struct fc_rport *rport; 760 + struct fc_rport *new_rport; 761 + struct fc_rport_libfc_priv *rdata; 762 + 763 + lport = disc->lport; 764 + 765 + if (dp->ids.port_id == fc_host_port_id(lport->host)) 766 + goto out; 767 + 768 + rport = lport->tt.rport_lookup(lport, dp->ids.port_id); 769 + if (rport) 770 + fc_disc_del_target(disc, rport); 771 + 772 + new_rport = fc_rport_rogue_create(dp); 773 + if (new_rport) { 774 + rdata = new_rport->dd_data; 775 + rdata->ops = &fc_disc_rport_ops; 776 + kfree(dp); 777 + lport->tt.rport_login(new_rport); 778 + } 779 + return; 780 + out: 781 + kfree(dp); 782 + } 783 + 784 + /** 785 + * fc_disc_stop - Stop discovery for a given lport 786 + * @lport: The lport that discovery should stop for 787 + */ 788 + void fc_disc_stop(struct fc_lport *lport) 789 + { 790 + struct fc_disc *disc = &lport->disc; 791 + 792 + if (disc) { 793 + cancel_delayed_work_sync(&disc->disc_work); 794 + fc_disc_stop_rports(disc); 795 + } 796 + } 797 + 798 + /** 799 + * fc_disc_stop_final - Stop discovery for a given lport 800 + * @lport: The lport that discovery should stop for 801 + * 802 + * This function will block until discovery has been 803 + * completely stopped and all rports have been deleted. 804 + */ 805 + void fc_disc_stop_final(struct fc_lport *lport) 806 + { 807 + fc_disc_stop(lport); 808 + lport->tt.rport_flush_queue(); 809 + } 810 + 811 + /** 812 + * fc_disc_init - Initialize the discovery block 813 + * @lport: FC local port 814 + */ 815 + int fc_disc_init(struct fc_lport *lport) 816 + { 817 + struct fc_disc *disc; 818 + 819 + if (!lport->tt.disc_start) 820 + lport->tt.disc_start = fc_disc_start; 821 + 822 + if (!lport->tt.disc_stop) 823 + lport->tt.disc_stop = fc_disc_stop; 824 + 825 + if (!lport->tt.disc_stop_final) 826 + lport->tt.disc_stop_final = fc_disc_stop_final; 827 + 828 + if (!lport->tt.disc_recv_req) 829 + lport->tt.disc_recv_req = fc_disc_recv_req; 830 + 831 + if (!lport->tt.rport_lookup) 832 + lport->tt.rport_lookup = fc_disc_lookup_rport; 833 + 834 + disc = &lport->disc; 835 + INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout); 836 + mutex_init(&disc->disc_mutex); 837 + INIT_LIST_HEAD(&disc->rports); 838 + 839 + disc->lport = lport; 840 + disc->delay = FC_DISC_DELAY; 841 + disc->event = DISC_EV_NONE; 842 + 843 + return 0; 844 + } 845 + EXPORT_SYMBOL(fc_disc_init);
+71
drivers/scsi/libfc/fc_elsct.c
··· 1 + /* 2 + * Copyright(c) 2008 Intel Corporation. All rights reserved. 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 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + /* 21 + * Provide interface to send ELS/CT FC frames 22 + */ 23 + 24 + #include <asm/unaligned.h> 25 + #include <scsi/fc/fc_gs.h> 26 + #include <scsi/fc/fc_ns.h> 27 + #include <scsi/fc/fc_els.h> 28 + #include <scsi/libfc.h> 29 + #include <scsi/fc_encode.h> 30 + 31 + /* 32 + * fc_elsct_send - sends ELS/CT frame 33 + */ 34 + static struct fc_seq *fc_elsct_send(struct fc_lport *lport, 35 + struct fc_rport *rport, 36 + struct fc_frame *fp, 37 + unsigned int op, 38 + void (*resp)(struct fc_seq *, 39 + struct fc_frame *fp, 40 + void *arg), 41 + void *arg, u32 timer_msec) 42 + { 43 + enum fc_rctl r_ctl; 44 + u32 did; 45 + enum fc_fh_type fh_type; 46 + int rc; 47 + 48 + /* ELS requests */ 49 + if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS)) 50 + rc = fc_els_fill(lport, rport, fp, op, &r_ctl, &did, &fh_type); 51 + else 52 + /* CT requests */ 53 + rc = fc_ct_fill(lport, fp, op, &r_ctl, &did, &fh_type); 54 + 55 + if (rc) 56 + return NULL; 57 + 58 + fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type, 59 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 60 + 61 + return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec); 62 + } 63 + 64 + int fc_elsct_init(struct fc_lport *lport) 65 + { 66 + if (!lport->tt.elsct_send) 67 + lport->tt.elsct_send = fc_elsct_send; 68 + 69 + return 0; 70 + } 71 + EXPORT_SYMBOL(fc_elsct_init);
+1970
drivers/scsi/libfc/fc_exch.c
··· 1 + /* 2 + * Copyright(c) 2007 Intel Corporation. All rights reserved. 3 + * Copyright(c) 2008 Red Hat, Inc. All rights reserved. 4 + * Copyright(c) 2008 Mike Christie 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms and conditions of the GNU General Public License, 8 + * version 2, as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope it will be useful, but WITHOUT 11 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 + * more details. 14 + * 15 + * You should have received a copy of the GNU General Public License along with 16 + * this program; if not, write to the Free Software Foundation, Inc., 17 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 + * 19 + * Maintained at www.Open-FCoE.org 20 + */ 21 + 22 + /* 23 + * Fibre Channel exchange and sequence handling. 24 + */ 25 + 26 + #include <linux/timer.h> 27 + #include <linux/gfp.h> 28 + #include <linux/err.h> 29 + 30 + #include <scsi/fc/fc_fc2.h> 31 + 32 + #include <scsi/libfc.h> 33 + #include <scsi/fc_encode.h> 34 + 35 + #define FC_DEF_R_A_TOV (10 * 1000) /* resource allocation timeout */ 36 + 37 + /* 38 + * fc_exch_debug can be set in debugger or at compile time to get more logs. 39 + */ 40 + static int fc_exch_debug; 41 + 42 + #define FC_DEBUG_EXCH(fmt...) \ 43 + do { \ 44 + if (fc_exch_debug) \ 45 + FC_DBG(fmt); \ 46 + } while (0) 47 + 48 + static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ 49 + 50 + /* 51 + * Structure and function definitions for managing Fibre Channel Exchanges 52 + * and Sequences. 53 + * 54 + * The three primary structures used here are fc_exch_mgr, fc_exch, and fc_seq. 55 + * 56 + * fc_exch_mgr holds the exchange state for an N port 57 + * 58 + * fc_exch holds state for one exchange and links to its active sequence. 59 + * 60 + * fc_seq holds the state for an individual sequence. 61 + */ 62 + 63 + /* 64 + * Exchange manager. 65 + * 66 + * This structure is the center for creating exchanges and sequences. 67 + * It manages the allocation of exchange IDs. 68 + */ 69 + struct fc_exch_mgr { 70 + enum fc_class class; /* default class for sequences */ 71 + spinlock_t em_lock; /* exchange manager lock, 72 + must be taken before ex_lock */ 73 + u16 last_xid; /* last allocated exchange ID */ 74 + u16 min_xid; /* min exchange ID */ 75 + u16 max_xid; /* max exchange ID */ 76 + u16 max_read; /* max exchange ID for read */ 77 + u16 last_read; /* last xid allocated for read */ 78 + u32 total_exches; /* total allocated exchanges */ 79 + struct list_head ex_list; /* allocated exchanges list */ 80 + struct fc_lport *lp; /* fc device instance */ 81 + mempool_t *ep_pool; /* reserve ep's */ 82 + 83 + /* 84 + * currently exchange mgr stats are updated but not used. 85 + * either stats can be expose via sysfs or remove them 86 + * all together if not used XXX 87 + */ 88 + struct { 89 + atomic_t no_free_exch; 90 + atomic_t no_free_exch_xid; 91 + atomic_t xid_not_found; 92 + atomic_t xid_busy; 93 + atomic_t seq_not_found; 94 + atomic_t non_bls_resp; 95 + } stats; 96 + struct fc_exch **exches; /* for exch pointers indexed by xid */ 97 + }; 98 + #define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq) 99 + 100 + static void fc_exch_rrq(struct fc_exch *); 101 + static void fc_seq_ls_acc(struct fc_seq *); 102 + static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason, 103 + enum fc_els_rjt_explan); 104 + static void fc_exch_els_rec(struct fc_seq *, struct fc_frame *); 105 + static void fc_exch_els_rrq(struct fc_seq *, struct fc_frame *); 106 + static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp); 107 + 108 + /* 109 + * Internal implementation notes. 110 + * 111 + * The exchange manager is one by default in libfc but LLD may choose 112 + * to have one per CPU. The sequence manager is one per exchange manager 113 + * and currently never separated. 114 + * 115 + * Section 9.8 in FC-FS-2 specifies: "The SEQ_ID is a one-byte field 116 + * assigned by the Sequence Initiator that shall be unique for a specific 117 + * D_ID and S_ID pair while the Sequence is open." Note that it isn't 118 + * qualified by exchange ID, which one might think it would be. 119 + * In practice this limits the number of open sequences and exchanges to 256 120 + * per session. For most targets we could treat this limit as per exchange. 121 + * 122 + * The exchange and its sequence are freed when the last sequence is received. 123 + * It's possible for the remote port to leave an exchange open without 124 + * sending any sequences. 125 + * 126 + * Notes on reference counts: 127 + * 128 + * Exchanges are reference counted and exchange gets freed when the reference 129 + * count becomes zero. 130 + * 131 + * Timeouts: 132 + * Sequences are timed out for E_D_TOV and R_A_TOV. 133 + * 134 + * Sequence event handling: 135 + * 136 + * The following events may occur on initiator sequences: 137 + * 138 + * Send. 139 + * For now, the whole thing is sent. 140 + * Receive ACK 141 + * This applies only to class F. 142 + * The sequence is marked complete. 143 + * ULP completion. 144 + * The upper layer calls fc_exch_done() when done 145 + * with exchange and sequence tuple. 146 + * RX-inferred completion. 147 + * When we receive the next sequence on the same exchange, we can 148 + * retire the previous sequence ID. (XXX not implemented). 149 + * Timeout. 150 + * R_A_TOV frees the sequence ID. If we're waiting for ACK, 151 + * E_D_TOV causes abort and calls upper layer response handler 152 + * with FC_EX_TIMEOUT error. 153 + * Receive RJT 154 + * XXX defer. 155 + * Send ABTS 156 + * On timeout. 157 + * 158 + * The following events may occur on recipient sequences: 159 + * 160 + * Receive 161 + * Allocate sequence for first frame received. 162 + * Hold during receive handler. 163 + * Release when final frame received. 164 + * Keep status of last N of these for the ELS RES command. XXX TBD. 165 + * Receive ABTS 166 + * Deallocate sequence 167 + * Send RJT 168 + * Deallocate 169 + * 170 + * For now, we neglect conditions where only part of a sequence was 171 + * received or transmitted, or where out-of-order receipt is detected. 172 + */ 173 + 174 + /* 175 + * Locking notes: 176 + * 177 + * The EM code run in a per-CPU worker thread. 178 + * 179 + * To protect against concurrency between a worker thread code and timers, 180 + * sequence allocation and deallocation must be locked. 181 + * - exchange refcnt can be done atomicly without locks. 182 + * - sequence allocation must be locked by exch lock. 183 + * - If the em_lock and ex_lock must be taken at the same time, then the 184 + * em_lock must be taken before the ex_lock. 185 + */ 186 + 187 + /* 188 + * opcode names for debugging. 189 + */ 190 + static char *fc_exch_rctl_names[] = FC_RCTL_NAMES_INIT; 191 + 192 + #define FC_TABLE_SIZE(x) (sizeof(x) / sizeof(x[0])) 193 + 194 + static inline const char *fc_exch_name_lookup(unsigned int op, char **table, 195 + unsigned int max_index) 196 + { 197 + const char *name = NULL; 198 + 199 + if (op < max_index) 200 + name = table[op]; 201 + if (!name) 202 + name = "unknown"; 203 + return name; 204 + } 205 + 206 + static const char *fc_exch_rctl_name(unsigned int op) 207 + { 208 + return fc_exch_name_lookup(op, fc_exch_rctl_names, 209 + FC_TABLE_SIZE(fc_exch_rctl_names)); 210 + } 211 + 212 + /* 213 + * Hold an exchange - keep it from being freed. 214 + */ 215 + static void fc_exch_hold(struct fc_exch *ep) 216 + { 217 + atomic_inc(&ep->ex_refcnt); 218 + } 219 + 220 + /* 221 + * setup fc hdr by initializing few more FC header fields and sof/eof. 222 + * Initialized fields by this func: 223 + * - fh_ox_id, fh_rx_id, fh_seq_id, fh_seq_cnt 224 + * - sof and eof 225 + */ 226 + static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp, 227 + u32 f_ctl) 228 + { 229 + struct fc_frame_header *fh = fc_frame_header_get(fp); 230 + u16 fill; 231 + 232 + fr_sof(fp) = ep->class; 233 + if (ep->seq.cnt) 234 + fr_sof(fp) = fc_sof_normal(ep->class); 235 + 236 + if (f_ctl & FC_FC_END_SEQ) { 237 + fr_eof(fp) = FC_EOF_T; 238 + if (fc_sof_needs_ack(ep->class)) 239 + fr_eof(fp) = FC_EOF_N; 240 + /* 241 + * Form f_ctl. 242 + * The number of fill bytes to make the length a 4-byte 243 + * multiple is the low order 2-bits of the f_ctl. 244 + * The fill itself will have been cleared by the frame 245 + * allocation. 246 + * After this, the length will be even, as expected by 247 + * the transport. 248 + */ 249 + fill = fr_len(fp) & 3; 250 + if (fill) { 251 + fill = 4 - fill; 252 + /* TODO, this may be a problem with fragmented skb */ 253 + skb_put(fp_skb(fp), fill); 254 + hton24(fh->fh_f_ctl, f_ctl | fill); 255 + } 256 + } else { 257 + WARN_ON(fr_len(fp) % 4 != 0); /* no pad to non last frame */ 258 + fr_eof(fp) = FC_EOF_N; 259 + } 260 + 261 + /* 262 + * Initialize remainig fh fields 263 + * from fc_fill_fc_hdr 264 + */ 265 + fh->fh_ox_id = htons(ep->oxid); 266 + fh->fh_rx_id = htons(ep->rxid); 267 + fh->fh_seq_id = ep->seq.id; 268 + fh->fh_seq_cnt = htons(ep->seq.cnt); 269 + } 270 + 271 + 272 + /* 273 + * Release a reference to an exchange. 274 + * If the refcnt goes to zero and the exchange is complete, it is freed. 275 + */ 276 + static void fc_exch_release(struct fc_exch *ep) 277 + { 278 + struct fc_exch_mgr *mp; 279 + 280 + if (atomic_dec_and_test(&ep->ex_refcnt)) { 281 + mp = ep->em; 282 + if (ep->destructor) 283 + ep->destructor(&ep->seq, ep->arg); 284 + if (ep->lp->tt.exch_put) 285 + ep->lp->tt.exch_put(ep->lp, mp, ep->xid); 286 + WARN_ON(!ep->esb_stat & ESB_ST_COMPLETE); 287 + mempool_free(ep, mp->ep_pool); 288 + } 289 + } 290 + 291 + static int fc_exch_done_locked(struct fc_exch *ep) 292 + { 293 + int rc = 1; 294 + 295 + /* 296 + * We must check for completion in case there are two threads 297 + * tyring to complete this. But the rrq code will reuse the 298 + * ep, and in that case we only clear the resp and set it as 299 + * complete, so it can be reused by the timer to send the rrq. 300 + */ 301 + ep->resp = NULL; 302 + if (ep->state & FC_EX_DONE) 303 + return rc; 304 + ep->esb_stat |= ESB_ST_COMPLETE; 305 + 306 + if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { 307 + ep->state |= FC_EX_DONE; 308 + if (cancel_delayed_work(&ep->timeout_work)) 309 + atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ 310 + rc = 0; 311 + } 312 + return rc; 313 + } 314 + 315 + static void fc_exch_mgr_delete_ep(struct fc_exch *ep) 316 + { 317 + struct fc_exch_mgr *mp; 318 + 319 + mp = ep->em; 320 + spin_lock_bh(&mp->em_lock); 321 + WARN_ON(mp->total_exches <= 0); 322 + mp->total_exches--; 323 + mp->exches[ep->xid - mp->min_xid] = NULL; 324 + list_del(&ep->ex_list); 325 + spin_unlock_bh(&mp->em_lock); 326 + fc_exch_release(ep); /* drop hold for exch in mp */ 327 + } 328 + 329 + /* 330 + * Internal version of fc_exch_timer_set - used with lock held. 331 + */ 332 + static inline void fc_exch_timer_set_locked(struct fc_exch *ep, 333 + unsigned int timer_msec) 334 + { 335 + if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) 336 + return; 337 + 338 + FC_DEBUG_EXCH("Exchange (%4x) timed out, notifying the upper layer\n", 339 + ep->xid); 340 + if (schedule_delayed_work(&ep->timeout_work, 341 + msecs_to_jiffies(timer_msec))) 342 + fc_exch_hold(ep); /* hold for timer */ 343 + } 344 + 345 + /* 346 + * Set timer for an exchange. 347 + * The time is a minimum delay in milliseconds until the timer fires. 348 + * Used for upper level protocols to time out the exchange. 349 + * The timer is cancelled when it fires or when the exchange completes. 350 + * Returns non-zero if a timer couldn't be allocated. 351 + */ 352 + static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) 353 + { 354 + spin_lock_bh(&ep->ex_lock); 355 + fc_exch_timer_set_locked(ep, timer_msec); 356 + spin_unlock_bh(&ep->ex_lock); 357 + } 358 + 359 + int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec) 360 + { 361 + struct fc_seq *sp; 362 + struct fc_exch *ep; 363 + struct fc_frame *fp; 364 + int error; 365 + 366 + ep = fc_seq_exch(req_sp); 367 + 368 + spin_lock_bh(&ep->ex_lock); 369 + if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) || 370 + ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) { 371 + spin_unlock_bh(&ep->ex_lock); 372 + return -ENXIO; 373 + } 374 + 375 + /* 376 + * Send the abort on a new sequence if possible. 377 + */ 378 + sp = fc_seq_start_next_locked(&ep->seq); 379 + if (!sp) { 380 + spin_unlock_bh(&ep->ex_lock); 381 + return -ENOMEM; 382 + } 383 + 384 + ep->esb_stat |= ESB_ST_SEQ_INIT | ESB_ST_ABNORMAL; 385 + if (timer_msec) 386 + fc_exch_timer_set_locked(ep, timer_msec); 387 + spin_unlock_bh(&ep->ex_lock); 388 + 389 + /* 390 + * If not logged into the fabric, don't send ABTS but leave 391 + * sequence active until next timeout. 392 + */ 393 + if (!ep->sid) 394 + return 0; 395 + 396 + /* 397 + * Send an abort for the sequence that timed out. 398 + */ 399 + fp = fc_frame_alloc(ep->lp, 0); 400 + if (fp) { 401 + fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid, 402 + FC_TYPE_BLS, FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 403 + error = fc_seq_send(ep->lp, sp, fp); 404 + } else 405 + error = -ENOBUFS; 406 + return error; 407 + } 408 + EXPORT_SYMBOL(fc_seq_exch_abort); 409 + 410 + /* 411 + * Exchange timeout - handle exchange timer expiration. 412 + * The timer will have been cancelled before this is called. 413 + */ 414 + static void fc_exch_timeout(struct work_struct *work) 415 + { 416 + struct fc_exch *ep = container_of(work, struct fc_exch, 417 + timeout_work.work); 418 + struct fc_seq *sp = &ep->seq; 419 + void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg); 420 + void *arg; 421 + u32 e_stat; 422 + int rc = 1; 423 + 424 + spin_lock_bh(&ep->ex_lock); 425 + if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) 426 + goto unlock; 427 + 428 + e_stat = ep->esb_stat; 429 + if (e_stat & ESB_ST_COMPLETE) { 430 + ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL; 431 + if (e_stat & ESB_ST_REC_QUAL) 432 + fc_exch_rrq(ep); 433 + spin_unlock_bh(&ep->ex_lock); 434 + goto done; 435 + } else { 436 + resp = ep->resp; 437 + arg = ep->arg; 438 + ep->resp = NULL; 439 + if (e_stat & ESB_ST_ABNORMAL) 440 + rc = fc_exch_done_locked(ep); 441 + spin_unlock_bh(&ep->ex_lock); 442 + if (!rc) 443 + fc_exch_mgr_delete_ep(ep); 444 + if (resp) 445 + resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg); 446 + fc_seq_exch_abort(sp, 2 * ep->r_a_tov); 447 + goto done; 448 + } 449 + unlock: 450 + spin_unlock_bh(&ep->ex_lock); 451 + done: 452 + /* 453 + * This release matches the hold taken when the timer was set. 454 + */ 455 + fc_exch_release(ep); 456 + } 457 + 458 + /* 459 + * Allocate a sequence. 460 + * 461 + * We don't support multiple originated sequences on the same exchange. 462 + * By implication, any previously originated sequence on this exchange 463 + * is complete, and we reallocate the same sequence. 464 + */ 465 + static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id) 466 + { 467 + struct fc_seq *sp; 468 + 469 + sp = &ep->seq; 470 + sp->ssb_stat = 0; 471 + sp->cnt = 0; 472 + sp->id = seq_id; 473 + return sp; 474 + } 475 + 476 + /* 477 + * fc_em_alloc_xid - returns an xid based on request type 478 + * @lp : ptr to associated lport 479 + * @fp : ptr to the assocated frame 480 + * 481 + * check the associated fc_fsp_pkt to get scsi command type and 482 + * command direction to decide from which range this exch id 483 + * will be allocated from. 484 + * 485 + * Returns : 0 or an valid xid 486 + */ 487 + static u16 fc_em_alloc_xid(struct fc_exch_mgr *mp, const struct fc_frame *fp) 488 + { 489 + u16 xid, min, max; 490 + u16 *plast; 491 + struct fc_exch *ep = NULL; 492 + 493 + if (mp->max_read) { 494 + if (fc_frame_is_read(fp)) { 495 + min = mp->min_xid; 496 + max = mp->max_read; 497 + plast = &mp->last_read; 498 + } else { 499 + min = mp->max_read + 1; 500 + max = mp->max_xid; 501 + plast = &mp->last_xid; 502 + } 503 + } else { 504 + min = mp->min_xid; 505 + max = mp->max_xid; 506 + plast = &mp->last_xid; 507 + } 508 + xid = *plast; 509 + do { 510 + xid = (xid == max) ? min : xid + 1; 511 + ep = mp->exches[xid - mp->min_xid]; 512 + } while ((ep != NULL) && (xid != *plast)); 513 + 514 + if (unlikely(ep)) 515 + xid = 0; 516 + else 517 + *plast = xid; 518 + 519 + return xid; 520 + } 521 + 522 + /* 523 + * fc_exch_alloc - allocate an exchange. 524 + * @mp : ptr to the exchange manager 525 + * @xid: input xid 526 + * 527 + * if xid is supplied zero then assign next free exchange ID 528 + * from exchange manager, otherwise use supplied xid. 529 + * Returns with exch lock held. 530 + */ 531 + struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, 532 + struct fc_frame *fp, u16 xid) 533 + { 534 + struct fc_exch *ep; 535 + 536 + /* allocate memory for exchange */ 537 + ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC); 538 + if (!ep) { 539 + atomic_inc(&mp->stats.no_free_exch); 540 + goto out; 541 + } 542 + memset(ep, 0, sizeof(*ep)); 543 + 544 + spin_lock_bh(&mp->em_lock); 545 + /* alloc xid if input xid 0 */ 546 + if (!xid) { 547 + /* alloc a new xid */ 548 + xid = fc_em_alloc_xid(mp, fp); 549 + if (!xid) { 550 + printk(KERN_ERR "fc_em_alloc_xid() failed\n"); 551 + goto err; 552 + } 553 + } 554 + 555 + fc_exch_hold(ep); /* hold for exch in mp */ 556 + spin_lock_init(&ep->ex_lock); 557 + /* 558 + * Hold exch lock for caller to prevent fc_exch_reset() 559 + * from releasing exch while fc_exch_alloc() caller is 560 + * still working on exch. 561 + */ 562 + spin_lock_bh(&ep->ex_lock); 563 + 564 + mp->exches[xid - mp->min_xid] = ep; 565 + list_add_tail(&ep->ex_list, &mp->ex_list); 566 + fc_seq_alloc(ep, ep->seq_id++); 567 + mp->total_exches++; 568 + spin_unlock_bh(&mp->em_lock); 569 + 570 + /* 571 + * update exchange 572 + */ 573 + ep->oxid = ep->xid = xid; 574 + ep->em = mp; 575 + ep->lp = mp->lp; 576 + ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */ 577 + ep->rxid = FC_XID_UNKNOWN; 578 + ep->class = mp->class; 579 + INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout); 580 + out: 581 + return ep; 582 + err: 583 + spin_unlock_bh(&mp->em_lock); 584 + atomic_inc(&mp->stats.no_free_exch_xid); 585 + mempool_free(ep, mp->ep_pool); 586 + return NULL; 587 + } 588 + EXPORT_SYMBOL(fc_exch_alloc); 589 + 590 + /* 591 + * Lookup and hold an exchange. 592 + */ 593 + static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid) 594 + { 595 + struct fc_exch *ep = NULL; 596 + 597 + if ((xid >= mp->min_xid) && (xid <= mp->max_xid)) { 598 + spin_lock_bh(&mp->em_lock); 599 + ep = mp->exches[xid - mp->min_xid]; 600 + if (ep) { 601 + fc_exch_hold(ep); 602 + WARN_ON(ep->xid != xid); 603 + } 604 + spin_unlock_bh(&mp->em_lock); 605 + } 606 + return ep; 607 + } 608 + 609 + void fc_exch_done(struct fc_seq *sp) 610 + { 611 + struct fc_exch *ep = fc_seq_exch(sp); 612 + int rc; 613 + 614 + spin_lock_bh(&ep->ex_lock); 615 + rc = fc_exch_done_locked(ep); 616 + spin_unlock_bh(&ep->ex_lock); 617 + if (!rc) 618 + fc_exch_mgr_delete_ep(ep); 619 + } 620 + EXPORT_SYMBOL(fc_exch_done); 621 + 622 + /* 623 + * Allocate a new exchange as responder. 624 + * Sets the responder ID in the frame header. 625 + */ 626 + static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) 627 + { 628 + struct fc_exch *ep; 629 + struct fc_frame_header *fh; 630 + u16 rxid; 631 + 632 + ep = mp->lp->tt.exch_get(mp->lp, fp); 633 + if (ep) { 634 + ep->class = fc_frame_class(fp); 635 + 636 + /* 637 + * Set EX_CTX indicating we're responding on this exchange. 638 + */ 639 + ep->f_ctl |= FC_FC_EX_CTX; /* we're responding */ 640 + ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not new */ 641 + fh = fc_frame_header_get(fp); 642 + ep->sid = ntoh24(fh->fh_d_id); 643 + ep->did = ntoh24(fh->fh_s_id); 644 + ep->oid = ep->did; 645 + 646 + /* 647 + * Allocated exchange has placed the XID in the 648 + * originator field. Move it to the responder field, 649 + * and set the originator XID from the frame. 650 + */ 651 + ep->rxid = ep->xid; 652 + ep->oxid = ntohs(fh->fh_ox_id); 653 + ep->esb_stat |= ESB_ST_RESP | ESB_ST_SEQ_INIT; 654 + if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0) 655 + ep->esb_stat &= ~ESB_ST_SEQ_INIT; 656 + 657 + /* 658 + * Set the responder ID in the frame header. 659 + * The old one should've been 0xffff. 660 + * If it isn't, don't assign one. 661 + * Incoming basic link service frames may specify 662 + * a referenced RX_ID. 663 + */ 664 + if (fh->fh_type != FC_TYPE_BLS) { 665 + rxid = ntohs(fh->fh_rx_id); 666 + WARN_ON(rxid != FC_XID_UNKNOWN); 667 + fh->fh_rx_id = htons(ep->rxid); 668 + } 669 + fc_exch_hold(ep); /* hold for caller */ 670 + spin_unlock_bh(&ep->ex_lock); /* lock from exch_get */ 671 + } 672 + return ep; 673 + } 674 + 675 + /* 676 + * Find a sequence for receive where the other end is originating the sequence. 677 + * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold 678 + * on the ep that should be released by the caller. 679 + */ 680 + static enum fc_pf_rjt_reason 681 + fc_seq_lookup_recip(struct fc_exch_mgr *mp, struct fc_frame *fp) 682 + { 683 + struct fc_frame_header *fh = fc_frame_header_get(fp); 684 + struct fc_exch *ep = NULL; 685 + struct fc_seq *sp = NULL; 686 + enum fc_pf_rjt_reason reject = FC_RJT_NONE; 687 + u32 f_ctl; 688 + u16 xid; 689 + 690 + f_ctl = ntoh24(fh->fh_f_ctl); 691 + WARN_ON((f_ctl & FC_FC_SEQ_CTX) != 0); 692 + 693 + /* 694 + * Lookup or create the exchange if we will be creating the sequence. 695 + */ 696 + if (f_ctl & FC_FC_EX_CTX) { 697 + xid = ntohs(fh->fh_ox_id); /* we originated exch */ 698 + ep = fc_exch_find(mp, xid); 699 + if (!ep) { 700 + atomic_inc(&mp->stats.xid_not_found); 701 + reject = FC_RJT_OX_ID; 702 + goto out; 703 + } 704 + if (ep->rxid == FC_XID_UNKNOWN) 705 + ep->rxid = ntohs(fh->fh_rx_id); 706 + else if (ep->rxid != ntohs(fh->fh_rx_id)) { 707 + reject = FC_RJT_OX_ID; 708 + goto rel; 709 + } 710 + } else { 711 + xid = ntohs(fh->fh_rx_id); /* we are the responder */ 712 + 713 + /* 714 + * Special case for MDS issuing an ELS TEST with a 715 + * bad rxid of 0. 716 + * XXX take this out once we do the proper reject. 717 + */ 718 + if (xid == 0 && fh->fh_r_ctl == FC_RCTL_ELS_REQ && 719 + fc_frame_payload_op(fp) == ELS_TEST) { 720 + fh->fh_rx_id = htons(FC_XID_UNKNOWN); 721 + xid = FC_XID_UNKNOWN; 722 + } 723 + 724 + /* 725 + * new sequence - find the exchange 726 + */ 727 + ep = fc_exch_find(mp, xid); 728 + if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) { 729 + if (ep) { 730 + atomic_inc(&mp->stats.xid_busy); 731 + reject = FC_RJT_RX_ID; 732 + goto rel; 733 + } 734 + ep = fc_exch_resp(mp, fp); 735 + if (!ep) { 736 + reject = FC_RJT_EXCH_EST; /* XXX */ 737 + goto out; 738 + } 739 + xid = ep->xid; /* get our XID */ 740 + } else if (!ep) { 741 + atomic_inc(&mp->stats.xid_not_found); 742 + reject = FC_RJT_RX_ID; /* XID not found */ 743 + goto out; 744 + } 745 + } 746 + 747 + /* 748 + * At this point, we have the exchange held. 749 + * Find or create the sequence. 750 + */ 751 + if (fc_sof_is_init(fr_sof(fp))) { 752 + sp = fc_seq_start_next(&ep->seq); 753 + if (!sp) { 754 + reject = FC_RJT_SEQ_XS; /* exchange shortage */ 755 + goto rel; 756 + } 757 + sp->id = fh->fh_seq_id; 758 + sp->ssb_stat |= SSB_ST_RESP; 759 + } else { 760 + sp = &ep->seq; 761 + if (sp->id != fh->fh_seq_id) { 762 + atomic_inc(&mp->stats.seq_not_found); 763 + reject = FC_RJT_SEQ_ID; /* sequence/exch should exist */ 764 + goto rel; 765 + } 766 + } 767 + WARN_ON(ep != fc_seq_exch(sp)); 768 + 769 + if (f_ctl & FC_FC_SEQ_INIT) 770 + ep->esb_stat |= ESB_ST_SEQ_INIT; 771 + 772 + fr_seq(fp) = sp; 773 + out: 774 + return reject; 775 + rel: 776 + fc_exch_done(&ep->seq); 777 + fc_exch_release(ep); /* hold from fc_exch_find/fc_exch_resp */ 778 + return reject; 779 + } 780 + 781 + /* 782 + * Find the sequence for a frame being received. 783 + * We originated the sequence, so it should be found. 784 + * We may or may not have originated the exchange. 785 + * Does not hold the sequence for the caller. 786 + */ 787 + static struct fc_seq *fc_seq_lookup_orig(struct fc_exch_mgr *mp, 788 + struct fc_frame *fp) 789 + { 790 + struct fc_frame_header *fh = fc_frame_header_get(fp); 791 + struct fc_exch *ep; 792 + struct fc_seq *sp = NULL; 793 + u32 f_ctl; 794 + u16 xid; 795 + 796 + f_ctl = ntoh24(fh->fh_f_ctl); 797 + WARN_ON((f_ctl & FC_FC_SEQ_CTX) != FC_FC_SEQ_CTX); 798 + xid = ntohs((f_ctl & FC_FC_EX_CTX) ? fh->fh_ox_id : fh->fh_rx_id); 799 + ep = fc_exch_find(mp, xid); 800 + if (!ep) 801 + return NULL; 802 + if (ep->seq.id == fh->fh_seq_id) { 803 + /* 804 + * Save the RX_ID if we didn't previously know it. 805 + */ 806 + sp = &ep->seq; 807 + if ((f_ctl & FC_FC_EX_CTX) != 0 && 808 + ep->rxid == FC_XID_UNKNOWN) { 809 + ep->rxid = ntohs(fh->fh_rx_id); 810 + } 811 + } 812 + fc_exch_release(ep); 813 + return sp; 814 + } 815 + 816 + /* 817 + * Set addresses for an exchange. 818 + * Note this must be done before the first sequence of the exchange is sent. 819 + */ 820 + static void fc_exch_set_addr(struct fc_exch *ep, 821 + u32 orig_id, u32 resp_id) 822 + { 823 + ep->oid = orig_id; 824 + if (ep->esb_stat & ESB_ST_RESP) { 825 + ep->sid = resp_id; 826 + ep->did = orig_id; 827 + } else { 828 + ep->sid = orig_id; 829 + ep->did = resp_id; 830 + } 831 + } 832 + 833 + static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp) 834 + { 835 + struct fc_exch *ep = fc_seq_exch(sp); 836 + 837 + sp = fc_seq_alloc(ep, ep->seq_id++); 838 + FC_DEBUG_EXCH("exch %4x f_ctl %6x seq %2x\n", 839 + ep->xid, ep->f_ctl, sp->id); 840 + return sp; 841 + } 842 + /* 843 + * Allocate a new sequence on the same exchange as the supplied sequence. 844 + * This will never return NULL. 845 + */ 846 + struct fc_seq *fc_seq_start_next(struct fc_seq *sp) 847 + { 848 + struct fc_exch *ep = fc_seq_exch(sp); 849 + 850 + spin_lock_bh(&ep->ex_lock); 851 + WARN_ON((ep->esb_stat & ESB_ST_COMPLETE) != 0); 852 + sp = fc_seq_start_next_locked(sp); 853 + spin_unlock_bh(&ep->ex_lock); 854 + 855 + return sp; 856 + } 857 + EXPORT_SYMBOL(fc_seq_start_next); 858 + 859 + int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp) 860 + { 861 + struct fc_exch *ep; 862 + struct fc_frame_header *fh = fc_frame_header_get(fp); 863 + int error; 864 + u32 f_ctl; 865 + 866 + ep = fc_seq_exch(sp); 867 + WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT); 868 + 869 + f_ctl = ntoh24(fh->fh_f_ctl); 870 + fc_exch_setup_hdr(ep, fp, f_ctl); 871 + 872 + /* 873 + * update sequence count if this frame is carrying 874 + * multiple FC frames when sequence offload is enabled 875 + * by LLD. 876 + */ 877 + if (fr_max_payload(fp)) 878 + sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)), 879 + fr_max_payload(fp)); 880 + else 881 + sp->cnt++; 882 + 883 + /* 884 + * Send the frame. 885 + */ 886 + error = lp->tt.frame_send(lp, fp); 887 + 888 + /* 889 + * Update the exchange and sequence flags, 890 + * assuming all frames for the sequence have been sent. 891 + * We can only be called to send once for each sequence. 892 + */ 893 + spin_lock_bh(&ep->ex_lock); 894 + ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ 895 + if (f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT)) 896 + ep->esb_stat &= ~ESB_ST_SEQ_INIT; 897 + spin_unlock_bh(&ep->ex_lock); 898 + return error; 899 + } 900 + EXPORT_SYMBOL(fc_seq_send); 901 + 902 + void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, 903 + struct fc_seq_els_data *els_data) 904 + { 905 + switch (els_cmd) { 906 + case ELS_LS_RJT: 907 + fc_seq_ls_rjt(sp, els_data->reason, els_data->explan); 908 + break; 909 + case ELS_LS_ACC: 910 + fc_seq_ls_acc(sp); 911 + break; 912 + case ELS_RRQ: 913 + fc_exch_els_rrq(sp, els_data->fp); 914 + break; 915 + case ELS_REC: 916 + fc_exch_els_rec(sp, els_data->fp); 917 + break; 918 + default: 919 + FC_DBG("Invalid ELS CMD:%x\n", els_cmd); 920 + } 921 + } 922 + EXPORT_SYMBOL(fc_seq_els_rsp_send); 923 + 924 + /* 925 + * Send a sequence, which is also the last sequence in the exchange. 926 + */ 927 + static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp, 928 + enum fc_rctl rctl, enum fc_fh_type fh_type) 929 + { 930 + u32 f_ctl; 931 + struct fc_exch *ep = fc_seq_exch(sp); 932 + 933 + f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT; 934 + f_ctl |= ep->f_ctl; 935 + fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0); 936 + fc_seq_send(ep->lp, sp, fp); 937 + } 938 + 939 + /* 940 + * Send ACK_1 (or equiv.) indicating we received something. 941 + * The frame we're acking is supplied. 942 + */ 943 + static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp) 944 + { 945 + struct fc_frame *fp; 946 + struct fc_frame_header *rx_fh; 947 + struct fc_frame_header *fh; 948 + struct fc_exch *ep = fc_seq_exch(sp); 949 + struct fc_lport *lp = ep->lp; 950 + unsigned int f_ctl; 951 + 952 + /* 953 + * Don't send ACKs for class 3. 954 + */ 955 + if (fc_sof_needs_ack(fr_sof(rx_fp))) { 956 + fp = fc_frame_alloc(lp, 0); 957 + if (!fp) 958 + return; 959 + 960 + fh = fc_frame_header_get(fp); 961 + fh->fh_r_ctl = FC_RCTL_ACK_1; 962 + fh->fh_type = FC_TYPE_BLS; 963 + 964 + /* 965 + * Form f_ctl by inverting EX_CTX and SEQ_CTX (bits 23, 22). 966 + * Echo FIRST_SEQ, LAST_SEQ, END_SEQ, END_CONN, SEQ_INIT. 967 + * Bits 9-8 are meaningful (retransmitted or unidirectional). 968 + * Last ACK uses bits 7-6 (continue sequence), 969 + * bits 5-4 are meaningful (what kind of ACK to use). 970 + */ 971 + rx_fh = fc_frame_header_get(rx_fp); 972 + f_ctl = ntoh24(rx_fh->fh_f_ctl); 973 + f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX | 974 + FC_FC_FIRST_SEQ | FC_FC_LAST_SEQ | 975 + FC_FC_END_SEQ | FC_FC_END_CONN | FC_FC_SEQ_INIT | 976 + FC_FC_RETX_SEQ | FC_FC_UNI_TX; 977 + f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX; 978 + hton24(fh->fh_f_ctl, f_ctl); 979 + 980 + fc_exch_setup_hdr(ep, fp, f_ctl); 981 + fh->fh_seq_id = rx_fh->fh_seq_id; 982 + fh->fh_seq_cnt = rx_fh->fh_seq_cnt; 983 + fh->fh_parm_offset = htonl(1); /* ack single frame */ 984 + 985 + fr_sof(fp) = fr_sof(rx_fp); 986 + if (f_ctl & FC_FC_END_SEQ) 987 + fr_eof(fp) = FC_EOF_T; 988 + else 989 + fr_eof(fp) = FC_EOF_N; 990 + 991 + (void) lp->tt.frame_send(lp, fp); 992 + } 993 + } 994 + 995 + /* 996 + * Send BLS Reject. 997 + * This is for rejecting BA_ABTS only. 998 + */ 999 + static void 1000 + fc_exch_send_ba_rjt(struct fc_frame *rx_fp, enum fc_ba_rjt_reason reason, 1001 + enum fc_ba_rjt_explan explan) 1002 + { 1003 + struct fc_frame *fp; 1004 + struct fc_frame_header *rx_fh; 1005 + struct fc_frame_header *fh; 1006 + struct fc_ba_rjt *rp; 1007 + struct fc_lport *lp; 1008 + unsigned int f_ctl; 1009 + 1010 + lp = fr_dev(rx_fp); 1011 + fp = fc_frame_alloc(lp, sizeof(*rp)); 1012 + if (!fp) 1013 + return; 1014 + fh = fc_frame_header_get(fp); 1015 + rx_fh = fc_frame_header_get(rx_fp); 1016 + 1017 + memset(fh, 0, sizeof(*fh) + sizeof(*rp)); 1018 + 1019 + rp = fc_frame_payload_get(fp, sizeof(*rp)); 1020 + rp->br_reason = reason; 1021 + rp->br_explan = explan; 1022 + 1023 + /* 1024 + * seq_id, cs_ctl, df_ctl and param/offset are zero. 1025 + */ 1026 + memcpy(fh->fh_s_id, rx_fh->fh_d_id, 3); 1027 + memcpy(fh->fh_d_id, rx_fh->fh_s_id, 3); 1028 + fh->fh_ox_id = rx_fh->fh_rx_id; 1029 + fh->fh_rx_id = rx_fh->fh_ox_id; 1030 + fh->fh_seq_cnt = rx_fh->fh_seq_cnt; 1031 + fh->fh_r_ctl = FC_RCTL_BA_RJT; 1032 + fh->fh_type = FC_TYPE_BLS; 1033 + 1034 + /* 1035 + * Form f_ctl by inverting EX_CTX and SEQ_CTX (bits 23, 22). 1036 + * Echo FIRST_SEQ, LAST_SEQ, END_SEQ, END_CONN, SEQ_INIT. 1037 + * Bits 9-8 are meaningful (retransmitted or unidirectional). 1038 + * Last ACK uses bits 7-6 (continue sequence), 1039 + * bits 5-4 are meaningful (what kind of ACK to use). 1040 + * Always set LAST_SEQ, END_SEQ. 1041 + */ 1042 + f_ctl = ntoh24(rx_fh->fh_f_ctl); 1043 + f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX | 1044 + FC_FC_END_CONN | FC_FC_SEQ_INIT | 1045 + FC_FC_RETX_SEQ | FC_FC_UNI_TX; 1046 + f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX; 1047 + f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ; 1048 + f_ctl &= ~FC_FC_FIRST_SEQ; 1049 + hton24(fh->fh_f_ctl, f_ctl); 1050 + 1051 + fr_sof(fp) = fc_sof_class(fr_sof(rx_fp)); 1052 + fr_eof(fp) = FC_EOF_T; 1053 + if (fc_sof_needs_ack(fr_sof(fp))) 1054 + fr_eof(fp) = FC_EOF_N; 1055 + 1056 + (void) lp->tt.frame_send(lp, fp); 1057 + } 1058 + 1059 + /* 1060 + * Handle an incoming ABTS. This would be for target mode usually, 1061 + * but could be due to lost FCP transfer ready, confirm or RRQ. 1062 + * We always handle this as an exchange abort, ignoring the parameter. 1063 + */ 1064 + static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp) 1065 + { 1066 + struct fc_frame *fp; 1067 + struct fc_ba_acc *ap; 1068 + struct fc_frame_header *fh; 1069 + struct fc_seq *sp; 1070 + 1071 + if (!ep) 1072 + goto reject; 1073 + spin_lock_bh(&ep->ex_lock); 1074 + if (ep->esb_stat & ESB_ST_COMPLETE) { 1075 + spin_unlock_bh(&ep->ex_lock); 1076 + goto reject; 1077 + } 1078 + if (!(ep->esb_stat & ESB_ST_REC_QUAL)) 1079 + fc_exch_hold(ep); /* hold for REC_QUAL */ 1080 + ep->esb_stat |= ESB_ST_ABNORMAL | ESB_ST_REC_QUAL; 1081 + fc_exch_timer_set_locked(ep, ep->r_a_tov); 1082 + 1083 + fp = fc_frame_alloc(ep->lp, sizeof(*ap)); 1084 + if (!fp) { 1085 + spin_unlock_bh(&ep->ex_lock); 1086 + goto free; 1087 + } 1088 + fh = fc_frame_header_get(fp); 1089 + ap = fc_frame_payload_get(fp, sizeof(*ap)); 1090 + memset(ap, 0, sizeof(*ap)); 1091 + sp = &ep->seq; 1092 + ap->ba_high_seq_cnt = htons(0xffff); 1093 + if (sp->ssb_stat & SSB_ST_RESP) { 1094 + ap->ba_seq_id = sp->id; 1095 + ap->ba_seq_id_val = FC_BA_SEQ_ID_VAL; 1096 + ap->ba_high_seq_cnt = fh->fh_seq_cnt; 1097 + ap->ba_low_seq_cnt = htons(sp->cnt); 1098 + } 1099 + sp = fc_seq_start_next(sp); 1100 + spin_unlock_bh(&ep->ex_lock); 1101 + fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS); 1102 + fc_frame_free(rx_fp); 1103 + return; 1104 + 1105 + reject: 1106 + fc_exch_send_ba_rjt(rx_fp, FC_BA_RJT_UNABLE, FC_BA_RJT_INV_XID); 1107 + free: 1108 + fc_frame_free(rx_fp); 1109 + } 1110 + 1111 + /* 1112 + * Handle receive where the other end is originating the sequence. 1113 + */ 1114 + static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp, 1115 + struct fc_frame *fp) 1116 + { 1117 + struct fc_frame_header *fh = fc_frame_header_get(fp); 1118 + struct fc_seq *sp = NULL; 1119 + struct fc_exch *ep = NULL; 1120 + enum fc_sof sof; 1121 + enum fc_eof eof; 1122 + u32 f_ctl; 1123 + enum fc_pf_rjt_reason reject; 1124 + 1125 + fr_seq(fp) = NULL; 1126 + reject = fc_seq_lookup_recip(mp, fp); 1127 + if (reject == FC_RJT_NONE) { 1128 + sp = fr_seq(fp); /* sequence will be held */ 1129 + ep = fc_seq_exch(sp); 1130 + sof = fr_sof(fp); 1131 + eof = fr_eof(fp); 1132 + f_ctl = ntoh24(fh->fh_f_ctl); 1133 + fc_seq_send_ack(sp, fp); 1134 + 1135 + /* 1136 + * Call the receive function. 1137 + * 1138 + * The receive function may allocate a new sequence 1139 + * over the old one, so we shouldn't change the 1140 + * sequence after this. 1141 + * 1142 + * The frame will be freed by the receive function. 1143 + * If new exch resp handler is valid then call that 1144 + * first. 1145 + */ 1146 + if (ep->resp) 1147 + ep->resp(sp, fp, ep->arg); 1148 + else 1149 + lp->tt.lport_recv(lp, sp, fp); 1150 + fc_exch_release(ep); /* release from lookup */ 1151 + } else { 1152 + FC_DEBUG_EXCH("exch/seq lookup failed: reject %x\n", reject); 1153 + fc_frame_free(fp); 1154 + } 1155 + } 1156 + 1157 + /* 1158 + * Handle receive where the other end is originating the sequence in 1159 + * response to our exchange. 1160 + */ 1161 + static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) 1162 + { 1163 + struct fc_frame_header *fh = fc_frame_header_get(fp); 1164 + struct fc_seq *sp; 1165 + struct fc_exch *ep; 1166 + enum fc_sof sof; 1167 + u32 f_ctl; 1168 + void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg); 1169 + void *ex_resp_arg; 1170 + int rc; 1171 + 1172 + ep = fc_exch_find(mp, ntohs(fh->fh_ox_id)); 1173 + if (!ep) { 1174 + atomic_inc(&mp->stats.xid_not_found); 1175 + goto out; 1176 + } 1177 + if (ep->rxid == FC_XID_UNKNOWN) 1178 + ep->rxid = ntohs(fh->fh_rx_id); 1179 + if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) { 1180 + atomic_inc(&mp->stats.xid_not_found); 1181 + goto rel; 1182 + } 1183 + if (ep->did != ntoh24(fh->fh_s_id) && 1184 + ep->did != FC_FID_FLOGI) { 1185 + atomic_inc(&mp->stats.xid_not_found); 1186 + goto rel; 1187 + } 1188 + sof = fr_sof(fp); 1189 + if (fc_sof_is_init(sof)) { 1190 + sp = fc_seq_start_next(&ep->seq); 1191 + sp->id = fh->fh_seq_id; 1192 + sp->ssb_stat |= SSB_ST_RESP; 1193 + } else { 1194 + sp = &ep->seq; 1195 + if (sp->id != fh->fh_seq_id) { 1196 + atomic_inc(&mp->stats.seq_not_found); 1197 + goto rel; 1198 + } 1199 + } 1200 + f_ctl = ntoh24(fh->fh_f_ctl); 1201 + fr_seq(fp) = sp; 1202 + if (f_ctl & FC_FC_SEQ_INIT) 1203 + ep->esb_stat |= ESB_ST_SEQ_INIT; 1204 + 1205 + if (fc_sof_needs_ack(sof)) 1206 + fc_seq_send_ack(sp, fp); 1207 + resp = ep->resp; 1208 + ex_resp_arg = ep->arg; 1209 + 1210 + if (fh->fh_type != FC_TYPE_FCP && fr_eof(fp) == FC_EOF_T && 1211 + (f_ctl & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) == 1212 + (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) { 1213 + spin_lock_bh(&ep->ex_lock); 1214 + rc = fc_exch_done_locked(ep); 1215 + WARN_ON(fc_seq_exch(sp) != ep); 1216 + spin_unlock_bh(&ep->ex_lock); 1217 + if (!rc) 1218 + fc_exch_mgr_delete_ep(ep); 1219 + } 1220 + 1221 + /* 1222 + * Call the receive function. 1223 + * The sequence is held (has a refcnt) for us, 1224 + * but not for the receive function. 1225 + * 1226 + * The receive function may allocate a new sequence 1227 + * over the old one, so we shouldn't change the 1228 + * sequence after this. 1229 + * 1230 + * The frame will be freed by the receive function. 1231 + * If new exch resp handler is valid then call that 1232 + * first. 1233 + */ 1234 + if (resp) 1235 + resp(sp, fp, ex_resp_arg); 1236 + else 1237 + fc_frame_free(fp); 1238 + fc_exch_release(ep); 1239 + return; 1240 + rel: 1241 + fc_exch_release(ep); 1242 + out: 1243 + fc_frame_free(fp); 1244 + } 1245 + 1246 + /* 1247 + * Handle receive for a sequence where other end is responding to our sequence. 1248 + */ 1249 + static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) 1250 + { 1251 + struct fc_seq *sp; 1252 + 1253 + sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */ 1254 + if (!sp) { 1255 + atomic_inc(&mp->stats.xid_not_found); 1256 + FC_DEBUG_EXCH("seq lookup failed\n"); 1257 + } else { 1258 + atomic_inc(&mp->stats.non_bls_resp); 1259 + FC_DEBUG_EXCH("non-BLS response to sequence"); 1260 + } 1261 + fc_frame_free(fp); 1262 + } 1263 + 1264 + /* 1265 + * Handle the response to an ABTS for exchange or sequence. 1266 + * This can be BA_ACC or BA_RJT. 1267 + */ 1268 + static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) 1269 + { 1270 + void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg); 1271 + void *ex_resp_arg; 1272 + struct fc_frame_header *fh; 1273 + struct fc_ba_acc *ap; 1274 + struct fc_seq *sp; 1275 + u16 low; 1276 + u16 high; 1277 + int rc = 1, has_rec = 0; 1278 + 1279 + fh = fc_frame_header_get(fp); 1280 + FC_DEBUG_EXCH("exch: BLS rctl %x - %s\n", 1281 + fh->fh_r_ctl, fc_exch_rctl_name(fh->fh_r_ctl)); 1282 + 1283 + if (cancel_delayed_work_sync(&ep->timeout_work)) 1284 + fc_exch_release(ep); /* release from pending timer hold */ 1285 + 1286 + spin_lock_bh(&ep->ex_lock); 1287 + switch (fh->fh_r_ctl) { 1288 + case FC_RCTL_BA_ACC: 1289 + ap = fc_frame_payload_get(fp, sizeof(*ap)); 1290 + if (!ap) 1291 + break; 1292 + 1293 + /* 1294 + * Decide whether to establish a Recovery Qualifier. 1295 + * We do this if there is a non-empty SEQ_CNT range and 1296 + * SEQ_ID is the same as the one we aborted. 1297 + */ 1298 + low = ntohs(ap->ba_low_seq_cnt); 1299 + high = ntohs(ap->ba_high_seq_cnt); 1300 + if ((ep->esb_stat & ESB_ST_REC_QUAL) == 0 && 1301 + (ap->ba_seq_id_val != FC_BA_SEQ_ID_VAL || 1302 + ap->ba_seq_id == ep->seq_id) && low != high) { 1303 + ep->esb_stat |= ESB_ST_REC_QUAL; 1304 + fc_exch_hold(ep); /* hold for recovery qualifier */ 1305 + has_rec = 1; 1306 + } 1307 + break; 1308 + case FC_RCTL_BA_RJT: 1309 + break; 1310 + default: 1311 + break; 1312 + } 1313 + 1314 + resp = ep->resp; 1315 + ex_resp_arg = ep->arg; 1316 + 1317 + /* do we need to do some other checks here. Can we reuse more of 1318 + * fc_exch_recv_seq_resp 1319 + */ 1320 + sp = &ep->seq; 1321 + /* 1322 + * do we want to check END_SEQ as well as LAST_SEQ here? 1323 + */ 1324 + if (ep->fh_type != FC_TYPE_FCP && 1325 + ntoh24(fh->fh_f_ctl) & FC_FC_LAST_SEQ) 1326 + rc = fc_exch_done_locked(ep); 1327 + spin_unlock_bh(&ep->ex_lock); 1328 + if (!rc) 1329 + fc_exch_mgr_delete_ep(ep); 1330 + 1331 + if (resp) 1332 + resp(sp, fp, ex_resp_arg); 1333 + else 1334 + fc_frame_free(fp); 1335 + 1336 + if (has_rec) 1337 + fc_exch_timer_set(ep, ep->r_a_tov); 1338 + 1339 + } 1340 + 1341 + /* 1342 + * Receive BLS sequence. 1343 + * This is always a sequence initiated by the remote side. 1344 + * We may be either the originator or recipient of the exchange. 1345 + */ 1346 + static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp) 1347 + { 1348 + struct fc_frame_header *fh; 1349 + struct fc_exch *ep; 1350 + u32 f_ctl; 1351 + 1352 + fh = fc_frame_header_get(fp); 1353 + f_ctl = ntoh24(fh->fh_f_ctl); 1354 + fr_seq(fp) = NULL; 1355 + 1356 + ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ? 1357 + ntohs(fh->fh_ox_id) : ntohs(fh->fh_rx_id)); 1358 + if (ep && (f_ctl & FC_FC_SEQ_INIT)) { 1359 + spin_lock_bh(&ep->ex_lock); 1360 + ep->esb_stat |= ESB_ST_SEQ_INIT; 1361 + spin_unlock_bh(&ep->ex_lock); 1362 + } 1363 + if (f_ctl & FC_FC_SEQ_CTX) { 1364 + /* 1365 + * A response to a sequence we initiated. 1366 + * This should only be ACKs for class 2 or F. 1367 + */ 1368 + switch (fh->fh_r_ctl) { 1369 + case FC_RCTL_ACK_1: 1370 + case FC_RCTL_ACK_0: 1371 + break; 1372 + default: 1373 + FC_DEBUG_EXCH("BLS rctl %x - %s received", 1374 + fh->fh_r_ctl, 1375 + fc_exch_rctl_name(fh->fh_r_ctl)); 1376 + break; 1377 + } 1378 + fc_frame_free(fp); 1379 + } else { 1380 + switch (fh->fh_r_ctl) { 1381 + case FC_RCTL_BA_RJT: 1382 + case FC_RCTL_BA_ACC: 1383 + if (ep) 1384 + fc_exch_abts_resp(ep, fp); 1385 + else 1386 + fc_frame_free(fp); 1387 + break; 1388 + case FC_RCTL_BA_ABTS: 1389 + fc_exch_recv_abts(ep, fp); 1390 + break; 1391 + default: /* ignore junk */ 1392 + fc_frame_free(fp); 1393 + break; 1394 + } 1395 + } 1396 + if (ep) 1397 + fc_exch_release(ep); /* release hold taken by fc_exch_find */ 1398 + } 1399 + 1400 + /* 1401 + * Accept sequence with LS_ACC. 1402 + * If this fails due to allocation or transmit congestion, assume the 1403 + * originator will repeat the sequence. 1404 + */ 1405 + static void fc_seq_ls_acc(struct fc_seq *req_sp) 1406 + { 1407 + struct fc_seq *sp; 1408 + struct fc_els_ls_acc *acc; 1409 + struct fc_frame *fp; 1410 + 1411 + sp = fc_seq_start_next(req_sp); 1412 + fp = fc_frame_alloc(fc_seq_exch(sp)->lp, sizeof(*acc)); 1413 + if (fp) { 1414 + acc = fc_frame_payload_get(fp, sizeof(*acc)); 1415 + memset(acc, 0, sizeof(*acc)); 1416 + acc->la_cmd = ELS_LS_ACC; 1417 + fc_seq_send_last(sp, fp, FC_RCTL_ELS_REP, FC_TYPE_ELS); 1418 + } 1419 + } 1420 + 1421 + /* 1422 + * Reject sequence with ELS LS_RJT. 1423 + * If this fails due to allocation or transmit congestion, assume the 1424 + * originator will repeat the sequence. 1425 + */ 1426 + static void fc_seq_ls_rjt(struct fc_seq *req_sp, enum fc_els_rjt_reason reason, 1427 + enum fc_els_rjt_explan explan) 1428 + { 1429 + struct fc_seq *sp; 1430 + struct fc_els_ls_rjt *rjt; 1431 + struct fc_frame *fp; 1432 + 1433 + sp = fc_seq_start_next(req_sp); 1434 + fp = fc_frame_alloc(fc_seq_exch(sp)->lp, sizeof(*rjt)); 1435 + if (fp) { 1436 + rjt = fc_frame_payload_get(fp, sizeof(*rjt)); 1437 + memset(rjt, 0, sizeof(*rjt)); 1438 + rjt->er_cmd = ELS_LS_RJT; 1439 + rjt->er_reason = reason; 1440 + rjt->er_explan = explan; 1441 + fc_seq_send_last(sp, fp, FC_RCTL_ELS_REP, FC_TYPE_ELS); 1442 + } 1443 + } 1444 + 1445 + static void fc_exch_reset(struct fc_exch *ep) 1446 + { 1447 + struct fc_seq *sp; 1448 + void (*resp)(struct fc_seq *, struct fc_frame *, void *); 1449 + void *arg; 1450 + int rc = 1; 1451 + 1452 + spin_lock_bh(&ep->ex_lock); 1453 + ep->state |= FC_EX_RST_CLEANUP; 1454 + /* 1455 + * we really want to call del_timer_sync, but cannot due 1456 + * to the lport calling with the lport lock held (some resp 1457 + * functions can also grab the lport lock which could cause 1458 + * a deadlock). 1459 + */ 1460 + if (cancel_delayed_work(&ep->timeout_work)) 1461 + atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ 1462 + resp = ep->resp; 1463 + ep->resp = NULL; 1464 + if (ep->esb_stat & ESB_ST_REC_QUAL) 1465 + atomic_dec(&ep->ex_refcnt); /* drop hold for rec_qual */ 1466 + ep->esb_stat &= ~ESB_ST_REC_QUAL; 1467 + arg = ep->arg; 1468 + sp = &ep->seq; 1469 + rc = fc_exch_done_locked(ep); 1470 + spin_unlock_bh(&ep->ex_lock); 1471 + if (!rc) 1472 + fc_exch_mgr_delete_ep(ep); 1473 + 1474 + if (resp) 1475 + resp(sp, ERR_PTR(-FC_EX_CLOSED), arg); 1476 + } 1477 + 1478 + /* 1479 + * Reset an exchange manager, releasing all sequences and exchanges. 1480 + * If sid is non-zero, reset only exchanges we source from that FID. 1481 + * If did is non-zero, reset only exchanges destined to that FID. 1482 + */ 1483 + void fc_exch_mgr_reset(struct fc_exch_mgr *mp, u32 sid, u32 did) 1484 + { 1485 + struct fc_exch *ep; 1486 + struct fc_exch *next; 1487 + 1488 + spin_lock_bh(&mp->em_lock); 1489 + restart: 1490 + list_for_each_entry_safe(ep, next, &mp->ex_list, ex_list) { 1491 + if ((sid == 0 || sid == ep->sid) && 1492 + (did == 0 || did == ep->did)) { 1493 + fc_exch_hold(ep); 1494 + spin_unlock_bh(&mp->em_lock); 1495 + 1496 + fc_exch_reset(ep); 1497 + 1498 + fc_exch_release(ep); 1499 + spin_lock_bh(&mp->em_lock); 1500 + 1501 + /* 1502 + * must restart loop incase while lock was down 1503 + * multiple eps were released. 1504 + */ 1505 + goto restart; 1506 + } 1507 + } 1508 + spin_unlock_bh(&mp->em_lock); 1509 + } 1510 + EXPORT_SYMBOL(fc_exch_mgr_reset); 1511 + 1512 + /* 1513 + * Handle incoming ELS REC - Read Exchange Concise. 1514 + * Note that the requesting port may be different than the S_ID in the request. 1515 + */ 1516 + static void fc_exch_els_rec(struct fc_seq *sp, struct fc_frame *rfp) 1517 + { 1518 + struct fc_frame *fp; 1519 + struct fc_exch *ep; 1520 + struct fc_exch_mgr *em; 1521 + struct fc_els_rec *rp; 1522 + struct fc_els_rec_acc *acc; 1523 + enum fc_els_rjt_reason reason = ELS_RJT_LOGIC; 1524 + enum fc_els_rjt_explan explan; 1525 + u32 sid; 1526 + u16 rxid; 1527 + u16 oxid; 1528 + 1529 + rp = fc_frame_payload_get(rfp, sizeof(*rp)); 1530 + explan = ELS_EXPL_INV_LEN; 1531 + if (!rp) 1532 + goto reject; 1533 + sid = ntoh24(rp->rec_s_id); 1534 + rxid = ntohs(rp->rec_rx_id); 1535 + oxid = ntohs(rp->rec_ox_id); 1536 + 1537 + /* 1538 + * Currently it's hard to find the local S_ID from the exchange 1539 + * manager. This will eventually be fixed, but for now it's easier 1540 + * to lookup the subject exchange twice, once as if we were 1541 + * the initiator, and then again if we weren't. 1542 + */ 1543 + em = fc_seq_exch(sp)->em; 1544 + ep = fc_exch_find(em, oxid); 1545 + explan = ELS_EXPL_OXID_RXID; 1546 + if (ep && ep->oid == sid) { 1547 + if (ep->rxid != FC_XID_UNKNOWN && 1548 + rxid != FC_XID_UNKNOWN && 1549 + ep->rxid != rxid) 1550 + goto rel; 1551 + } else { 1552 + if (ep) 1553 + fc_exch_release(ep); 1554 + ep = NULL; 1555 + if (rxid != FC_XID_UNKNOWN) 1556 + ep = fc_exch_find(em, rxid); 1557 + if (!ep) 1558 + goto reject; 1559 + } 1560 + 1561 + fp = fc_frame_alloc(fc_seq_exch(sp)->lp, sizeof(*acc)); 1562 + if (!fp) { 1563 + fc_exch_done(sp); 1564 + goto out; 1565 + } 1566 + sp = fc_seq_start_next(sp); 1567 + acc = fc_frame_payload_get(fp, sizeof(*acc)); 1568 + memset(acc, 0, sizeof(*acc)); 1569 + acc->reca_cmd = ELS_LS_ACC; 1570 + acc->reca_ox_id = rp->rec_ox_id; 1571 + memcpy(acc->reca_ofid, rp->rec_s_id, 3); 1572 + acc->reca_rx_id = htons(ep->rxid); 1573 + if (ep->sid == ep->oid) 1574 + hton24(acc->reca_rfid, ep->did); 1575 + else 1576 + hton24(acc->reca_rfid, ep->sid); 1577 + acc->reca_fc4value = htonl(ep->seq.rec_data); 1578 + acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP | 1579 + ESB_ST_SEQ_INIT | 1580 + ESB_ST_COMPLETE)); 1581 + sp = fc_seq_start_next(sp); 1582 + fc_seq_send_last(sp, fp, FC_RCTL_ELS_REP, FC_TYPE_ELS); 1583 + out: 1584 + fc_exch_release(ep); 1585 + fc_frame_free(rfp); 1586 + return; 1587 + 1588 + rel: 1589 + fc_exch_release(ep); 1590 + reject: 1591 + fc_seq_ls_rjt(sp, reason, explan); 1592 + fc_frame_free(rfp); 1593 + } 1594 + 1595 + /* 1596 + * Handle response from RRQ. 1597 + * Not much to do here, really. 1598 + * Should report errors. 1599 + * 1600 + * TODO: fix error handler. 1601 + */ 1602 + static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg) 1603 + { 1604 + struct fc_exch *aborted_ep = arg; 1605 + unsigned int op; 1606 + 1607 + if (IS_ERR(fp)) { 1608 + int err = PTR_ERR(fp); 1609 + 1610 + if (err == -FC_EX_CLOSED) 1611 + goto cleanup; 1612 + FC_DBG("Cannot process RRQ, because of frame error %d\n", err); 1613 + return; 1614 + } 1615 + 1616 + op = fc_frame_payload_op(fp); 1617 + fc_frame_free(fp); 1618 + 1619 + switch (op) { 1620 + case ELS_LS_RJT: 1621 + FC_DBG("LS_RJT for RRQ"); 1622 + /* fall through */ 1623 + case ELS_LS_ACC: 1624 + goto cleanup; 1625 + default: 1626 + FC_DBG("unexpected response op %x for RRQ", op); 1627 + return; 1628 + } 1629 + 1630 + cleanup: 1631 + fc_exch_done(&aborted_ep->seq); 1632 + /* drop hold for rec qual */ 1633 + fc_exch_release(aborted_ep); 1634 + } 1635 + 1636 + /* 1637 + * Send ELS RRQ - Reinstate Recovery Qualifier. 1638 + * This tells the remote port to stop blocking the use of 1639 + * the exchange and the seq_cnt range. 1640 + */ 1641 + static void fc_exch_rrq(struct fc_exch *ep) 1642 + { 1643 + struct fc_lport *lp; 1644 + struct fc_els_rrq *rrq; 1645 + struct fc_frame *fp; 1646 + struct fc_seq *rrq_sp; 1647 + u32 did; 1648 + 1649 + lp = ep->lp; 1650 + 1651 + fp = fc_frame_alloc(lp, sizeof(*rrq)); 1652 + if (!fp) 1653 + return; 1654 + rrq = fc_frame_payload_get(fp, sizeof(*rrq)); 1655 + memset(rrq, 0, sizeof(*rrq)); 1656 + rrq->rrq_cmd = ELS_RRQ; 1657 + hton24(rrq->rrq_s_id, ep->sid); 1658 + rrq->rrq_ox_id = htons(ep->oxid); 1659 + rrq->rrq_rx_id = htons(ep->rxid); 1660 + 1661 + did = ep->did; 1662 + if (ep->esb_stat & ESB_ST_RESP) 1663 + did = ep->sid; 1664 + 1665 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did, 1666 + fc_host_port_id(lp->host), FC_TYPE_ELS, 1667 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1668 + 1669 + rrq_sp = fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep, 1670 + lp->e_d_tov); 1671 + if (!rrq_sp) { 1672 + ep->esb_stat |= ESB_ST_REC_QUAL; 1673 + fc_exch_timer_set_locked(ep, ep->r_a_tov); 1674 + return; 1675 + } 1676 + } 1677 + 1678 + 1679 + /* 1680 + * Handle incoming ELS RRQ - Reset Recovery Qualifier. 1681 + */ 1682 + static void fc_exch_els_rrq(struct fc_seq *sp, struct fc_frame *fp) 1683 + { 1684 + struct fc_exch *ep; /* request or subject exchange */ 1685 + struct fc_els_rrq *rp; 1686 + u32 sid; 1687 + u16 xid; 1688 + enum fc_els_rjt_explan explan; 1689 + 1690 + rp = fc_frame_payload_get(fp, sizeof(*rp)); 1691 + explan = ELS_EXPL_INV_LEN; 1692 + if (!rp) 1693 + goto reject; 1694 + 1695 + /* 1696 + * lookup subject exchange. 1697 + */ 1698 + ep = fc_seq_exch(sp); 1699 + sid = ntoh24(rp->rrq_s_id); /* subject source */ 1700 + xid = ep->did == sid ? ntohs(rp->rrq_ox_id) : ntohs(rp->rrq_rx_id); 1701 + ep = fc_exch_find(ep->em, xid); 1702 + 1703 + explan = ELS_EXPL_OXID_RXID; 1704 + if (!ep) 1705 + goto reject; 1706 + spin_lock_bh(&ep->ex_lock); 1707 + if (ep->oxid != ntohs(rp->rrq_ox_id)) 1708 + goto unlock_reject; 1709 + if (ep->rxid != ntohs(rp->rrq_rx_id) && 1710 + ep->rxid != FC_XID_UNKNOWN) 1711 + goto unlock_reject; 1712 + explan = ELS_EXPL_SID; 1713 + if (ep->sid != sid) 1714 + goto unlock_reject; 1715 + 1716 + /* 1717 + * Clear Recovery Qualifier state, and cancel timer if complete. 1718 + */ 1719 + if (ep->esb_stat & ESB_ST_REC_QUAL) { 1720 + ep->esb_stat &= ~ESB_ST_REC_QUAL; 1721 + atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */ 1722 + } 1723 + if (ep->esb_stat & ESB_ST_COMPLETE) { 1724 + if (cancel_delayed_work(&ep->timeout_work)) 1725 + atomic_dec(&ep->ex_refcnt); /* drop timer hold */ 1726 + } 1727 + 1728 + spin_unlock_bh(&ep->ex_lock); 1729 + 1730 + /* 1731 + * Send LS_ACC. 1732 + */ 1733 + fc_seq_ls_acc(sp); 1734 + fc_frame_free(fp); 1735 + return; 1736 + 1737 + unlock_reject: 1738 + spin_unlock_bh(&ep->ex_lock); 1739 + fc_exch_release(ep); /* drop hold from fc_exch_find */ 1740 + reject: 1741 + fc_seq_ls_rjt(sp, ELS_RJT_LOGIC, explan); 1742 + fc_frame_free(fp); 1743 + } 1744 + 1745 + struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, 1746 + enum fc_class class, 1747 + u16 min_xid, u16 max_xid) 1748 + { 1749 + struct fc_exch_mgr *mp; 1750 + size_t len; 1751 + 1752 + if (max_xid <= min_xid || min_xid == 0 || max_xid == FC_XID_UNKNOWN) { 1753 + FC_DBG("Invalid min_xid 0x:%x and max_xid 0x:%x\n", 1754 + min_xid, max_xid); 1755 + return NULL; 1756 + } 1757 + 1758 + /* 1759 + * Memory need for EM 1760 + */ 1761 + #define xid_ok(i, m1, m2) (((i) >= (m1)) && ((i) <= (m2))) 1762 + len = (max_xid - min_xid + 1) * (sizeof(struct fc_exch *)); 1763 + len += sizeof(struct fc_exch_mgr); 1764 + 1765 + mp = kzalloc(len, GFP_ATOMIC); 1766 + if (!mp) 1767 + return NULL; 1768 + 1769 + mp->class = class; 1770 + mp->total_exches = 0; 1771 + mp->exches = (struct fc_exch **)(mp + 1); 1772 + mp->lp = lp; 1773 + /* adjust em exch xid range for offload */ 1774 + mp->min_xid = min_xid; 1775 + mp->max_xid = max_xid; 1776 + mp->last_xid = min_xid - 1; 1777 + mp->max_read = 0; 1778 + mp->last_read = 0; 1779 + if (lp->lro_enabled && xid_ok(lp->lro_xid, min_xid, max_xid)) { 1780 + mp->max_read = lp->lro_xid; 1781 + mp->last_read = min_xid - 1; 1782 + mp->last_xid = mp->max_read; 1783 + } else { 1784 + /* disable lro if no xid control over read */ 1785 + lp->lro_enabled = 0; 1786 + } 1787 + 1788 + INIT_LIST_HEAD(&mp->ex_list); 1789 + spin_lock_init(&mp->em_lock); 1790 + 1791 + mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep); 1792 + if (!mp->ep_pool) 1793 + goto free_mp; 1794 + 1795 + return mp; 1796 + 1797 + free_mp: 1798 + kfree(mp); 1799 + return NULL; 1800 + } 1801 + EXPORT_SYMBOL(fc_exch_mgr_alloc); 1802 + 1803 + void fc_exch_mgr_free(struct fc_exch_mgr *mp) 1804 + { 1805 + WARN_ON(!mp); 1806 + /* 1807 + * The total exch count must be zero 1808 + * before freeing exchange manager. 1809 + */ 1810 + WARN_ON(mp->total_exches != 0); 1811 + mempool_destroy(mp->ep_pool); 1812 + kfree(mp); 1813 + } 1814 + EXPORT_SYMBOL(fc_exch_mgr_free); 1815 + 1816 + struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp) 1817 + { 1818 + if (!lp || !lp->emp) 1819 + return NULL; 1820 + 1821 + return fc_exch_alloc(lp->emp, fp, 0); 1822 + } 1823 + EXPORT_SYMBOL(fc_exch_get); 1824 + 1825 + struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, 1826 + struct fc_frame *fp, 1827 + void (*resp)(struct fc_seq *, 1828 + struct fc_frame *fp, 1829 + void *arg), 1830 + void (*destructor)(struct fc_seq *, void *), 1831 + void *arg, u32 timer_msec) 1832 + { 1833 + struct fc_exch *ep; 1834 + struct fc_seq *sp = NULL; 1835 + struct fc_frame_header *fh; 1836 + int rc = 1; 1837 + 1838 + ep = lp->tt.exch_get(lp, fp); 1839 + if (!ep) { 1840 + fc_frame_free(fp); 1841 + return NULL; 1842 + } 1843 + ep->esb_stat |= ESB_ST_SEQ_INIT; 1844 + fh = fc_frame_header_get(fp); 1845 + fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id)); 1846 + ep->resp = resp; 1847 + ep->destructor = destructor; 1848 + ep->arg = arg; 1849 + ep->r_a_tov = FC_DEF_R_A_TOV; 1850 + ep->lp = lp; 1851 + sp = &ep->seq; 1852 + 1853 + ep->fh_type = fh->fh_type; /* save for possbile timeout handling */ 1854 + ep->f_ctl = ntoh24(fh->fh_f_ctl); 1855 + fc_exch_setup_hdr(ep, fp, ep->f_ctl); 1856 + sp->cnt++; 1857 + 1858 + if (unlikely(lp->tt.frame_send(lp, fp))) 1859 + goto err; 1860 + 1861 + if (timer_msec) 1862 + fc_exch_timer_set_locked(ep, timer_msec); 1863 + ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */ 1864 + 1865 + if (ep->f_ctl & FC_FC_SEQ_INIT) 1866 + ep->esb_stat &= ~ESB_ST_SEQ_INIT; 1867 + spin_unlock_bh(&ep->ex_lock); 1868 + return sp; 1869 + err: 1870 + rc = fc_exch_done_locked(ep); 1871 + spin_unlock_bh(&ep->ex_lock); 1872 + if (!rc) 1873 + fc_exch_mgr_delete_ep(ep); 1874 + return NULL; 1875 + } 1876 + EXPORT_SYMBOL(fc_exch_seq_send); 1877 + 1878 + /* 1879 + * Receive a frame 1880 + */ 1881 + void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, 1882 + struct fc_frame *fp) 1883 + { 1884 + struct fc_frame_header *fh = fc_frame_header_get(fp); 1885 + u32 f_ctl; 1886 + 1887 + /* lport lock ? */ 1888 + if (!lp || !mp || (lp->state == LPORT_ST_NONE)) { 1889 + FC_DBG("fc_lport or EM is not allocated and configured"); 1890 + fc_frame_free(fp); 1891 + return; 1892 + } 1893 + 1894 + /* 1895 + * If frame is marked invalid, just drop it. 1896 + */ 1897 + f_ctl = ntoh24(fh->fh_f_ctl); 1898 + switch (fr_eof(fp)) { 1899 + case FC_EOF_T: 1900 + if (f_ctl & FC_FC_END_SEQ) 1901 + skb_trim(fp_skb(fp), fr_len(fp) - FC_FC_FILL(f_ctl)); 1902 + /* fall through */ 1903 + case FC_EOF_N: 1904 + if (fh->fh_type == FC_TYPE_BLS) 1905 + fc_exch_recv_bls(mp, fp); 1906 + else if ((f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) == 1907 + FC_FC_EX_CTX) 1908 + fc_exch_recv_seq_resp(mp, fp); 1909 + else if (f_ctl & FC_FC_SEQ_CTX) 1910 + fc_exch_recv_resp(mp, fp); 1911 + else 1912 + fc_exch_recv_req(lp, mp, fp); 1913 + break; 1914 + default: 1915 + FC_DBG("dropping invalid frame (eof %x)", fr_eof(fp)); 1916 + fc_frame_free(fp); 1917 + break; 1918 + } 1919 + } 1920 + EXPORT_SYMBOL(fc_exch_recv); 1921 + 1922 + int fc_exch_init(struct fc_lport *lp) 1923 + { 1924 + if (!lp->tt.exch_get) { 1925 + /* 1926 + * exch_put() should be NULL if 1927 + * exch_get() is NULL 1928 + */ 1929 + WARN_ON(lp->tt.exch_put); 1930 + lp->tt.exch_get = fc_exch_get; 1931 + } 1932 + 1933 + if (!lp->tt.seq_start_next) 1934 + lp->tt.seq_start_next = fc_seq_start_next; 1935 + 1936 + if (!lp->tt.exch_seq_send) 1937 + lp->tt.exch_seq_send = fc_exch_seq_send; 1938 + 1939 + if (!lp->tt.seq_send) 1940 + lp->tt.seq_send = fc_seq_send; 1941 + 1942 + if (!lp->tt.seq_els_rsp_send) 1943 + lp->tt.seq_els_rsp_send = fc_seq_els_rsp_send; 1944 + 1945 + if (!lp->tt.exch_done) 1946 + lp->tt.exch_done = fc_exch_done; 1947 + 1948 + if (!lp->tt.exch_mgr_reset) 1949 + lp->tt.exch_mgr_reset = fc_exch_mgr_reset; 1950 + 1951 + if (!lp->tt.seq_exch_abort) 1952 + lp->tt.seq_exch_abort = fc_seq_exch_abort; 1953 + 1954 + return 0; 1955 + } 1956 + EXPORT_SYMBOL(fc_exch_init); 1957 + 1958 + int fc_setup_exch_mgr(void) 1959 + { 1960 + fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch), 1961 + 0, SLAB_HWCACHE_ALIGN, NULL); 1962 + if (!fc_em_cachep) 1963 + return -ENOMEM; 1964 + return 0; 1965 + } 1966 + 1967 + void fc_destroy_exch_mgr(void) 1968 + { 1969 + kmem_cache_destroy(fc_em_cachep); 1970 + }
+2131
drivers/scsi/libfc/fc_fcp.c
··· 1 + /* 2 + * Copyright(c) 2007 Intel Corporation. All rights reserved. 3 + * Copyright(c) 2008 Red Hat, Inc. All rights reserved. 4 + * Copyright(c) 2008 Mike Christie 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms and conditions of the GNU General Public License, 8 + * version 2, as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope it will be useful, but WITHOUT 11 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 + * more details. 14 + * 15 + * You should have received a copy of the GNU General Public License along with 16 + * this program; if not, write to the Free Software Foundation, Inc., 17 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 + * 19 + * Maintained at www.Open-FCoE.org 20 + */ 21 + 22 + #include <linux/module.h> 23 + #include <linux/delay.h> 24 + #include <linux/kernel.h> 25 + #include <linux/types.h> 26 + #include <linux/spinlock.h> 27 + #include <linux/scatterlist.h> 28 + #include <linux/err.h> 29 + #include <linux/crc32.h> 30 + 31 + #include <scsi/scsi_tcq.h> 32 + #include <scsi/scsi.h> 33 + #include <scsi/scsi_host.h> 34 + #include <scsi/scsi_device.h> 35 + #include <scsi/scsi_cmnd.h> 36 + 37 + #include <scsi/fc/fc_fc2.h> 38 + 39 + #include <scsi/libfc.h> 40 + #include <scsi/fc_encode.h> 41 + 42 + MODULE_AUTHOR("Open-FCoE.org"); 43 + MODULE_DESCRIPTION("libfc"); 44 + MODULE_LICENSE("GPL"); 45 + 46 + static int fc_fcp_debug; 47 + 48 + #define FC_DEBUG_FCP(fmt...) \ 49 + do { \ 50 + if (fc_fcp_debug) \ 51 + FC_DBG(fmt); \ 52 + } while (0) 53 + 54 + static struct kmem_cache *scsi_pkt_cachep; 55 + 56 + /* SRB state definitions */ 57 + #define FC_SRB_FREE 0 /* cmd is free */ 58 + #define FC_SRB_CMD_SENT (1 << 0) /* cmd has been sent */ 59 + #define FC_SRB_RCV_STATUS (1 << 1) /* response has arrived */ 60 + #define FC_SRB_ABORT_PENDING (1 << 2) /* cmd abort sent to device */ 61 + #define FC_SRB_ABORTED (1 << 3) /* abort acknowleged */ 62 + #define FC_SRB_DISCONTIG (1 << 4) /* non-sequential data recvd */ 63 + #define FC_SRB_COMPL (1 << 5) /* fc_io_compl has been run */ 64 + #define FC_SRB_FCP_PROCESSING_TMO (1 << 6) /* timer function processing */ 65 + #define FC_SRB_NOMEM (1 << 7) /* dropped to out of mem */ 66 + 67 + #define FC_SRB_READ (1 << 1) 68 + #define FC_SRB_WRITE (1 << 0) 69 + 70 + /* 71 + * The SCp.ptr should be tested and set under the host lock. NULL indicates 72 + * that the command has been retruned to the scsi layer. 73 + */ 74 + #define CMD_SP(Cmnd) ((struct fc_fcp_pkt *)(Cmnd)->SCp.ptr) 75 + #define CMD_ENTRY_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in) 76 + #define CMD_COMPL_STATUS(Cmnd) ((Cmnd)->SCp.this_residual) 77 + #define CMD_SCSI_STATUS(Cmnd) ((Cmnd)->SCp.Status) 78 + #define CMD_RESID_LEN(Cmnd) ((Cmnd)->SCp.buffers_residual) 79 + 80 + struct fc_fcp_internal { 81 + mempool_t *scsi_pkt_pool; 82 + struct list_head scsi_pkt_queue; 83 + u8 throttled; 84 + }; 85 + 86 + #define fc_get_scsi_internal(x) ((struct fc_fcp_internal *)(x)->scsi_priv) 87 + 88 + /* 89 + * function prototypes 90 + * FC scsi I/O related functions 91 + */ 92 + static void fc_fcp_recv_data(struct fc_fcp_pkt *, struct fc_frame *); 93 + static void fc_fcp_recv(struct fc_seq *, struct fc_frame *, void *); 94 + static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *); 95 + static void fc_fcp_complete_locked(struct fc_fcp_pkt *); 96 + static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *); 97 + static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp); 98 + static void fc_timeout_error(struct fc_fcp_pkt *); 99 + static void fc_fcp_timeout(unsigned long data); 100 + static void fc_fcp_rec(struct fc_fcp_pkt *); 101 + static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *); 102 + static void fc_fcp_rec_resp(struct fc_seq *, struct fc_frame *, void *); 103 + static void fc_io_compl(struct fc_fcp_pkt *); 104 + 105 + static void fc_fcp_srr(struct fc_fcp_pkt *, enum fc_rctl, u32); 106 + static void fc_fcp_srr_resp(struct fc_seq *, struct fc_frame *, void *); 107 + static void fc_fcp_srr_error(struct fc_fcp_pkt *, struct fc_frame *); 108 + 109 + /* 110 + * command status codes 111 + */ 112 + #define FC_COMPLETE 0 113 + #define FC_CMD_ABORTED 1 114 + #define FC_CMD_RESET 2 115 + #define FC_CMD_PLOGO 3 116 + #define FC_SNS_RCV 4 117 + #define FC_TRANS_ERR 5 118 + #define FC_DATA_OVRRUN 6 119 + #define FC_DATA_UNDRUN 7 120 + #define FC_ERROR 8 121 + #define FC_HRD_ERROR 9 122 + #define FC_CMD_TIME_OUT 10 123 + 124 + /* 125 + * Error recovery timeout values. 126 + */ 127 + #define FC_SCSI_ER_TIMEOUT (10 * HZ) 128 + #define FC_SCSI_TM_TOV (10 * HZ) 129 + #define FC_SCSI_REC_TOV (2 * HZ) 130 + #define FC_HOST_RESET_TIMEOUT (30 * HZ) 131 + 132 + #define FC_MAX_ERROR_CNT 5 133 + #define FC_MAX_RECOV_RETRY 3 134 + 135 + #define FC_FCP_DFLT_QUEUE_DEPTH 32 136 + 137 + /** 138 + * fc_fcp_pkt_alloc - allocation routine for scsi_pkt packet 139 + * @lp: fc lport struct 140 + * @gfp: gfp flags for allocation 141 + * 142 + * This is used by upper layer scsi driver. 143 + * Return Value : scsi_pkt structure or null on allocation failure. 144 + * Context : call from process context. no locking required. 145 + */ 146 + static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lp, gfp_t gfp) 147 + { 148 + struct fc_fcp_internal *si = fc_get_scsi_internal(lp); 149 + struct fc_fcp_pkt *fsp; 150 + 151 + fsp = mempool_alloc(si->scsi_pkt_pool, gfp); 152 + if (fsp) { 153 + memset(fsp, 0, sizeof(*fsp)); 154 + fsp->lp = lp; 155 + atomic_set(&fsp->ref_cnt, 1); 156 + init_timer(&fsp->timer); 157 + INIT_LIST_HEAD(&fsp->list); 158 + spin_lock_init(&fsp->scsi_pkt_lock); 159 + } 160 + return fsp; 161 + } 162 + 163 + /** 164 + * fc_fcp_pkt_release - release hold on scsi_pkt packet 165 + * @fsp: fcp packet struct 166 + * 167 + * This is used by upper layer scsi driver. 168 + * Context : call from process and interrupt context. 169 + * no locking required 170 + */ 171 + static void fc_fcp_pkt_release(struct fc_fcp_pkt *fsp) 172 + { 173 + if (atomic_dec_and_test(&fsp->ref_cnt)) { 174 + struct fc_fcp_internal *si = fc_get_scsi_internal(fsp->lp); 175 + 176 + mempool_free(fsp, si->scsi_pkt_pool); 177 + } 178 + } 179 + 180 + static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp) 181 + { 182 + atomic_inc(&fsp->ref_cnt); 183 + } 184 + 185 + /** 186 + * fc_fcp_pkt_destory - release hold on scsi_pkt packet 187 + * 188 + * @seq: exchange sequence 189 + * @fsp: fcp packet struct 190 + * 191 + * Release hold on scsi_pkt packet set to keep scsi_pkt 192 + * till EM layer exch resource is not freed. 193 + * Context : called from from EM layer. 194 + * no locking required 195 + */ 196 + static void fc_fcp_pkt_destroy(struct fc_seq *seq, void *fsp) 197 + { 198 + fc_fcp_pkt_release(fsp); 199 + } 200 + 201 + /** 202 + * fc_fcp_lock_pkt - lock a packet and get a ref to it. 203 + * @fsp: fcp packet 204 + * 205 + * We should only return error if we return a command to scsi-ml before 206 + * getting a response. This can happen in cases where we send a abort, but 207 + * do not wait for the response and the abort and command can be passing 208 + * each other on the wire/network-layer. 209 + * 210 + * Note: this function locks the packet and gets a reference to allow 211 + * callers to call the completion function while the lock is held and 212 + * not have to worry about the packets refcount. 213 + * 214 + * TODO: Maybe we should just have callers grab/release the lock and 215 + * have a function that they call to verify the fsp and grab a ref if 216 + * needed. 217 + */ 218 + static inline int fc_fcp_lock_pkt(struct fc_fcp_pkt *fsp) 219 + { 220 + spin_lock_bh(&fsp->scsi_pkt_lock); 221 + if (fsp->state & FC_SRB_COMPL) { 222 + spin_unlock_bh(&fsp->scsi_pkt_lock); 223 + return -EPERM; 224 + } 225 + 226 + fc_fcp_pkt_hold(fsp); 227 + return 0; 228 + } 229 + 230 + static inline void fc_fcp_unlock_pkt(struct fc_fcp_pkt *fsp) 231 + { 232 + spin_unlock_bh(&fsp->scsi_pkt_lock); 233 + fc_fcp_pkt_release(fsp); 234 + } 235 + 236 + static void fc_fcp_timer_set(struct fc_fcp_pkt *fsp, unsigned long delay) 237 + { 238 + if (!(fsp->state & FC_SRB_COMPL)) 239 + mod_timer(&fsp->timer, jiffies + delay); 240 + } 241 + 242 + static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) 243 + { 244 + if (!fsp->seq_ptr) 245 + return -EINVAL; 246 + 247 + fsp->state |= FC_SRB_ABORT_PENDING; 248 + return fsp->lp->tt.seq_exch_abort(fsp->seq_ptr, 0); 249 + } 250 + 251 + /* 252 + * Retry command. 253 + * An abort isn't needed. 254 + */ 255 + static void fc_fcp_retry_cmd(struct fc_fcp_pkt *fsp) 256 + { 257 + if (fsp->seq_ptr) { 258 + fsp->lp->tt.exch_done(fsp->seq_ptr); 259 + fsp->seq_ptr = NULL; 260 + } 261 + 262 + fsp->state &= ~FC_SRB_ABORT_PENDING; 263 + fsp->io_status = SUGGEST_RETRY << 24; 264 + fsp->status_code = FC_ERROR; 265 + fc_fcp_complete_locked(fsp); 266 + } 267 + 268 + /* 269 + * Receive SCSI data from target. 270 + * Called after receiving solicited data. 271 + */ 272 + static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) 273 + { 274 + struct scsi_cmnd *sc = fsp->cmd; 275 + struct fc_lport *lp = fsp->lp; 276 + struct fcoe_dev_stats *stats; 277 + struct fc_frame_header *fh; 278 + size_t start_offset; 279 + size_t offset; 280 + u32 crc; 281 + u32 copy_len = 0; 282 + size_t len; 283 + void *buf; 284 + struct scatterlist *sg; 285 + size_t remaining; 286 + 287 + fh = fc_frame_header_get(fp); 288 + offset = ntohl(fh->fh_parm_offset); 289 + start_offset = offset; 290 + len = fr_len(fp) - sizeof(*fh); 291 + buf = fc_frame_payload_get(fp, 0); 292 + 293 + if (offset + len > fsp->data_len) { 294 + /* 295 + * this should never happen 296 + */ 297 + if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && 298 + fc_frame_crc_check(fp)) 299 + goto crc_err; 300 + FC_DEBUG_FCP("data received past end. len %zx offset %zx " 301 + "data_len %x\n", len, offset, fsp->data_len); 302 + fc_fcp_retry_cmd(fsp); 303 + return; 304 + } 305 + if (offset != fsp->xfer_len) 306 + fsp->state |= FC_SRB_DISCONTIG; 307 + 308 + crc = 0; 309 + if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) 310 + crc = crc32(~0, (u8 *) fh, sizeof(*fh)); 311 + 312 + sg = scsi_sglist(sc); 313 + remaining = len; 314 + 315 + while (remaining > 0 && sg) { 316 + size_t off; 317 + void *page_addr; 318 + size_t sg_bytes; 319 + 320 + if (offset >= sg->length) { 321 + offset -= sg->length; 322 + sg = sg_next(sg); 323 + continue; 324 + } 325 + sg_bytes = min(remaining, sg->length - offset); 326 + 327 + /* 328 + * The scatterlist item may be bigger than PAGE_SIZE, 329 + * but we are limited to mapping PAGE_SIZE at a time. 330 + */ 331 + off = offset + sg->offset; 332 + sg_bytes = min(sg_bytes, (size_t) 333 + (PAGE_SIZE - (off & ~PAGE_MASK))); 334 + page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT), 335 + KM_SOFTIRQ0); 336 + if (!page_addr) 337 + break; /* XXX panic? */ 338 + 339 + if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) 340 + crc = crc32(crc, buf, sg_bytes); 341 + memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, 342 + sg_bytes); 343 + 344 + kunmap_atomic(page_addr, KM_SOFTIRQ0); 345 + buf += sg_bytes; 346 + offset += sg_bytes; 347 + remaining -= sg_bytes; 348 + copy_len += sg_bytes; 349 + } 350 + 351 + if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) { 352 + buf = fc_frame_payload_get(fp, 0); 353 + if (len % 4) { 354 + crc = crc32(crc, buf + len, 4 - (len % 4)); 355 + len += 4 - (len % 4); 356 + } 357 + 358 + if (~crc != le32_to_cpu(fr_crc(fp))) { 359 + crc_err: 360 + stats = lp->dev_stats[smp_processor_id()]; 361 + stats->ErrorFrames++; 362 + if (stats->InvalidCRCCount++ < 5) 363 + FC_DBG("CRC error on data frame\n"); 364 + /* 365 + * Assume the frame is total garbage. 366 + * We may have copied it over the good part 367 + * of the buffer. 368 + * If so, we need to retry the entire operation. 369 + * Otherwise, ignore it. 370 + */ 371 + if (fsp->state & FC_SRB_DISCONTIG) 372 + fc_fcp_retry_cmd(fsp); 373 + return; 374 + } 375 + } 376 + 377 + if (fsp->xfer_contig_end == start_offset) 378 + fsp->xfer_contig_end += copy_len; 379 + fsp->xfer_len += copy_len; 380 + 381 + /* 382 + * In the very rare event that this data arrived after the response 383 + * and completes the transfer, call the completion handler. 384 + */ 385 + if (unlikely(fsp->state & FC_SRB_RCV_STATUS) && 386 + fsp->xfer_len == fsp->data_len - fsp->scsi_resid) 387 + fc_fcp_complete_locked(fsp); 388 + } 389 + 390 + /* 391 + * fc_fcp_send_data - Send SCSI data to target. 392 + * @fsp: ptr to fc_fcp_pkt 393 + * @sp: ptr to this sequence 394 + * @offset: starting offset for this data request 395 + * @seq_blen: the burst length for this data request 396 + * 397 + * Called after receiving a Transfer Ready data descriptor. 398 + * if LLD is capable of seq offload then send down seq_blen 399 + * size of data in single frame, otherwise send multiple FC 400 + * frames of max FC frame payload supported by target port. 401 + * 402 + * Returns : 0 for success. 403 + */ 404 + static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, 405 + size_t offset, size_t seq_blen) 406 + { 407 + struct fc_exch *ep; 408 + struct scsi_cmnd *sc; 409 + struct scatterlist *sg; 410 + struct fc_frame *fp = NULL; 411 + struct fc_lport *lp = fsp->lp; 412 + size_t remaining; 413 + size_t t_blen; 414 + size_t tlen; 415 + size_t sg_bytes; 416 + size_t frame_offset, fh_parm_offset; 417 + int error; 418 + void *data = NULL; 419 + void *page_addr; 420 + int using_sg = lp->sg_supp; 421 + u32 f_ctl; 422 + 423 + WARN_ON(seq_blen <= 0); 424 + if (unlikely(offset + seq_blen > fsp->data_len)) { 425 + /* this should never happen */ 426 + FC_DEBUG_FCP("xfer-ready past end. seq_blen %zx offset %zx\n", 427 + seq_blen, offset); 428 + fc_fcp_send_abort(fsp); 429 + return 0; 430 + } else if (offset != fsp->xfer_len) { 431 + /* Out of Order Data Request - no problem, but unexpected. */ 432 + FC_DEBUG_FCP("xfer-ready non-contiguous. " 433 + "seq_blen %zx offset %zx\n", seq_blen, offset); 434 + } 435 + 436 + /* 437 + * if LLD is capable of seq_offload then set transport 438 + * burst length (t_blen) to seq_blen, otherwise set t_blen 439 + * to max FC frame payload previously set in fsp->max_payload. 440 + */ 441 + t_blen = lp->seq_offload ? seq_blen : fsp->max_payload; 442 + WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD); 443 + if (t_blen > 512) 444 + t_blen &= ~(512 - 1); /* round down to block size */ 445 + WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD); /* won't go below 256 */ 446 + sc = fsp->cmd; 447 + 448 + remaining = seq_blen; 449 + fh_parm_offset = frame_offset = offset; 450 + tlen = 0; 451 + seq = lp->tt.seq_start_next(seq); 452 + f_ctl = FC_FC_REL_OFF; 453 + WARN_ON(!seq); 454 + 455 + /* 456 + * If a get_page()/put_page() will fail, don't use sg lists 457 + * in the fc_frame structure. 458 + * 459 + * The put_page() may be long after the I/O has completed 460 + * in the case of FCoE, since the network driver does it 461 + * via free_skb(). See the test in free_pages_check(). 462 + * 463 + * Test this case with 'dd </dev/zero >/dev/st0 bs=64k'. 464 + */ 465 + if (using_sg) { 466 + for (sg = scsi_sglist(sc); sg; sg = sg_next(sg)) { 467 + if (page_count(sg_page(sg)) == 0 || 468 + (sg_page(sg)->flags & (1 << PG_lru | 469 + 1 << PG_private | 470 + 1 << PG_locked | 471 + 1 << PG_active | 472 + 1 << PG_slab | 473 + 1 << PG_swapcache | 474 + 1 << PG_writeback | 475 + 1 << PG_reserved | 476 + 1 << PG_buddy))) { 477 + using_sg = 0; 478 + break; 479 + } 480 + } 481 + } 482 + sg = scsi_sglist(sc); 483 + 484 + while (remaining > 0 && sg) { 485 + if (offset >= sg->length) { 486 + offset -= sg->length; 487 + sg = sg_next(sg); 488 + continue; 489 + } 490 + if (!fp) { 491 + tlen = min(t_blen, remaining); 492 + 493 + /* 494 + * TODO. Temporary workaround. fc_seq_send() can't 495 + * handle odd lengths in non-linear skbs. 496 + * This will be the final fragment only. 497 + */ 498 + if (tlen % 4) 499 + using_sg = 0; 500 + if (using_sg) { 501 + fp = _fc_frame_alloc(lp, 0); 502 + if (!fp) 503 + return -ENOMEM; 504 + } else { 505 + fp = fc_frame_alloc(lp, tlen); 506 + if (!fp) 507 + return -ENOMEM; 508 + 509 + data = (void *)(fr_hdr(fp)) + 510 + sizeof(struct fc_frame_header); 511 + } 512 + fh_parm_offset = frame_offset; 513 + fr_max_payload(fp) = fsp->max_payload; 514 + } 515 + sg_bytes = min(tlen, sg->length - offset); 516 + if (using_sg) { 517 + WARN_ON(skb_shinfo(fp_skb(fp))->nr_frags > 518 + FC_FRAME_SG_LEN); 519 + get_page(sg_page(sg)); 520 + skb_fill_page_desc(fp_skb(fp), 521 + skb_shinfo(fp_skb(fp))->nr_frags, 522 + sg_page(sg), sg->offset + offset, 523 + sg_bytes); 524 + fp_skb(fp)->data_len += sg_bytes; 525 + fr_len(fp) += sg_bytes; 526 + fp_skb(fp)->truesize += PAGE_SIZE; 527 + } else { 528 + size_t off = offset + sg->offset; 529 + 530 + /* 531 + * The scatterlist item may be bigger than PAGE_SIZE, 532 + * but we must not cross pages inside the kmap. 533 + */ 534 + sg_bytes = min(sg_bytes, (size_t) (PAGE_SIZE - 535 + (off & ~PAGE_MASK))); 536 + page_addr = kmap_atomic(sg_page(sg) + 537 + (off >> PAGE_SHIFT), 538 + KM_SOFTIRQ0); 539 + memcpy(data, (char *)page_addr + (off & ~PAGE_MASK), 540 + sg_bytes); 541 + kunmap_atomic(page_addr, KM_SOFTIRQ0); 542 + data += sg_bytes; 543 + } 544 + offset += sg_bytes; 545 + frame_offset += sg_bytes; 546 + tlen -= sg_bytes; 547 + remaining -= sg_bytes; 548 + 549 + if (tlen) 550 + continue; 551 + 552 + /* 553 + * Send sequence with transfer sequence initiative in case 554 + * this is last FCP frame of the sequence. 555 + */ 556 + if (remaining == 0) 557 + f_ctl |= FC_FC_SEQ_INIT | FC_FC_END_SEQ; 558 + 559 + ep = fc_seq_exch(seq); 560 + fc_fill_fc_hdr(fp, FC_RCTL_DD_SOL_DATA, ep->did, ep->sid, 561 + FC_TYPE_FCP, f_ctl, fh_parm_offset); 562 + 563 + /* 564 + * send fragment using for a sequence. 565 + */ 566 + error = lp->tt.seq_send(lp, seq, fp); 567 + if (error) { 568 + WARN_ON(1); /* send error should be rare */ 569 + fc_fcp_retry_cmd(fsp); 570 + return 0; 571 + } 572 + fp = NULL; 573 + } 574 + fsp->xfer_len += seq_blen; /* premature count? */ 575 + return 0; 576 + } 577 + 578 + static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) 579 + { 580 + int ba_done = 1; 581 + struct fc_ba_rjt *brp; 582 + struct fc_frame_header *fh; 583 + 584 + fh = fc_frame_header_get(fp); 585 + switch (fh->fh_r_ctl) { 586 + case FC_RCTL_BA_ACC: 587 + break; 588 + case FC_RCTL_BA_RJT: 589 + brp = fc_frame_payload_get(fp, sizeof(*brp)); 590 + if (brp && brp->br_reason == FC_BA_RJT_LOG_ERR) 591 + break; 592 + /* fall thru */ 593 + default: 594 + /* 595 + * we will let the command timeout 596 + * and scsi-ml recover in this case, 597 + * therefore cleared the ba_done flag. 598 + */ 599 + ba_done = 0; 600 + } 601 + 602 + if (ba_done) { 603 + fsp->state |= FC_SRB_ABORTED; 604 + fsp->state &= ~FC_SRB_ABORT_PENDING; 605 + 606 + if (fsp->wait_for_comp) 607 + complete(&fsp->tm_done); 608 + else 609 + fc_fcp_complete_locked(fsp); 610 + } 611 + } 612 + 613 + /* 614 + * fc_fcp_reduce_can_queue - drop can_queue 615 + * @lp: lport to drop queueing for 616 + * 617 + * If we are getting memory allocation failures, then we may 618 + * be trying to execute too many commands. We let the running 619 + * commands complete or timeout, then try again with a reduced 620 + * can_queue. Eventually we will hit the point where we run 621 + * on all reserved structs. 622 + */ 623 + static void fc_fcp_reduce_can_queue(struct fc_lport *lp) 624 + { 625 + struct fc_fcp_internal *si = fc_get_scsi_internal(lp); 626 + unsigned long flags; 627 + int can_queue; 628 + 629 + spin_lock_irqsave(lp->host->host_lock, flags); 630 + if (si->throttled) 631 + goto done; 632 + si->throttled = 1; 633 + 634 + can_queue = lp->host->can_queue; 635 + can_queue >>= 1; 636 + if (!can_queue) 637 + can_queue = 1; 638 + lp->host->can_queue = can_queue; 639 + shost_printk(KERN_ERR, lp->host, "Could not allocate frame.\n" 640 + "Reducing can_queue to %d.\n", can_queue); 641 + done: 642 + spin_unlock_irqrestore(lp->host->host_lock, flags); 643 + } 644 + 645 + /* 646 + * exch mgr calls this routine to process scsi 647 + * exchanges. 648 + * 649 + * Return : None 650 + * Context : called from Soft IRQ context 651 + * can not called holding list lock 652 + */ 653 + static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg) 654 + { 655 + struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)arg; 656 + struct fc_lport *lp; 657 + struct fc_frame_header *fh; 658 + struct fcp_txrdy *dd; 659 + u8 r_ctl; 660 + int rc = 0; 661 + 662 + if (IS_ERR(fp)) 663 + goto errout; 664 + 665 + fh = fc_frame_header_get(fp); 666 + r_ctl = fh->fh_r_ctl; 667 + lp = fsp->lp; 668 + 669 + if (!(lp->state & LPORT_ST_READY)) 670 + goto out; 671 + if (fc_fcp_lock_pkt(fsp)) 672 + goto out; 673 + fsp->last_pkt_time = jiffies; 674 + 675 + if (fh->fh_type == FC_TYPE_BLS) { 676 + fc_fcp_abts_resp(fsp, fp); 677 + goto unlock; 678 + } 679 + 680 + if (fsp->state & (FC_SRB_ABORTED | FC_SRB_ABORT_PENDING)) 681 + goto unlock; 682 + 683 + if (r_ctl == FC_RCTL_DD_DATA_DESC) { 684 + /* 685 + * received XFER RDY from the target 686 + * need to send data to the target 687 + */ 688 + WARN_ON(fr_flags(fp) & FCPHF_CRC_UNCHECKED); 689 + dd = fc_frame_payload_get(fp, sizeof(*dd)); 690 + WARN_ON(!dd); 691 + 692 + rc = fc_fcp_send_data(fsp, seq, 693 + (size_t) ntohl(dd->ft_data_ro), 694 + (size_t) ntohl(dd->ft_burst_len)); 695 + if (!rc) 696 + seq->rec_data = fsp->xfer_len; 697 + else if (rc == -ENOMEM) 698 + fsp->state |= FC_SRB_NOMEM; 699 + } else if (r_ctl == FC_RCTL_DD_SOL_DATA) { 700 + /* 701 + * received a DATA frame 702 + * next we will copy the data to the system buffer 703 + */ 704 + WARN_ON(fr_len(fp) < sizeof(*fh)); /* len may be 0 */ 705 + fc_fcp_recv_data(fsp, fp); 706 + seq->rec_data = fsp->xfer_contig_end; 707 + } else if (r_ctl == FC_RCTL_DD_CMD_STATUS) { 708 + WARN_ON(fr_flags(fp) & FCPHF_CRC_UNCHECKED); 709 + 710 + fc_fcp_resp(fsp, fp); 711 + } else { 712 + FC_DBG("unexpected frame. r_ctl %x\n", r_ctl); 713 + } 714 + unlock: 715 + fc_fcp_unlock_pkt(fsp); 716 + out: 717 + fc_frame_free(fp); 718 + errout: 719 + if (IS_ERR(fp)) 720 + fc_fcp_error(fsp, fp); 721 + else if (rc == -ENOMEM) 722 + fc_fcp_reduce_can_queue(lp); 723 + } 724 + 725 + static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) 726 + { 727 + struct fc_frame_header *fh; 728 + struct fcp_resp *fc_rp; 729 + struct fcp_resp_ext *rp_ex; 730 + struct fcp_resp_rsp_info *fc_rp_info; 731 + u32 plen; 732 + u32 expected_len; 733 + u32 respl = 0; 734 + u32 snsl = 0; 735 + u8 flags = 0; 736 + 737 + plen = fr_len(fp); 738 + fh = (struct fc_frame_header *)fr_hdr(fp); 739 + if (unlikely(plen < sizeof(*fh) + sizeof(*fc_rp))) 740 + goto len_err; 741 + plen -= sizeof(*fh); 742 + fc_rp = (struct fcp_resp *)(fh + 1); 743 + fsp->cdb_status = fc_rp->fr_status; 744 + flags = fc_rp->fr_flags; 745 + fsp->scsi_comp_flags = flags; 746 + expected_len = fsp->data_len; 747 + 748 + if (unlikely((flags & ~FCP_CONF_REQ) || fc_rp->fr_status)) { 749 + rp_ex = (void *)(fc_rp + 1); 750 + if (flags & (FCP_RSP_LEN_VAL | FCP_SNS_LEN_VAL)) { 751 + if (plen < sizeof(*fc_rp) + sizeof(*rp_ex)) 752 + goto len_err; 753 + fc_rp_info = (struct fcp_resp_rsp_info *)(rp_ex + 1); 754 + if (flags & FCP_RSP_LEN_VAL) { 755 + respl = ntohl(rp_ex->fr_rsp_len); 756 + if (respl != sizeof(*fc_rp_info)) 757 + goto len_err; 758 + if (fsp->wait_for_comp) { 759 + /* Abuse cdb_status for rsp code */ 760 + fsp->cdb_status = fc_rp_info->rsp_code; 761 + complete(&fsp->tm_done); 762 + /* 763 + * tmfs will not have any scsi cmd so 764 + * exit here 765 + */ 766 + return; 767 + } else 768 + goto err; 769 + } 770 + if (flags & FCP_SNS_LEN_VAL) { 771 + snsl = ntohl(rp_ex->fr_sns_len); 772 + if (snsl > SCSI_SENSE_BUFFERSIZE) 773 + snsl = SCSI_SENSE_BUFFERSIZE; 774 + memcpy(fsp->cmd->sense_buffer, 775 + (char *)fc_rp_info + respl, snsl); 776 + } 777 + } 778 + if (flags & (FCP_RESID_UNDER | FCP_RESID_OVER)) { 779 + if (plen < sizeof(*fc_rp) + sizeof(rp_ex->fr_resid)) 780 + goto len_err; 781 + if (flags & FCP_RESID_UNDER) { 782 + fsp->scsi_resid = ntohl(rp_ex->fr_resid); 783 + /* 784 + * The cmnd->underflow is the minimum number of 785 + * bytes that must be transfered for this 786 + * command. Provided a sense condition is not 787 + * present, make sure the actual amount 788 + * transferred is at least the underflow value 789 + * or fail. 790 + */ 791 + if (!(flags & FCP_SNS_LEN_VAL) && 792 + (fc_rp->fr_status == 0) && 793 + (scsi_bufflen(fsp->cmd) - 794 + fsp->scsi_resid) < fsp->cmd->underflow) 795 + goto err; 796 + expected_len -= fsp->scsi_resid; 797 + } else { 798 + fsp->status_code = FC_ERROR; 799 + } 800 + } 801 + } 802 + fsp->state |= FC_SRB_RCV_STATUS; 803 + 804 + /* 805 + * Check for missing or extra data frames. 806 + */ 807 + if (unlikely(fsp->xfer_len != expected_len)) { 808 + if (fsp->xfer_len < expected_len) { 809 + /* 810 + * Some data may be queued locally, 811 + * Wait a at least one jiffy to see if it is delivered. 812 + * If this expires without data, we may do SRR. 813 + */ 814 + fc_fcp_timer_set(fsp, 2); 815 + return; 816 + } 817 + fsp->status_code = FC_DATA_OVRRUN; 818 + FC_DBG("tgt %6x xfer len %zx greater than expected len %x. " 819 + "data len %x\n", 820 + fsp->rport->port_id, 821 + fsp->xfer_len, expected_len, fsp->data_len); 822 + } 823 + fc_fcp_complete_locked(fsp); 824 + return; 825 + 826 + len_err: 827 + FC_DBG("short FCP response. flags 0x%x len %u respl %u snsl %u\n", 828 + flags, fr_len(fp), respl, snsl); 829 + err: 830 + fsp->status_code = FC_ERROR; 831 + fc_fcp_complete_locked(fsp); 832 + } 833 + 834 + /** 835 + * fc_fcp_complete_locked - complete processing of a fcp packet 836 + * @fsp: fcp packet 837 + * 838 + * This function may sleep if a timer is pending. The packet lock must be 839 + * held, and the host lock must not be held. 840 + */ 841 + static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp) 842 + { 843 + struct fc_lport *lp = fsp->lp; 844 + struct fc_seq *seq; 845 + struct fc_exch *ep; 846 + u32 f_ctl; 847 + 848 + if (fsp->state & FC_SRB_ABORT_PENDING) 849 + return; 850 + 851 + if (fsp->state & FC_SRB_ABORTED) { 852 + if (!fsp->status_code) 853 + fsp->status_code = FC_CMD_ABORTED; 854 + } else { 855 + /* 856 + * Test for transport underrun, independent of response 857 + * underrun status. 858 + */ 859 + if (fsp->xfer_len < fsp->data_len && !fsp->io_status && 860 + (!(fsp->scsi_comp_flags & FCP_RESID_UNDER) || 861 + fsp->xfer_len < fsp->data_len - fsp->scsi_resid)) { 862 + fsp->status_code = FC_DATA_UNDRUN; 863 + fsp->io_status = SUGGEST_RETRY << 24; 864 + } 865 + } 866 + 867 + seq = fsp->seq_ptr; 868 + if (seq) { 869 + fsp->seq_ptr = NULL; 870 + if (unlikely(fsp->scsi_comp_flags & FCP_CONF_REQ)) { 871 + struct fc_frame *conf_frame; 872 + struct fc_seq *csp; 873 + 874 + csp = lp->tt.seq_start_next(seq); 875 + conf_frame = fc_frame_alloc(fsp->lp, 0); 876 + if (conf_frame) { 877 + f_ctl = FC_FC_SEQ_INIT; 878 + f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ; 879 + ep = fc_seq_exch(seq); 880 + fc_fill_fc_hdr(conf_frame, FC_RCTL_DD_SOL_CTL, 881 + ep->did, ep->sid, 882 + FC_TYPE_FCP, f_ctl, 0); 883 + lp->tt.seq_send(lp, csp, conf_frame); 884 + } 885 + } 886 + lp->tt.exch_done(seq); 887 + } 888 + fc_io_compl(fsp); 889 + } 890 + 891 + static void fc_fcp_cleanup_cmd(struct fc_fcp_pkt *fsp, int error) 892 + { 893 + struct fc_lport *lp = fsp->lp; 894 + 895 + if (fsp->seq_ptr) { 896 + lp->tt.exch_done(fsp->seq_ptr); 897 + fsp->seq_ptr = NULL; 898 + } 899 + fsp->status_code = error; 900 + } 901 + 902 + /** 903 + * fc_fcp_cleanup_each_cmd - run fn on each active command 904 + * @lp: logical port 905 + * @id: target id 906 + * @lun: lun 907 + * @error: fsp status code 908 + * 909 + * If lun or id is -1, they are ignored. 910 + */ 911 + static void fc_fcp_cleanup_each_cmd(struct fc_lport *lp, unsigned int id, 912 + unsigned int lun, int error) 913 + { 914 + struct fc_fcp_internal *si = fc_get_scsi_internal(lp); 915 + struct fc_fcp_pkt *fsp; 916 + struct scsi_cmnd *sc_cmd; 917 + unsigned long flags; 918 + 919 + spin_lock_irqsave(lp->host->host_lock, flags); 920 + restart: 921 + list_for_each_entry(fsp, &si->scsi_pkt_queue, list) { 922 + sc_cmd = fsp->cmd; 923 + if (id != -1 && scmd_id(sc_cmd) != id) 924 + continue; 925 + 926 + if (lun != -1 && sc_cmd->device->lun != lun) 927 + continue; 928 + 929 + fc_fcp_pkt_hold(fsp); 930 + spin_unlock_irqrestore(lp->host->host_lock, flags); 931 + 932 + if (!fc_fcp_lock_pkt(fsp)) { 933 + fc_fcp_cleanup_cmd(fsp, error); 934 + fc_io_compl(fsp); 935 + fc_fcp_unlock_pkt(fsp); 936 + } 937 + 938 + fc_fcp_pkt_release(fsp); 939 + spin_lock_irqsave(lp->host->host_lock, flags); 940 + /* 941 + * while we dropped the lock multiple pkts could 942 + * have been released, so we have to start over. 943 + */ 944 + goto restart; 945 + } 946 + spin_unlock_irqrestore(lp->host->host_lock, flags); 947 + } 948 + 949 + static void fc_fcp_abort_io(struct fc_lport *lp) 950 + { 951 + fc_fcp_cleanup_each_cmd(lp, -1, -1, FC_HRD_ERROR); 952 + } 953 + 954 + /** 955 + * fc_fcp_pkt_send - send a fcp packet to the lower level. 956 + * @lp: fc lport 957 + * @fsp: fc packet. 958 + * 959 + * This is called by upper layer protocol. 960 + * Return : zero for success and -1 for failure 961 + * Context : called from queuecommand which can be called from process 962 + * or scsi soft irq. 963 + * Locks : called with the host lock and irqs disabled. 964 + */ 965 + static int fc_fcp_pkt_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp) 966 + { 967 + struct fc_fcp_internal *si = fc_get_scsi_internal(lp); 968 + int rc; 969 + 970 + fsp->cmd->SCp.ptr = (char *)fsp; 971 + fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); 972 + fsp->cdb_cmd.fc_flags = fsp->req_flags & ~FCP_CFL_LEN_MASK; 973 + 974 + int_to_scsilun(fsp->cmd->device->lun, 975 + (struct scsi_lun *)fsp->cdb_cmd.fc_lun); 976 + memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len); 977 + list_add_tail(&fsp->list, &si->scsi_pkt_queue); 978 + 979 + spin_unlock_irq(lp->host->host_lock); 980 + rc = lp->tt.fcp_cmd_send(lp, fsp, fc_fcp_recv); 981 + spin_lock_irq(lp->host->host_lock); 982 + if (rc) 983 + list_del(&fsp->list); 984 + 985 + return rc; 986 + } 987 + 988 + static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp, 989 + void (*resp)(struct fc_seq *, 990 + struct fc_frame *fp, 991 + void *arg)) 992 + { 993 + struct fc_frame *fp; 994 + struct fc_seq *seq; 995 + struct fc_rport *rport; 996 + struct fc_rport_libfc_priv *rp; 997 + const size_t len = sizeof(fsp->cdb_cmd); 998 + int rc = 0; 999 + 1000 + if (fc_fcp_lock_pkt(fsp)) 1001 + return 0; 1002 + 1003 + fp = fc_frame_alloc(lp, sizeof(fsp->cdb_cmd)); 1004 + if (!fp) { 1005 + rc = -1; 1006 + goto unlock; 1007 + } 1008 + 1009 + memcpy(fc_frame_payload_get(fp, len), &fsp->cdb_cmd, len); 1010 + fr_cmd(fp) = fsp->cmd; 1011 + rport = fsp->rport; 1012 + fsp->max_payload = rport->maxframe_size; 1013 + rp = rport->dd_data; 1014 + 1015 + fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id, 1016 + fc_host_port_id(rp->local_port->host), FC_TYPE_FCP, 1017 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1018 + 1019 + seq = lp->tt.exch_seq_send(lp, fp, resp, fc_fcp_pkt_destroy, fsp, 0); 1020 + if (!seq) { 1021 + fc_frame_free(fp); 1022 + rc = -1; 1023 + goto unlock; 1024 + } 1025 + fsp->last_pkt_time = jiffies; 1026 + fsp->seq_ptr = seq; 1027 + fc_fcp_pkt_hold(fsp); /* hold for fc_fcp_pkt_destroy */ 1028 + 1029 + setup_timer(&fsp->timer, fc_fcp_timeout, (unsigned long)fsp); 1030 + fc_fcp_timer_set(fsp, 1031 + (fsp->tgt_flags & FC_RP_FLAGS_REC_SUPPORTED) ? 1032 + FC_SCSI_REC_TOV : FC_SCSI_ER_TIMEOUT); 1033 + unlock: 1034 + fc_fcp_unlock_pkt(fsp); 1035 + return rc; 1036 + } 1037 + 1038 + /* 1039 + * transport error handler 1040 + */ 1041 + static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) 1042 + { 1043 + int error = PTR_ERR(fp); 1044 + 1045 + if (fc_fcp_lock_pkt(fsp)) 1046 + return; 1047 + 1048 + switch (error) { 1049 + case -FC_EX_CLOSED: 1050 + fc_fcp_retry_cmd(fsp); 1051 + goto unlock; 1052 + default: 1053 + FC_DBG("unknown error %ld\n", PTR_ERR(fp)); 1054 + } 1055 + /* 1056 + * clear abort pending, because the lower layer 1057 + * decided to force completion. 1058 + */ 1059 + fsp->state &= ~FC_SRB_ABORT_PENDING; 1060 + fsp->status_code = FC_CMD_PLOGO; 1061 + fc_fcp_complete_locked(fsp); 1062 + unlock: 1063 + fc_fcp_unlock_pkt(fsp); 1064 + } 1065 + 1066 + /* 1067 + * Scsi abort handler- calls to send an abort 1068 + * and then wait for abort completion 1069 + */ 1070 + static int fc_fcp_pkt_abort(struct fc_lport *lp, struct fc_fcp_pkt *fsp) 1071 + { 1072 + int rc = FAILED; 1073 + 1074 + if (fc_fcp_send_abort(fsp)) 1075 + return FAILED; 1076 + 1077 + init_completion(&fsp->tm_done); 1078 + fsp->wait_for_comp = 1; 1079 + 1080 + spin_unlock_bh(&fsp->scsi_pkt_lock); 1081 + rc = wait_for_completion_timeout(&fsp->tm_done, FC_SCSI_TM_TOV); 1082 + spin_lock_bh(&fsp->scsi_pkt_lock); 1083 + fsp->wait_for_comp = 0; 1084 + 1085 + if (!rc) { 1086 + FC_DBG("target abort cmd failed\n"); 1087 + rc = FAILED; 1088 + } else if (fsp->state & FC_SRB_ABORTED) { 1089 + FC_DBG("target abort cmd passed\n"); 1090 + rc = SUCCESS; 1091 + fc_fcp_complete_locked(fsp); 1092 + } 1093 + 1094 + return rc; 1095 + } 1096 + 1097 + /* 1098 + * Retry LUN reset after resource allocation failed. 1099 + */ 1100 + static void fc_lun_reset_send(unsigned long data) 1101 + { 1102 + struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data; 1103 + struct fc_lport *lp = fsp->lp; 1104 + if (lp->tt.fcp_cmd_send(lp, fsp, fc_tm_done)) { 1105 + if (fsp->recov_retry++ >= FC_MAX_RECOV_RETRY) 1106 + return; 1107 + if (fc_fcp_lock_pkt(fsp)) 1108 + return; 1109 + setup_timer(&fsp->timer, fc_lun_reset_send, (unsigned long)fsp); 1110 + fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1111 + fc_fcp_unlock_pkt(fsp); 1112 + } 1113 + } 1114 + 1115 + /* 1116 + * Scsi device reset handler- send a LUN RESET to the device 1117 + * and wait for reset reply 1118 + */ 1119 + static int fc_lun_reset(struct fc_lport *lp, struct fc_fcp_pkt *fsp, 1120 + unsigned int id, unsigned int lun) 1121 + { 1122 + int rc; 1123 + 1124 + fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); 1125 + fsp->cdb_cmd.fc_tm_flags = FCP_TMF_LUN_RESET; 1126 + int_to_scsilun(lun, (struct scsi_lun *)fsp->cdb_cmd.fc_lun); 1127 + 1128 + fsp->wait_for_comp = 1; 1129 + init_completion(&fsp->tm_done); 1130 + 1131 + fc_lun_reset_send((unsigned long)fsp); 1132 + 1133 + /* 1134 + * wait for completion of reset 1135 + * after that make sure all commands are terminated 1136 + */ 1137 + rc = wait_for_completion_timeout(&fsp->tm_done, FC_SCSI_TM_TOV); 1138 + 1139 + spin_lock_bh(&fsp->scsi_pkt_lock); 1140 + fsp->state |= FC_SRB_COMPL; 1141 + spin_unlock_bh(&fsp->scsi_pkt_lock); 1142 + 1143 + del_timer_sync(&fsp->timer); 1144 + 1145 + spin_lock_bh(&fsp->scsi_pkt_lock); 1146 + if (fsp->seq_ptr) { 1147 + lp->tt.exch_done(fsp->seq_ptr); 1148 + fsp->seq_ptr = NULL; 1149 + } 1150 + fsp->wait_for_comp = 0; 1151 + spin_unlock_bh(&fsp->scsi_pkt_lock); 1152 + 1153 + if (!rc) { 1154 + FC_DBG("lun reset failed\n"); 1155 + return FAILED; 1156 + } 1157 + 1158 + /* cdb_status holds the tmf's rsp code */ 1159 + if (fsp->cdb_status != FCP_TMF_CMPL) 1160 + return FAILED; 1161 + 1162 + FC_DBG("lun reset to lun %u completed\n", lun); 1163 + fc_fcp_cleanup_each_cmd(lp, id, lun, FC_CMD_ABORTED); 1164 + return SUCCESS; 1165 + } 1166 + 1167 + /* 1168 + * Task Managment response handler 1169 + */ 1170 + static void fc_tm_done(struct fc_seq *seq, struct fc_frame *fp, void *arg) 1171 + { 1172 + struct fc_fcp_pkt *fsp = arg; 1173 + struct fc_frame_header *fh; 1174 + 1175 + if (IS_ERR(fp)) { 1176 + /* 1177 + * If there is an error just let it timeout or wait 1178 + * for TMF to be aborted if it timedout. 1179 + * 1180 + * scsi-eh will escalate for when either happens. 1181 + */ 1182 + return; 1183 + } 1184 + 1185 + if (fc_fcp_lock_pkt(fsp)) 1186 + return; 1187 + 1188 + /* 1189 + * raced with eh timeout handler. 1190 + */ 1191 + if (!fsp->seq_ptr || !fsp->wait_for_comp) { 1192 + spin_unlock_bh(&fsp->scsi_pkt_lock); 1193 + return; 1194 + } 1195 + 1196 + fh = fc_frame_header_get(fp); 1197 + if (fh->fh_type != FC_TYPE_BLS) 1198 + fc_fcp_resp(fsp, fp); 1199 + fsp->seq_ptr = NULL; 1200 + fsp->lp->tt.exch_done(seq); 1201 + fc_frame_free(fp); 1202 + fc_fcp_unlock_pkt(fsp); 1203 + } 1204 + 1205 + static void fc_fcp_cleanup(struct fc_lport *lp) 1206 + { 1207 + fc_fcp_cleanup_each_cmd(lp, -1, -1, FC_ERROR); 1208 + } 1209 + 1210 + /* 1211 + * fc_fcp_timeout: called by OS timer function. 1212 + * 1213 + * The timer has been inactivated and must be reactivated if desired 1214 + * using fc_fcp_timer_set(). 1215 + * 1216 + * Algorithm: 1217 + * 1218 + * If REC is supported, just issue it, and return. The REC exchange will 1219 + * complete or time out, and recovery can continue at that point. 1220 + * 1221 + * Otherwise, if the response has been received without all the data, 1222 + * it has been ER_TIMEOUT since the response was received. 1223 + * 1224 + * If the response has not been received, 1225 + * we see if data was received recently. If it has been, we continue waiting, 1226 + * otherwise, we abort the command. 1227 + */ 1228 + static void fc_fcp_timeout(unsigned long data) 1229 + { 1230 + struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data; 1231 + struct fc_rport *rport = fsp->rport; 1232 + struct fc_rport_libfc_priv *rp = rport->dd_data; 1233 + 1234 + if (fc_fcp_lock_pkt(fsp)) 1235 + return; 1236 + 1237 + if (fsp->cdb_cmd.fc_tm_flags) 1238 + goto unlock; 1239 + 1240 + fsp->state |= FC_SRB_FCP_PROCESSING_TMO; 1241 + 1242 + if (rp->flags & FC_RP_FLAGS_REC_SUPPORTED) 1243 + fc_fcp_rec(fsp); 1244 + else if (time_after_eq(fsp->last_pkt_time + (FC_SCSI_ER_TIMEOUT / 2), 1245 + jiffies)) 1246 + fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT); 1247 + else if (fsp->state & FC_SRB_RCV_STATUS) 1248 + fc_fcp_complete_locked(fsp); 1249 + else 1250 + fc_timeout_error(fsp); 1251 + fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO; 1252 + unlock: 1253 + fc_fcp_unlock_pkt(fsp); 1254 + } 1255 + 1256 + /* 1257 + * Send a REC ELS request 1258 + */ 1259 + static void fc_fcp_rec(struct fc_fcp_pkt *fsp) 1260 + { 1261 + struct fc_lport *lp; 1262 + struct fc_frame *fp; 1263 + struct fc_rport *rport; 1264 + struct fc_rport_libfc_priv *rp; 1265 + 1266 + lp = fsp->lp; 1267 + rport = fsp->rport; 1268 + rp = rport->dd_data; 1269 + if (!fsp->seq_ptr || rp->rp_state != RPORT_ST_READY) { 1270 + fsp->status_code = FC_HRD_ERROR; 1271 + fsp->io_status = SUGGEST_RETRY << 24; 1272 + fc_fcp_complete_locked(fsp); 1273 + return; 1274 + } 1275 + fp = fc_frame_alloc(lp, sizeof(struct fc_els_rec)); 1276 + if (!fp) 1277 + goto retry; 1278 + 1279 + fr_seq(fp) = fsp->seq_ptr; 1280 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id, 1281 + fc_host_port_id(rp->local_port->host), FC_TYPE_ELS, 1282 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1283 + if (lp->tt.elsct_send(lp, rport, fp, ELS_REC, fc_fcp_rec_resp, 1284 + fsp, jiffies_to_msecs(FC_SCSI_REC_TOV))) { 1285 + fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */ 1286 + return; 1287 + } 1288 + fc_frame_free(fp); 1289 + retry: 1290 + if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1291 + fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1292 + else 1293 + fc_timeout_error(fsp); 1294 + } 1295 + 1296 + /* 1297 + * Receive handler for REC ELS frame 1298 + * if it is a reject then let the scsi layer to handle 1299 + * the timeout. if it is a LS_ACC then if the io was not completed 1300 + * then set the timeout and return otherwise complete the exchange 1301 + * and tell the scsi layer to restart the I/O. 1302 + */ 1303 + static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) 1304 + { 1305 + struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)arg; 1306 + struct fc_els_rec_acc *recp; 1307 + struct fc_els_ls_rjt *rjt; 1308 + u32 e_stat; 1309 + u8 opcode; 1310 + u32 offset; 1311 + enum dma_data_direction data_dir; 1312 + enum fc_rctl r_ctl; 1313 + struct fc_rport_libfc_priv *rp; 1314 + 1315 + if (IS_ERR(fp)) { 1316 + fc_fcp_rec_error(fsp, fp); 1317 + return; 1318 + } 1319 + 1320 + if (fc_fcp_lock_pkt(fsp)) 1321 + goto out; 1322 + 1323 + fsp->recov_retry = 0; 1324 + opcode = fc_frame_payload_op(fp); 1325 + if (opcode == ELS_LS_RJT) { 1326 + rjt = fc_frame_payload_get(fp, sizeof(*rjt)); 1327 + switch (rjt->er_reason) { 1328 + default: 1329 + FC_DEBUG_FCP("device %x unexpected REC reject " 1330 + "reason %d expl %d\n", 1331 + fsp->rport->port_id, rjt->er_reason, 1332 + rjt->er_explan); 1333 + /* fall through */ 1334 + case ELS_RJT_UNSUP: 1335 + FC_DEBUG_FCP("device does not support REC\n"); 1336 + rp = fsp->rport->dd_data; 1337 + /* 1338 + * if we do not spport RECs or got some bogus 1339 + * reason then resetup timer so we check for 1340 + * making progress. 1341 + */ 1342 + rp->flags &= ~FC_RP_FLAGS_REC_SUPPORTED; 1343 + fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT); 1344 + break; 1345 + case ELS_RJT_LOGIC: 1346 + case ELS_RJT_UNAB: 1347 + /* 1348 + * If no data transfer, the command frame got dropped 1349 + * so we just retry. If data was transferred, we 1350 + * lost the response but the target has no record, 1351 + * so we abort and retry. 1352 + */ 1353 + if (rjt->er_explan == ELS_EXPL_OXID_RXID && 1354 + fsp->xfer_len == 0) { 1355 + fc_fcp_retry_cmd(fsp); 1356 + break; 1357 + } 1358 + fc_timeout_error(fsp); 1359 + break; 1360 + } 1361 + } else if (opcode == ELS_LS_ACC) { 1362 + if (fsp->state & FC_SRB_ABORTED) 1363 + goto unlock_out; 1364 + 1365 + data_dir = fsp->cmd->sc_data_direction; 1366 + recp = fc_frame_payload_get(fp, sizeof(*recp)); 1367 + offset = ntohl(recp->reca_fc4value); 1368 + e_stat = ntohl(recp->reca_e_stat); 1369 + 1370 + if (e_stat & ESB_ST_COMPLETE) { 1371 + 1372 + /* 1373 + * The exchange is complete. 1374 + * 1375 + * For output, we must've lost the response. 1376 + * For input, all data must've been sent. 1377 + * We lost may have lost the response 1378 + * (and a confirmation was requested) and maybe 1379 + * some data. 1380 + * 1381 + * If all data received, send SRR 1382 + * asking for response. If partial data received, 1383 + * or gaps, SRR requests data at start of gap. 1384 + * Recovery via SRR relies on in-order-delivery. 1385 + */ 1386 + if (data_dir == DMA_TO_DEVICE) { 1387 + r_ctl = FC_RCTL_DD_CMD_STATUS; 1388 + } else if (fsp->xfer_contig_end == offset) { 1389 + r_ctl = FC_RCTL_DD_CMD_STATUS; 1390 + } else { 1391 + offset = fsp->xfer_contig_end; 1392 + r_ctl = FC_RCTL_DD_SOL_DATA; 1393 + } 1394 + fc_fcp_srr(fsp, r_ctl, offset); 1395 + } else if (e_stat & ESB_ST_SEQ_INIT) { 1396 + 1397 + /* 1398 + * The remote port has the initiative, so just 1399 + * keep waiting for it to complete. 1400 + */ 1401 + fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1402 + } else { 1403 + 1404 + /* 1405 + * The exchange is incomplete, we have seq. initiative. 1406 + * Lost response with requested confirmation, 1407 + * lost confirmation, lost transfer ready or 1408 + * lost write data. 1409 + * 1410 + * For output, if not all data was received, ask 1411 + * for transfer ready to be repeated. 1412 + * 1413 + * If we received or sent all the data, send SRR to 1414 + * request response. 1415 + * 1416 + * If we lost a response, we may have lost some read 1417 + * data as well. 1418 + */ 1419 + r_ctl = FC_RCTL_DD_SOL_DATA; 1420 + if (data_dir == DMA_TO_DEVICE) { 1421 + r_ctl = FC_RCTL_DD_CMD_STATUS; 1422 + if (offset < fsp->data_len) 1423 + r_ctl = FC_RCTL_DD_DATA_DESC; 1424 + } else if (offset == fsp->xfer_contig_end) { 1425 + r_ctl = FC_RCTL_DD_CMD_STATUS; 1426 + } else if (fsp->xfer_contig_end < offset) { 1427 + offset = fsp->xfer_contig_end; 1428 + } 1429 + fc_fcp_srr(fsp, r_ctl, offset); 1430 + } 1431 + } 1432 + unlock_out: 1433 + fc_fcp_unlock_pkt(fsp); 1434 + out: 1435 + fc_fcp_pkt_release(fsp); /* drop hold for outstanding REC */ 1436 + fc_frame_free(fp); 1437 + } 1438 + 1439 + /* 1440 + * Handle error response or timeout for REC exchange. 1441 + */ 1442 + static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) 1443 + { 1444 + int error = PTR_ERR(fp); 1445 + 1446 + if (fc_fcp_lock_pkt(fsp)) 1447 + goto out; 1448 + 1449 + switch (error) { 1450 + case -FC_EX_CLOSED: 1451 + fc_fcp_retry_cmd(fsp); 1452 + break; 1453 + 1454 + default: 1455 + FC_DBG("REC %p fid %x error unexpected error %d\n", 1456 + fsp, fsp->rport->port_id, error); 1457 + fsp->status_code = FC_CMD_PLOGO; 1458 + /* fall through */ 1459 + 1460 + case -FC_EX_TIMEOUT: 1461 + /* 1462 + * Assume REC or LS_ACC was lost. 1463 + * The exchange manager will have aborted REC, so retry. 1464 + */ 1465 + FC_DBG("REC fid %x error error %d retry %d/%d\n", 1466 + fsp->rport->port_id, error, fsp->recov_retry, 1467 + FC_MAX_RECOV_RETRY); 1468 + if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1469 + fc_fcp_rec(fsp); 1470 + else 1471 + fc_timeout_error(fsp); 1472 + break; 1473 + } 1474 + fc_fcp_unlock_pkt(fsp); 1475 + out: 1476 + fc_fcp_pkt_release(fsp); /* drop hold for outstanding REC */ 1477 + } 1478 + 1479 + /* 1480 + * Time out error routine: 1481 + * abort's the I/O close the exchange and 1482 + * send completion notification to scsi layer 1483 + */ 1484 + static void fc_timeout_error(struct fc_fcp_pkt *fsp) 1485 + { 1486 + fsp->status_code = FC_CMD_TIME_OUT; 1487 + fsp->cdb_status = 0; 1488 + fsp->io_status = 0; 1489 + /* 1490 + * if this fails then we let the scsi command timer fire and 1491 + * scsi-ml escalate. 1492 + */ 1493 + fc_fcp_send_abort(fsp); 1494 + } 1495 + 1496 + /* 1497 + * Sequence retransmission request. 1498 + * This is called after receiving status but insufficient data, or 1499 + * when expecting status but the request has timed out. 1500 + */ 1501 + static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset) 1502 + { 1503 + struct fc_lport *lp = fsp->lp; 1504 + struct fc_rport *rport; 1505 + struct fc_rport_libfc_priv *rp; 1506 + struct fc_exch *ep = fc_seq_exch(fsp->seq_ptr); 1507 + struct fc_seq *seq; 1508 + struct fcp_srr *srr; 1509 + struct fc_frame *fp; 1510 + u8 cdb_op; 1511 + 1512 + rport = fsp->rport; 1513 + rp = rport->dd_data; 1514 + cdb_op = fsp->cdb_cmd.fc_cdb[0]; 1515 + 1516 + if (!(rp->flags & FC_RP_FLAGS_RETRY) || rp->rp_state != RPORT_ST_READY) 1517 + goto retry; /* shouldn't happen */ 1518 + fp = fc_frame_alloc(lp, sizeof(*srr)); 1519 + if (!fp) 1520 + goto retry; 1521 + 1522 + srr = fc_frame_payload_get(fp, sizeof(*srr)); 1523 + memset(srr, 0, sizeof(*srr)); 1524 + srr->srr_op = ELS_SRR; 1525 + srr->srr_ox_id = htons(ep->oxid); 1526 + srr->srr_rx_id = htons(ep->rxid); 1527 + srr->srr_r_ctl = r_ctl; 1528 + srr->srr_rel_off = htonl(offset); 1529 + 1530 + fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id, 1531 + fc_host_port_id(rp->local_port->host), FC_TYPE_FCP, 1532 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1533 + 1534 + seq = lp->tt.exch_seq_send(lp, fp, fc_fcp_srr_resp, NULL, 1535 + fsp, jiffies_to_msecs(FC_SCSI_REC_TOV)); 1536 + if (!seq) { 1537 + fc_frame_free(fp); 1538 + goto retry; 1539 + } 1540 + fsp->recov_seq = seq; 1541 + fsp->xfer_len = offset; 1542 + fsp->xfer_contig_end = offset; 1543 + fsp->state &= ~FC_SRB_RCV_STATUS; 1544 + fc_fcp_pkt_hold(fsp); /* hold for outstanding SRR */ 1545 + return; 1546 + retry: 1547 + fc_fcp_retry_cmd(fsp); 1548 + } 1549 + 1550 + /* 1551 + * Handle response from SRR. 1552 + */ 1553 + static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) 1554 + { 1555 + struct fc_fcp_pkt *fsp = arg; 1556 + struct fc_frame_header *fh; 1557 + 1558 + if (IS_ERR(fp)) { 1559 + fc_fcp_srr_error(fsp, fp); 1560 + return; 1561 + } 1562 + 1563 + if (fc_fcp_lock_pkt(fsp)) 1564 + goto out; 1565 + 1566 + fh = fc_frame_header_get(fp); 1567 + /* 1568 + * BUG? fc_fcp_srr_error calls exch_done which would release 1569 + * the ep. But if fc_fcp_srr_error had got -FC_EX_TIMEOUT, 1570 + * then fc_exch_timeout would be sending an abort. The exch_done 1571 + * call by fc_fcp_srr_error would prevent fc_exch.c from seeing 1572 + * an abort response though. 1573 + */ 1574 + if (fh->fh_type == FC_TYPE_BLS) { 1575 + fc_fcp_unlock_pkt(fsp); 1576 + return; 1577 + } 1578 + 1579 + fsp->recov_seq = NULL; 1580 + switch (fc_frame_payload_op(fp)) { 1581 + case ELS_LS_ACC: 1582 + fsp->recov_retry = 0; 1583 + fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1584 + break; 1585 + case ELS_LS_RJT: 1586 + default: 1587 + fc_timeout_error(fsp); 1588 + break; 1589 + } 1590 + fc_fcp_unlock_pkt(fsp); 1591 + fsp->lp->tt.exch_done(seq); 1592 + out: 1593 + fc_frame_free(fp); 1594 + fc_fcp_pkt_release(fsp); /* drop hold for outstanding SRR */ 1595 + } 1596 + 1597 + static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) 1598 + { 1599 + if (fc_fcp_lock_pkt(fsp)) 1600 + goto out; 1601 + fsp->lp->tt.exch_done(fsp->recov_seq); 1602 + fsp->recov_seq = NULL; 1603 + switch (PTR_ERR(fp)) { 1604 + case -FC_EX_TIMEOUT: 1605 + if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1606 + fc_fcp_rec(fsp); 1607 + else 1608 + fc_timeout_error(fsp); 1609 + break; 1610 + case -FC_EX_CLOSED: /* e.g., link failure */ 1611 + /* fall through */ 1612 + default: 1613 + fc_fcp_retry_cmd(fsp); 1614 + break; 1615 + } 1616 + fc_fcp_unlock_pkt(fsp); 1617 + out: 1618 + fc_fcp_pkt_release(fsp); /* drop hold for outstanding SRR */ 1619 + } 1620 + 1621 + static inline int fc_fcp_lport_queue_ready(struct fc_lport *lp) 1622 + { 1623 + /* lock ? */ 1624 + return (lp->state == LPORT_ST_READY) && (lp->link_status & FC_LINK_UP); 1625 + } 1626 + 1627 + /** 1628 + * fc_queuecommand - The queuecommand function of the scsi template 1629 + * @cmd: struct scsi_cmnd to be executed 1630 + * @done: Callback function to be called when cmd is completed 1631 + * 1632 + * this is the i/o strategy routine, called by the scsi layer 1633 + * this routine is called with holding the host_lock. 1634 + */ 1635 + int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *)) 1636 + { 1637 + struct fc_lport *lp; 1638 + struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); 1639 + struct fc_fcp_pkt *fsp; 1640 + struct fc_rport_libfc_priv *rp; 1641 + int rval; 1642 + int rc = 0; 1643 + struct fcoe_dev_stats *stats; 1644 + 1645 + lp = shost_priv(sc_cmd->device->host); 1646 + 1647 + rval = fc_remote_port_chkready(rport); 1648 + if (rval) { 1649 + sc_cmd->result = rval; 1650 + done(sc_cmd); 1651 + goto out; 1652 + } 1653 + 1654 + if (!*(struct fc_remote_port **)rport->dd_data) { 1655 + /* 1656 + * rport is transitioning from blocked/deleted to 1657 + * online 1658 + */ 1659 + sc_cmd->result = DID_IMM_RETRY << 16; 1660 + done(sc_cmd); 1661 + goto out; 1662 + } 1663 + 1664 + rp = rport->dd_data; 1665 + 1666 + if (!fc_fcp_lport_queue_ready(lp)) { 1667 + rc = SCSI_MLQUEUE_HOST_BUSY; 1668 + goto out; 1669 + } 1670 + 1671 + fsp = fc_fcp_pkt_alloc(lp, GFP_ATOMIC); 1672 + if (fsp == NULL) { 1673 + rc = SCSI_MLQUEUE_HOST_BUSY; 1674 + goto out; 1675 + } 1676 + 1677 + /* 1678 + * build the libfc request pkt 1679 + */ 1680 + fsp->cmd = sc_cmd; /* save the cmd */ 1681 + fsp->lp = lp; /* save the softc ptr */ 1682 + fsp->rport = rport; /* set the remote port ptr */ 1683 + sc_cmd->scsi_done = done; 1684 + 1685 + /* 1686 + * set up the transfer length 1687 + */ 1688 + fsp->data_len = scsi_bufflen(sc_cmd); 1689 + fsp->xfer_len = 0; 1690 + 1691 + /* 1692 + * setup the data direction 1693 + */ 1694 + stats = lp->dev_stats[smp_processor_id()]; 1695 + if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) { 1696 + fsp->req_flags = FC_SRB_READ; 1697 + stats->InputRequests++; 1698 + stats->InputMegabytes = fsp->data_len; 1699 + } else if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) { 1700 + fsp->req_flags = FC_SRB_WRITE; 1701 + stats->OutputRequests++; 1702 + stats->OutputMegabytes = fsp->data_len; 1703 + } else { 1704 + fsp->req_flags = 0; 1705 + stats->ControlRequests++; 1706 + } 1707 + 1708 + fsp->tgt_flags = rp->flags; 1709 + 1710 + init_timer(&fsp->timer); 1711 + fsp->timer.data = (unsigned long)fsp; 1712 + 1713 + /* 1714 + * send it to the lower layer 1715 + * if we get -1 return then put the request in the pending 1716 + * queue. 1717 + */ 1718 + rval = fc_fcp_pkt_send(lp, fsp); 1719 + if (rval != 0) { 1720 + fsp->state = FC_SRB_FREE; 1721 + fc_fcp_pkt_release(fsp); 1722 + rc = SCSI_MLQUEUE_HOST_BUSY; 1723 + } 1724 + out: 1725 + return rc; 1726 + } 1727 + EXPORT_SYMBOL(fc_queuecommand); 1728 + 1729 + /** 1730 + * fc_io_compl - Handle responses for completed commands 1731 + * @fsp: scsi packet 1732 + * 1733 + * Translates a error to a Linux SCSI error. 1734 + * 1735 + * The fcp packet lock must be held when calling. 1736 + */ 1737 + static void fc_io_compl(struct fc_fcp_pkt *fsp) 1738 + { 1739 + struct fc_fcp_internal *si; 1740 + struct scsi_cmnd *sc_cmd; 1741 + struct fc_lport *lp; 1742 + unsigned long flags; 1743 + 1744 + fsp->state |= FC_SRB_COMPL; 1745 + if (!(fsp->state & FC_SRB_FCP_PROCESSING_TMO)) { 1746 + spin_unlock_bh(&fsp->scsi_pkt_lock); 1747 + del_timer_sync(&fsp->timer); 1748 + spin_lock_bh(&fsp->scsi_pkt_lock); 1749 + } 1750 + 1751 + lp = fsp->lp; 1752 + si = fc_get_scsi_internal(lp); 1753 + spin_lock_irqsave(lp->host->host_lock, flags); 1754 + if (!fsp->cmd) { 1755 + spin_unlock_irqrestore(lp->host->host_lock, flags); 1756 + return; 1757 + } 1758 + 1759 + /* 1760 + * if a command timed out while we had to try and throttle IO 1761 + * and it is now getting cleaned up, then we are about to 1762 + * try again so clear the throttled flag incase we get more 1763 + * time outs. 1764 + */ 1765 + if (si->throttled && fsp->state & FC_SRB_NOMEM) 1766 + si->throttled = 0; 1767 + 1768 + sc_cmd = fsp->cmd; 1769 + fsp->cmd = NULL; 1770 + 1771 + if (!sc_cmd->SCp.ptr) { 1772 + spin_unlock_irqrestore(lp->host->host_lock, flags); 1773 + return; 1774 + } 1775 + 1776 + CMD_SCSI_STATUS(sc_cmd) = fsp->cdb_status; 1777 + switch (fsp->status_code) { 1778 + case FC_COMPLETE: 1779 + if (fsp->cdb_status == 0) { 1780 + /* 1781 + * good I/O status 1782 + */ 1783 + sc_cmd->result = DID_OK << 16; 1784 + if (fsp->scsi_resid) 1785 + CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid; 1786 + } else if (fsp->cdb_status == QUEUE_FULL) { 1787 + struct scsi_device *tmp_sdev; 1788 + struct scsi_device *sdev = sc_cmd->device; 1789 + 1790 + shost_for_each_device(tmp_sdev, sdev->host) { 1791 + if (tmp_sdev->id != sdev->id) 1792 + continue; 1793 + 1794 + if (tmp_sdev->queue_depth > 1) { 1795 + scsi_track_queue_full(tmp_sdev, 1796 + tmp_sdev-> 1797 + queue_depth - 1); 1798 + } 1799 + } 1800 + sc_cmd->result = (DID_OK << 16) | fsp->cdb_status; 1801 + } else { 1802 + /* 1803 + * transport level I/O was ok but scsi 1804 + * has non zero status 1805 + */ 1806 + sc_cmd->result = (DID_OK << 16) | fsp->cdb_status; 1807 + } 1808 + break; 1809 + case FC_ERROR: 1810 + sc_cmd->result = DID_ERROR << 16; 1811 + break; 1812 + case FC_DATA_UNDRUN: 1813 + if (fsp->cdb_status == 0) { 1814 + /* 1815 + * scsi status is good but transport level 1816 + * underrun. for read it should be an error?? 1817 + */ 1818 + sc_cmd->result = (DID_OK << 16) | fsp->cdb_status; 1819 + } else { 1820 + /* 1821 + * scsi got underrun, this is an error 1822 + */ 1823 + CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid; 1824 + sc_cmd->result = (DID_ERROR << 16) | fsp->cdb_status; 1825 + } 1826 + break; 1827 + case FC_DATA_OVRRUN: 1828 + /* 1829 + * overrun is an error 1830 + */ 1831 + sc_cmd->result = (DID_ERROR << 16) | fsp->cdb_status; 1832 + break; 1833 + case FC_CMD_ABORTED: 1834 + sc_cmd->result = (DID_ABORT << 16) | fsp->io_status; 1835 + break; 1836 + case FC_CMD_TIME_OUT: 1837 + sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status; 1838 + break; 1839 + case FC_CMD_RESET: 1840 + sc_cmd->result = (DID_RESET << 16); 1841 + break; 1842 + case FC_HRD_ERROR: 1843 + sc_cmd->result = (DID_NO_CONNECT << 16); 1844 + break; 1845 + default: 1846 + sc_cmd->result = (DID_ERROR << 16); 1847 + break; 1848 + } 1849 + 1850 + list_del(&fsp->list); 1851 + sc_cmd->SCp.ptr = NULL; 1852 + sc_cmd->scsi_done(sc_cmd); 1853 + spin_unlock_irqrestore(lp->host->host_lock, flags); 1854 + 1855 + /* release ref from initial allocation in queue command */ 1856 + fc_fcp_pkt_release(fsp); 1857 + } 1858 + 1859 + /** 1860 + * fc_fcp_complete - complete processing of a fcp packet 1861 + * @fsp: fcp packet 1862 + * 1863 + * This function may sleep if a fsp timer is pending. 1864 + * The host lock must not be held by caller. 1865 + */ 1866 + void fc_fcp_complete(struct fc_fcp_pkt *fsp) 1867 + { 1868 + if (fc_fcp_lock_pkt(fsp)) 1869 + return; 1870 + 1871 + fc_fcp_complete_locked(fsp); 1872 + fc_fcp_unlock_pkt(fsp); 1873 + } 1874 + EXPORT_SYMBOL(fc_fcp_complete); 1875 + 1876 + /** 1877 + * fc_eh_abort - Abort a command...from scsi host template 1878 + * @sc_cmd: scsi command to abort 1879 + * 1880 + * send ABTS to the target device and wait for the response 1881 + * sc_cmd is the pointer to the command to be aborted. 1882 + */ 1883 + int fc_eh_abort(struct scsi_cmnd *sc_cmd) 1884 + { 1885 + struct fc_fcp_pkt *fsp; 1886 + struct fc_lport *lp; 1887 + int rc = FAILED; 1888 + unsigned long flags; 1889 + 1890 + lp = shost_priv(sc_cmd->device->host); 1891 + if (lp->state != LPORT_ST_READY) 1892 + return rc; 1893 + else if (!(lp->link_status & FC_LINK_UP)) 1894 + return rc; 1895 + 1896 + spin_lock_irqsave(lp->host->host_lock, flags); 1897 + fsp = CMD_SP(sc_cmd); 1898 + if (!fsp) { 1899 + /* command completed while scsi eh was setting up */ 1900 + spin_unlock_irqrestore(lp->host->host_lock, flags); 1901 + return SUCCESS; 1902 + } 1903 + /* grab a ref so the fsp and sc_cmd cannot be relased from under us */ 1904 + fc_fcp_pkt_hold(fsp); 1905 + spin_unlock_irqrestore(lp->host->host_lock, flags); 1906 + 1907 + if (fc_fcp_lock_pkt(fsp)) { 1908 + /* completed while we were waiting for timer to be deleted */ 1909 + rc = SUCCESS; 1910 + goto release_pkt; 1911 + } 1912 + 1913 + rc = fc_fcp_pkt_abort(lp, fsp); 1914 + fc_fcp_unlock_pkt(fsp); 1915 + 1916 + release_pkt: 1917 + fc_fcp_pkt_release(fsp); 1918 + return rc; 1919 + } 1920 + EXPORT_SYMBOL(fc_eh_abort); 1921 + 1922 + /** 1923 + * fc_eh_device_reset: Reset a single LUN 1924 + * @sc_cmd: scsi command 1925 + * 1926 + * Set from scsi host template to send tm cmd to the target and wait for the 1927 + * response. 1928 + */ 1929 + int fc_eh_device_reset(struct scsi_cmnd *sc_cmd) 1930 + { 1931 + struct fc_lport *lp; 1932 + struct fc_fcp_pkt *fsp; 1933 + struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); 1934 + int rc = FAILED; 1935 + struct fc_rport_libfc_priv *rp; 1936 + int rval; 1937 + 1938 + rval = fc_remote_port_chkready(rport); 1939 + if (rval) 1940 + goto out; 1941 + 1942 + rp = rport->dd_data; 1943 + lp = shost_priv(sc_cmd->device->host); 1944 + 1945 + if (lp->state != LPORT_ST_READY) 1946 + return rc; 1947 + 1948 + fsp = fc_fcp_pkt_alloc(lp, GFP_NOIO); 1949 + if (fsp == NULL) { 1950 + FC_DBG("could not allocate scsi_pkt\n"); 1951 + sc_cmd->result = DID_NO_CONNECT << 16; 1952 + goto out; 1953 + } 1954 + 1955 + /* 1956 + * Build the libfc request pkt. Do not set the scsi cmnd, because 1957 + * the sc passed in is not setup for execution like when sent 1958 + * through the queuecommand callout. 1959 + */ 1960 + fsp->lp = lp; /* save the softc ptr */ 1961 + fsp->rport = rport; /* set the remote port ptr */ 1962 + 1963 + /* 1964 + * flush outstanding commands 1965 + */ 1966 + rc = fc_lun_reset(lp, fsp, scmd_id(sc_cmd), sc_cmd->device->lun); 1967 + fsp->state = FC_SRB_FREE; 1968 + fc_fcp_pkt_release(fsp); 1969 + 1970 + out: 1971 + return rc; 1972 + } 1973 + EXPORT_SYMBOL(fc_eh_device_reset); 1974 + 1975 + /** 1976 + * fc_eh_host_reset - The reset function will reset the ports on the host. 1977 + * @sc_cmd: scsi command 1978 + */ 1979 + int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) 1980 + { 1981 + struct Scsi_Host *shost = sc_cmd->device->host; 1982 + struct fc_lport *lp = shost_priv(shost); 1983 + unsigned long wait_tmo; 1984 + 1985 + lp->tt.lport_reset(lp); 1986 + wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT; 1987 + while (!fc_fcp_lport_queue_ready(lp) && time_before(jiffies, wait_tmo)) 1988 + msleep(1000); 1989 + 1990 + if (fc_fcp_lport_queue_ready(lp)) { 1991 + shost_printk(KERN_INFO, shost, "Host reset succeeded.\n"); 1992 + return SUCCESS; 1993 + } else { 1994 + shost_printk(KERN_INFO, shost, "Host reset failed. " 1995 + "lport not ready.\n"); 1996 + return FAILED; 1997 + } 1998 + } 1999 + EXPORT_SYMBOL(fc_eh_host_reset); 2000 + 2001 + /** 2002 + * fc_slave_alloc - configure queue depth 2003 + * @sdev: scsi device 2004 + * 2005 + * Configures queue depth based on host's cmd_per_len. If not set 2006 + * then we use the libfc default. 2007 + */ 2008 + int fc_slave_alloc(struct scsi_device *sdev) 2009 + { 2010 + struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); 2011 + int queue_depth; 2012 + 2013 + if (!rport || fc_remote_port_chkready(rport)) 2014 + return -ENXIO; 2015 + 2016 + if (sdev->tagged_supported) { 2017 + if (sdev->host->hostt->cmd_per_lun) 2018 + queue_depth = sdev->host->hostt->cmd_per_lun; 2019 + else 2020 + queue_depth = FC_FCP_DFLT_QUEUE_DEPTH; 2021 + scsi_activate_tcq(sdev, queue_depth); 2022 + } 2023 + return 0; 2024 + } 2025 + EXPORT_SYMBOL(fc_slave_alloc); 2026 + 2027 + int fc_change_queue_depth(struct scsi_device *sdev, int qdepth) 2028 + { 2029 + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); 2030 + return sdev->queue_depth; 2031 + } 2032 + EXPORT_SYMBOL(fc_change_queue_depth); 2033 + 2034 + int fc_change_queue_type(struct scsi_device *sdev, int tag_type) 2035 + { 2036 + if (sdev->tagged_supported) { 2037 + scsi_set_tag_type(sdev, tag_type); 2038 + if (tag_type) 2039 + scsi_activate_tcq(sdev, sdev->queue_depth); 2040 + else 2041 + scsi_deactivate_tcq(sdev, sdev->queue_depth); 2042 + } else 2043 + tag_type = 0; 2044 + 2045 + return tag_type; 2046 + } 2047 + EXPORT_SYMBOL(fc_change_queue_type); 2048 + 2049 + void fc_fcp_destroy(struct fc_lport *lp) 2050 + { 2051 + struct fc_fcp_internal *si = fc_get_scsi_internal(lp); 2052 + 2053 + if (!list_empty(&si->scsi_pkt_queue)) 2054 + printk(KERN_ERR "Leaked scsi packets.\n"); 2055 + 2056 + mempool_destroy(si->scsi_pkt_pool); 2057 + kfree(si); 2058 + lp->scsi_priv = NULL; 2059 + } 2060 + EXPORT_SYMBOL(fc_fcp_destroy); 2061 + 2062 + int fc_fcp_init(struct fc_lport *lp) 2063 + { 2064 + int rc; 2065 + struct fc_fcp_internal *si; 2066 + 2067 + if (!lp->tt.fcp_cmd_send) 2068 + lp->tt.fcp_cmd_send = fc_fcp_cmd_send; 2069 + 2070 + if (!lp->tt.fcp_cleanup) 2071 + lp->tt.fcp_cleanup = fc_fcp_cleanup; 2072 + 2073 + if (!lp->tt.fcp_abort_io) 2074 + lp->tt.fcp_abort_io = fc_fcp_abort_io; 2075 + 2076 + si = kzalloc(sizeof(struct fc_fcp_internal), GFP_KERNEL); 2077 + if (!si) 2078 + return -ENOMEM; 2079 + lp->scsi_priv = si; 2080 + INIT_LIST_HEAD(&si->scsi_pkt_queue); 2081 + 2082 + si->scsi_pkt_pool = mempool_create_slab_pool(2, scsi_pkt_cachep); 2083 + if (!si->scsi_pkt_pool) { 2084 + rc = -ENOMEM; 2085 + goto free_internal; 2086 + } 2087 + return 0; 2088 + 2089 + free_internal: 2090 + kfree(si); 2091 + return rc; 2092 + } 2093 + EXPORT_SYMBOL(fc_fcp_init); 2094 + 2095 + static int __init libfc_init(void) 2096 + { 2097 + int rc; 2098 + 2099 + scsi_pkt_cachep = kmem_cache_create("libfc_fcp_pkt", 2100 + sizeof(struct fc_fcp_pkt), 2101 + 0, SLAB_HWCACHE_ALIGN, NULL); 2102 + if (scsi_pkt_cachep == NULL) { 2103 + FC_DBG("Unable to allocate SRB cache...module load failed!"); 2104 + return -ENOMEM; 2105 + } 2106 + 2107 + rc = fc_setup_exch_mgr(); 2108 + if (rc) 2109 + goto destroy_pkt_cache; 2110 + 2111 + rc = fc_setup_rport(); 2112 + if (rc) 2113 + goto destroy_em; 2114 + 2115 + return rc; 2116 + destroy_em: 2117 + fc_destroy_exch_mgr(); 2118 + destroy_pkt_cache: 2119 + kmem_cache_destroy(scsi_pkt_cachep); 2120 + return rc; 2121 + } 2122 + 2123 + static void __exit libfc_exit(void) 2124 + { 2125 + kmem_cache_destroy(scsi_pkt_cachep); 2126 + fc_destroy_exch_mgr(); 2127 + fc_destroy_rport(); 2128 + } 2129 + 2130 + module_init(libfc_init); 2131 + module_exit(libfc_exit);
+89
drivers/scsi/libfc/fc_frame.c
··· 1 + /* 2 + * Copyright(c) 2007 Intel Corporation. All rights reserved. 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 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + /* 21 + * Frame allocation. 22 + */ 23 + #include <linux/module.h> 24 + #include <linux/kernel.h> 25 + #include <linux/skbuff.h> 26 + #include <linux/crc32.h> 27 + 28 + #include <scsi/fc_frame.h> 29 + 30 + /* 31 + * Check the CRC in a frame. 32 + */ 33 + u32 fc_frame_crc_check(struct fc_frame *fp) 34 + { 35 + u32 crc; 36 + u32 error; 37 + const u8 *bp; 38 + unsigned int len; 39 + 40 + WARN_ON(!fc_frame_is_linear(fp)); 41 + fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; 42 + len = (fr_len(fp) + 3) & ~3; /* round up length to include fill */ 43 + bp = (const u8 *) fr_hdr(fp); 44 + crc = ~crc32(~0, bp, len); 45 + error = crc ^ fr_crc(fp); 46 + return error; 47 + } 48 + EXPORT_SYMBOL(fc_frame_crc_check); 49 + 50 + /* 51 + * Allocate a frame intended to be sent via fcoe_xmit. 52 + * Get an sk_buff for the frame and set the length. 53 + */ 54 + struct fc_frame *__fc_frame_alloc(size_t len) 55 + { 56 + struct fc_frame *fp; 57 + struct sk_buff *skb; 58 + 59 + WARN_ON((len % sizeof(u32)) != 0); 60 + len += sizeof(struct fc_frame_header); 61 + skb = dev_alloc_skb(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM); 62 + if (!skb) 63 + return NULL; 64 + fp = (struct fc_frame *) skb; 65 + fc_frame_init(fp); 66 + skb_reserve(skb, FC_FRAME_HEADROOM); 67 + skb_put(skb, len); 68 + return fp; 69 + } 70 + EXPORT_SYMBOL(__fc_frame_alloc); 71 + 72 + 73 + struct fc_frame *fc_frame_alloc_fill(struct fc_lport *lp, size_t payload_len) 74 + { 75 + struct fc_frame *fp; 76 + size_t fill; 77 + 78 + fill = payload_len % 4; 79 + if (fill != 0) 80 + fill = 4 - fill; 81 + fp = __fc_frame_alloc(payload_len + fill); 82 + if (fp) { 83 + memset((char *) fr_hdr(fp) + payload_len, 0, fill); 84 + /* trim is OK, we just allocated it so there are no fragments */ 85 + skb_trim(fp_skb(fp), 86 + payload_len + sizeof(struct fc_frame_header)); 87 + } 88 + return fp; 89 + }
+1604
drivers/scsi/libfc/fc_lport.c
··· 1 + /* 2 + * Copyright(c) 2007 Intel Corporation. All rights reserved. 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 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + /* 21 + * PORT LOCKING NOTES 22 + * 23 + * These comments only apply to the 'port code' which consists of the lport, 24 + * disc and rport blocks. 25 + * 26 + * MOTIVATION 27 + * 28 + * The lport, disc and rport blocks all have mutexes that are used to protect 29 + * those objects. The main motivation for these locks is to prevent from 30 + * having an lport reset just before we send a frame. In that scenario the 31 + * lport's FID would get set to zero and then we'd send a frame with an 32 + * invalid SID. We also need to ensure that states don't change unexpectedly 33 + * while processing another state. 34 + * 35 + * HEIRARCHY 36 + * 37 + * The following heirarchy defines the locking rules. A greater lock 38 + * may be held before acquiring a lesser lock, but a lesser lock should never 39 + * be held while attempting to acquire a greater lock. Here is the heirarchy- 40 + * 41 + * lport > disc, lport > rport, disc > rport 42 + * 43 + * CALLBACKS 44 + * 45 + * The callbacks cause complications with this scheme. There is a callback 46 + * from the rport (to either lport or disc) and a callback from disc 47 + * (to the lport). 48 + * 49 + * As rports exit the rport state machine a callback is made to the owner of 50 + * the rport to notify success or failure. Since the callback is likely to 51 + * cause the lport or disc to grab its lock we cannot hold the rport lock 52 + * while making the callback. To ensure that the rport is not free'd while 53 + * processing the callback the rport callbacks are serialized through a 54 + * single-threaded workqueue. An rport would never be free'd while in a 55 + * callback handler becuase no other rport work in this queue can be executed 56 + * at the same time. 57 + * 58 + * When discovery succeeds or fails a callback is made to the lport as 59 + * notification. Currently, succesful discovery causes the lport to take no 60 + * action. A failure will cause the lport to reset. There is likely a circular 61 + * locking problem with this implementation. 62 + */ 63 + 64 + /* 65 + * LPORT LOCKING 66 + * 67 + * The critical sections protected by the lport's mutex are quite broad and 68 + * may be improved upon in the future. The lport code and its locking doesn't 69 + * influence the I/O path, so excessive locking doesn't penalize I/O 70 + * performance. 71 + * 72 + * The strategy is to lock whenever processing a request or response. Note 73 + * that every _enter_* function corresponds to a state change. They generally 74 + * change the lports state and then send a request out on the wire. We lock 75 + * before calling any of these functions to protect that state change. This 76 + * means that the entry points into the lport block manage the locks while 77 + * the state machine can transition between states (i.e. _enter_* functions) 78 + * while always staying protected. 79 + * 80 + * When handling responses we also hold the lport mutex broadly. When the 81 + * lport receives the response frame it locks the mutex and then calls the 82 + * appropriate handler for the particuar response. Generally a response will 83 + * trigger a state change and so the lock must already be held. 84 + * 85 + * Retries also have to consider the locking. The retries occur from a work 86 + * context and the work function will lock the lport and then retry the state 87 + * (i.e. _enter_* function). 88 + */ 89 + 90 + #include <linux/timer.h> 91 + #include <asm/unaligned.h> 92 + 93 + #include <scsi/fc/fc_gs.h> 94 + 95 + #include <scsi/libfc.h> 96 + #include <scsi/fc_encode.h> 97 + 98 + /* Fabric IDs to use for point-to-point mode, chosen on whims. */ 99 + #define FC_LOCAL_PTP_FID_LO 0x010101 100 + #define FC_LOCAL_PTP_FID_HI 0x010102 101 + 102 + #define DNS_DELAY 3 /* Discovery delay after RSCN (in seconds)*/ 103 + 104 + static int fc_lport_debug; 105 + 106 + #define FC_DEBUG_LPORT(fmt...) \ 107 + do { \ 108 + if (fc_lport_debug) \ 109 + FC_DBG(fmt); \ 110 + } while (0) 111 + 112 + static void fc_lport_error(struct fc_lport *, struct fc_frame *); 113 + 114 + static void fc_lport_enter_reset(struct fc_lport *); 115 + static void fc_lport_enter_flogi(struct fc_lport *); 116 + static void fc_lport_enter_dns(struct fc_lport *); 117 + static void fc_lport_enter_rpn_id(struct fc_lport *); 118 + static void fc_lport_enter_rft_id(struct fc_lport *); 119 + static void fc_lport_enter_scr(struct fc_lport *); 120 + static void fc_lport_enter_ready(struct fc_lport *); 121 + static void fc_lport_enter_logo(struct fc_lport *); 122 + 123 + static const char *fc_lport_state_names[] = { 124 + [LPORT_ST_NONE] = "none", 125 + [LPORT_ST_FLOGI] = "FLOGI", 126 + [LPORT_ST_DNS] = "dNS", 127 + [LPORT_ST_RPN_ID] = "RPN_ID", 128 + [LPORT_ST_RFT_ID] = "RFT_ID", 129 + [LPORT_ST_SCR] = "SCR", 130 + [LPORT_ST_READY] = "Ready", 131 + [LPORT_ST_LOGO] = "LOGO", 132 + [LPORT_ST_RESET] = "reset", 133 + }; 134 + 135 + static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp) 136 + { 137 + fc_frame_free(fp); 138 + return 0; 139 + } 140 + 141 + /** 142 + * fc_lport_rport_callback - Event handler for rport events 143 + * @lport: The lport which is receiving the event 144 + * @rport: The rport which the event has occured on 145 + * @event: The event that occured 146 + * 147 + * Locking Note: The rport lock should not be held when calling 148 + * this function. 149 + */ 150 + static void fc_lport_rport_callback(struct fc_lport *lport, 151 + struct fc_rport *rport, 152 + enum fc_rport_event event) 153 + { 154 + FC_DEBUG_LPORT("Received a %d event for port (%6x)\n", event, 155 + rport->port_id); 156 + 157 + switch (event) { 158 + case RPORT_EV_CREATED: 159 + if (rport->port_id == FC_FID_DIR_SERV) { 160 + mutex_lock(&lport->lp_mutex); 161 + if (lport->state == LPORT_ST_DNS) { 162 + lport->dns_rp = rport; 163 + fc_lport_enter_rpn_id(lport); 164 + } else { 165 + FC_DEBUG_LPORT("Received an CREATED event on " 166 + "port (%6x) for the directory " 167 + "server, but the lport is not " 168 + "in the DNS state, it's in the " 169 + "%d state", rport->port_id, 170 + lport->state); 171 + lport->tt.rport_logoff(rport); 172 + } 173 + mutex_unlock(&lport->lp_mutex); 174 + } else 175 + FC_DEBUG_LPORT("Received an event for port (%6x) " 176 + "which is not the directory server\n", 177 + rport->port_id); 178 + break; 179 + case RPORT_EV_LOGO: 180 + case RPORT_EV_FAILED: 181 + case RPORT_EV_STOP: 182 + if (rport->port_id == FC_FID_DIR_SERV) { 183 + mutex_lock(&lport->lp_mutex); 184 + lport->dns_rp = NULL; 185 + mutex_unlock(&lport->lp_mutex); 186 + 187 + } else 188 + FC_DEBUG_LPORT("Received an event for port (%6x) " 189 + "which is not the directory server\n", 190 + rport->port_id); 191 + break; 192 + case RPORT_EV_NONE: 193 + break; 194 + } 195 + } 196 + 197 + /** 198 + * fc_lport_state - Return a string which represents the lport's state 199 + * @lport: The lport whose state is to converted to a string 200 + */ 201 + static const char *fc_lport_state(struct fc_lport *lport) 202 + { 203 + const char *cp; 204 + 205 + cp = fc_lport_state_names[lport->state]; 206 + if (!cp) 207 + cp = "unknown"; 208 + return cp; 209 + } 210 + 211 + /** 212 + * fc_lport_ptp_setup - Create an rport for point-to-point mode 213 + * @lport: The lport to attach the ptp rport to 214 + * @fid: The FID of the ptp rport 215 + * @remote_wwpn: The WWPN of the ptp rport 216 + * @remote_wwnn: The WWNN of the ptp rport 217 + */ 218 + static void fc_lport_ptp_setup(struct fc_lport *lport, 219 + u32 remote_fid, u64 remote_wwpn, 220 + u64 remote_wwnn) 221 + { 222 + struct fc_disc_port dp; 223 + 224 + dp.lp = lport; 225 + dp.ids.port_id = remote_fid; 226 + dp.ids.port_name = remote_wwpn; 227 + dp.ids.node_name = remote_wwnn; 228 + dp.ids.roles = FC_RPORT_ROLE_UNKNOWN; 229 + 230 + if (lport->ptp_rp) { 231 + lport->tt.rport_logoff(lport->ptp_rp); 232 + lport->ptp_rp = NULL; 233 + } 234 + 235 + lport->ptp_rp = fc_rport_rogue_create(&dp); 236 + 237 + lport->tt.rport_login(lport->ptp_rp); 238 + 239 + fc_lport_enter_ready(lport); 240 + } 241 + 242 + void fc_get_host_port_type(struct Scsi_Host *shost) 243 + { 244 + /* TODO - currently just NPORT */ 245 + fc_host_port_type(shost) = FC_PORTTYPE_NPORT; 246 + } 247 + EXPORT_SYMBOL(fc_get_host_port_type); 248 + 249 + void fc_get_host_port_state(struct Scsi_Host *shost) 250 + { 251 + struct fc_lport *lp = shost_priv(shost); 252 + 253 + if ((lp->link_status & FC_LINK_UP) == FC_LINK_UP) 254 + fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; 255 + else 256 + fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; 257 + } 258 + EXPORT_SYMBOL(fc_get_host_port_state); 259 + 260 + void fc_get_host_speed(struct Scsi_Host *shost) 261 + { 262 + struct fc_lport *lport = shost_priv(shost); 263 + 264 + fc_host_speed(shost) = lport->link_speed; 265 + } 266 + EXPORT_SYMBOL(fc_get_host_speed); 267 + 268 + struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost) 269 + { 270 + int i; 271 + struct fc_host_statistics *fcoe_stats; 272 + struct fc_lport *lp = shost_priv(shost); 273 + struct timespec v0, v1; 274 + 275 + fcoe_stats = &lp->host_stats; 276 + memset(fcoe_stats, 0, sizeof(struct fc_host_statistics)); 277 + 278 + jiffies_to_timespec(jiffies, &v0); 279 + jiffies_to_timespec(lp->boot_time, &v1); 280 + fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec); 281 + 282 + for_each_online_cpu(i) { 283 + struct fcoe_dev_stats *stats = lp->dev_stats[i]; 284 + if (stats == NULL) 285 + continue; 286 + fcoe_stats->tx_frames += stats->TxFrames; 287 + fcoe_stats->tx_words += stats->TxWords; 288 + fcoe_stats->rx_frames += stats->RxFrames; 289 + fcoe_stats->rx_words += stats->RxWords; 290 + fcoe_stats->error_frames += stats->ErrorFrames; 291 + fcoe_stats->invalid_crc_count += stats->InvalidCRCCount; 292 + fcoe_stats->fcp_input_requests += stats->InputRequests; 293 + fcoe_stats->fcp_output_requests += stats->OutputRequests; 294 + fcoe_stats->fcp_control_requests += stats->ControlRequests; 295 + fcoe_stats->fcp_input_megabytes += stats->InputMegabytes; 296 + fcoe_stats->fcp_output_megabytes += stats->OutputMegabytes; 297 + fcoe_stats->link_failure_count += stats->LinkFailureCount; 298 + } 299 + fcoe_stats->lip_count = -1; 300 + fcoe_stats->nos_count = -1; 301 + fcoe_stats->loss_of_sync_count = -1; 302 + fcoe_stats->loss_of_signal_count = -1; 303 + fcoe_stats->prim_seq_protocol_err_count = -1; 304 + fcoe_stats->dumped_frames = -1; 305 + return fcoe_stats; 306 + } 307 + EXPORT_SYMBOL(fc_get_host_stats); 308 + 309 + /* 310 + * Fill in FLOGI command for request. 311 + */ 312 + static void 313 + fc_lport_flogi_fill(struct fc_lport *lport, struct fc_els_flogi *flogi, 314 + unsigned int op) 315 + { 316 + struct fc_els_csp *sp; 317 + struct fc_els_cssp *cp; 318 + 319 + memset(flogi, 0, sizeof(*flogi)); 320 + flogi->fl_cmd = (u8) op; 321 + put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn); 322 + put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn); 323 + sp = &flogi->fl_csp; 324 + sp->sp_hi_ver = 0x20; 325 + sp->sp_lo_ver = 0x20; 326 + sp->sp_bb_cred = htons(10); /* this gets set by gateway */ 327 + sp->sp_bb_data = htons((u16) lport->mfs); 328 + cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ 329 + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 330 + if (op != ELS_FLOGI) { 331 + sp->sp_features = htons(FC_SP_FT_CIRO); 332 + sp->sp_tot_seq = htons(255); /* seq. we accept */ 333 + sp->sp_rel_off = htons(0x1f); 334 + sp->sp_e_d_tov = htonl(lport->e_d_tov); 335 + 336 + cp->cp_rdfs = htons((u16) lport->mfs); 337 + cp->cp_con_seq = htons(255); 338 + cp->cp_open_seq = 1; 339 + } 340 + } 341 + 342 + /* 343 + * Add a supported FC-4 type. 344 + */ 345 + static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type) 346 + { 347 + __be32 *mp; 348 + 349 + mp = &lport->fcts.ff_type_map[type / FC_NS_BPW]; 350 + *mp = htonl(ntohl(*mp) | 1UL << (type % FC_NS_BPW)); 351 + } 352 + 353 + /** 354 + * fc_lport_recv_rlir_req - Handle received Registered Link Incident Report. 355 + * @lport: Fibre Channel local port recieving the RLIR 356 + * @sp: current sequence in the RLIR exchange 357 + * @fp: RLIR request frame 358 + * 359 + * Locking Note: The lport lock is exected to be held before calling 360 + * this function. 361 + */ 362 + static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp, 363 + struct fc_lport *lport) 364 + { 365 + FC_DEBUG_LPORT("Received RLIR request while in state %s\n", 366 + fc_lport_state(lport)); 367 + 368 + lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); 369 + fc_frame_free(fp); 370 + } 371 + 372 + /** 373 + * fc_lport_recv_echo_req - Handle received ECHO request 374 + * @lport: Fibre Channel local port recieving the ECHO 375 + * @sp: current sequence in the ECHO exchange 376 + * @fp: ECHO request frame 377 + * 378 + * Locking Note: The lport lock is exected to be held before calling 379 + * this function. 380 + */ 381 + static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, 382 + struct fc_lport *lport) 383 + { 384 + struct fc_frame *fp; 385 + struct fc_exch *ep = fc_seq_exch(sp); 386 + unsigned int len; 387 + void *pp; 388 + void *dp; 389 + u32 f_ctl; 390 + 391 + FC_DEBUG_LPORT("Received RLIR request while in state %s\n", 392 + fc_lport_state(lport)); 393 + 394 + len = fr_len(in_fp) - sizeof(struct fc_frame_header); 395 + pp = fc_frame_payload_get(in_fp, len); 396 + 397 + if (len < sizeof(__be32)) 398 + len = sizeof(__be32); 399 + 400 + fp = fc_frame_alloc(lport, len); 401 + if (fp) { 402 + dp = fc_frame_payload_get(fp, len); 403 + memcpy(dp, pp, len); 404 + *((u32 *)dp) = htonl(ELS_LS_ACC << 24); 405 + sp = lport->tt.seq_start_next(sp); 406 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 407 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 408 + FC_TYPE_ELS, f_ctl, 0); 409 + lport->tt.seq_send(lport, sp, fp); 410 + } 411 + fc_frame_free(in_fp); 412 + } 413 + 414 + /** 415 + * fc_lport_recv_echo_req - Handle received Request Node ID data request 416 + * @lport: Fibre Channel local port recieving the RNID 417 + * @sp: current sequence in the RNID exchange 418 + * @fp: RNID request frame 419 + * 420 + * Locking Note: The lport lock is exected to be held before calling 421 + * this function. 422 + */ 423 + static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp, 424 + struct fc_lport *lport) 425 + { 426 + struct fc_frame *fp; 427 + struct fc_exch *ep = fc_seq_exch(sp); 428 + struct fc_els_rnid *req; 429 + struct { 430 + struct fc_els_rnid_resp rnid; 431 + struct fc_els_rnid_cid cid; 432 + struct fc_els_rnid_gen gen; 433 + } *rp; 434 + struct fc_seq_els_data rjt_data; 435 + u8 fmt; 436 + size_t len; 437 + u32 f_ctl; 438 + 439 + FC_DEBUG_LPORT("Received RNID request while in state %s\n", 440 + fc_lport_state(lport)); 441 + 442 + req = fc_frame_payload_get(in_fp, sizeof(*req)); 443 + if (!req) { 444 + rjt_data.fp = NULL; 445 + rjt_data.reason = ELS_RJT_LOGIC; 446 + rjt_data.explan = ELS_EXPL_NONE; 447 + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 448 + } else { 449 + fmt = req->rnid_fmt; 450 + len = sizeof(*rp); 451 + if (fmt != ELS_RNIDF_GEN || 452 + ntohl(lport->rnid_gen.rnid_atype) == 0) { 453 + fmt = ELS_RNIDF_NONE; /* nothing to provide */ 454 + len -= sizeof(rp->gen); 455 + } 456 + fp = fc_frame_alloc(lport, len); 457 + if (fp) { 458 + rp = fc_frame_payload_get(fp, len); 459 + memset(rp, 0, len); 460 + rp->rnid.rnid_cmd = ELS_LS_ACC; 461 + rp->rnid.rnid_fmt = fmt; 462 + rp->rnid.rnid_cid_len = sizeof(rp->cid); 463 + rp->cid.rnid_wwpn = htonll(lport->wwpn); 464 + rp->cid.rnid_wwnn = htonll(lport->wwnn); 465 + if (fmt == ELS_RNIDF_GEN) { 466 + rp->rnid.rnid_sid_len = sizeof(rp->gen); 467 + memcpy(&rp->gen, &lport->rnid_gen, 468 + sizeof(rp->gen)); 469 + } 470 + sp = lport->tt.seq_start_next(sp); 471 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 472 + f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 473 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 474 + FC_TYPE_ELS, f_ctl, 0); 475 + lport->tt.seq_send(lport, sp, fp); 476 + } 477 + } 478 + fc_frame_free(in_fp); 479 + } 480 + 481 + /** 482 + * fc_lport_recv_adisc_req - Handle received Address Discovery Request 483 + * @lport: Fibre Channel local port recieving the ADISC 484 + * @sp: current sequence in the ADISC exchange 485 + * @fp: ADISC request frame 486 + * 487 + * Locking Note: The lport lock is expected to be held before calling 488 + * this function. 489 + */ 490 + static void fc_lport_recv_adisc_req(struct fc_seq *sp, struct fc_frame *in_fp, 491 + struct fc_lport *lport) 492 + { 493 + struct fc_frame *fp; 494 + struct fc_exch *ep = fc_seq_exch(sp); 495 + struct fc_els_adisc *req, *rp; 496 + struct fc_seq_els_data rjt_data; 497 + size_t len; 498 + u32 f_ctl; 499 + 500 + FC_DEBUG_LPORT("Received ADISC request while in state %s\n", 501 + fc_lport_state(lport)); 502 + 503 + req = fc_frame_payload_get(in_fp, sizeof(*req)); 504 + if (!req) { 505 + rjt_data.fp = NULL; 506 + rjt_data.reason = ELS_RJT_LOGIC; 507 + rjt_data.explan = ELS_EXPL_NONE; 508 + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 509 + } else { 510 + len = sizeof(*rp); 511 + fp = fc_frame_alloc(lport, len); 512 + if (fp) { 513 + rp = fc_frame_payload_get(fp, len); 514 + memset(rp, 0, len); 515 + rp->adisc_cmd = ELS_LS_ACC; 516 + rp->adisc_wwpn = htonll(lport->wwpn); 517 + rp->adisc_wwnn = htonll(lport->wwnn); 518 + hton24(rp->adisc_port_id, 519 + fc_host_port_id(lport->host)); 520 + sp = lport->tt.seq_start_next(sp); 521 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 522 + f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 523 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 524 + FC_TYPE_ELS, f_ctl, 0); 525 + lport->tt.seq_send(lport, sp, fp); 526 + } 527 + } 528 + fc_frame_free(in_fp); 529 + } 530 + 531 + /** 532 + * fc_lport_recv_logo_req - Handle received fabric LOGO request 533 + * @lport: Fibre Channel local port recieving the LOGO 534 + * @sp: current sequence in the LOGO exchange 535 + * @fp: LOGO request frame 536 + * 537 + * Locking Note: The lport lock is exected to be held before calling 538 + * this function. 539 + */ 540 + static void fc_lport_recv_logo_req(struct fc_seq *sp, struct fc_frame *fp, 541 + struct fc_lport *lport) 542 + { 543 + lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); 544 + fc_lport_enter_reset(lport); 545 + fc_frame_free(fp); 546 + } 547 + 548 + /** 549 + * fc_fabric_login - Start the lport state machine 550 + * @lport: The lport that should log into the fabric 551 + * 552 + * Locking Note: This function should not be called 553 + * with the lport lock held. 554 + */ 555 + int fc_fabric_login(struct fc_lport *lport) 556 + { 557 + int rc = -1; 558 + 559 + mutex_lock(&lport->lp_mutex); 560 + if (lport->state == LPORT_ST_NONE) { 561 + fc_lport_enter_reset(lport); 562 + rc = 0; 563 + } 564 + mutex_unlock(&lport->lp_mutex); 565 + 566 + return rc; 567 + } 568 + EXPORT_SYMBOL(fc_fabric_login); 569 + 570 + /** 571 + * fc_linkup - Handler for transport linkup events 572 + * @lport: The lport whose link is up 573 + */ 574 + void fc_linkup(struct fc_lport *lport) 575 + { 576 + FC_DEBUG_LPORT("Link is up for port (%6x)\n", 577 + fc_host_port_id(lport->host)); 578 + 579 + mutex_lock(&lport->lp_mutex); 580 + if ((lport->link_status & FC_LINK_UP) != FC_LINK_UP) { 581 + lport->link_status |= FC_LINK_UP; 582 + 583 + if (lport->state == LPORT_ST_RESET) 584 + fc_lport_enter_flogi(lport); 585 + } 586 + mutex_unlock(&lport->lp_mutex); 587 + } 588 + EXPORT_SYMBOL(fc_linkup); 589 + 590 + /** 591 + * fc_linkdown - Handler for transport linkdown events 592 + * @lport: The lport whose link is down 593 + */ 594 + void fc_linkdown(struct fc_lport *lport) 595 + { 596 + mutex_lock(&lport->lp_mutex); 597 + FC_DEBUG_LPORT("Link is down for port (%6x)\n", 598 + fc_host_port_id(lport->host)); 599 + 600 + if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) { 601 + lport->link_status &= ~(FC_LINK_UP); 602 + fc_lport_enter_reset(lport); 603 + lport->tt.fcp_cleanup(lport); 604 + } 605 + mutex_unlock(&lport->lp_mutex); 606 + } 607 + EXPORT_SYMBOL(fc_linkdown); 608 + 609 + /** 610 + * fc_pause - Pause the flow of frames 611 + * @lport: The lport to be paused 612 + */ 613 + void fc_pause(struct fc_lport *lport) 614 + { 615 + mutex_lock(&lport->lp_mutex); 616 + lport->link_status |= FC_PAUSE; 617 + mutex_unlock(&lport->lp_mutex); 618 + } 619 + EXPORT_SYMBOL(fc_pause); 620 + 621 + /** 622 + * fc_unpause - Unpause the flow of frames 623 + * @lport: The lport to be unpaused 624 + */ 625 + void fc_unpause(struct fc_lport *lport) 626 + { 627 + mutex_lock(&lport->lp_mutex); 628 + lport->link_status &= ~(FC_PAUSE); 629 + mutex_unlock(&lport->lp_mutex); 630 + } 631 + EXPORT_SYMBOL(fc_unpause); 632 + 633 + /** 634 + * fc_fabric_logoff - Logout of the fabric 635 + * @lport: fc_lport pointer to logoff the fabric 636 + * 637 + * Return value: 638 + * 0 for success, -1 for failure 639 + **/ 640 + int fc_fabric_logoff(struct fc_lport *lport) 641 + { 642 + lport->tt.disc_stop_final(lport); 643 + mutex_lock(&lport->lp_mutex); 644 + fc_lport_enter_logo(lport); 645 + mutex_unlock(&lport->lp_mutex); 646 + return 0; 647 + } 648 + EXPORT_SYMBOL(fc_fabric_logoff); 649 + 650 + /** 651 + * fc_lport_destroy - unregister a fc_lport 652 + * @lport: fc_lport pointer to unregister 653 + * 654 + * Return value: 655 + * None 656 + * Note: 657 + * exit routine for fc_lport instance 658 + * clean-up all the allocated memory 659 + * and free up other system resources. 660 + * 661 + **/ 662 + int fc_lport_destroy(struct fc_lport *lport) 663 + { 664 + lport->tt.frame_send = fc_frame_drop; 665 + lport->tt.fcp_abort_io(lport); 666 + lport->tt.exch_mgr_reset(lport->emp, 0, 0); 667 + return 0; 668 + } 669 + EXPORT_SYMBOL(fc_lport_destroy); 670 + 671 + /** 672 + * fc_set_mfs - sets up the mfs for the corresponding fc_lport 673 + * @lport: fc_lport pointer to unregister 674 + * @mfs: the new mfs for fc_lport 675 + * 676 + * Set mfs for the given fc_lport to the new mfs. 677 + * 678 + * Return: 0 for success 679 + * 680 + **/ 681 + int fc_set_mfs(struct fc_lport *lport, u32 mfs) 682 + { 683 + unsigned int old_mfs; 684 + int rc = -EINVAL; 685 + 686 + mutex_lock(&lport->lp_mutex); 687 + 688 + old_mfs = lport->mfs; 689 + 690 + if (mfs >= FC_MIN_MAX_FRAME) { 691 + mfs &= ~3; 692 + if (mfs > FC_MAX_FRAME) 693 + mfs = FC_MAX_FRAME; 694 + mfs -= sizeof(struct fc_frame_header); 695 + lport->mfs = mfs; 696 + rc = 0; 697 + } 698 + 699 + if (!rc && mfs < old_mfs) 700 + fc_lport_enter_reset(lport); 701 + 702 + mutex_unlock(&lport->lp_mutex); 703 + 704 + return rc; 705 + } 706 + EXPORT_SYMBOL(fc_set_mfs); 707 + 708 + /** 709 + * fc_lport_disc_callback - Callback for discovery events 710 + * @lport: FC local port 711 + * @event: The discovery event 712 + */ 713 + void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event) 714 + { 715 + switch (event) { 716 + case DISC_EV_SUCCESS: 717 + FC_DEBUG_LPORT("Got a SUCCESS event for port (%6x)\n", 718 + fc_host_port_id(lport->host)); 719 + break; 720 + case DISC_EV_FAILED: 721 + FC_DEBUG_LPORT("Got a FAILED event for port (%6x)\n", 722 + fc_host_port_id(lport->host)); 723 + mutex_lock(&lport->lp_mutex); 724 + fc_lport_enter_reset(lport); 725 + mutex_unlock(&lport->lp_mutex); 726 + break; 727 + case DISC_EV_NONE: 728 + WARN_ON(1); 729 + break; 730 + } 731 + } 732 + 733 + /** 734 + * fc_rport_enter_ready - Enter the ready state and start discovery 735 + * @lport: Fibre Channel local port that is ready 736 + * 737 + * Locking Note: The lport lock is expected to be held before calling 738 + * this routine. 739 + */ 740 + static void fc_lport_enter_ready(struct fc_lport *lport) 741 + { 742 + FC_DEBUG_LPORT("Port (%6x) entered Ready from state %s\n", 743 + fc_host_port_id(lport->host), fc_lport_state(lport)); 744 + 745 + fc_lport_state_enter(lport, LPORT_ST_READY); 746 + 747 + lport->tt.disc_start(fc_lport_disc_callback, lport); 748 + } 749 + 750 + /** 751 + * fc_lport_recv_flogi_req - Receive a FLOGI request 752 + * @sp_in: The sequence the FLOGI is on 753 + * @rx_fp: The frame the FLOGI is in 754 + * @lport: The lport that recieved the request 755 + * 756 + * A received FLOGI request indicates a point-to-point connection. 757 + * Accept it with the common service parameters indicating our N port. 758 + * Set up to do a PLOGI if we have the higher-number WWPN. 759 + * 760 + * Locking Note: The lport lock is exected to be held before calling 761 + * this function. 762 + */ 763 + static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, 764 + struct fc_frame *rx_fp, 765 + struct fc_lport *lport) 766 + { 767 + struct fc_frame *fp; 768 + struct fc_frame_header *fh; 769 + struct fc_seq *sp; 770 + struct fc_exch *ep; 771 + struct fc_els_flogi *flp; 772 + struct fc_els_flogi *new_flp; 773 + u64 remote_wwpn; 774 + u32 remote_fid; 775 + u32 local_fid; 776 + u32 f_ctl; 777 + 778 + FC_DEBUG_LPORT("Received FLOGI request while in state %s\n", 779 + fc_lport_state(lport)); 780 + 781 + fh = fc_frame_header_get(rx_fp); 782 + remote_fid = ntoh24(fh->fh_s_id); 783 + flp = fc_frame_payload_get(rx_fp, sizeof(*flp)); 784 + if (!flp) 785 + goto out; 786 + remote_wwpn = get_unaligned_be64(&flp->fl_wwpn); 787 + if (remote_wwpn == lport->wwpn) { 788 + FC_DBG("FLOGI from port with same WWPN %llx " 789 + "possible configuration error\n", remote_wwpn); 790 + goto out; 791 + } 792 + FC_DBG("FLOGI from port WWPN %llx\n", remote_wwpn); 793 + 794 + /* 795 + * XXX what is the right thing to do for FIDs? 796 + * The originator might expect our S_ID to be 0xfffffe. 797 + * But if so, both of us could end up with the same FID. 798 + */ 799 + local_fid = FC_LOCAL_PTP_FID_LO; 800 + if (remote_wwpn < lport->wwpn) { 801 + local_fid = FC_LOCAL_PTP_FID_HI; 802 + if (!remote_fid || remote_fid == local_fid) 803 + remote_fid = FC_LOCAL_PTP_FID_LO; 804 + } else if (!remote_fid) { 805 + remote_fid = FC_LOCAL_PTP_FID_HI; 806 + } 807 + 808 + fc_host_port_id(lport->host) = local_fid; 809 + 810 + fp = fc_frame_alloc(lport, sizeof(*flp)); 811 + if (fp) { 812 + sp = lport->tt.seq_start_next(fr_seq(rx_fp)); 813 + new_flp = fc_frame_payload_get(fp, sizeof(*flp)); 814 + fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI); 815 + new_flp->fl_cmd = (u8) ELS_LS_ACC; 816 + 817 + /* 818 + * Send the response. If this fails, the originator should 819 + * repeat the sequence. 820 + */ 821 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 822 + ep = fc_seq_exch(sp); 823 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 824 + FC_TYPE_ELS, f_ctl, 0); 825 + lport->tt.seq_send(lport, sp, fp); 826 + 827 + } else { 828 + fc_lport_error(lport, fp); 829 + } 830 + fc_lport_ptp_setup(lport, remote_fid, remote_wwpn, 831 + get_unaligned_be64(&flp->fl_wwnn)); 832 + 833 + lport->tt.disc_start(fc_lport_disc_callback, lport); 834 + 835 + out: 836 + sp = fr_seq(rx_fp); 837 + fc_frame_free(rx_fp); 838 + } 839 + 840 + /** 841 + * fc_lport_recv_req - The generic lport request handler 842 + * @lport: The lport that received the request 843 + * @sp: The sequence the request is on 844 + * @fp: The frame the request is in 845 + * 846 + * This function will see if the lport handles the request or 847 + * if an rport should handle the request. 848 + * 849 + * Locking Note: This function should not be called with the lport 850 + * lock held becuase it will grab the lock. 851 + */ 852 + static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, 853 + struct fc_frame *fp) 854 + { 855 + struct fc_frame_header *fh = fc_frame_header_get(fp); 856 + void (*recv) (struct fc_seq *, struct fc_frame *, struct fc_lport *); 857 + struct fc_rport *rport; 858 + u32 s_id; 859 + u32 d_id; 860 + struct fc_seq_els_data rjt_data; 861 + 862 + mutex_lock(&lport->lp_mutex); 863 + 864 + /* 865 + * Handle special ELS cases like FLOGI, LOGO, and 866 + * RSCN here. These don't require a session. 867 + * Even if we had a session, it might not be ready. 868 + */ 869 + if (fh->fh_type == FC_TYPE_ELS && fh->fh_r_ctl == FC_RCTL_ELS_REQ) { 870 + /* 871 + * Check opcode. 872 + */ 873 + recv = NULL; 874 + switch (fc_frame_payload_op(fp)) { 875 + case ELS_FLOGI: 876 + recv = fc_lport_recv_flogi_req; 877 + break; 878 + case ELS_LOGO: 879 + fh = fc_frame_header_get(fp); 880 + if (ntoh24(fh->fh_s_id) == FC_FID_FLOGI) 881 + recv = fc_lport_recv_logo_req; 882 + break; 883 + case ELS_RSCN: 884 + recv = lport->tt.disc_recv_req; 885 + break; 886 + case ELS_ECHO: 887 + recv = fc_lport_recv_echo_req; 888 + break; 889 + case ELS_RLIR: 890 + recv = fc_lport_recv_rlir_req; 891 + break; 892 + case ELS_RNID: 893 + recv = fc_lport_recv_rnid_req; 894 + break; 895 + case ELS_ADISC: 896 + recv = fc_lport_recv_adisc_req; 897 + break; 898 + } 899 + 900 + if (recv) 901 + recv(sp, fp, lport); 902 + else { 903 + /* 904 + * Find session. 905 + * If this is a new incoming PLOGI, we won't find it. 906 + */ 907 + s_id = ntoh24(fh->fh_s_id); 908 + d_id = ntoh24(fh->fh_d_id); 909 + 910 + rport = lport->tt.rport_lookup(lport, s_id); 911 + if (rport) 912 + lport->tt.rport_recv_req(sp, fp, rport); 913 + else { 914 + rjt_data.fp = NULL; 915 + rjt_data.reason = ELS_RJT_UNAB; 916 + rjt_data.explan = ELS_EXPL_NONE; 917 + lport->tt.seq_els_rsp_send(sp, 918 + ELS_LS_RJT, 919 + &rjt_data); 920 + fc_frame_free(fp); 921 + } 922 + } 923 + } else { 924 + FC_DBG("dropping invalid frame (eof %x)\n", fr_eof(fp)); 925 + fc_frame_free(fp); 926 + } 927 + mutex_unlock(&lport->lp_mutex); 928 + 929 + /* 930 + * The common exch_done for all request may not be good 931 + * if any request requires longer hold on exhange. XXX 932 + */ 933 + lport->tt.exch_done(sp); 934 + } 935 + 936 + /** 937 + * fc_lport_reset - Reset an lport 938 + * @lport: The lport which should be reset 939 + * 940 + * Locking Note: This functions should not be called with the 941 + * lport lock held. 942 + */ 943 + int fc_lport_reset(struct fc_lport *lport) 944 + { 945 + mutex_lock(&lport->lp_mutex); 946 + fc_lport_enter_reset(lport); 947 + mutex_unlock(&lport->lp_mutex); 948 + return 0; 949 + } 950 + EXPORT_SYMBOL(fc_lport_reset); 951 + 952 + /** 953 + * fc_rport_enter_reset - Reset the local port 954 + * @lport: Fibre Channel local port to be reset 955 + * 956 + * Locking Note: The lport lock is expected to be held before calling 957 + * this routine. 958 + */ 959 + static void fc_lport_enter_reset(struct fc_lport *lport) 960 + { 961 + FC_DEBUG_LPORT("Port (%6x) entered RESET state from %s state\n", 962 + fc_host_port_id(lport->host), fc_lport_state(lport)); 963 + 964 + fc_lport_state_enter(lport, LPORT_ST_RESET); 965 + 966 + if (lport->dns_rp) 967 + lport->tt.rport_logoff(lport->dns_rp); 968 + 969 + if (lport->ptp_rp) { 970 + lport->tt.rport_logoff(lport->ptp_rp); 971 + lport->ptp_rp = NULL; 972 + } 973 + 974 + lport->tt.disc_stop(lport); 975 + 976 + lport->tt.exch_mgr_reset(lport->emp, 0, 0); 977 + fc_host_fabric_name(lport->host) = 0; 978 + fc_host_port_id(lport->host) = 0; 979 + 980 + if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) 981 + fc_lport_enter_flogi(lport); 982 + } 983 + 984 + /** 985 + * fc_lport_error - Handler for any errors 986 + * @lport: The fc_lport object 987 + * @fp: The frame pointer 988 + * 989 + * If the error was caused by a resource allocation failure 990 + * then wait for half a second and retry, otherwise retry 991 + * after the e_d_tov time. 992 + */ 993 + static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) 994 + { 995 + unsigned long delay = 0; 996 + FC_DEBUG_LPORT("Error %ld in state %s, retries %d\n", 997 + PTR_ERR(fp), fc_lport_state(lport), 998 + lport->retry_count); 999 + 1000 + if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { 1001 + /* 1002 + * Memory allocation failure, or the exchange timed out. 1003 + * Retry after delay 1004 + */ 1005 + if (lport->retry_count < lport->max_retry_count) { 1006 + lport->retry_count++; 1007 + if (!fp) 1008 + delay = msecs_to_jiffies(500); 1009 + else 1010 + delay = msecs_to_jiffies(lport->e_d_tov); 1011 + 1012 + schedule_delayed_work(&lport->retry_work, delay); 1013 + } else { 1014 + switch (lport->state) { 1015 + case LPORT_ST_NONE: 1016 + case LPORT_ST_READY: 1017 + case LPORT_ST_RESET: 1018 + case LPORT_ST_RPN_ID: 1019 + case LPORT_ST_RFT_ID: 1020 + case LPORT_ST_SCR: 1021 + case LPORT_ST_DNS: 1022 + case LPORT_ST_FLOGI: 1023 + case LPORT_ST_LOGO: 1024 + fc_lport_enter_reset(lport); 1025 + break; 1026 + } 1027 + } 1028 + } 1029 + } 1030 + 1031 + /** 1032 + * fc_lport_rft_id_resp - Handle response to Register Fibre 1033 + * Channel Types by ID (RPN_ID) request 1034 + * @sp: current sequence in RPN_ID exchange 1035 + * @fp: response frame 1036 + * @lp_arg: Fibre Channel host port instance 1037 + * 1038 + * Locking Note: This function will be called without the lport lock 1039 + * held, but it will lock, call an _enter_* function or fc_lport_error 1040 + * and then unlock the lport. 1041 + */ 1042 + static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, 1043 + void *lp_arg) 1044 + { 1045 + struct fc_lport *lport = lp_arg; 1046 + struct fc_frame_header *fh; 1047 + struct fc_ct_hdr *ct; 1048 + 1049 + if (fp == ERR_PTR(-FC_EX_CLOSED)) 1050 + return; 1051 + 1052 + mutex_lock(&lport->lp_mutex); 1053 + 1054 + FC_DEBUG_LPORT("Received a RFT_ID response\n"); 1055 + 1056 + if (lport->state != LPORT_ST_RFT_ID) { 1057 + FC_DBG("Received a RFT_ID response, but in state %s\n", 1058 + fc_lport_state(lport)); 1059 + goto out; 1060 + } 1061 + 1062 + if (IS_ERR(fp)) { 1063 + fc_lport_error(lport, fp); 1064 + goto err; 1065 + } 1066 + 1067 + fh = fc_frame_header_get(fp); 1068 + ct = fc_frame_payload_get(fp, sizeof(*ct)); 1069 + 1070 + if (fh && ct && fh->fh_type == FC_TYPE_CT && 1071 + ct->ct_fs_type == FC_FST_DIR && 1072 + ct->ct_fs_subtype == FC_NS_SUBTYPE && 1073 + ntohs(ct->ct_cmd) == FC_FS_ACC) 1074 + fc_lport_enter_scr(lport); 1075 + else 1076 + fc_lport_error(lport, fp); 1077 + out: 1078 + fc_frame_free(fp); 1079 + err: 1080 + mutex_unlock(&lport->lp_mutex); 1081 + } 1082 + 1083 + /** 1084 + * fc_lport_rpn_id_resp - Handle response to Register Port 1085 + * Name by ID (RPN_ID) request 1086 + * @sp: current sequence in RPN_ID exchange 1087 + * @fp: response frame 1088 + * @lp_arg: Fibre Channel host port instance 1089 + * 1090 + * Locking Note: This function will be called without the lport lock 1091 + * held, but it will lock, call an _enter_* function or fc_lport_error 1092 + * and then unlock the lport. 1093 + */ 1094 + static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, 1095 + void *lp_arg) 1096 + { 1097 + struct fc_lport *lport = lp_arg; 1098 + struct fc_frame_header *fh; 1099 + struct fc_ct_hdr *ct; 1100 + 1101 + if (fp == ERR_PTR(-FC_EX_CLOSED)) 1102 + return; 1103 + 1104 + mutex_lock(&lport->lp_mutex); 1105 + 1106 + FC_DEBUG_LPORT("Received a RPN_ID response\n"); 1107 + 1108 + if (lport->state != LPORT_ST_RPN_ID) { 1109 + FC_DBG("Received a RPN_ID response, but in state %s\n", 1110 + fc_lport_state(lport)); 1111 + goto out; 1112 + } 1113 + 1114 + if (IS_ERR(fp)) { 1115 + fc_lport_error(lport, fp); 1116 + goto err; 1117 + } 1118 + 1119 + fh = fc_frame_header_get(fp); 1120 + ct = fc_frame_payload_get(fp, sizeof(*ct)); 1121 + if (fh && ct && fh->fh_type == FC_TYPE_CT && 1122 + ct->ct_fs_type == FC_FST_DIR && 1123 + ct->ct_fs_subtype == FC_NS_SUBTYPE && 1124 + ntohs(ct->ct_cmd) == FC_FS_ACC) 1125 + fc_lport_enter_rft_id(lport); 1126 + else 1127 + fc_lport_error(lport, fp); 1128 + 1129 + out: 1130 + fc_frame_free(fp); 1131 + err: 1132 + mutex_unlock(&lport->lp_mutex); 1133 + } 1134 + 1135 + /** 1136 + * fc_lport_scr_resp - Handle response to State Change Register (SCR) request 1137 + * @sp: current sequence in SCR exchange 1138 + * @fp: response frame 1139 + * @lp_arg: Fibre Channel lport port instance that sent the registration request 1140 + * 1141 + * Locking Note: This function will be called without the lport lock 1142 + * held, but it will lock, call an _enter_* function or fc_lport_error 1143 + * and then unlock the lport. 1144 + */ 1145 + static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, 1146 + void *lp_arg) 1147 + { 1148 + struct fc_lport *lport = lp_arg; 1149 + u8 op; 1150 + 1151 + if (fp == ERR_PTR(-FC_EX_CLOSED)) 1152 + return; 1153 + 1154 + mutex_lock(&lport->lp_mutex); 1155 + 1156 + FC_DEBUG_LPORT("Received a SCR response\n"); 1157 + 1158 + if (lport->state != LPORT_ST_SCR) { 1159 + FC_DBG("Received a SCR response, but in state %s\n", 1160 + fc_lport_state(lport)); 1161 + goto out; 1162 + } 1163 + 1164 + if (IS_ERR(fp)) { 1165 + fc_lport_error(lport, fp); 1166 + goto err; 1167 + } 1168 + 1169 + op = fc_frame_payload_op(fp); 1170 + if (op == ELS_LS_ACC) 1171 + fc_lport_enter_ready(lport); 1172 + else 1173 + fc_lport_error(lport, fp); 1174 + 1175 + out: 1176 + fc_frame_free(fp); 1177 + err: 1178 + mutex_unlock(&lport->lp_mutex); 1179 + } 1180 + 1181 + /** 1182 + * fc_lport_enter_scr - Send a State Change Register (SCR) request 1183 + * @lport: Fibre Channel local port to register for state changes 1184 + * 1185 + * Locking Note: The lport lock is expected to be held before calling 1186 + * this routine. 1187 + */ 1188 + static void fc_lport_enter_scr(struct fc_lport *lport) 1189 + { 1190 + struct fc_frame *fp; 1191 + 1192 + FC_DEBUG_LPORT("Port (%6x) entered SCR state from %s state\n", 1193 + fc_host_port_id(lport->host), fc_lport_state(lport)); 1194 + 1195 + fc_lport_state_enter(lport, LPORT_ST_SCR); 1196 + 1197 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_scr)); 1198 + if (!fp) { 1199 + fc_lport_error(lport, fp); 1200 + return; 1201 + } 1202 + 1203 + if (!lport->tt.elsct_send(lport, NULL, fp, ELS_SCR, 1204 + fc_lport_scr_resp, lport, lport->e_d_tov)) 1205 + fc_lport_error(lport, fp); 1206 + } 1207 + 1208 + /** 1209 + * fc_lport_enter_rft_id - Register FC4-types with the name server 1210 + * @lport: Fibre Channel local port to register 1211 + * 1212 + * Locking Note: The lport lock is expected to be held before calling 1213 + * this routine. 1214 + */ 1215 + static void fc_lport_enter_rft_id(struct fc_lport *lport) 1216 + { 1217 + struct fc_frame *fp; 1218 + struct fc_ns_fts *lps; 1219 + int i; 1220 + 1221 + FC_DEBUG_LPORT("Port (%6x) entered RFT_ID state from %s state\n", 1222 + fc_host_port_id(lport->host), fc_lport_state(lport)); 1223 + 1224 + fc_lport_state_enter(lport, LPORT_ST_RFT_ID); 1225 + 1226 + lps = &lport->fcts; 1227 + i = sizeof(lps->ff_type_map) / sizeof(lps->ff_type_map[0]); 1228 + while (--i >= 0) 1229 + if (ntohl(lps->ff_type_map[i]) != 0) 1230 + break; 1231 + if (i < 0) { 1232 + /* nothing to register, move on to SCR */ 1233 + fc_lport_enter_scr(lport); 1234 + return; 1235 + } 1236 + 1237 + fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) + 1238 + sizeof(struct fc_ns_rft)); 1239 + if (!fp) { 1240 + fc_lport_error(lport, fp); 1241 + return; 1242 + } 1243 + 1244 + if (!lport->tt.elsct_send(lport, NULL, fp, FC_NS_RFT_ID, 1245 + fc_lport_rft_id_resp, 1246 + lport, lport->e_d_tov)) 1247 + fc_lport_error(lport, fp); 1248 + } 1249 + 1250 + /** 1251 + * fc_rport_enter_rft_id - Register port name with the name server 1252 + * @lport: Fibre Channel local port to register 1253 + * 1254 + * Locking Note: The lport lock is expected to be held before calling 1255 + * this routine. 1256 + */ 1257 + static void fc_lport_enter_rpn_id(struct fc_lport *lport) 1258 + { 1259 + struct fc_frame *fp; 1260 + 1261 + FC_DEBUG_LPORT("Port (%6x) entered RPN_ID state from %s state\n", 1262 + fc_host_port_id(lport->host), fc_lport_state(lport)); 1263 + 1264 + fc_lport_state_enter(lport, LPORT_ST_RPN_ID); 1265 + 1266 + fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) + 1267 + sizeof(struct fc_ns_rn_id)); 1268 + if (!fp) { 1269 + fc_lport_error(lport, fp); 1270 + return; 1271 + } 1272 + 1273 + if (!lport->tt.elsct_send(lport, NULL, fp, FC_NS_RPN_ID, 1274 + fc_lport_rpn_id_resp, 1275 + lport, lport->e_d_tov)) 1276 + fc_lport_error(lport, fp); 1277 + } 1278 + 1279 + static struct fc_rport_operations fc_lport_rport_ops = { 1280 + .event_callback = fc_lport_rport_callback, 1281 + }; 1282 + 1283 + /** 1284 + * fc_rport_enter_dns - Create a rport to the name server 1285 + * @lport: Fibre Channel local port requesting a rport for the name server 1286 + * 1287 + * Locking Note: The lport lock is expected to be held before calling 1288 + * this routine. 1289 + */ 1290 + static void fc_lport_enter_dns(struct fc_lport *lport) 1291 + { 1292 + struct fc_rport *rport; 1293 + struct fc_rport_libfc_priv *rdata; 1294 + struct fc_disc_port dp; 1295 + 1296 + dp.ids.port_id = FC_FID_DIR_SERV; 1297 + dp.ids.port_name = -1; 1298 + dp.ids.node_name = -1; 1299 + dp.ids.roles = FC_RPORT_ROLE_UNKNOWN; 1300 + dp.lp = lport; 1301 + 1302 + FC_DEBUG_LPORT("Port (%6x) entered DNS state from %s state\n", 1303 + fc_host_port_id(lport->host), fc_lport_state(lport)); 1304 + 1305 + fc_lport_state_enter(lport, LPORT_ST_DNS); 1306 + 1307 + rport = fc_rport_rogue_create(&dp); 1308 + if (!rport) 1309 + goto err; 1310 + 1311 + rdata = rport->dd_data; 1312 + rdata->ops = &fc_lport_rport_ops; 1313 + lport->tt.rport_login(rport); 1314 + return; 1315 + 1316 + err: 1317 + fc_lport_error(lport, NULL); 1318 + } 1319 + 1320 + /** 1321 + * fc_lport_timeout - Handler for the retry_work timer. 1322 + * @work: The work struct of the fc_lport 1323 + */ 1324 + static void fc_lport_timeout(struct work_struct *work) 1325 + { 1326 + struct fc_lport *lport = 1327 + container_of(work, struct fc_lport, 1328 + retry_work.work); 1329 + 1330 + mutex_lock(&lport->lp_mutex); 1331 + 1332 + switch (lport->state) { 1333 + case LPORT_ST_NONE: 1334 + case LPORT_ST_READY: 1335 + case LPORT_ST_RESET: 1336 + WARN_ON(1); 1337 + break; 1338 + case LPORT_ST_FLOGI: 1339 + fc_lport_enter_flogi(lport); 1340 + break; 1341 + case LPORT_ST_DNS: 1342 + fc_lport_enter_dns(lport); 1343 + break; 1344 + case LPORT_ST_RPN_ID: 1345 + fc_lport_enter_rpn_id(lport); 1346 + break; 1347 + case LPORT_ST_RFT_ID: 1348 + fc_lport_enter_rft_id(lport); 1349 + break; 1350 + case LPORT_ST_SCR: 1351 + fc_lport_enter_scr(lport); 1352 + break; 1353 + case LPORT_ST_LOGO: 1354 + fc_lport_enter_logo(lport); 1355 + break; 1356 + } 1357 + 1358 + mutex_unlock(&lport->lp_mutex); 1359 + } 1360 + 1361 + /** 1362 + * fc_lport_logo_resp - Handle response to LOGO request 1363 + * @sp: current sequence in LOGO exchange 1364 + * @fp: response frame 1365 + * @lp_arg: Fibre Channel lport port instance that sent the LOGO request 1366 + * 1367 + * Locking Note: This function will be called without the lport lock 1368 + * held, but it will lock, call an _enter_* function or fc_lport_error 1369 + * and then unlock the lport. 1370 + */ 1371 + static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, 1372 + void *lp_arg) 1373 + { 1374 + struct fc_lport *lport = lp_arg; 1375 + u8 op; 1376 + 1377 + if (fp == ERR_PTR(-FC_EX_CLOSED)) 1378 + return; 1379 + 1380 + mutex_lock(&lport->lp_mutex); 1381 + 1382 + FC_DEBUG_LPORT("Received a LOGO response\n"); 1383 + 1384 + if (lport->state != LPORT_ST_LOGO) { 1385 + FC_DBG("Received a LOGO response, but in state %s\n", 1386 + fc_lport_state(lport)); 1387 + goto out; 1388 + } 1389 + 1390 + if (IS_ERR(fp)) { 1391 + fc_lport_error(lport, fp); 1392 + goto err; 1393 + } 1394 + 1395 + op = fc_frame_payload_op(fp); 1396 + if (op == ELS_LS_ACC) 1397 + fc_lport_enter_reset(lport); 1398 + else 1399 + fc_lport_error(lport, fp); 1400 + 1401 + out: 1402 + fc_frame_free(fp); 1403 + err: 1404 + mutex_unlock(&lport->lp_mutex); 1405 + } 1406 + 1407 + /** 1408 + * fc_rport_enter_logo - Logout of the fabric 1409 + * @lport: Fibre Channel local port to be logged out 1410 + * 1411 + * Locking Note: The lport lock is expected to be held before calling 1412 + * this routine. 1413 + */ 1414 + static void fc_lport_enter_logo(struct fc_lport *lport) 1415 + { 1416 + struct fc_frame *fp; 1417 + struct fc_els_logo *logo; 1418 + 1419 + FC_DEBUG_LPORT("Port (%6x) entered LOGO state from %s state\n", 1420 + fc_host_port_id(lport->host), fc_lport_state(lport)); 1421 + 1422 + fc_lport_state_enter(lport, LPORT_ST_LOGO); 1423 + 1424 + /* DNS session should be closed so we can release it here */ 1425 + if (lport->dns_rp) 1426 + lport->tt.rport_logoff(lport->dns_rp); 1427 + 1428 + fp = fc_frame_alloc(lport, sizeof(*logo)); 1429 + if (!fp) { 1430 + fc_lport_error(lport, fp); 1431 + return; 1432 + } 1433 + 1434 + if (!lport->tt.elsct_send(lport, NULL, fp, ELS_LOGO, fc_lport_logo_resp, 1435 + lport, lport->e_d_tov)) 1436 + fc_lport_error(lport, fp); 1437 + } 1438 + 1439 + /** 1440 + * fc_lport_flogi_resp - Handle response to FLOGI request 1441 + * @sp: current sequence in FLOGI exchange 1442 + * @fp: response frame 1443 + * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request 1444 + * 1445 + * Locking Note: This function will be called without the lport lock 1446 + * held, but it will lock, call an _enter_* function or fc_lport_error 1447 + * and then unlock the lport. 1448 + */ 1449 + static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, 1450 + void *lp_arg) 1451 + { 1452 + struct fc_lport *lport = lp_arg; 1453 + struct fc_frame_header *fh; 1454 + struct fc_els_flogi *flp; 1455 + u32 did; 1456 + u16 csp_flags; 1457 + unsigned int r_a_tov; 1458 + unsigned int e_d_tov; 1459 + u16 mfs; 1460 + 1461 + if (fp == ERR_PTR(-FC_EX_CLOSED)) 1462 + return; 1463 + 1464 + mutex_lock(&lport->lp_mutex); 1465 + 1466 + FC_DEBUG_LPORT("Received a FLOGI response\n"); 1467 + 1468 + if (lport->state != LPORT_ST_FLOGI) { 1469 + FC_DBG("Received a FLOGI response, but in state %s\n", 1470 + fc_lport_state(lport)); 1471 + goto out; 1472 + } 1473 + 1474 + if (IS_ERR(fp)) { 1475 + fc_lport_error(lport, fp); 1476 + goto err; 1477 + } 1478 + 1479 + fh = fc_frame_header_get(fp); 1480 + did = ntoh24(fh->fh_d_id); 1481 + if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { 1482 + 1483 + FC_DEBUG_LPORT("Assigned fid %x\n", did); 1484 + fc_host_port_id(lport->host) = did; 1485 + 1486 + flp = fc_frame_payload_get(fp, sizeof(*flp)); 1487 + if (flp) { 1488 + mfs = ntohs(flp->fl_csp.sp_bb_data) & 1489 + FC_SP_BB_DATA_MASK; 1490 + if (mfs >= FC_SP_MIN_MAX_PAYLOAD && 1491 + mfs < lport->mfs) 1492 + lport->mfs = mfs; 1493 + csp_flags = ntohs(flp->fl_csp.sp_features); 1494 + r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov); 1495 + e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); 1496 + if (csp_flags & FC_SP_FT_EDTR) 1497 + e_d_tov /= 1000000; 1498 + if ((csp_flags & FC_SP_FT_FPORT) == 0) { 1499 + if (e_d_tov > lport->e_d_tov) 1500 + lport->e_d_tov = e_d_tov; 1501 + lport->r_a_tov = 2 * e_d_tov; 1502 + FC_DBG("Point-to-Point mode\n"); 1503 + fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id), 1504 + get_unaligned_be64( 1505 + &flp->fl_wwpn), 1506 + get_unaligned_be64( 1507 + &flp->fl_wwnn)); 1508 + } else { 1509 + lport->e_d_tov = e_d_tov; 1510 + lport->r_a_tov = r_a_tov; 1511 + fc_host_fabric_name(lport->host) = 1512 + get_unaligned_be64(&flp->fl_wwnn); 1513 + fc_lport_enter_dns(lport); 1514 + } 1515 + } 1516 + 1517 + if (flp) { 1518 + csp_flags = ntohs(flp->fl_csp.sp_features); 1519 + if ((csp_flags & FC_SP_FT_FPORT) == 0) { 1520 + lport->tt.disc_start(fc_lport_disc_callback, 1521 + lport); 1522 + } 1523 + } 1524 + } else { 1525 + FC_DBG("bad FLOGI response\n"); 1526 + } 1527 + 1528 + out: 1529 + fc_frame_free(fp); 1530 + err: 1531 + mutex_unlock(&lport->lp_mutex); 1532 + } 1533 + 1534 + /** 1535 + * fc_rport_enter_flogi - Send a FLOGI request to the fabric manager 1536 + * @lport: Fibre Channel local port to be logged in to the fabric 1537 + * 1538 + * Locking Note: The lport lock is expected to be held before calling 1539 + * this routine. 1540 + */ 1541 + void fc_lport_enter_flogi(struct fc_lport *lport) 1542 + { 1543 + struct fc_frame *fp; 1544 + 1545 + FC_DEBUG_LPORT("Processing FLOGI state\n"); 1546 + 1547 + fc_lport_state_enter(lport, LPORT_ST_FLOGI); 1548 + 1549 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); 1550 + if (!fp) 1551 + return fc_lport_error(lport, fp); 1552 + 1553 + if (!lport->tt.elsct_send(lport, NULL, fp, ELS_FLOGI, 1554 + fc_lport_flogi_resp, lport, lport->e_d_tov)) 1555 + fc_lport_error(lport, fp); 1556 + } 1557 + 1558 + /* Configure a fc_lport */ 1559 + int fc_lport_config(struct fc_lport *lport) 1560 + { 1561 + INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout); 1562 + mutex_init(&lport->lp_mutex); 1563 + 1564 + fc_lport_state_enter(lport, LPORT_ST_NONE); 1565 + 1566 + fc_lport_add_fc4_type(lport, FC_TYPE_FCP); 1567 + fc_lport_add_fc4_type(lport, FC_TYPE_CT); 1568 + 1569 + return 0; 1570 + } 1571 + EXPORT_SYMBOL(fc_lport_config); 1572 + 1573 + int fc_lport_init(struct fc_lport *lport) 1574 + { 1575 + if (!lport->tt.lport_recv) 1576 + lport->tt.lport_recv = fc_lport_recv_req; 1577 + 1578 + if (!lport->tt.lport_reset) 1579 + lport->tt.lport_reset = fc_lport_reset; 1580 + 1581 + fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; 1582 + fc_host_node_name(lport->host) = lport->wwnn; 1583 + fc_host_port_name(lport->host) = lport->wwpn; 1584 + fc_host_supported_classes(lport->host) = FC_COS_CLASS3; 1585 + memset(fc_host_supported_fc4s(lport->host), 0, 1586 + sizeof(fc_host_supported_fc4s(lport->host))); 1587 + fc_host_supported_fc4s(lport->host)[2] = 1; 1588 + fc_host_supported_fc4s(lport->host)[7] = 1; 1589 + 1590 + /* This value is also unchanging */ 1591 + memset(fc_host_active_fc4s(lport->host), 0, 1592 + sizeof(fc_host_active_fc4s(lport->host))); 1593 + fc_host_active_fc4s(lport->host)[2] = 1; 1594 + fc_host_active_fc4s(lport->host)[7] = 1; 1595 + fc_host_maxframe_size(lport->host) = lport->mfs; 1596 + fc_host_supported_speeds(lport->host) = 0; 1597 + if (lport->link_supported_speeds & FC_PORTSPEED_1GBIT) 1598 + fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT; 1599 + if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT) 1600 + fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT; 1601 + 1602 + return 0; 1603 + } 1604 + EXPORT_SYMBOL(fc_lport_init);
+1291
drivers/scsi/libfc/fc_rport.c
··· 1 + /* 2 + * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. 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 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + /* 21 + * RPORT GENERAL INFO 22 + * 23 + * This file contains all processing regarding fc_rports. It contains the 24 + * rport state machine and does all rport interaction with the transport class. 25 + * There should be no other places in libfc that interact directly with the 26 + * transport class in regards to adding and deleting rports. 27 + * 28 + * fc_rport's represent N_Port's within the fabric. 29 + */ 30 + 31 + /* 32 + * RPORT LOCKING 33 + * 34 + * The rport should never hold the rport mutex and then attempt to acquire 35 + * either the lport or disc mutexes. The rport's mutex is considered lesser 36 + * than both the lport's mutex and the disc mutex. Refer to fc_lport.c for 37 + * more comments on the heirarchy. 38 + * 39 + * The locking strategy is similar to the lport's strategy. The lock protects 40 + * the rport's states and is held and released by the entry points to the rport 41 + * block. All _enter_* functions correspond to rport states and expect the rport 42 + * mutex to be locked before calling them. This means that rports only handle 43 + * one request or response at a time, since they're not critical for the I/O 44 + * path this potential over-use of the mutex is acceptable. 45 + */ 46 + 47 + #include <linux/kernel.h> 48 + #include <linux/spinlock.h> 49 + #include <linux/interrupt.h> 50 + #include <linux/rcupdate.h> 51 + #include <linux/timer.h> 52 + #include <linux/workqueue.h> 53 + #include <asm/unaligned.h> 54 + 55 + #include <scsi/libfc.h> 56 + #include <scsi/fc_encode.h> 57 + 58 + static int fc_rport_debug; 59 + 60 + #define FC_DEBUG_RPORT(fmt...) \ 61 + do { \ 62 + if (fc_rport_debug) \ 63 + FC_DBG(fmt); \ 64 + } while (0) 65 + 66 + struct workqueue_struct *rport_event_queue; 67 + 68 + static void fc_rport_enter_plogi(struct fc_rport *); 69 + static void fc_rport_enter_prli(struct fc_rport *); 70 + static void fc_rport_enter_rtv(struct fc_rport *); 71 + static void fc_rport_enter_ready(struct fc_rport *); 72 + static void fc_rport_enter_logo(struct fc_rport *); 73 + 74 + static void fc_rport_recv_plogi_req(struct fc_rport *, 75 + struct fc_seq *, struct fc_frame *); 76 + static void fc_rport_recv_prli_req(struct fc_rport *, 77 + struct fc_seq *, struct fc_frame *); 78 + static void fc_rport_recv_prlo_req(struct fc_rport *, 79 + struct fc_seq *, struct fc_frame *); 80 + static void fc_rport_recv_logo_req(struct fc_rport *, 81 + struct fc_seq *, struct fc_frame *); 82 + static void fc_rport_timeout(struct work_struct *); 83 + static void fc_rport_error(struct fc_rport *, struct fc_frame *); 84 + static void fc_rport_work(struct work_struct *); 85 + 86 + static const char *fc_rport_state_names[] = { 87 + [RPORT_ST_NONE] = "None", 88 + [RPORT_ST_INIT] = "Init", 89 + [RPORT_ST_PLOGI] = "PLOGI", 90 + [RPORT_ST_PRLI] = "PRLI", 91 + [RPORT_ST_RTV] = "RTV", 92 + [RPORT_ST_READY] = "Ready", 93 + [RPORT_ST_LOGO] = "LOGO", 94 + }; 95 + 96 + static void fc_rport_rogue_destroy(struct device *dev) 97 + { 98 + struct fc_rport *rport = dev_to_rport(dev); 99 + FC_DEBUG_RPORT("Destroying rogue rport (%6x)\n", rport->port_id); 100 + kfree(rport); 101 + } 102 + 103 + struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp) 104 + { 105 + struct fc_rport *rport; 106 + struct fc_rport_libfc_priv *rdata; 107 + rport = kzalloc(sizeof(*rport) + sizeof(*rdata), GFP_KERNEL); 108 + 109 + if (!rport) 110 + return NULL; 111 + 112 + rdata = RPORT_TO_PRIV(rport); 113 + 114 + rport->dd_data = rdata; 115 + rport->port_id = dp->ids.port_id; 116 + rport->port_name = dp->ids.port_name; 117 + rport->node_name = dp->ids.node_name; 118 + rport->roles = dp->ids.roles; 119 + rport->maxframe_size = FC_MIN_MAX_PAYLOAD; 120 + /* 121 + * Note: all this libfc rogue rport code will be removed for 122 + * upstream so it fine that this is really ugly and hacky right now. 123 + */ 124 + device_initialize(&rport->dev); 125 + rport->dev.release = fc_rport_rogue_destroy; 126 + 127 + mutex_init(&rdata->rp_mutex); 128 + rdata->local_port = dp->lp; 129 + rdata->trans_state = FC_PORTSTATE_ROGUE; 130 + rdata->rp_state = RPORT_ST_INIT; 131 + rdata->event = RPORT_EV_NONE; 132 + rdata->flags = FC_RP_FLAGS_REC_SUPPORTED; 133 + rdata->ops = NULL; 134 + rdata->e_d_tov = dp->lp->e_d_tov; 135 + rdata->r_a_tov = dp->lp->r_a_tov; 136 + INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout); 137 + INIT_WORK(&rdata->event_work, fc_rport_work); 138 + /* 139 + * For good measure, but not necessary as we should only 140 + * add REAL rport to the lport list. 141 + */ 142 + INIT_LIST_HEAD(&rdata->peers); 143 + 144 + return rport; 145 + } 146 + 147 + /** 148 + * fc_rport_state - return a string for the state the rport is in 149 + * @rport: The rport whose state we want to get a string for 150 + */ 151 + static const char *fc_rport_state(struct fc_rport *rport) 152 + { 153 + const char *cp; 154 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 155 + 156 + cp = fc_rport_state_names[rdata->rp_state]; 157 + if (!cp) 158 + cp = "Unknown"; 159 + return cp; 160 + } 161 + 162 + /** 163 + * fc_set_rport_loss_tmo - Set the remote port loss timeout in seconds. 164 + * @rport: Pointer to Fibre Channel remote port structure 165 + * @timeout: timeout in seconds 166 + */ 167 + void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) 168 + { 169 + if (timeout) 170 + rport->dev_loss_tmo = timeout + 5; 171 + else 172 + rport->dev_loss_tmo = 30; 173 + } 174 + EXPORT_SYMBOL(fc_set_rport_loss_tmo); 175 + 176 + /** 177 + * fc_plogi_get_maxframe - Get max payload from the common service parameters 178 + * @flp: FLOGI payload structure 179 + * @maxval: upper limit, may be less than what is in the service parameters 180 + */ 181 + static unsigned int 182 + fc_plogi_get_maxframe(struct fc_els_flogi *flp, unsigned int maxval) 183 + { 184 + unsigned int mfs; 185 + 186 + /* 187 + * Get max payload from the common service parameters and the 188 + * class 3 receive data field size. 189 + */ 190 + mfs = ntohs(flp->fl_csp.sp_bb_data) & FC_SP_BB_DATA_MASK; 191 + if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval) 192 + maxval = mfs; 193 + mfs = ntohs(flp->fl_cssp[3 - 1].cp_rdfs); 194 + if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval) 195 + maxval = mfs; 196 + return maxval; 197 + } 198 + 199 + /** 200 + * fc_rport_state_enter - Change the rport's state 201 + * @rport: The rport whose state should change 202 + * @new: The new state of the rport 203 + * 204 + * Locking Note: Called with the rport lock held 205 + */ 206 + static void fc_rport_state_enter(struct fc_rport *rport, 207 + enum fc_rport_state new) 208 + { 209 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 210 + if (rdata->rp_state != new) 211 + rdata->retries = 0; 212 + rdata->rp_state = new; 213 + } 214 + 215 + static void fc_rport_work(struct work_struct *work) 216 + { 217 + struct fc_rport_libfc_priv *rdata = 218 + container_of(work, struct fc_rport_libfc_priv, event_work); 219 + enum fc_rport_event event; 220 + enum fc_rport_trans_state trans_state; 221 + struct fc_lport *lport = rdata->local_port; 222 + struct fc_rport_operations *rport_ops; 223 + struct fc_rport *rport = PRIV_TO_RPORT(rdata); 224 + 225 + mutex_lock(&rdata->rp_mutex); 226 + event = rdata->event; 227 + rport_ops = rdata->ops; 228 + 229 + if (event == RPORT_EV_CREATED) { 230 + struct fc_rport *new_rport; 231 + struct fc_rport_libfc_priv *new_rdata; 232 + struct fc_rport_identifiers ids; 233 + 234 + ids.port_id = rport->port_id; 235 + ids.roles = rport->roles; 236 + ids.port_name = rport->port_name; 237 + ids.node_name = rport->node_name; 238 + 239 + mutex_unlock(&rdata->rp_mutex); 240 + 241 + new_rport = fc_remote_port_add(lport->host, 0, &ids); 242 + if (new_rport) { 243 + /* 244 + * Switch from the rogue rport to the rport 245 + * returned by the FC class. 246 + */ 247 + new_rport->maxframe_size = rport->maxframe_size; 248 + 249 + new_rdata = new_rport->dd_data; 250 + new_rdata->e_d_tov = rdata->e_d_tov; 251 + new_rdata->r_a_tov = rdata->r_a_tov; 252 + new_rdata->ops = rdata->ops; 253 + new_rdata->local_port = rdata->local_port; 254 + new_rdata->flags = FC_RP_FLAGS_REC_SUPPORTED; 255 + new_rdata->trans_state = FC_PORTSTATE_REAL; 256 + mutex_init(&new_rdata->rp_mutex); 257 + INIT_DELAYED_WORK(&new_rdata->retry_work, 258 + fc_rport_timeout); 259 + INIT_LIST_HEAD(&new_rdata->peers); 260 + INIT_WORK(&new_rdata->event_work, fc_rport_work); 261 + 262 + fc_rport_state_enter(new_rport, RPORT_ST_READY); 263 + } else { 264 + FC_DBG("Failed to create the rport for port " 265 + "(%6x).\n", ids.port_id); 266 + event = RPORT_EV_FAILED; 267 + } 268 + put_device(&rport->dev); 269 + rport = new_rport; 270 + rdata = new_rport->dd_data; 271 + if (rport_ops->event_callback) 272 + rport_ops->event_callback(lport, rport, event); 273 + } else if ((event == RPORT_EV_FAILED) || 274 + (event == RPORT_EV_LOGO) || 275 + (event == RPORT_EV_STOP)) { 276 + trans_state = rdata->trans_state; 277 + mutex_unlock(&rdata->rp_mutex); 278 + if (rport_ops->event_callback) 279 + rport_ops->event_callback(lport, rport, event); 280 + if (trans_state == FC_PORTSTATE_ROGUE) 281 + put_device(&rport->dev); 282 + else 283 + fc_remote_port_delete(rport); 284 + } else 285 + mutex_unlock(&rdata->rp_mutex); 286 + } 287 + 288 + /** 289 + * fc_rport_login - Start the remote port login state machine 290 + * @rport: Fibre Channel remote port 291 + * 292 + * Locking Note: Called without the rport lock held. This 293 + * function will hold the rport lock, call an _enter_* 294 + * function and then unlock the rport. 295 + */ 296 + int fc_rport_login(struct fc_rport *rport) 297 + { 298 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 299 + 300 + mutex_lock(&rdata->rp_mutex); 301 + 302 + FC_DEBUG_RPORT("Login to port (%6x)\n", rport->port_id); 303 + 304 + fc_rport_enter_plogi(rport); 305 + 306 + mutex_unlock(&rdata->rp_mutex); 307 + 308 + return 0; 309 + } 310 + 311 + /** 312 + * fc_rport_logoff - Logoff and remove an rport 313 + * @rport: Fibre Channel remote port to be removed 314 + * 315 + * Locking Note: Called without the rport lock held. This 316 + * function will hold the rport lock, call an _enter_* 317 + * function and then unlock the rport. 318 + */ 319 + int fc_rport_logoff(struct fc_rport *rport) 320 + { 321 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 322 + 323 + mutex_lock(&rdata->rp_mutex); 324 + 325 + FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id); 326 + 327 + fc_rport_enter_logo(rport); 328 + 329 + /* 330 + * Change the state to NONE so that we discard 331 + * the response. 332 + */ 333 + fc_rport_state_enter(rport, RPORT_ST_NONE); 334 + 335 + mutex_unlock(&rdata->rp_mutex); 336 + 337 + cancel_delayed_work_sync(&rdata->retry_work); 338 + 339 + mutex_lock(&rdata->rp_mutex); 340 + 341 + rdata->event = RPORT_EV_STOP; 342 + queue_work(rport_event_queue, &rdata->event_work); 343 + 344 + mutex_unlock(&rdata->rp_mutex); 345 + 346 + return 0; 347 + } 348 + 349 + /** 350 + * fc_rport_enter_ready - The rport is ready 351 + * @rport: Fibre Channel remote port that is ready 352 + * 353 + * Locking Note: The rport lock is expected to be held before calling 354 + * this routine. 355 + */ 356 + static void fc_rport_enter_ready(struct fc_rport *rport) 357 + { 358 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 359 + 360 + fc_rport_state_enter(rport, RPORT_ST_READY); 361 + 362 + FC_DEBUG_RPORT("Port (%6x) is Ready\n", rport->port_id); 363 + 364 + rdata->event = RPORT_EV_CREATED; 365 + queue_work(rport_event_queue, &rdata->event_work); 366 + } 367 + 368 + /** 369 + * fc_rport_timeout - Handler for the retry_work timer. 370 + * @work: The work struct of the fc_rport_libfc_priv 371 + * 372 + * Locking Note: Called without the rport lock held. This 373 + * function will hold the rport lock, call an _enter_* 374 + * function and then unlock the rport. 375 + */ 376 + static void fc_rport_timeout(struct work_struct *work) 377 + { 378 + struct fc_rport_libfc_priv *rdata = 379 + container_of(work, struct fc_rport_libfc_priv, retry_work.work); 380 + struct fc_rport *rport = PRIV_TO_RPORT(rdata); 381 + 382 + mutex_lock(&rdata->rp_mutex); 383 + 384 + switch (rdata->rp_state) { 385 + case RPORT_ST_PLOGI: 386 + fc_rport_enter_plogi(rport); 387 + break; 388 + case RPORT_ST_PRLI: 389 + fc_rport_enter_prli(rport); 390 + break; 391 + case RPORT_ST_RTV: 392 + fc_rport_enter_rtv(rport); 393 + break; 394 + case RPORT_ST_LOGO: 395 + fc_rport_enter_logo(rport); 396 + break; 397 + case RPORT_ST_READY: 398 + case RPORT_ST_INIT: 399 + case RPORT_ST_NONE: 400 + break; 401 + } 402 + 403 + mutex_unlock(&rdata->rp_mutex); 404 + put_device(&rport->dev); 405 + } 406 + 407 + /** 408 + * fc_rport_error - Handler for any errors 409 + * @rport: The fc_rport object 410 + * @fp: The frame pointer 411 + * 412 + * If the error was caused by a resource allocation failure 413 + * then wait for half a second and retry, otherwise retry 414 + * immediately. 415 + * 416 + * Locking Note: The rport lock is expected to be held before 417 + * calling this routine 418 + */ 419 + static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) 420 + { 421 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 422 + unsigned long delay = 0; 423 + 424 + FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n", 425 + PTR_ERR(fp), fc_rport_state(rport), rdata->retries); 426 + 427 + if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { 428 + /* 429 + * Memory allocation failure, or the exchange timed out. 430 + * Retry after delay 431 + */ 432 + if (rdata->retries < rdata->local_port->max_retry_count) { 433 + rdata->retries++; 434 + if (!fp) 435 + delay = msecs_to_jiffies(500); 436 + get_device(&rport->dev); 437 + schedule_delayed_work(&rdata->retry_work, delay); 438 + } else { 439 + switch (rdata->rp_state) { 440 + case RPORT_ST_PLOGI: 441 + case RPORT_ST_PRLI: 442 + case RPORT_ST_LOGO: 443 + rdata->event = RPORT_EV_FAILED; 444 + queue_work(rport_event_queue, 445 + &rdata->event_work); 446 + break; 447 + case RPORT_ST_RTV: 448 + fc_rport_enter_ready(rport); 449 + break; 450 + case RPORT_ST_NONE: 451 + case RPORT_ST_READY: 452 + case RPORT_ST_INIT: 453 + break; 454 + } 455 + } 456 + } 457 + } 458 + 459 + /** 460 + * fc_rport_plogi_recv_resp - Handle incoming ELS PLOGI response 461 + * @sp: current sequence in the PLOGI exchange 462 + * @fp: response frame 463 + * @rp_arg: Fibre Channel remote port 464 + * 465 + * Locking Note: This function will be called without the rport lock 466 + * held, but it will lock, call an _enter_* function or fc_rport_error 467 + * and then unlock the rport. 468 + */ 469 + static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, 470 + void *rp_arg) 471 + { 472 + struct fc_rport *rport = rp_arg; 473 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 474 + struct fc_lport *lport = rdata->local_port; 475 + struct fc_els_flogi *plp; 476 + unsigned int tov; 477 + u16 csp_seq; 478 + u16 cssp_seq; 479 + u8 op; 480 + 481 + mutex_lock(&rdata->rp_mutex); 482 + 483 + FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", 484 + rport->port_id); 485 + 486 + if (rdata->rp_state != RPORT_ST_PLOGI) { 487 + FC_DBG("Received a PLOGI response, but in state %s\n", 488 + fc_rport_state(rport)); 489 + goto out; 490 + } 491 + 492 + if (IS_ERR(fp)) { 493 + fc_rport_error(rport, fp); 494 + goto err; 495 + } 496 + 497 + op = fc_frame_payload_op(fp); 498 + if (op == ELS_LS_ACC && 499 + (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) { 500 + rport->port_name = get_unaligned_be64(&plp->fl_wwpn); 501 + rport->node_name = get_unaligned_be64(&plp->fl_wwnn); 502 + 503 + tov = ntohl(plp->fl_csp.sp_e_d_tov); 504 + if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR) 505 + tov /= 1000; 506 + if (tov > rdata->e_d_tov) 507 + rdata->e_d_tov = tov; 508 + csp_seq = ntohs(plp->fl_csp.sp_tot_seq); 509 + cssp_seq = ntohs(plp->fl_cssp[3 - 1].cp_con_seq); 510 + if (cssp_seq < csp_seq) 511 + csp_seq = cssp_seq; 512 + rdata->max_seq = csp_seq; 513 + rport->maxframe_size = 514 + fc_plogi_get_maxframe(plp, lport->mfs); 515 + 516 + /* 517 + * If the rport is one of the well known addresses 518 + * we skip PRLI and RTV and go straight to READY. 519 + */ 520 + if (rport->port_id >= FC_FID_DOM_MGR) 521 + fc_rport_enter_ready(rport); 522 + else 523 + fc_rport_enter_prli(rport); 524 + } else 525 + fc_rport_error(rport, fp); 526 + 527 + out: 528 + fc_frame_free(fp); 529 + err: 530 + mutex_unlock(&rdata->rp_mutex); 531 + put_device(&rport->dev); 532 + } 533 + 534 + /** 535 + * fc_rport_enter_plogi - Send Port Login (PLOGI) request to peer 536 + * @rport: Fibre Channel remote port to send PLOGI to 537 + * 538 + * Locking Note: The rport lock is expected to be held before calling 539 + * this routine. 540 + */ 541 + static void fc_rport_enter_plogi(struct fc_rport *rport) 542 + { 543 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 544 + struct fc_lport *lport = rdata->local_port; 545 + struct fc_frame *fp; 546 + 547 + FC_DEBUG_RPORT("Port (%6x) entered PLOGI state from %s state\n", 548 + rport->port_id, fc_rport_state(rport)); 549 + 550 + fc_rport_state_enter(rport, RPORT_ST_PLOGI); 551 + 552 + rport->maxframe_size = FC_MIN_MAX_PAYLOAD; 553 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); 554 + if (!fp) { 555 + fc_rport_error(rport, fp); 556 + return; 557 + } 558 + rdata->e_d_tov = lport->e_d_tov; 559 + 560 + if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI, 561 + fc_rport_plogi_resp, rport, lport->e_d_tov)) 562 + fc_rport_error(rport, fp); 563 + else 564 + get_device(&rport->dev); 565 + } 566 + 567 + /** 568 + * fc_rport_prli_resp - Process Login (PRLI) response handler 569 + * @sp: current sequence in the PRLI exchange 570 + * @fp: response frame 571 + * @rp_arg: Fibre Channel remote port 572 + * 573 + * Locking Note: This function will be called without the rport lock 574 + * held, but it will lock, call an _enter_* function or fc_rport_error 575 + * and then unlock the rport. 576 + */ 577 + static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, 578 + void *rp_arg) 579 + { 580 + struct fc_rport *rport = rp_arg; 581 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 582 + struct { 583 + struct fc_els_prli prli; 584 + struct fc_els_spp spp; 585 + } *pp; 586 + u32 roles = FC_RPORT_ROLE_UNKNOWN; 587 + u32 fcp_parm = 0; 588 + u8 op; 589 + 590 + mutex_lock(&rdata->rp_mutex); 591 + 592 + FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", 593 + rport->port_id); 594 + 595 + if (rdata->rp_state != RPORT_ST_PRLI) { 596 + FC_DBG("Received a PRLI response, but in state %s\n", 597 + fc_rport_state(rport)); 598 + goto out; 599 + } 600 + 601 + if (IS_ERR(fp)) { 602 + fc_rport_error(rport, fp); 603 + goto err; 604 + } 605 + 606 + op = fc_frame_payload_op(fp); 607 + if (op == ELS_LS_ACC) { 608 + pp = fc_frame_payload_get(fp, sizeof(*pp)); 609 + if (pp && pp->prli.prli_spp_len >= sizeof(pp->spp)) { 610 + fcp_parm = ntohl(pp->spp.spp_params); 611 + if (fcp_parm & FCP_SPPF_RETRY) 612 + rdata->flags |= FC_RP_FLAGS_RETRY; 613 + } 614 + 615 + rport->supported_classes = FC_COS_CLASS3; 616 + if (fcp_parm & FCP_SPPF_INIT_FCN) 617 + roles |= FC_RPORT_ROLE_FCP_INITIATOR; 618 + if (fcp_parm & FCP_SPPF_TARG_FCN) 619 + roles |= FC_RPORT_ROLE_FCP_TARGET; 620 + 621 + rport->roles = roles; 622 + fc_rport_enter_rtv(rport); 623 + 624 + } else { 625 + FC_DBG("Bad ELS response\n"); 626 + rdata->event = RPORT_EV_FAILED; 627 + queue_work(rport_event_queue, &rdata->event_work); 628 + } 629 + 630 + out: 631 + fc_frame_free(fp); 632 + err: 633 + mutex_unlock(&rdata->rp_mutex); 634 + put_device(&rport->dev); 635 + } 636 + 637 + /** 638 + * fc_rport_logo_resp - Logout (LOGO) response handler 639 + * @sp: current sequence in the LOGO exchange 640 + * @fp: response frame 641 + * @rp_arg: Fibre Channel remote port 642 + * 643 + * Locking Note: This function will be called without the rport lock 644 + * held, but it will lock, call an _enter_* function or fc_rport_error 645 + * and then unlock the rport. 646 + */ 647 + static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, 648 + void *rp_arg) 649 + { 650 + struct fc_rport *rport = rp_arg; 651 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 652 + u8 op; 653 + 654 + mutex_lock(&rdata->rp_mutex); 655 + 656 + FC_DEBUG_RPORT("Received a LOGO response from port (%6x)\n", 657 + rport->port_id); 658 + 659 + if (IS_ERR(fp)) { 660 + fc_rport_error(rport, fp); 661 + goto err; 662 + } 663 + 664 + if (rdata->rp_state != RPORT_ST_LOGO) { 665 + FC_DEBUG_RPORT("Received a LOGO response, but in state %s\n", 666 + fc_rport_state(rport)); 667 + goto out; 668 + } 669 + 670 + op = fc_frame_payload_op(fp); 671 + if (op == ELS_LS_ACC) { 672 + fc_rport_enter_rtv(rport); 673 + } else { 674 + FC_DBG("Bad ELS response\n"); 675 + rdata->event = RPORT_EV_LOGO; 676 + queue_work(rport_event_queue, &rdata->event_work); 677 + } 678 + 679 + out: 680 + fc_frame_free(fp); 681 + err: 682 + mutex_unlock(&rdata->rp_mutex); 683 + put_device(&rport->dev); 684 + } 685 + 686 + /** 687 + * fc_rport_enter_prli - Send Process Login (PRLI) request to peer 688 + * @rport: Fibre Channel remote port to send PRLI to 689 + * 690 + * Locking Note: The rport lock is expected to be held before calling 691 + * this routine. 692 + */ 693 + static void fc_rport_enter_prli(struct fc_rport *rport) 694 + { 695 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 696 + struct fc_lport *lport = rdata->local_port; 697 + struct { 698 + struct fc_els_prli prli; 699 + struct fc_els_spp spp; 700 + } *pp; 701 + struct fc_frame *fp; 702 + 703 + FC_DEBUG_RPORT("Port (%6x) entered PRLI state from %s state\n", 704 + rport->port_id, fc_rport_state(rport)); 705 + 706 + fc_rport_state_enter(rport, RPORT_ST_PRLI); 707 + 708 + fp = fc_frame_alloc(lport, sizeof(*pp)); 709 + if (!fp) { 710 + fc_rport_error(rport, fp); 711 + return; 712 + } 713 + 714 + if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI, 715 + fc_rport_prli_resp, rport, lport->e_d_tov)) 716 + fc_rport_error(rport, fp); 717 + else 718 + get_device(&rport->dev); 719 + } 720 + 721 + /** 722 + * fc_rport_els_rtv_resp - Request Timeout Value response handler 723 + * @sp: current sequence in the RTV exchange 724 + * @fp: response frame 725 + * @rp_arg: Fibre Channel remote port 726 + * 727 + * Many targets don't seem to support this. 728 + * 729 + * Locking Note: This function will be called without the rport lock 730 + * held, but it will lock, call an _enter_* function or fc_rport_error 731 + * and then unlock the rport. 732 + */ 733 + static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, 734 + void *rp_arg) 735 + { 736 + struct fc_rport *rport = rp_arg; 737 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 738 + u8 op; 739 + 740 + mutex_lock(&rdata->rp_mutex); 741 + 742 + FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", 743 + rport->port_id); 744 + 745 + if (rdata->rp_state != RPORT_ST_RTV) { 746 + FC_DBG("Received a RTV response, but in state %s\n", 747 + fc_rport_state(rport)); 748 + goto out; 749 + } 750 + 751 + if (IS_ERR(fp)) { 752 + fc_rport_error(rport, fp); 753 + goto err; 754 + } 755 + 756 + op = fc_frame_payload_op(fp); 757 + if (op == ELS_LS_ACC) { 758 + struct fc_els_rtv_acc *rtv; 759 + u32 toq; 760 + u32 tov; 761 + 762 + rtv = fc_frame_payload_get(fp, sizeof(*rtv)); 763 + if (rtv) { 764 + toq = ntohl(rtv->rtv_toq); 765 + tov = ntohl(rtv->rtv_r_a_tov); 766 + if (tov == 0) 767 + tov = 1; 768 + rdata->r_a_tov = tov; 769 + tov = ntohl(rtv->rtv_e_d_tov); 770 + if (toq & FC_ELS_RTV_EDRES) 771 + tov /= 1000000; 772 + if (tov == 0) 773 + tov = 1; 774 + rdata->e_d_tov = tov; 775 + } 776 + } 777 + 778 + fc_rport_enter_ready(rport); 779 + 780 + out: 781 + fc_frame_free(fp); 782 + err: 783 + mutex_unlock(&rdata->rp_mutex); 784 + put_device(&rport->dev); 785 + } 786 + 787 + /** 788 + * fc_rport_enter_rtv - Send Request Timeout Value (RTV) request to peer 789 + * @rport: Fibre Channel remote port to send RTV to 790 + * 791 + * Locking Note: The rport lock is expected to be held before calling 792 + * this routine. 793 + */ 794 + static void fc_rport_enter_rtv(struct fc_rport *rport) 795 + { 796 + struct fc_frame *fp; 797 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 798 + struct fc_lport *lport = rdata->local_port; 799 + 800 + FC_DEBUG_RPORT("Port (%6x) entered RTV state from %s state\n", 801 + rport->port_id, fc_rport_state(rport)); 802 + 803 + fc_rport_state_enter(rport, RPORT_ST_RTV); 804 + 805 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv)); 806 + if (!fp) { 807 + fc_rport_error(rport, fp); 808 + return; 809 + } 810 + 811 + if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV, 812 + fc_rport_rtv_resp, rport, lport->e_d_tov)) 813 + fc_rport_error(rport, fp); 814 + else 815 + get_device(&rport->dev); 816 + } 817 + 818 + /** 819 + * fc_rport_enter_logo - Send Logout (LOGO) request to peer 820 + * @rport: Fibre Channel remote port to send LOGO to 821 + * 822 + * Locking Note: The rport lock is expected to be held before calling 823 + * this routine. 824 + */ 825 + static void fc_rport_enter_logo(struct fc_rport *rport) 826 + { 827 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 828 + struct fc_lport *lport = rdata->local_port; 829 + struct fc_frame *fp; 830 + 831 + FC_DEBUG_RPORT("Port (%6x) entered LOGO state from %s state\n", 832 + rport->port_id, fc_rport_state(rport)); 833 + 834 + fc_rport_state_enter(rport, RPORT_ST_LOGO); 835 + 836 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo)); 837 + if (!fp) { 838 + fc_rport_error(rport, fp); 839 + return; 840 + } 841 + 842 + if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO, 843 + fc_rport_logo_resp, rport, lport->e_d_tov)) 844 + fc_rport_error(rport, fp); 845 + else 846 + get_device(&rport->dev); 847 + } 848 + 849 + 850 + /** 851 + * fc_rport_recv_req - Receive a request from a rport 852 + * @sp: current sequence in the PLOGI exchange 853 + * @fp: response frame 854 + * @rp_arg: Fibre Channel remote port 855 + * 856 + * Locking Note: Called without the rport lock held. This 857 + * function will hold the rport lock, call an _enter_* 858 + * function and then unlock the rport. 859 + */ 860 + void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp, 861 + struct fc_rport *rport) 862 + { 863 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 864 + struct fc_lport *lport = rdata->local_port; 865 + 866 + struct fc_frame_header *fh; 867 + struct fc_seq_els_data els_data; 868 + u8 op; 869 + 870 + mutex_lock(&rdata->rp_mutex); 871 + 872 + els_data.fp = NULL; 873 + els_data.explan = ELS_EXPL_NONE; 874 + els_data.reason = ELS_RJT_NONE; 875 + 876 + fh = fc_frame_header_get(fp); 877 + 878 + if (fh->fh_r_ctl == FC_RCTL_ELS_REQ && fh->fh_type == FC_TYPE_ELS) { 879 + op = fc_frame_payload_op(fp); 880 + switch (op) { 881 + case ELS_PLOGI: 882 + fc_rport_recv_plogi_req(rport, sp, fp); 883 + break; 884 + case ELS_PRLI: 885 + fc_rport_recv_prli_req(rport, sp, fp); 886 + break; 887 + case ELS_PRLO: 888 + fc_rport_recv_prlo_req(rport, sp, fp); 889 + break; 890 + case ELS_LOGO: 891 + fc_rport_recv_logo_req(rport, sp, fp); 892 + break; 893 + case ELS_RRQ: 894 + els_data.fp = fp; 895 + lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data); 896 + break; 897 + case ELS_REC: 898 + els_data.fp = fp; 899 + lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data); 900 + break; 901 + default: 902 + els_data.reason = ELS_RJT_UNSUP; 903 + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data); 904 + break; 905 + } 906 + } 907 + 908 + mutex_unlock(&rdata->rp_mutex); 909 + } 910 + 911 + /** 912 + * fc_rport_recv_plogi_req - Handle incoming Port Login (PLOGI) request 913 + * @rport: Fibre Channel remote port that initiated PLOGI 914 + * @sp: current sequence in the PLOGI exchange 915 + * @fp: PLOGI request frame 916 + * 917 + * Locking Note: The rport lock is exected to be held before calling 918 + * this function. 919 + */ 920 + static void fc_rport_recv_plogi_req(struct fc_rport *rport, 921 + struct fc_seq *sp, struct fc_frame *rx_fp) 922 + { 923 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 924 + struct fc_lport *lport = rdata->local_port; 925 + struct fc_frame *fp = rx_fp; 926 + struct fc_exch *ep; 927 + struct fc_frame_header *fh; 928 + struct fc_els_flogi *pl; 929 + struct fc_seq_els_data rjt_data; 930 + u32 sid; 931 + u64 wwpn; 932 + u64 wwnn; 933 + enum fc_els_rjt_reason reject = 0; 934 + u32 f_ctl; 935 + rjt_data.fp = NULL; 936 + 937 + fh = fc_frame_header_get(fp); 938 + 939 + FC_DEBUG_RPORT("Received PLOGI request from port (%6x) " 940 + "while in state %s\n", ntoh24(fh->fh_s_id), 941 + fc_rport_state(rport)); 942 + 943 + sid = ntoh24(fh->fh_s_id); 944 + pl = fc_frame_payload_get(fp, sizeof(*pl)); 945 + if (!pl) { 946 + FC_DBG("incoming PLOGI from %x too short\n", sid); 947 + WARN_ON(1); 948 + /* XXX TBD: send reject? */ 949 + fc_frame_free(fp); 950 + return; 951 + } 952 + wwpn = get_unaligned_be64(&pl->fl_wwpn); 953 + wwnn = get_unaligned_be64(&pl->fl_wwnn); 954 + 955 + /* 956 + * If the session was just created, possibly due to the incoming PLOGI, 957 + * set the state appropriately and accept the PLOGI. 958 + * 959 + * If we had also sent a PLOGI, and if the received PLOGI is from a 960 + * higher WWPN, we accept it, otherwise an LS_RJT is sent with reason 961 + * "command already in progress". 962 + * 963 + * XXX TBD: If the session was ready before, the PLOGI should result in 964 + * all outstanding exchanges being reset. 965 + */ 966 + switch (rdata->rp_state) { 967 + case RPORT_ST_INIT: 968 + FC_DEBUG_RPORT("incoming PLOGI from %6x wwpn %llx state INIT " 969 + "- reject\n", sid, wwpn); 970 + reject = ELS_RJT_UNSUP; 971 + break; 972 + case RPORT_ST_PLOGI: 973 + FC_DEBUG_RPORT("incoming PLOGI from %x in PLOGI state %d\n", 974 + sid, rdata->rp_state); 975 + if (wwpn < lport->wwpn) 976 + reject = ELS_RJT_INPROG; 977 + break; 978 + case RPORT_ST_PRLI: 979 + case RPORT_ST_READY: 980 + FC_DEBUG_RPORT("incoming PLOGI from %x in logged-in state %d " 981 + "- ignored for now\n", sid, rdata->rp_state); 982 + /* XXX TBD - should reset */ 983 + break; 984 + case RPORT_ST_NONE: 985 + default: 986 + FC_DEBUG_RPORT("incoming PLOGI from %x in unexpected " 987 + "state %d\n", sid, rdata->rp_state); 988 + break; 989 + } 990 + 991 + if (reject) { 992 + rjt_data.reason = reject; 993 + rjt_data.explan = ELS_EXPL_NONE; 994 + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 995 + fc_frame_free(fp); 996 + } else { 997 + fp = fc_frame_alloc(lport, sizeof(*pl)); 998 + if (fp == NULL) { 999 + fp = rx_fp; 1000 + rjt_data.reason = ELS_RJT_UNAB; 1001 + rjt_data.explan = ELS_EXPL_NONE; 1002 + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 1003 + fc_frame_free(fp); 1004 + } else { 1005 + sp = lport->tt.seq_start_next(sp); 1006 + WARN_ON(!sp); 1007 + fc_rport_set_name(rport, wwpn, wwnn); 1008 + 1009 + /* 1010 + * Get session payload size from incoming PLOGI. 1011 + */ 1012 + rport->maxframe_size = 1013 + fc_plogi_get_maxframe(pl, lport->mfs); 1014 + fc_frame_free(rx_fp); 1015 + fc_plogi_fill(lport, fp, ELS_LS_ACC); 1016 + 1017 + /* 1018 + * Send LS_ACC. If this fails, 1019 + * the originator should retry. 1020 + */ 1021 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 1022 + f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1023 + ep = fc_seq_exch(sp); 1024 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1025 + FC_TYPE_ELS, f_ctl, 0); 1026 + lport->tt.seq_send(lport, sp, fp); 1027 + if (rdata->rp_state == RPORT_ST_PLOGI) 1028 + fc_rport_enter_prli(rport); 1029 + } 1030 + } 1031 + } 1032 + 1033 + /** 1034 + * fc_rport_recv_prli_req - Handle incoming Process Login (PRLI) request 1035 + * @rport: Fibre Channel remote port that initiated PRLI 1036 + * @sp: current sequence in the PRLI exchange 1037 + * @fp: PRLI request frame 1038 + * 1039 + * Locking Note: The rport lock is exected to be held before calling 1040 + * this function. 1041 + */ 1042 + static void fc_rport_recv_prli_req(struct fc_rport *rport, 1043 + struct fc_seq *sp, struct fc_frame *rx_fp) 1044 + { 1045 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 1046 + struct fc_lport *lport = rdata->local_port; 1047 + struct fc_exch *ep; 1048 + struct fc_frame *fp; 1049 + struct fc_frame_header *fh; 1050 + struct { 1051 + struct fc_els_prli prli; 1052 + struct fc_els_spp spp; 1053 + } *pp; 1054 + struct fc_els_spp *rspp; /* request service param page */ 1055 + struct fc_els_spp *spp; /* response spp */ 1056 + unsigned int len; 1057 + unsigned int plen; 1058 + enum fc_els_rjt_reason reason = ELS_RJT_UNAB; 1059 + enum fc_els_rjt_explan explan = ELS_EXPL_NONE; 1060 + enum fc_els_spp_resp resp; 1061 + struct fc_seq_els_data rjt_data; 1062 + u32 f_ctl; 1063 + u32 fcp_parm; 1064 + u32 roles = FC_RPORT_ROLE_UNKNOWN; 1065 + rjt_data.fp = NULL; 1066 + 1067 + fh = fc_frame_header_get(rx_fp); 1068 + 1069 + FC_DEBUG_RPORT("Received PRLI request from port (%6x) " 1070 + "while in state %s\n", ntoh24(fh->fh_s_id), 1071 + fc_rport_state(rport)); 1072 + 1073 + switch (rdata->rp_state) { 1074 + case RPORT_ST_PRLI: 1075 + case RPORT_ST_READY: 1076 + reason = ELS_RJT_NONE; 1077 + break; 1078 + default: 1079 + break; 1080 + } 1081 + len = fr_len(rx_fp) - sizeof(*fh); 1082 + pp = fc_frame_payload_get(rx_fp, sizeof(*pp)); 1083 + if (pp == NULL) { 1084 + reason = ELS_RJT_PROT; 1085 + explan = ELS_EXPL_INV_LEN; 1086 + } else { 1087 + plen = ntohs(pp->prli.prli_len); 1088 + if ((plen % 4) != 0 || plen > len) { 1089 + reason = ELS_RJT_PROT; 1090 + explan = ELS_EXPL_INV_LEN; 1091 + } else if (plen < len) { 1092 + len = plen; 1093 + } 1094 + plen = pp->prli.prli_spp_len; 1095 + if ((plen % 4) != 0 || plen < sizeof(*spp) || 1096 + plen > len || len < sizeof(*pp)) { 1097 + reason = ELS_RJT_PROT; 1098 + explan = ELS_EXPL_INV_LEN; 1099 + } 1100 + rspp = &pp->spp; 1101 + } 1102 + if (reason != ELS_RJT_NONE || 1103 + (fp = fc_frame_alloc(lport, len)) == NULL) { 1104 + rjt_data.reason = reason; 1105 + rjt_data.explan = explan; 1106 + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 1107 + } else { 1108 + sp = lport->tt.seq_start_next(sp); 1109 + WARN_ON(!sp); 1110 + pp = fc_frame_payload_get(fp, len); 1111 + WARN_ON(!pp); 1112 + memset(pp, 0, len); 1113 + pp->prli.prli_cmd = ELS_LS_ACC; 1114 + pp->prli.prli_spp_len = plen; 1115 + pp->prli.prli_len = htons(len); 1116 + len -= sizeof(struct fc_els_prli); 1117 + 1118 + /* 1119 + * Go through all the service parameter pages and build 1120 + * response. If plen indicates longer SPP than standard, 1121 + * use that. The entire response has been pre-cleared above. 1122 + */ 1123 + spp = &pp->spp; 1124 + while (len >= plen) { 1125 + spp->spp_type = rspp->spp_type; 1126 + spp->spp_type_ext = rspp->spp_type_ext; 1127 + spp->spp_flags = rspp->spp_flags & FC_SPP_EST_IMG_PAIR; 1128 + resp = FC_SPP_RESP_ACK; 1129 + if (rspp->spp_flags & FC_SPP_RPA_VAL) 1130 + resp = FC_SPP_RESP_NO_PA; 1131 + switch (rspp->spp_type) { 1132 + case 0: /* common to all FC-4 types */ 1133 + break; 1134 + case FC_TYPE_FCP: 1135 + fcp_parm = ntohl(rspp->spp_params); 1136 + if (fcp_parm * FCP_SPPF_RETRY) 1137 + rdata->flags |= FC_RP_FLAGS_RETRY; 1138 + rport->supported_classes = FC_COS_CLASS3; 1139 + if (fcp_parm & FCP_SPPF_INIT_FCN) 1140 + roles |= FC_RPORT_ROLE_FCP_INITIATOR; 1141 + if (fcp_parm & FCP_SPPF_TARG_FCN) 1142 + roles |= FC_RPORT_ROLE_FCP_TARGET; 1143 + rport->roles = roles; 1144 + 1145 + spp->spp_params = 1146 + htonl(lport->service_params); 1147 + break; 1148 + default: 1149 + resp = FC_SPP_RESP_INVL; 1150 + break; 1151 + } 1152 + spp->spp_flags |= resp; 1153 + len -= plen; 1154 + rspp = (struct fc_els_spp *)((char *)rspp + plen); 1155 + spp = (struct fc_els_spp *)((char *)spp + plen); 1156 + } 1157 + 1158 + /* 1159 + * Send LS_ACC. If this fails, the originator should retry. 1160 + */ 1161 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 1162 + f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1163 + ep = fc_seq_exch(sp); 1164 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1165 + FC_TYPE_ELS, f_ctl, 0); 1166 + lport->tt.seq_send(lport, sp, fp); 1167 + 1168 + /* 1169 + * Get lock and re-check state. 1170 + */ 1171 + switch (rdata->rp_state) { 1172 + case RPORT_ST_PRLI: 1173 + fc_rport_enter_ready(rport); 1174 + break; 1175 + case RPORT_ST_READY: 1176 + break; 1177 + default: 1178 + break; 1179 + } 1180 + } 1181 + fc_frame_free(rx_fp); 1182 + } 1183 + 1184 + /** 1185 + * fc_rport_recv_prlo_req - Handle incoming Process Logout (PRLO) request 1186 + * @rport: Fibre Channel remote port that initiated PRLO 1187 + * @sp: current sequence in the PRLO exchange 1188 + * @fp: PRLO request frame 1189 + * 1190 + * Locking Note: The rport lock is exected to be held before calling 1191 + * this function. 1192 + */ 1193 + static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp, 1194 + struct fc_frame *fp) 1195 + { 1196 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 1197 + struct fc_lport *lport = rdata->local_port; 1198 + 1199 + struct fc_frame_header *fh; 1200 + struct fc_seq_els_data rjt_data; 1201 + 1202 + fh = fc_frame_header_get(fp); 1203 + 1204 + FC_DEBUG_RPORT("Received PRLO request from port (%6x) " 1205 + "while in state %s\n", ntoh24(fh->fh_s_id), 1206 + fc_rport_state(rport)); 1207 + 1208 + rjt_data.fp = NULL; 1209 + rjt_data.reason = ELS_RJT_UNAB; 1210 + rjt_data.explan = ELS_EXPL_NONE; 1211 + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 1212 + fc_frame_free(fp); 1213 + } 1214 + 1215 + /** 1216 + * fc_rport_recv_logo_req - Handle incoming Logout (LOGO) request 1217 + * @rport: Fibre Channel remote port that initiated LOGO 1218 + * @sp: current sequence in the LOGO exchange 1219 + * @fp: LOGO request frame 1220 + * 1221 + * Locking Note: The rport lock is exected to be held before calling 1222 + * this function. 1223 + */ 1224 + static void fc_rport_recv_logo_req(struct fc_rport *rport, struct fc_seq *sp, 1225 + struct fc_frame *fp) 1226 + { 1227 + struct fc_frame_header *fh; 1228 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 1229 + struct fc_lport *lport = rdata->local_port; 1230 + 1231 + fh = fc_frame_header_get(fp); 1232 + 1233 + FC_DEBUG_RPORT("Received LOGO request from port (%6x) " 1234 + "while in state %s\n", ntoh24(fh->fh_s_id), 1235 + fc_rport_state(rport)); 1236 + 1237 + rdata->event = RPORT_EV_LOGO; 1238 + queue_work(rport_event_queue, &rdata->event_work); 1239 + 1240 + lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); 1241 + fc_frame_free(fp); 1242 + } 1243 + 1244 + static void fc_rport_flush_queue(void) 1245 + { 1246 + flush_workqueue(rport_event_queue); 1247 + } 1248 + 1249 + 1250 + int fc_rport_init(struct fc_lport *lport) 1251 + { 1252 + if (!lport->tt.rport_login) 1253 + lport->tt.rport_login = fc_rport_login; 1254 + 1255 + if (!lport->tt.rport_logoff) 1256 + lport->tt.rport_logoff = fc_rport_logoff; 1257 + 1258 + if (!lport->tt.rport_recv_req) 1259 + lport->tt.rport_recv_req = fc_rport_recv_req; 1260 + 1261 + if (!lport->tt.rport_flush_queue) 1262 + lport->tt.rport_flush_queue = fc_rport_flush_queue; 1263 + 1264 + return 0; 1265 + } 1266 + EXPORT_SYMBOL(fc_rport_init); 1267 + 1268 + int fc_setup_rport() 1269 + { 1270 + rport_event_queue = create_singlethread_workqueue("fc_rport_eq"); 1271 + if (!rport_event_queue) 1272 + return -ENOMEM; 1273 + return 0; 1274 + } 1275 + EXPORT_SYMBOL(fc_setup_rport); 1276 + 1277 + void fc_destroy_rport() 1278 + { 1279 + destroy_workqueue(rport_event_queue); 1280 + } 1281 + EXPORT_SYMBOL(fc_destroy_rport); 1282 + 1283 + void fc_rport_terminate_io(struct fc_rport *rport) 1284 + { 1285 + struct fc_rport_libfc_priv *rdata = rport->dd_data; 1286 + struct fc_lport *lport = rdata->local_port; 1287 + 1288 + lport->tt.exch_mgr_reset(lport->emp, 0, rport->port_id); 1289 + lport->tt.exch_mgr_reset(lport->emp, rport->port_id, 0); 1290 + } 1291 + EXPORT_SYMBOL(fc_rport_terminate_io);
+309
include/scsi/fc_encode.h
··· 1 + /* 2 + * Copyright(c) 2008 Intel Corporation. All rights reserved. 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 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + #ifndef _FC_ENCODE_H_ 21 + #define _FC_ENCODE_H_ 22 + #include <asm/unaligned.h> 23 + 24 + struct fc_ns_rft { 25 + struct fc_ns_fid fid; /* port ID object */ 26 + struct fc_ns_fts fts; /* FC4-types object */ 27 + }; 28 + 29 + struct fc_ct_req { 30 + struct fc_ct_hdr hdr; 31 + union { 32 + struct fc_ns_gid_ft gid; 33 + struct fc_ns_rn_id rn; 34 + struct fc_ns_rft rft; 35 + } payload; 36 + }; 37 + 38 + /** 39 + * fill FC header fields in specified fc_frame 40 + */ 41 + static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, 42 + u32 did, u32 sid, enum fc_fh_type type, 43 + u32 f_ctl, u32 parm_offset) 44 + { 45 + struct fc_frame_header *fh; 46 + 47 + fh = fc_frame_header_get(fp); 48 + WARN_ON(r_ctl == 0); 49 + fh->fh_r_ctl = r_ctl; 50 + hton24(fh->fh_d_id, did); 51 + hton24(fh->fh_s_id, sid); 52 + fh->fh_type = type; 53 + hton24(fh->fh_f_ctl, f_ctl); 54 + fh->fh_cs_ctl = 0; 55 + fh->fh_df_ctl = 0; 56 + fh->fh_parm_offset = htonl(parm_offset); 57 + } 58 + 59 + /** 60 + * fc_ct_hdr_fill- fills ct header and reset ct payload 61 + * returns pointer to ct request. 62 + */ 63 + static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, 64 + unsigned int op, size_t req_size) 65 + { 66 + struct fc_ct_req *ct; 67 + size_t ct_plen; 68 + 69 + ct_plen = sizeof(struct fc_ct_hdr) + req_size; 70 + ct = fc_frame_payload_get(fp, ct_plen); 71 + memset(ct, 0, ct_plen); 72 + ct->hdr.ct_rev = FC_CT_REV; 73 + ct->hdr.ct_fs_type = FC_FST_DIR; 74 + ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE; 75 + ct->hdr.ct_cmd = htons((u16) op); 76 + return ct; 77 + } 78 + 79 + /** 80 + * fc_ct_fill - Fill in a name service request frame 81 + */ 82 + static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp, 83 + unsigned int op, enum fc_rctl *r_ctl, u32 *did, 84 + enum fc_fh_type *fh_type) 85 + { 86 + struct fc_ct_req *ct; 87 + 88 + switch (op) { 89 + case FC_NS_GPN_FT: 90 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft)); 91 + ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; 92 + break; 93 + 94 + case FC_NS_RFT_ID: 95 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); 96 + hton24(ct->payload.rft.fid.fp_fid, 97 + fc_host_port_id(lport->host)); 98 + ct->payload.rft.fts = lport->fcts; 99 + break; 100 + 101 + case FC_NS_RPN_ID: 102 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); 103 + hton24(ct->payload.rn.fr_fid.fp_fid, 104 + fc_host_port_id(lport->host)); 105 + ct->payload.rft.fts = lport->fcts; 106 + put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn); 107 + break; 108 + 109 + default: 110 + FC_DBG("Invalid op code %x \n", op); 111 + return -EINVAL; 112 + } 113 + *r_ctl = FC_RCTL_DD_UNSOL_CTL; 114 + *did = FC_FID_DIR_SERV; 115 + *fh_type = FC_TYPE_CT; 116 + return 0; 117 + } 118 + 119 + /** 120 + * fc_plogi_fill - Fill in plogi request frame 121 + */ 122 + static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp, 123 + unsigned int op) 124 + { 125 + struct fc_els_flogi *plogi; 126 + struct fc_els_csp *csp; 127 + struct fc_els_cssp *cp; 128 + 129 + plogi = fc_frame_payload_get(fp, sizeof(*plogi)); 130 + memset(plogi, 0, sizeof(*plogi)); 131 + plogi->fl_cmd = (u8) op; 132 + put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn); 133 + put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn); 134 + 135 + csp = &plogi->fl_csp; 136 + csp->sp_hi_ver = 0x20; 137 + csp->sp_lo_ver = 0x20; 138 + csp->sp_bb_cred = htons(10); /* this gets set by gateway */ 139 + csp->sp_bb_data = htons((u16) lport->mfs); 140 + cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */ 141 + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 142 + csp->sp_features = htons(FC_SP_FT_CIRO); 143 + csp->sp_tot_seq = htons(255); /* seq. we accept */ 144 + csp->sp_rel_off = htons(0x1f); 145 + csp->sp_e_d_tov = htonl(lport->e_d_tov); 146 + 147 + cp->cp_rdfs = htons((u16) lport->mfs); 148 + cp->cp_con_seq = htons(255); 149 + cp->cp_open_seq = 1; 150 + } 151 + 152 + /** 153 + * fc_flogi_fill - Fill in a flogi request frame. 154 + */ 155 + static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp) 156 + { 157 + struct fc_els_csp *sp; 158 + struct fc_els_cssp *cp; 159 + struct fc_els_flogi *flogi; 160 + 161 + flogi = fc_frame_payload_get(fp, sizeof(*flogi)); 162 + memset(flogi, 0, sizeof(*flogi)); 163 + flogi->fl_cmd = (u8) ELS_FLOGI; 164 + put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn); 165 + put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn); 166 + sp = &flogi->fl_csp; 167 + sp->sp_hi_ver = 0x20; 168 + sp->sp_lo_ver = 0x20; 169 + sp->sp_bb_cred = htons(10); /* this gets set by gateway */ 170 + sp->sp_bb_data = htons((u16) lport->mfs); 171 + cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ 172 + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 173 + } 174 + 175 + /** 176 + * fc_logo_fill - Fill in a logo request frame. 177 + */ 178 + static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp) 179 + { 180 + struct fc_els_logo *logo; 181 + 182 + logo = fc_frame_payload_get(fp, sizeof(*logo)); 183 + memset(logo, 0, sizeof(*logo)); 184 + logo->fl_cmd = ELS_LOGO; 185 + hton24(logo->fl_n_port_id, fc_host_port_id(lport->host)); 186 + logo->fl_n_port_wwn = htonll(lport->wwpn); 187 + } 188 + 189 + /** 190 + * fc_rtv_fill - Fill in RTV (read timeout value) request frame. 191 + */ 192 + static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp) 193 + { 194 + struct fc_els_rtv *rtv; 195 + 196 + rtv = fc_frame_payload_get(fp, sizeof(*rtv)); 197 + memset(rtv, 0, sizeof(*rtv)); 198 + rtv->rtv_cmd = ELS_RTV; 199 + } 200 + 201 + /** 202 + * fc_rec_fill - Fill in rec request frame 203 + */ 204 + static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp) 205 + { 206 + struct fc_els_rec *rec; 207 + struct fc_exch *ep = fc_seq_exch(fr_seq(fp)); 208 + 209 + rec = fc_frame_payload_get(fp, sizeof(*rec)); 210 + memset(rec, 0, sizeof(*rec)); 211 + rec->rec_cmd = ELS_REC; 212 + hton24(rec->rec_s_id, fc_host_port_id(lport->host)); 213 + rec->rec_ox_id = htons(ep->oxid); 214 + rec->rec_rx_id = htons(ep->rxid); 215 + } 216 + 217 + /** 218 + * fc_prli_fill - Fill in prli request frame 219 + */ 220 + static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp) 221 + { 222 + struct { 223 + struct fc_els_prli prli; 224 + struct fc_els_spp spp; 225 + } *pp; 226 + 227 + pp = fc_frame_payload_get(fp, sizeof(*pp)); 228 + memset(pp, 0, sizeof(*pp)); 229 + pp->prli.prli_cmd = ELS_PRLI; 230 + pp->prli.prli_spp_len = sizeof(struct fc_els_spp); 231 + pp->prli.prli_len = htons(sizeof(*pp)); 232 + pp->spp.spp_type = FC_TYPE_FCP; 233 + pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR; 234 + pp->spp.spp_params = htonl(lport->service_params); 235 + } 236 + 237 + /** 238 + * fc_scr_fill - Fill in a scr request frame. 239 + */ 240 + static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp) 241 + { 242 + struct fc_els_scr *scr; 243 + 244 + scr = fc_frame_payload_get(fp, sizeof(*scr)); 245 + memset(scr, 0, sizeof(*scr)); 246 + scr->scr_cmd = ELS_SCR; 247 + scr->scr_reg_func = ELS_SCRF_FULL; 248 + } 249 + 250 + /** 251 + * fc_els_fill - Fill in an ELS request frame 252 + */ 253 + static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport, 254 + struct fc_frame *fp, unsigned int op, 255 + enum fc_rctl *r_ctl, u32 *did, enum fc_fh_type *fh_type) 256 + { 257 + switch (op) { 258 + case ELS_PLOGI: 259 + fc_plogi_fill(lport, fp, ELS_PLOGI); 260 + *did = rport->port_id; 261 + break; 262 + 263 + case ELS_FLOGI: 264 + fc_flogi_fill(lport, fp); 265 + *did = FC_FID_FLOGI; 266 + break; 267 + 268 + case ELS_LOGO: 269 + fc_logo_fill(lport, fp); 270 + *did = FC_FID_FLOGI; 271 + /* 272 + * if rport is valid then it 273 + * is port logo, therefore 274 + * set did to rport id. 275 + */ 276 + if (rport) 277 + *did = rport->port_id; 278 + break; 279 + 280 + case ELS_RTV: 281 + fc_rtv_fill(lport, fp); 282 + *did = rport->port_id; 283 + break; 284 + 285 + case ELS_REC: 286 + fc_rec_fill(lport, fp); 287 + *did = rport->port_id; 288 + break; 289 + 290 + case ELS_PRLI: 291 + fc_prli_fill(lport, fp); 292 + *did = rport->port_id; 293 + break; 294 + 295 + case ELS_SCR: 296 + fc_scr_fill(lport, fp); 297 + *did = FC_FID_FCTRL; 298 + break; 299 + 300 + default: 301 + FC_DBG("Invalid op code %x \n", op); 302 + return -EINVAL; 303 + } 304 + 305 + *r_ctl = FC_RCTL_ELS_REQ; 306 + *fh_type = FC_TYPE_ELS; 307 + return 0; 308 + } 309 + #endif /* _FC_ENCODE_H_ */
+242
include/scsi/fc_frame.h
··· 1 + /* 2 + * Copyright(c) 2007 Intel Corporation. All rights reserved. 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 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + #ifndef _FC_FRAME_H_ 21 + #define _FC_FRAME_H_ 22 + 23 + #include <linux/scatterlist.h> 24 + #include <linux/skbuff.h> 25 + #include <scsi/scsi_cmnd.h> 26 + 27 + #include <scsi/fc/fc_fs.h> 28 + #include <scsi/fc/fc_fcp.h> 29 + #include <scsi/fc/fc_encaps.h> 30 + 31 + /* 32 + * The fc_frame interface is used to pass frame data between functions. 33 + * The frame includes the data buffer, length, and SOF / EOF delimiter types. 34 + * A pointer to the port structure of the receiving port is also includeded. 35 + */ 36 + 37 + #define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */ 38 + #define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */ 39 + 40 + /* 41 + * Information about an individual fibre channel frame received or to be sent. 42 + * The buffer may be in up to 4 additional non-contiguous sections, 43 + * but the linear section must hold the frame header. 44 + */ 45 + #define FC_FRAME_SG_LEN 4 /* scatter/gather list maximum length */ 46 + 47 + #define fp_skb(fp) (&((fp)->skb)) 48 + #define fr_hdr(fp) ((fp)->skb.data) 49 + #define fr_len(fp) ((fp)->skb.len) 50 + #define fr_cb(fp) ((struct fcoe_rcv_info *)&((fp)->skb.cb[0])) 51 + #define fr_dev(fp) (fr_cb(fp)->fr_dev) 52 + #define fr_seq(fp) (fr_cb(fp)->fr_seq) 53 + #define fr_sof(fp) (fr_cb(fp)->fr_sof) 54 + #define fr_eof(fp) (fr_cb(fp)->fr_eof) 55 + #define fr_flags(fp) (fr_cb(fp)->fr_flags) 56 + #define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload) 57 + #define fr_cmd(fp) (fr_cb(fp)->fr_cmd) 58 + #define fr_dir(fp) (fr_cmd(fp)->sc_data_direction) 59 + #define fr_crc(fp) (fr_cb(fp)->fr_crc) 60 + 61 + struct fc_frame { 62 + struct sk_buff skb; 63 + }; 64 + 65 + struct fcoe_rcv_info { 66 + struct packet_type *ptype; 67 + struct fc_lport *fr_dev; /* transport layer private pointer */ 68 + struct fc_seq *fr_seq; /* for use with exchange manager */ 69 + struct scsi_cmnd *fr_cmd; /* for use of scsi command */ 70 + u32 fr_crc; 71 + u16 fr_max_payload; /* max FC payload */ 72 + enum fc_sof fr_sof; /* start of frame delimiter */ 73 + enum fc_eof fr_eof; /* end of frame delimiter */ 74 + u8 fr_flags; /* flags - see below */ 75 + }; 76 + 77 + 78 + /* 79 + * Get fc_frame pointer for an skb that's already been imported. 80 + */ 81 + static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb) 82 + { 83 + BUILD_BUG_ON(sizeof(struct fcoe_rcv_info) > sizeof(skb->cb)); 84 + return (struct fcoe_rcv_info *) skb->cb; 85 + } 86 + 87 + /* 88 + * fr_flags. 89 + */ 90 + #define FCPHF_CRC_UNCHECKED 0x01 /* CRC not computed, still appended */ 91 + 92 + /* 93 + * Initialize a frame. 94 + * We don't do a complete memset here for performance reasons. 95 + * The caller must set fr_free, fr_hdr, fr_len, fr_sof, and fr_eof eventually. 96 + */ 97 + static inline void fc_frame_init(struct fc_frame *fp) 98 + { 99 + fr_dev(fp) = NULL; 100 + fr_seq(fp) = NULL; 101 + fr_flags(fp) = 0; 102 + } 103 + 104 + struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len); 105 + 106 + struct fc_frame *__fc_frame_alloc(size_t payload_len); 107 + 108 + /* 109 + * Get frame for sending via port. 110 + */ 111 + static inline struct fc_frame *_fc_frame_alloc(struct fc_lport *dev, 112 + size_t payload_len) 113 + { 114 + return __fc_frame_alloc(payload_len); 115 + } 116 + 117 + /* 118 + * Allocate fc_frame structure and buffer. Set the initial length to 119 + * payload_size + sizeof (struct fc_frame_header). 120 + */ 121 + static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len) 122 + { 123 + struct fc_frame *fp; 124 + 125 + /* 126 + * Note: Since len will often be a constant multiple of 4, 127 + * this check will usually be evaluated and eliminated at compile time. 128 + */ 129 + if ((len % 4) != 0) 130 + fp = fc_frame_alloc_fill(dev, len); 131 + else 132 + fp = _fc_frame_alloc(dev, len); 133 + return fp; 134 + } 135 + 136 + /* 137 + * Free the fc_frame structure and buffer. 138 + */ 139 + static inline void fc_frame_free(struct fc_frame *fp) 140 + { 141 + kfree_skb(fp_skb(fp)); 142 + } 143 + 144 + static inline int fc_frame_is_linear(struct fc_frame *fp) 145 + { 146 + return !skb_is_nonlinear(fp_skb(fp)); 147 + } 148 + 149 + /* 150 + * Get frame header from message in fc_frame structure. 151 + * This hides a cast and provides a place to add some checking. 152 + */ 153 + static inline 154 + struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp) 155 + { 156 + WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header)); 157 + return (struct fc_frame_header *) fr_hdr(fp); 158 + } 159 + 160 + /* 161 + * Get frame payload from message in fc_frame structure. 162 + * This hides a cast and provides a place to add some checking. 163 + * The len parameter is the minimum length for the payload portion. 164 + * Returns NULL if the frame is too short. 165 + * 166 + * This assumes the interesting part of the payload is in the first part 167 + * of the buffer for received data. This may not be appropriate to use for 168 + * buffers being transmitted. 169 + */ 170 + static inline void *fc_frame_payload_get(const struct fc_frame *fp, 171 + size_t len) 172 + { 173 + void *pp = NULL; 174 + 175 + if (fr_len(fp) >= sizeof(struct fc_frame_header) + len) 176 + pp = fc_frame_header_get(fp) + 1; 177 + return pp; 178 + } 179 + 180 + /* 181 + * Get frame payload opcode (first byte) from message in fc_frame structure. 182 + * This hides a cast and provides a place to add some checking. Return 0 183 + * if the frame has no payload. 184 + */ 185 + static inline u8 fc_frame_payload_op(const struct fc_frame *fp) 186 + { 187 + u8 *cp; 188 + 189 + cp = fc_frame_payload_get(fp, sizeof(u8)); 190 + if (!cp) 191 + return 0; 192 + return *cp; 193 + 194 + } 195 + 196 + /* 197 + * Get FC class from frame. 198 + */ 199 + static inline enum fc_class fc_frame_class(const struct fc_frame *fp) 200 + { 201 + return fc_sof_class(fr_sof(fp)); 202 + } 203 + 204 + /* 205 + * Check the CRC in a frame. 206 + * The CRC immediately follows the last data item *AFTER* the length. 207 + * The return value is zero if the CRC matches. 208 + */ 209 + u32 fc_frame_crc_check(struct fc_frame *); 210 + 211 + static inline u8 fc_frame_rctl(const struct fc_frame *fp) 212 + { 213 + return fc_frame_header_get(fp)->fh_r_ctl; 214 + } 215 + 216 + static inline bool fc_frame_is_cmd(const struct fc_frame *fp) 217 + { 218 + return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD; 219 + } 220 + 221 + static inline bool fc_frame_is_read(const struct fc_frame *fp) 222 + { 223 + if (fc_frame_is_cmd(fp) && fr_cmd(fp)) 224 + return fr_dir(fp) == DMA_FROM_DEVICE; 225 + return false; 226 + } 227 + 228 + static inline bool fc_frame_is_write(const struct fc_frame *fp) 229 + { 230 + if (fc_frame_is_cmd(fp) && fr_cmd(fp)) 231 + return fr_dir(fp) == DMA_TO_DEVICE; 232 + return false; 233 + } 234 + 235 + /* 236 + * Check for leaks. 237 + * Print the frame header of any currently allocated frame, assuming there 238 + * should be none at this point. 239 + */ 240 + void fc_frame_leak_check(void); 241 + 242 + #endif /* _FC_FRAME_H_ */
+938
include/scsi/libfc.h
··· 1 + /* 2 + * Copyright(c) 2007 Intel Corporation. All rights reserved. 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 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + #ifndef _LIBFC_H_ 21 + #define _LIBFC_H_ 22 + 23 + #include <linux/timer.h> 24 + #include <linux/if.h> 25 + 26 + #include <scsi/scsi_transport.h> 27 + #include <scsi/scsi_transport_fc.h> 28 + 29 + #include <scsi/fc/fc_fcp.h> 30 + #include <scsi/fc/fc_ns.h> 31 + #include <scsi/fc/fc_els.h> 32 + #include <scsi/fc/fc_gs.h> 33 + 34 + #include <scsi/fc_frame.h> 35 + 36 + #define LIBFC_DEBUG 37 + 38 + #ifdef LIBFC_DEBUG 39 + /* Log messages */ 40 + #define FC_DBG(fmt, args...) \ 41 + do { \ 42 + printk(KERN_INFO "%s " fmt, __func__, ##args); \ 43 + } while (0) 44 + #else 45 + #define FC_DBG(fmt, args...) 46 + #endif 47 + 48 + /* 49 + * libfc error codes 50 + */ 51 + #define FC_NO_ERR 0 /* no error */ 52 + #define FC_EX_TIMEOUT 1 /* Exchange timeout */ 53 + #define FC_EX_CLOSED 2 /* Exchange closed */ 54 + 55 + /* some helpful macros */ 56 + 57 + #define ntohll(x) be64_to_cpu(x) 58 + #define htonll(x) cpu_to_be64(x) 59 + 60 + #define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2])) 61 + 62 + #define hton24(p, v) do { \ 63 + p[0] = (((v) >> 16) & 0xFF); \ 64 + p[1] = (((v) >> 8) & 0xFF); \ 65 + p[2] = ((v) & 0xFF); \ 66 + } while (0) 67 + 68 + /* 69 + * FC HBA status 70 + */ 71 + #define FC_PAUSE (1 << 1) 72 + #define FC_LINK_UP (1 << 0) 73 + 74 + enum fc_lport_state { 75 + LPORT_ST_NONE = 0, 76 + LPORT_ST_FLOGI, 77 + LPORT_ST_DNS, 78 + LPORT_ST_RPN_ID, 79 + LPORT_ST_RFT_ID, 80 + LPORT_ST_SCR, 81 + LPORT_ST_READY, 82 + LPORT_ST_LOGO, 83 + LPORT_ST_RESET 84 + }; 85 + 86 + enum fc_disc_event { 87 + DISC_EV_NONE = 0, 88 + DISC_EV_SUCCESS, 89 + DISC_EV_FAILED 90 + }; 91 + 92 + enum fc_rport_state { 93 + RPORT_ST_NONE = 0, 94 + RPORT_ST_INIT, /* initialized */ 95 + RPORT_ST_PLOGI, /* waiting for PLOGI completion */ 96 + RPORT_ST_PRLI, /* waiting for PRLI completion */ 97 + RPORT_ST_RTV, /* waiting for RTV completion */ 98 + RPORT_ST_READY, /* ready for use */ 99 + RPORT_ST_LOGO, /* port logout sent */ 100 + }; 101 + 102 + enum fc_rport_trans_state { 103 + FC_PORTSTATE_ROGUE, 104 + FC_PORTSTATE_REAL, 105 + }; 106 + 107 + /** 108 + * struct fc_disc_port - temporary discovery port to hold rport identifiers 109 + * @lp: Fibre Channel host port instance 110 + * @peers: node for list management during discovery and RSCN processing 111 + * @ids: identifiers structure to pass to fc_remote_port_add() 112 + * @rport_work: work struct for starting the rport state machine 113 + */ 114 + struct fc_disc_port { 115 + struct fc_lport *lp; 116 + struct list_head peers; 117 + struct fc_rport_identifiers ids; 118 + struct work_struct rport_work; 119 + }; 120 + 121 + enum fc_rport_event { 122 + RPORT_EV_NONE = 0, 123 + RPORT_EV_CREATED, 124 + RPORT_EV_FAILED, 125 + RPORT_EV_STOP, 126 + RPORT_EV_LOGO 127 + }; 128 + 129 + struct fc_rport_operations { 130 + void (*event_callback)(struct fc_lport *, struct fc_rport *, 131 + enum fc_rport_event); 132 + }; 133 + 134 + /** 135 + * struct fc_rport_libfc_priv - libfc internal information about a remote port 136 + * @local_port: Fibre Channel host port instance 137 + * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges 138 + * @flags: REC and RETRY supported flags 139 + * @max_seq: maximum number of concurrent sequences 140 + * @retries: retry count in current state 141 + * @e_d_tov: error detect timeout value (in msec) 142 + * @r_a_tov: resource allocation timeout value (in msec) 143 + * @rp_mutex: mutex protects rport 144 + * @retry_work: 145 + * @event_callback: Callback for rport READY, FAILED or LOGO 146 + */ 147 + struct fc_rport_libfc_priv { 148 + struct fc_lport *local_port; 149 + enum fc_rport_state rp_state; 150 + u16 flags; 151 + #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) 152 + #define FC_RP_FLAGS_RETRY (1 << 1) 153 + u16 max_seq; 154 + unsigned int retries; 155 + unsigned int e_d_tov; 156 + unsigned int r_a_tov; 157 + enum fc_rport_trans_state trans_state; 158 + struct mutex rp_mutex; 159 + struct delayed_work retry_work; 160 + enum fc_rport_event event; 161 + struct fc_rport_operations *ops; 162 + struct list_head peers; 163 + struct work_struct event_work; 164 + }; 165 + 166 + #define PRIV_TO_RPORT(x) \ 167 + (struct fc_rport *)((void *)x - sizeof(struct fc_rport)); 168 + #define RPORT_TO_PRIV(x) \ 169 + (struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport)); 170 + 171 + struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *); 172 + 173 + static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn) 174 + { 175 + rport->node_name = wwnn; 176 + rport->port_name = wwpn; 177 + } 178 + 179 + /* 180 + * fcoe stats structure 181 + */ 182 + struct fcoe_dev_stats { 183 + u64 SecondsSinceLastReset; 184 + u64 TxFrames; 185 + u64 TxWords; 186 + u64 RxFrames; 187 + u64 RxWords; 188 + u64 ErrorFrames; 189 + u64 DumpedFrames; 190 + u64 LinkFailureCount; 191 + u64 LossOfSignalCount; 192 + u64 InvalidTxWordCount; 193 + u64 InvalidCRCCount; 194 + u64 InputRequests; 195 + u64 OutputRequests; 196 + u64 ControlRequests; 197 + u64 InputMegabytes; 198 + u64 OutputMegabytes; 199 + }; 200 + 201 + /* 202 + * els data is used for passing ELS respone specific 203 + * data to send ELS response mainly using infomation 204 + * in exchange and sequence in EM layer. 205 + */ 206 + struct fc_seq_els_data { 207 + struct fc_frame *fp; 208 + enum fc_els_rjt_reason reason; 209 + enum fc_els_rjt_explan explan; 210 + }; 211 + 212 + /* 213 + * FCP request structure, one for each scsi cmd request 214 + */ 215 + struct fc_fcp_pkt { 216 + /* 217 + * housekeeping stuff 218 + */ 219 + struct fc_lport *lp; /* handle to hba struct */ 220 + u16 state; /* scsi_pkt state state */ 221 + u16 tgt_flags; /* target flags */ 222 + atomic_t ref_cnt; /* fcp pkt ref count */ 223 + spinlock_t scsi_pkt_lock; /* Must be taken before the host lock 224 + * if both are held at the same time */ 225 + /* 226 + * SCSI I/O related stuff 227 + */ 228 + struct scsi_cmnd *cmd; /* scsi command pointer. set/clear 229 + * under host lock */ 230 + struct list_head list; /* tracks queued commands. access under 231 + * host lock */ 232 + /* 233 + * timeout related stuff 234 + */ 235 + struct timer_list timer; /* command timer */ 236 + struct completion tm_done; 237 + int wait_for_comp; 238 + unsigned long start_time; /* start jiffie */ 239 + unsigned long end_time; /* end jiffie */ 240 + unsigned long last_pkt_time; /* jiffies of last frame received */ 241 + 242 + /* 243 + * scsi cmd and data transfer information 244 + */ 245 + u32 data_len; 246 + /* 247 + * transport related veriables 248 + */ 249 + struct fcp_cmnd cdb_cmd; 250 + size_t xfer_len; 251 + u32 xfer_contig_end; /* offset of end of contiguous xfer */ 252 + u16 max_payload; /* max payload size in bytes */ 253 + 254 + /* 255 + * scsi/fcp return status 256 + */ 257 + u32 io_status; /* SCSI result upper 24 bits */ 258 + u8 cdb_status; 259 + u8 status_code; /* FCP I/O status */ 260 + /* bit 3 Underrun bit 2: overrun */ 261 + u8 scsi_comp_flags; 262 + u32 req_flags; /* bit 0: read bit:1 write */ 263 + u32 scsi_resid; /* residule length */ 264 + 265 + struct fc_rport *rport; /* remote port pointer */ 266 + struct fc_seq *seq_ptr; /* current sequence pointer */ 267 + /* 268 + * Error Processing 269 + */ 270 + u8 recov_retry; /* count of recovery retries */ 271 + struct fc_seq *recov_seq; /* sequence for REC or SRR */ 272 + }; 273 + 274 + /* 275 + * Structure and function definitions for managing Fibre Channel Exchanges 276 + * and Sequences 277 + * 278 + * fc_exch holds state for one exchange and links to its active sequence. 279 + * 280 + * fc_seq holds the state for an individual sequence. 281 + */ 282 + 283 + struct fc_exch_mgr; 284 + 285 + /* 286 + * Sequence. 287 + */ 288 + struct fc_seq { 289 + u8 id; /* seq ID */ 290 + u16 ssb_stat; /* status flags for sequence status block */ 291 + u16 cnt; /* frames sent so far on sequence */ 292 + u32 rec_data; /* FC-4 value for REC */ 293 + }; 294 + 295 + #define FC_EX_DONE (1 << 0) /* ep is completed */ 296 + #define FC_EX_RST_CLEANUP (1 << 1) /* reset is forcing completion */ 297 + 298 + /* 299 + * Exchange. 300 + * 301 + * Locking notes: The ex_lock protects following items: 302 + * state, esb_stat, f_ctl, seq.ssb_stat 303 + * seq_id 304 + * sequence allocation 305 + */ 306 + struct fc_exch { 307 + struct fc_exch_mgr *em; /* exchange manager */ 308 + u32 state; /* internal driver state */ 309 + u16 xid; /* our exchange ID */ 310 + struct list_head ex_list; /* free or busy list linkage */ 311 + spinlock_t ex_lock; /* lock covering exchange state */ 312 + atomic_t ex_refcnt; /* reference counter */ 313 + struct delayed_work timeout_work; /* timer for upper level protocols */ 314 + struct fc_lport *lp; /* fc device instance */ 315 + u16 oxid; /* originator's exchange ID */ 316 + u16 rxid; /* responder's exchange ID */ 317 + u32 oid; /* originator's FCID */ 318 + u32 sid; /* source FCID */ 319 + u32 did; /* destination FCID */ 320 + u32 esb_stat; /* exchange status for ESB */ 321 + u32 r_a_tov; /* r_a_tov from rport (msec) */ 322 + u8 seq_id; /* next sequence ID to use */ 323 + u32 f_ctl; /* F_CTL flags for sequences */ 324 + u8 fh_type; /* frame type */ 325 + enum fc_class class; /* class of service */ 326 + struct fc_seq seq; /* single sequence */ 327 + /* 328 + * Handler for responses to this current exchange. 329 + */ 330 + void (*resp)(struct fc_seq *, struct fc_frame *, void *); 331 + void (*destructor)(struct fc_seq *, void *); 332 + /* 333 + * arg is passed as void pointer to exchange 334 + * resp and destructor handlers 335 + */ 336 + void *arg; 337 + }; 338 + #define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq) 339 + 340 + struct libfc_function_template { 341 + 342 + /** 343 + * Mandatory Fields 344 + * 345 + * These handlers must be implemented by the LLD. 346 + */ 347 + 348 + /* 349 + * Interface to send a FC frame 350 + */ 351 + int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp); 352 + 353 + /** 354 + * Optional Fields 355 + * 356 + * The LLD may choose to implement any of the following handlers. 357 + * If LLD doesn't specify hander and leaves its pointer NULL then 358 + * the default libfc function will be used for that handler. 359 + */ 360 + 361 + /** 362 + * ELS/CT interfaces 363 + */ 364 + 365 + /* 366 + * elsct_send - sends ELS/CT frame 367 + */ 368 + struct fc_seq *(*elsct_send)(struct fc_lport *lport, 369 + struct fc_rport *rport, 370 + struct fc_frame *fp, 371 + unsigned int op, 372 + void (*resp)(struct fc_seq *, 373 + struct fc_frame *fp, 374 + void *arg), 375 + void *arg, u32 timer_msec); 376 + /** 377 + * Exhance Manager interfaces 378 + */ 379 + 380 + /* 381 + * Send the FC frame payload using a new exchange and sequence. 382 + * 383 + * The frame pointer with some of the header's fields must be 384 + * filled before calling exch_seq_send(), those fields are, 385 + * 386 + * - routing control 387 + * - FC port did 388 + * - FC port sid 389 + * - FC header type 390 + * - frame control 391 + * - parameter or relative offset 392 + * 393 + * The exchange response handler is set in this routine to resp() 394 + * function pointer. It can be called in two scenarios: if a timeout 395 + * occurs or if a response frame is received for the exchange. The 396 + * fc_frame pointer in response handler will also indicate timeout 397 + * as error using IS_ERR related macros. 398 + * 399 + * The exchange destructor handler is also set in this routine. 400 + * The destructor handler is invoked by EM layer when exchange 401 + * is about to free, this can be used by caller to free its 402 + * resources along with exchange free. 403 + * 404 + * The arg is passed back to resp and destructor handler. 405 + * 406 + * The timeout value (in msec) for an exchange is set if non zero 407 + * timer_msec argument is specified. The timer is canceled when 408 + * it fires or when the exchange is done. The exchange timeout handler 409 + * is registered by EM layer. 410 + */ 411 + struct fc_seq *(*exch_seq_send)(struct fc_lport *lp, 412 + struct fc_frame *fp, 413 + void (*resp)(struct fc_seq *sp, 414 + struct fc_frame *fp, 415 + void *arg), 416 + void (*destructor)(struct fc_seq *sp, 417 + void *arg), 418 + void *arg, unsigned int timer_msec); 419 + 420 + /* 421 + * send a frame using existing sequence and exchange. 422 + */ 423 + int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp, 424 + struct fc_frame *fp); 425 + 426 + /* 427 + * Send ELS response using mainly infomation 428 + * in exchange and sequence in EM layer. 429 + */ 430 + void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd, 431 + struct fc_seq_els_data *els_data); 432 + 433 + /* 434 + * Abort an exchange and sequence. Generally called because of a 435 + * exchange timeout or an abort from the upper layer. 436 + * 437 + * A timer_msec can be specified for abort timeout, if non-zero 438 + * timer_msec value is specified then exchange resp handler 439 + * will be called with timeout error if no response to abort. 440 + */ 441 + int (*seq_exch_abort)(const struct fc_seq *req_sp, 442 + unsigned int timer_msec); 443 + 444 + /* 445 + * Indicate that an exchange/sequence tuple is complete and the memory 446 + * allocated for the related objects may be freed. 447 + */ 448 + void (*exch_done)(struct fc_seq *sp); 449 + 450 + /* 451 + * Assigns a EM and a free XID for an new exchange and then 452 + * allocates a new exchange and sequence pair. 453 + * The fp can be used to determine free XID. 454 + */ 455 + struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp); 456 + 457 + /* 458 + * Release previously assigned XID by exch_get API. 459 + * The LLD may implement this if XID is assigned by LLD 460 + * in exch_get(). 461 + */ 462 + void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp, 463 + u16 ex_id); 464 + 465 + /* 466 + * Start a new sequence on the same exchange/sequence tuple. 467 + */ 468 + struct fc_seq *(*seq_start_next)(struct fc_seq *sp); 469 + 470 + /* 471 + * Reset an exchange manager, completing all sequences and exchanges. 472 + * If s_id is non-zero, reset only exchanges originating from that FID. 473 + * If d_id is non-zero, reset only exchanges sending to that FID. 474 + */ 475 + void (*exch_mgr_reset)(struct fc_exch_mgr *, 476 + u32 s_id, u32 d_id); 477 + 478 + void (*rport_flush_queue)(void); 479 + /** 480 + * Local Port interfaces 481 + */ 482 + 483 + /* 484 + * Receive a frame to a local port. 485 + */ 486 + void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp, 487 + struct fc_frame *fp); 488 + 489 + int (*lport_reset)(struct fc_lport *); 490 + 491 + /** 492 + * Remote Port interfaces 493 + */ 494 + 495 + /* 496 + * Initiates the RP state machine. It is called from the LP module. 497 + * This function will issue the following commands to the N_Port 498 + * identified by the FC ID provided. 499 + * 500 + * - PLOGI 501 + * - PRLI 502 + * - RTV 503 + */ 504 + int (*rport_login)(struct fc_rport *rport); 505 + 506 + /* 507 + * Logoff, and remove the rport from the transport if 508 + * it had been added. This will send a LOGO to the target. 509 + */ 510 + int (*rport_logoff)(struct fc_rport *rport); 511 + 512 + /* 513 + * Recieve a request from a remote port. 514 + */ 515 + void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, 516 + struct fc_rport *); 517 + 518 + struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32); 519 + 520 + /** 521 + * FCP interfaces 522 + */ 523 + 524 + /* 525 + * Send a fcp cmd from fsp pkt. 526 + * Called with the SCSI host lock unlocked and irqs disabled. 527 + * 528 + * The resp handler is called when FCP_RSP received. 529 + * 530 + */ 531 + int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp, 532 + void (*resp)(struct fc_seq *, struct fc_frame *fp, 533 + void *arg)); 534 + 535 + /* 536 + * Used at least durring linkdown and reset 537 + */ 538 + void (*fcp_cleanup)(struct fc_lport *lp); 539 + 540 + /* 541 + * Abort all I/O on a local port 542 + */ 543 + void (*fcp_abort_io)(struct fc_lport *lp); 544 + 545 + /** 546 + * Discovery interfaces 547 + */ 548 + 549 + void (*disc_recv_req)(struct fc_seq *, 550 + struct fc_frame *, struct fc_lport *); 551 + 552 + /* 553 + * Start discovery for a local port. 554 + */ 555 + void (*disc_start)(void (*disc_callback)(struct fc_lport *, 556 + enum fc_disc_event), 557 + struct fc_lport *); 558 + 559 + /* 560 + * Stop discovery for a given lport. This will remove 561 + * all discovered rports 562 + */ 563 + void (*disc_stop) (struct fc_lport *); 564 + 565 + /* 566 + * Stop discovery for a given lport. This will block 567 + * until all discovered rports are deleted from the 568 + * FC transport class 569 + */ 570 + void (*disc_stop_final) (struct fc_lport *); 571 + }; 572 + 573 + /* information used by the discovery layer */ 574 + struct fc_disc { 575 + unsigned char retry_count; 576 + unsigned char delay; 577 + unsigned char pending; 578 + unsigned char requested; 579 + unsigned short seq_count; 580 + unsigned char buf_len; 581 + enum fc_disc_event event; 582 + 583 + void (*disc_callback)(struct fc_lport *, 584 + enum fc_disc_event); 585 + 586 + struct list_head rports; 587 + struct fc_lport *lport; 588 + struct mutex disc_mutex; 589 + struct fc_gpn_ft_resp partial_buf; /* partial name buffer */ 590 + struct delayed_work disc_work; 591 + }; 592 + 593 + struct fc_lport { 594 + struct list_head list; 595 + 596 + /* Associations */ 597 + struct Scsi_Host *host; 598 + struct fc_exch_mgr *emp; 599 + struct fc_rport *dns_rp; 600 + struct fc_rport *ptp_rp; 601 + void *scsi_priv; 602 + struct fc_disc disc; 603 + 604 + /* Operational Information */ 605 + struct libfc_function_template tt; 606 + u16 link_status; 607 + enum fc_lport_state state; 608 + unsigned long boot_time; 609 + 610 + struct fc_host_statistics host_stats; 611 + struct fcoe_dev_stats *dev_stats[NR_CPUS]; 612 + u64 wwpn; 613 + u64 wwnn; 614 + u8 retry_count; 615 + 616 + /* Capabilities */ 617 + u32 sg_supp:1; /* scatter gather supported */ 618 + u32 seq_offload:1; /* seq offload supported */ 619 + u32 crc_offload:1; /* crc offload supported */ 620 + u32 lro_enabled:1; /* large receive offload */ 621 + u32 mfs; /* max FC payload size */ 622 + unsigned int service_params; 623 + unsigned int e_d_tov; 624 + unsigned int r_a_tov; 625 + u8 max_retry_count; 626 + u16 link_speed; 627 + u16 link_supported_speeds; 628 + u16 lro_xid; /* max xid for fcoe lro */ 629 + struct fc_ns_fts fcts; /* FC-4 type masks */ 630 + struct fc_els_rnid_gen rnid_gen; /* RNID information */ 631 + 632 + /* Semaphores */ 633 + struct mutex lp_mutex; 634 + 635 + /* Miscellaneous */ 636 + struct delayed_work retry_work; 637 + struct delayed_work disc_work; 638 + }; 639 + 640 + /** 641 + * FC_LPORT HELPER FUNCTIONS 642 + *****************************/ 643 + static inline void *lport_priv(const struct fc_lport *lp) 644 + { 645 + return (void *)(lp + 1); 646 + } 647 + 648 + static inline int fc_lport_test_ready(struct fc_lport *lp) 649 + { 650 + return lp->state == LPORT_ST_READY; 651 + } 652 + 653 + static inline void fc_set_wwnn(struct fc_lport *lp, u64 wwnn) 654 + { 655 + lp->wwnn = wwnn; 656 + } 657 + 658 + static inline void fc_set_wwpn(struct fc_lport *lp, u64 wwnn) 659 + { 660 + lp->wwpn = wwnn; 661 + } 662 + 663 + static inline void fc_lport_state_enter(struct fc_lport *lp, 664 + enum fc_lport_state state) 665 + { 666 + if (state != lp->state) 667 + lp->retry_count = 0; 668 + lp->state = state; 669 + } 670 + 671 + 672 + /** 673 + * LOCAL PORT LAYER 674 + *****************************/ 675 + int fc_lport_init(struct fc_lport *lp); 676 + 677 + /* 678 + * Destroy the specified local port by finding and freeing all 679 + * fc_rports associated with it and then by freeing the fc_lport 680 + * itself. 681 + */ 682 + int fc_lport_destroy(struct fc_lport *lp); 683 + 684 + /* 685 + * Logout the specified local port from the fabric 686 + */ 687 + int fc_fabric_logoff(struct fc_lport *lp); 688 + 689 + /* 690 + * Initiate the LP state machine. This handler will use fc_host_attr 691 + * to store the FLOGI service parameters, so fc_host_attr must be 692 + * initialized before calling this handler. 693 + */ 694 + int fc_fabric_login(struct fc_lport *lp); 695 + 696 + /* 697 + * The link is up for the given local port. 698 + */ 699 + void fc_linkup(struct fc_lport *); 700 + 701 + /* 702 + * Link is down for the given local port. 703 + */ 704 + void fc_linkdown(struct fc_lport *); 705 + 706 + /* 707 + * Pause and unpause traffic. 708 + */ 709 + void fc_pause(struct fc_lport *); 710 + void fc_unpause(struct fc_lport *); 711 + 712 + /* 713 + * Configure the local port. 714 + */ 715 + int fc_lport_config(struct fc_lport *); 716 + 717 + /* 718 + * Reset the local port. 719 + */ 720 + int fc_lport_reset(struct fc_lport *); 721 + 722 + /* 723 + * Set the mfs or reset 724 + */ 725 + int fc_set_mfs(struct fc_lport *lp, u32 mfs); 726 + 727 + 728 + /** 729 + * REMOTE PORT LAYER 730 + *****************************/ 731 + int fc_rport_init(struct fc_lport *lp); 732 + void fc_rport_terminate_io(struct fc_rport *rp); 733 + 734 + /** 735 + * DISCOVERY LAYER 736 + *****************************/ 737 + int fc_disc_init(struct fc_lport *lp); 738 + 739 + 740 + /** 741 + * SCSI LAYER 742 + *****************************/ 743 + /* 744 + * Initialize the SCSI block of libfc 745 + */ 746 + int fc_fcp_init(struct fc_lport *); 747 + 748 + /* 749 + * This section provides an API which allows direct interaction 750 + * with the SCSI-ml. Each of these functions satisfies a function 751 + * pointer defined in Scsi_Host and therefore is always called 752 + * directly from the SCSI-ml. 753 + */ 754 + int fc_queuecommand(struct scsi_cmnd *sc_cmd, 755 + void (*done)(struct scsi_cmnd *)); 756 + 757 + /* 758 + * complete processing of a fcp packet 759 + * 760 + * This function may sleep if a fsp timer is pending. 761 + * The host lock must not be held by caller. 762 + */ 763 + void fc_fcp_complete(struct fc_fcp_pkt *fsp); 764 + 765 + /* 766 + * Send an ABTS frame to the target device. The sc_cmd argument 767 + * is a pointer to the SCSI command to be aborted. 768 + */ 769 + int fc_eh_abort(struct scsi_cmnd *sc_cmd); 770 + 771 + /* 772 + * Reset a LUN by sending send the tm cmd to the target. 773 + */ 774 + int fc_eh_device_reset(struct scsi_cmnd *sc_cmd); 775 + 776 + /* 777 + * Reset the host adapter. 778 + */ 779 + int fc_eh_host_reset(struct scsi_cmnd *sc_cmd); 780 + 781 + /* 782 + * Check rport status. 783 + */ 784 + int fc_slave_alloc(struct scsi_device *sdev); 785 + 786 + /* 787 + * Adjust the queue depth. 788 + */ 789 + int fc_change_queue_depth(struct scsi_device *sdev, int qdepth); 790 + 791 + /* 792 + * Change the tag type. 793 + */ 794 + int fc_change_queue_type(struct scsi_device *sdev, int tag_type); 795 + 796 + /* 797 + * Free memory pools used by the FCP layer. 798 + */ 799 + void fc_fcp_destroy(struct fc_lport *); 800 + 801 + /** 802 + * ELS/CT interface 803 + *****************************/ 804 + /* 805 + * Initializes ELS/CT interface 806 + */ 807 + int fc_elsct_init(struct fc_lport *lp); 808 + 809 + 810 + /** 811 + * EXCHANGE MANAGER LAYER 812 + *****************************/ 813 + /* 814 + * Initializes Exchange Manager related 815 + * function pointers in struct libfc_function_template. 816 + */ 817 + int fc_exch_init(struct fc_lport *lp); 818 + 819 + /* 820 + * Allocates an Exchange Manager (EM). 821 + * 822 + * The EM manages exchanges for their allocation and 823 + * free, also allows exchange lookup for received 824 + * frame. 825 + * 826 + * The class is used for initializing FC class of 827 + * allocated exchange from EM. 828 + * 829 + * The min_xid and max_xid will limit new 830 + * exchange ID (XID) within this range for 831 + * a new exchange. 832 + * The LLD may choose to have multiple EMs, 833 + * e.g. one EM instance per CPU receive thread in LLD. 834 + * The LLD can use exch_get() of struct libfc_function_template 835 + * to specify XID for a new exchange within 836 + * a specified EM instance. 837 + * 838 + * The em_idx to uniquely identify an EM instance. 839 + */ 840 + struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, 841 + enum fc_class class, 842 + u16 min_xid, 843 + u16 max_xid); 844 + 845 + /* 846 + * Free an exchange manager. 847 + */ 848 + void fc_exch_mgr_free(struct fc_exch_mgr *mp); 849 + 850 + /* 851 + * Receive a frame on specified local port and exchange manager. 852 + */ 853 + void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, 854 + struct fc_frame *fp); 855 + 856 + /* 857 + * This function is for exch_seq_send function pointer in 858 + * struct libfc_function_template, see comment block on 859 + * exch_seq_send for description of this function. 860 + */ 861 + struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, 862 + struct fc_frame *fp, 863 + void (*resp)(struct fc_seq *sp, 864 + struct fc_frame *fp, 865 + void *arg), 866 + void (*destructor)(struct fc_seq *sp, 867 + void *arg), 868 + void *arg, u32 timer_msec); 869 + 870 + /* 871 + * send a frame using existing sequence and exchange. 872 + */ 873 + int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp); 874 + 875 + /* 876 + * Send ELS response using mainly infomation 877 + * in exchange and sequence in EM layer. 878 + */ 879 + void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, 880 + struct fc_seq_els_data *els_data); 881 + 882 + /* 883 + * This function is for seq_exch_abort function pointer in 884 + * struct libfc_function_template, see comment block on 885 + * seq_exch_abort for description of this function. 886 + */ 887 + int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec); 888 + 889 + /* 890 + * Indicate that an exchange/sequence tuple is complete and the memory 891 + * allocated for the related objects may be freed. 892 + */ 893 + void fc_exch_done(struct fc_seq *sp); 894 + 895 + /* 896 + * Assigns a EM and XID for a frame and then allocates 897 + * a new exchange and sequence pair. 898 + * The fp can be used to determine free XID. 899 + */ 900 + struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp); 901 + 902 + /* 903 + * Allocate a new exchange and sequence pair. 904 + * if ex_id is zero then next free exchange id 905 + * from specified exchange manger mp will be assigned. 906 + */ 907 + struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, 908 + struct fc_frame *fp, u16 ex_id); 909 + /* 910 + * Start a new sequence on the same exchange as the supplied sequence. 911 + */ 912 + struct fc_seq *fc_seq_start_next(struct fc_seq *sp); 913 + 914 + /* 915 + * Reset an exchange manager, completing all sequences and exchanges. 916 + * If s_id is non-zero, reset only exchanges originating from that FID. 917 + * If d_id is non-zero, reset only exchanges sending to that FID. 918 + */ 919 + void fc_exch_mgr_reset(struct fc_exch_mgr *, u32 s_id, u32 d_id); 920 + 921 + /* 922 + * Functions for fc_functions_template 923 + */ 924 + void fc_get_host_speed(struct Scsi_Host *shost); 925 + void fc_get_host_port_type(struct Scsi_Host *shost); 926 + void fc_get_host_port_state(struct Scsi_Host *shost); 927 + void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout); 928 + struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *); 929 + 930 + /* 931 + * module setup functions. 932 + */ 933 + int fc_setup_exch_mgr(void); 934 + void fc_destroy_exch_mgr(void); 935 + int fc_setup_rport(void); 936 + void fc_destroy_rport(void); 937 + 938 + #endif /* _LIBFC_H_ */