forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/nvme/target/fcloop.c
....@@ -1,17 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (c) 2016 Avago Technologies. All rights reserved.
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of version 2 of the GNU General Public License as
6
- * published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful.
9
- * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
10
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
11
- * PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO
12
- * THE EXTENT THAT SUCH DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
13
- * See the GNU General Public License for more details, a copy of which
14
- * can be found in the file COPYING included with this package
154 */
165 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
176 #include <linux/module.h>
....@@ -54,6 +43,17 @@
5443 { NVMF_OPT_ERR, NULL }
5544 };
5645
46
+static int fcloop_verify_addr(substring_t *s)
47
+{
48
+ size_t blen = s->to - s->from + 1;
49
+
50
+ if (strnlen(s->from, blen) != NVME_FC_TRADDR_HEXNAMELEN + 2 ||
51
+ strncmp(s->from, "0x", 2))
52
+ return -EINVAL;
53
+
54
+ return 0;
55
+}
56
+
5757 static int
5858 fcloop_parse_options(struct fcloop_ctrl_options *opts,
5959 const char *buf)
....@@ -75,14 +75,16 @@
7575 opts->mask |= token;
7676 switch (token) {
7777 case NVMF_OPT_WWNN:
78
- if (match_u64(args, &token64)) {
78
+ if (fcloop_verify_addr(args) ||
79
+ match_u64(args, &token64)) {
7980 ret = -EINVAL;
8081 goto out_free_options;
8182 }
8283 opts->wwnn = token64;
8384 break;
8485 case NVMF_OPT_WWPN:
85
- if (match_u64(args, &token64)) {
86
+ if (fcloop_verify_addr(args) ||
87
+ match_u64(args, &token64)) {
8688 ret = -EINVAL;
8789 goto out_free_options;
8890 }
....@@ -103,14 +105,16 @@
103105 opts->fcaddr = token;
104106 break;
105107 case NVMF_OPT_LPWWNN:
106
- if (match_u64(args, &token64)) {
108
+ if (fcloop_verify_addr(args) ||
109
+ match_u64(args, &token64)) {
107110 ret = -EINVAL;
108111 goto out_free_options;
109112 }
110113 opts->lpwwnn = token64;
111114 break;
112115 case NVMF_OPT_LPWWPN:
113
- if (match_u64(args, &token64)) {
116
+ if (fcloop_verify_addr(args) ||
117
+ match_u64(args, &token64)) {
114118 ret = -EINVAL;
115119 goto out_free_options;
116120 }
....@@ -152,14 +156,16 @@
152156 token = match_token(p, opt_tokens, args);
153157 switch (token) {
154158 case NVMF_OPT_WWNN:
155
- if (match_u64(args, &token64)) {
159
+ if (fcloop_verify_addr(args) ||
160
+ match_u64(args, &token64)) {
156161 ret = -EINVAL;
157162 goto out_free_options;
158163 }
159164 *nname = token64;
160165 break;
161166 case NVMF_OPT_WWPN:
162
- if (match_u64(args, &token64)) {
167
+ if (fcloop_verify_addr(args) ||
168
+ match_u64(args, &token64)) {
163169 ret = -EINVAL;
164170 goto out_free_options;
165171 }
....@@ -209,17 +215,23 @@
209215 };
210216
211217 struct fcloop_rport {
212
- struct nvme_fc_remote_port *remoteport;
213
- struct nvmet_fc_target_port *targetport;
214
- struct fcloop_nport *nport;
215
- struct fcloop_lport *lport;
218
+ struct nvme_fc_remote_port *remoteport;
219
+ struct nvmet_fc_target_port *targetport;
220
+ struct fcloop_nport *nport;
221
+ struct fcloop_lport *lport;
222
+ spinlock_t lock;
223
+ struct list_head ls_list;
224
+ struct work_struct ls_work;
216225 };
217226
218227 struct fcloop_tport {
219
- struct nvmet_fc_target_port *targetport;
220
- struct nvme_fc_remote_port *remoteport;
221
- struct fcloop_nport *nport;
222
- struct fcloop_lport *lport;
228
+ struct nvmet_fc_target_port *targetport;
229
+ struct nvme_fc_remote_port *remoteport;
230
+ struct fcloop_nport *nport;
231
+ struct fcloop_lport *lport;
232
+ spinlock_t lock;
233
+ struct list_head ls_list;
234
+ struct work_struct ls_work;
223235 };
224236
225237 struct fcloop_nport {
....@@ -235,11 +247,16 @@
235247 };
236248
237249 struct fcloop_lsreq {
238
- struct fcloop_tport *tport;
239250 struct nvmefc_ls_req *lsreq;
240
- struct work_struct work;
241
- struct nvmefc_tgt_ls_req tgt_ls_req;
251
+ struct nvmefc_ls_rsp ls_rsp;
252
+ int lsdir; /* H2T or T2H */
242253 int status;
254
+ struct list_head ls_list; /* fcloop_rport->ls_list */
255
+};
256
+
257
+struct fcloop_rscn {
258
+ struct fcloop_tport *tport;
259
+ struct work_struct work;
243260 };
244261
245262 enum {
....@@ -271,9 +288,9 @@
271288 };
272289
273290 static inline struct fcloop_lsreq *
274
-tgt_ls_req_to_lsreq(struct nvmefc_tgt_ls_req *tgt_lsreq)
291
+ls_rsp_to_lsreq(struct nvmefc_ls_rsp *lsrsp)
275292 {
276
- return container_of(tgt_lsreq, struct fcloop_lsreq, tgt_ls_req);
293
+ return container_of(lsrsp, struct fcloop_lsreq, ls_rsp);
277294 }
278295
279296 static inline struct fcloop_fcpreq *
....@@ -298,25 +315,36 @@
298315 {
299316 }
300317
301
-
302
-/*
303
- * Transmit of LS RSP done (e.g. buffers all set). call back up
304
- * initiator "done" flows.
305
- */
306318 static void
307
-fcloop_tgt_lsrqst_done_work(struct work_struct *work)
319
+fcloop_rport_lsrqst_work(struct work_struct *work)
308320 {
309
- struct fcloop_lsreq *tls_req =
310
- container_of(work, struct fcloop_lsreq, work);
311
- struct fcloop_tport *tport = tls_req->tport;
312
- struct nvmefc_ls_req *lsreq = tls_req->lsreq;
321
+ struct fcloop_rport *rport =
322
+ container_of(work, struct fcloop_rport, ls_work);
323
+ struct fcloop_lsreq *tls_req;
313324
314
- if (!tport || tport->remoteport)
315
- lsreq->done(lsreq, tls_req->status);
325
+ spin_lock(&rport->lock);
326
+ for (;;) {
327
+ tls_req = list_first_entry_or_null(&rport->ls_list,
328
+ struct fcloop_lsreq, ls_list);
329
+ if (!tls_req)
330
+ break;
331
+
332
+ list_del(&tls_req->ls_list);
333
+ spin_unlock(&rport->lock);
334
+
335
+ tls_req->lsreq->done(tls_req->lsreq, tls_req->status);
336
+ /*
337
+ * callee may free memory containing tls_req.
338
+ * do not reference lsreq after this.
339
+ */
340
+
341
+ spin_lock(&rport->lock);
342
+ }
343
+ spin_unlock(&rport->lock);
316344 }
317345
318346 static int
319
-fcloop_ls_req(struct nvme_fc_local_port *localport,
347
+fcloop_h2t_ls_req(struct nvme_fc_local_port *localport,
320348 struct nvme_fc_remote_port *remoteport,
321349 struct nvmefc_ls_req *lsreq)
322350 {
....@@ -325,38 +353,174 @@
325353 int ret = 0;
326354
327355 tls_req->lsreq = lsreq;
328
- INIT_WORK(&tls_req->work, fcloop_tgt_lsrqst_done_work);
356
+ INIT_LIST_HEAD(&tls_req->ls_list);
329357
330358 if (!rport->targetport) {
331359 tls_req->status = -ECONNREFUSED;
332
- tls_req->tport = NULL;
333
- schedule_work(&tls_req->work);
360
+ spin_lock(&rport->lock);
361
+ list_add_tail(&rport->ls_list, &tls_req->ls_list);
362
+ spin_unlock(&rport->lock);
363
+ schedule_work(&rport->ls_work);
334364 return ret;
335365 }
336366
337367 tls_req->status = 0;
338
- tls_req->tport = rport->targetport->private;
339
- ret = nvmet_fc_rcv_ls_req(rport->targetport, &tls_req->tgt_ls_req,
368
+ ret = nvmet_fc_rcv_ls_req(rport->targetport, rport,
369
+ &tls_req->ls_rsp,
370
+ lsreq->rqstaddr, lsreq->rqstlen);
371
+
372
+ return ret;
373
+}
374
+
375
+static int
376
+fcloop_h2t_xmt_ls_rsp(struct nvmet_fc_target_port *targetport,
377
+ struct nvmefc_ls_rsp *lsrsp)
378
+{
379
+ struct fcloop_lsreq *tls_req = ls_rsp_to_lsreq(lsrsp);
380
+ struct nvmefc_ls_req *lsreq = tls_req->lsreq;
381
+ struct fcloop_tport *tport = targetport->private;
382
+ struct nvme_fc_remote_port *remoteport = tport->remoteport;
383
+ struct fcloop_rport *rport;
384
+
385
+ memcpy(lsreq->rspaddr, lsrsp->rspbuf,
386
+ ((lsreq->rsplen < lsrsp->rsplen) ?
387
+ lsreq->rsplen : lsrsp->rsplen));
388
+
389
+ lsrsp->done(lsrsp);
390
+
391
+ if (remoteport) {
392
+ rport = remoteport->private;
393
+ spin_lock(&rport->lock);
394
+ list_add_tail(&rport->ls_list, &tls_req->ls_list);
395
+ spin_unlock(&rport->lock);
396
+ schedule_work(&rport->ls_work);
397
+ }
398
+
399
+ return 0;
400
+}
401
+
402
+static void
403
+fcloop_tport_lsrqst_work(struct work_struct *work)
404
+{
405
+ struct fcloop_tport *tport =
406
+ container_of(work, struct fcloop_tport, ls_work);
407
+ struct fcloop_lsreq *tls_req;
408
+
409
+ spin_lock(&tport->lock);
410
+ for (;;) {
411
+ tls_req = list_first_entry_or_null(&tport->ls_list,
412
+ struct fcloop_lsreq, ls_list);
413
+ if (!tls_req)
414
+ break;
415
+
416
+ list_del(&tls_req->ls_list);
417
+ spin_unlock(&tport->lock);
418
+
419
+ tls_req->lsreq->done(tls_req->lsreq, tls_req->status);
420
+ /*
421
+ * callee may free memory containing tls_req.
422
+ * do not reference lsreq after this.
423
+ */
424
+
425
+ spin_lock(&tport->lock);
426
+ }
427
+ spin_unlock(&tport->lock);
428
+}
429
+
430
+static int
431
+fcloop_t2h_ls_req(struct nvmet_fc_target_port *targetport, void *hosthandle,
432
+ struct nvmefc_ls_req *lsreq)
433
+{
434
+ struct fcloop_lsreq *tls_req = lsreq->private;
435
+ struct fcloop_tport *tport = targetport->private;
436
+ int ret = 0;
437
+
438
+ /*
439
+ * hosthandle should be the dst.rport value.
440
+ * hosthandle ignored as fcloop currently is
441
+ * 1:1 tgtport vs remoteport
442
+ */
443
+ tls_req->lsreq = lsreq;
444
+ INIT_LIST_HEAD(&tls_req->ls_list);
445
+
446
+ if (!tport->remoteport) {
447
+ tls_req->status = -ECONNREFUSED;
448
+ spin_lock(&tport->lock);
449
+ list_add_tail(&tport->ls_list, &tls_req->ls_list);
450
+ spin_unlock(&tport->lock);
451
+ schedule_work(&tport->ls_work);
452
+ return ret;
453
+ }
454
+
455
+ tls_req->status = 0;
456
+ ret = nvme_fc_rcv_ls_req(tport->remoteport, &tls_req->ls_rsp,
340457 lsreq->rqstaddr, lsreq->rqstlen);
341458
342459 return ret;
343460 }
344461
345462 static int
346
-fcloop_xmt_ls_rsp(struct nvmet_fc_target_port *tport,
347
- struct nvmefc_tgt_ls_req *tgt_lsreq)
463
+fcloop_t2h_xmt_ls_rsp(struct nvme_fc_local_port *localport,
464
+ struct nvme_fc_remote_port *remoteport,
465
+ struct nvmefc_ls_rsp *lsrsp)
348466 {
349
- struct fcloop_lsreq *tls_req = tgt_ls_req_to_lsreq(tgt_lsreq);
467
+ struct fcloop_lsreq *tls_req = ls_rsp_to_lsreq(lsrsp);
350468 struct nvmefc_ls_req *lsreq = tls_req->lsreq;
469
+ struct fcloop_rport *rport = remoteport->private;
470
+ struct nvmet_fc_target_port *targetport = rport->targetport;
471
+ struct fcloop_tport *tport;
351472
352
- memcpy(lsreq->rspaddr, tgt_lsreq->rspbuf,
353
- ((lsreq->rsplen < tgt_lsreq->rsplen) ?
354
- lsreq->rsplen : tgt_lsreq->rsplen));
355
- tgt_lsreq->done(tgt_lsreq);
473
+ memcpy(lsreq->rspaddr, lsrsp->rspbuf,
474
+ ((lsreq->rsplen < lsrsp->rsplen) ?
475
+ lsreq->rsplen : lsrsp->rsplen));
476
+ lsrsp->done(lsrsp);
356477
357
- schedule_work(&tls_req->work);
478
+ if (targetport) {
479
+ tport = targetport->private;
480
+ spin_lock(&tport->lock);
481
+ list_add_tail(&tport->ls_list, &tls_req->ls_list);
482
+ spin_unlock(&tport->lock);
483
+ schedule_work(&tport->ls_work);
484
+ }
358485
359486 return 0;
487
+}
488
+
489
+static void
490
+fcloop_t2h_host_release(void *hosthandle)
491
+{
492
+ /* host handle ignored for now */
493
+}
494
+
495
+/*
496
+ * Simulate reception of RSCN and converting it to a initiator transport
497
+ * call to rescan a remote port.
498
+ */
499
+static void
500
+fcloop_tgt_rscn_work(struct work_struct *work)
501
+{
502
+ struct fcloop_rscn *tgt_rscn =
503
+ container_of(work, struct fcloop_rscn, work);
504
+ struct fcloop_tport *tport = tgt_rscn->tport;
505
+
506
+ if (tport->remoteport)
507
+ nvme_fc_rescan_remoteport(tport->remoteport);
508
+ kfree(tgt_rscn);
509
+}
510
+
511
+static void
512
+fcloop_tgt_discovery_evt(struct nvmet_fc_target_port *tgtport)
513
+{
514
+ struct fcloop_rscn *tgt_rscn;
515
+
516
+ tgt_rscn = kzalloc(sizeof(*tgt_rscn), GFP_KERNEL);
517
+ if (!tgt_rscn)
518
+ return;
519
+
520
+ tgt_rscn->tport = tgtport->private;
521
+ INIT_WORK(&tgt_rscn->work, fcloop_tgt_rscn_work);
522
+
523
+ schedule_work(&tgt_rscn->work);
360524 }
361525
362526 static void
....@@ -409,7 +573,7 @@
409573 int ret = 0;
410574 bool aborted = false;
411575
412
- spin_lock(&tfcp_req->reqlock);
576
+ spin_lock_irq(&tfcp_req->reqlock);
413577 switch (tfcp_req->inistate) {
414578 case INI_IO_START:
415579 tfcp_req->inistate = INI_IO_ACTIVE;
....@@ -418,11 +582,11 @@
418582 aborted = true;
419583 break;
420584 default:
421
- spin_unlock(&tfcp_req->reqlock);
585
+ spin_unlock_irq(&tfcp_req->reqlock);
422586 WARN_ON(1);
423587 return;
424588 }
425
- spin_unlock(&tfcp_req->reqlock);
589
+ spin_unlock_irq(&tfcp_req->reqlock);
426590
427591 if (unlikely(aborted))
428592 ret = -ECANCELED;
....@@ -444,7 +608,7 @@
444608 struct nvmefc_fcp_req *fcpreq;
445609 bool completed = false;
446610
447
- spin_lock(&tfcp_req->reqlock);
611
+ spin_lock_irq(&tfcp_req->reqlock);
448612 fcpreq = tfcp_req->fcpreq;
449613 switch (tfcp_req->inistate) {
450614 case INI_IO_ABORTED:
....@@ -453,11 +617,11 @@
453617 completed = true;
454618 break;
455619 default:
456
- spin_unlock(&tfcp_req->reqlock);
620
+ spin_unlock_irq(&tfcp_req->reqlock);
457621 WARN_ON(1);
458622 return;
459623 }
460
- spin_unlock(&tfcp_req->reqlock);
624
+ spin_unlock_irq(&tfcp_req->reqlock);
461625
462626 if (unlikely(completed)) {
463627 /* remove reference taken in original abort downcall */
....@@ -469,9 +633,9 @@
469633 nvmet_fc_rcv_fcp_abort(tfcp_req->tport->targetport,
470634 &tfcp_req->tgt_fcp_req);
471635
472
- spin_lock(&tfcp_req->reqlock);
636
+ spin_lock_irq(&tfcp_req->reqlock);
473637 tfcp_req->fcpreq = NULL;
474
- spin_unlock(&tfcp_req->reqlock);
638
+ spin_unlock_irq(&tfcp_req->reqlock);
475639
476640 fcloop_call_host_done(fcpreq, tfcp_req, -ECANCELED);
477641 /* call_host_done releases reference for abort downcall */
....@@ -488,10 +652,10 @@
488652 container_of(work, struct fcloop_fcpreq, tio_done_work);
489653 struct nvmefc_fcp_req *fcpreq;
490654
491
- spin_lock(&tfcp_req->reqlock);
655
+ spin_lock_irq(&tfcp_req->reqlock);
492656 fcpreq = tfcp_req->fcpreq;
493657 tfcp_req->inistate = INI_IO_COMPLETED;
494
- spin_unlock(&tfcp_req->reqlock);
658
+ spin_unlock_irq(&tfcp_req->reqlock);
495659
496660 fcloop_call_host_done(fcpreq, tfcp_req, tfcp_req->status);
497661 }
....@@ -510,7 +674,7 @@
510674 if (!rport->targetport)
511675 return -ECONNREFUSED;
512676
513
- tfcp_req = kzalloc(sizeof(*tfcp_req), GFP_KERNEL);
677
+ tfcp_req = kzalloc(sizeof(*tfcp_req), GFP_ATOMIC);
514678 if (!tfcp_req)
515679 return -ENOMEM;
516680
....@@ -596,12 +760,12 @@
596760 int fcp_err = 0, active, aborted;
597761 u8 op = tgt_fcpreq->op;
598762
599
- spin_lock(&tfcp_req->reqlock);
763
+ spin_lock_irq(&tfcp_req->reqlock);
600764 fcpreq = tfcp_req->fcpreq;
601765 active = tfcp_req->active;
602766 aborted = tfcp_req->aborted;
603767 tfcp_req->active = true;
604
- spin_unlock(&tfcp_req->reqlock);
768
+ spin_unlock_irq(&tfcp_req->reqlock);
605769
606770 if (unlikely(active))
607771 /* illegal - call while i/o active */
....@@ -609,9 +773,9 @@
609773
610774 if (unlikely(aborted)) {
611775 /* target transport has aborted i/o prior */
612
- spin_lock(&tfcp_req->reqlock);
776
+ spin_lock_irq(&tfcp_req->reqlock);
613777 tfcp_req->active = false;
614
- spin_unlock(&tfcp_req->reqlock);
778
+ spin_unlock_irq(&tfcp_req->reqlock);
615779 tgt_fcpreq->transferred_length = 0;
616780 tgt_fcpreq->fcp_error = -ECANCELED;
617781 tgt_fcpreq->done(tgt_fcpreq);
....@@ -648,7 +812,7 @@
648812 break;
649813
650814 /* Fall-Thru to RSP handling */
651
- /* FALLTHRU */
815
+ fallthrough;
652816
653817 case NVMET_FCOP_RSP:
654818 if (fcpreq) {
....@@ -668,9 +832,9 @@
668832 break;
669833 }
670834
671
- spin_lock(&tfcp_req->reqlock);
835
+ spin_lock_irq(&tfcp_req->reqlock);
672836 tfcp_req->active = false;
673
- spin_unlock(&tfcp_req->reqlock);
837
+ spin_unlock_irq(&tfcp_req->reqlock);
674838
675839 tgt_fcpreq->transferred_length = xfrlen;
676840 tgt_fcpreq->fcp_error = fcp_err;
....@@ -690,9 +854,9 @@
690854 * (one doing io, other doing abort) and only kills ops posted
691855 * after the abort request
692856 */
693
- spin_lock(&tfcp_req->reqlock);
857
+ spin_lock_irq(&tfcp_req->reqlock);
694858 tfcp_req->aborted = true;
695
- spin_unlock(&tfcp_req->reqlock);
859
+ spin_unlock_irq(&tfcp_req->reqlock);
696860
697861 tfcp_req->status = NVME_SC_INTERNAL;
698862
....@@ -713,9 +877,15 @@
713877 }
714878
715879 static void
716
-fcloop_ls_abort(struct nvme_fc_local_port *localport,
880
+fcloop_h2t_ls_abort(struct nvme_fc_local_port *localport,
717881 struct nvme_fc_remote_port *remoteport,
718882 struct nvmefc_ls_req *lsreq)
883
+{
884
+}
885
+
886
+static void
887
+fcloop_t2h_ls_abort(struct nvmet_fc_target_port *targetport,
888
+ void *hosthandle, struct nvmefc_ls_req *lsreq)
719889 {
720890 }
721891
....@@ -740,7 +910,7 @@
740910 return;
741911
742912 /* break initiator/target relationship for io */
743
- spin_lock(&tfcp_req->reqlock);
913
+ spin_lock_irq(&tfcp_req->reqlock);
744914 switch (tfcp_req->inistate) {
745915 case INI_IO_START:
746916 case INI_IO_ACTIVE:
....@@ -750,11 +920,11 @@
750920 abortio = false;
751921 break;
752922 default:
753
- spin_unlock(&tfcp_req->reqlock);
923
+ spin_unlock_irq(&tfcp_req->reqlock);
754924 WARN_ON(1);
755925 return;
756926 }
757
- spin_unlock(&tfcp_req->reqlock);
927
+ spin_unlock_irq(&tfcp_req->reqlock);
758928
759929 if (abortio)
760930 /* leave the reference while the work item is scheduled */
....@@ -809,6 +979,7 @@
809979 {
810980 struct fcloop_rport *rport = remoteport->private;
811981
982
+ flush_work(&rport->ls_work);
812983 fcloop_nport_put(rport->nport);
813984 }
814985
....@@ -817,6 +988,7 @@
817988 {
818989 struct fcloop_tport *tport = targetport->private;
819990
991
+ flush_work(&tport->ls_work);
820992 fcloop_nport_put(tport->nport);
821993 }
822994
....@@ -829,10 +1001,11 @@
8291001 .remoteport_delete = fcloop_remoteport_delete,
8301002 .create_queue = fcloop_create_queue,
8311003 .delete_queue = fcloop_delete_queue,
832
- .ls_req = fcloop_ls_req,
1004
+ .ls_req = fcloop_h2t_ls_req,
8331005 .fcp_io = fcloop_fcp_req,
834
- .ls_abort = fcloop_ls_abort,
1006
+ .ls_abort = fcloop_h2t_ls_abort,
8351007 .fcp_abort = fcloop_fcp_abort,
1008
+ .xmt_ls_rsp = fcloop_t2h_xmt_ls_rsp,
8361009 .max_hw_queues = FCLOOP_HW_QUEUES,
8371010 .max_sgl_segments = FCLOOP_SGL_SEGS,
8381011 .max_dif_sgl_segments = FCLOOP_SGL_SEGS,
....@@ -846,10 +1019,14 @@
8461019
8471020 static struct nvmet_fc_target_template tgttemplate = {
8481021 .targetport_delete = fcloop_targetport_delete,
849
- .xmt_ls_rsp = fcloop_xmt_ls_rsp,
1022
+ .xmt_ls_rsp = fcloop_h2t_xmt_ls_rsp,
8501023 .fcp_op = fcloop_fcp_op,
8511024 .fcp_abort = fcloop_tgt_fcp_abort,
8521025 .fcp_req_release = fcloop_fcp_req_release,
1026
+ .discovery_event = fcloop_tgt_discovery_evt,
1027
+ .ls_req = fcloop_t2h_ls_req,
1028
+ .ls_abort = fcloop_t2h_ls_abort,
1029
+ .host_release = fcloop_t2h_host_release,
8531030 .max_hw_queues = FCLOOP_HW_QUEUES,
8541031 .max_sgl_segments = FCLOOP_SGL_SEGS,
8551032 .max_dif_sgl_segments = FCLOOP_SGL_SEGS,
....@@ -858,6 +1035,7 @@
8581035 .target_features = 0,
8591036 /* sizes of additional private data for data structures */
8601037 .target_priv_sz = sizeof(struct fcloop_tport),
1038
+ .lsrqst_priv_sz = sizeof(struct fcloop_lsreq),
8611039 };
8621040
8631041 static ssize_t
....@@ -1109,6 +1287,9 @@
11091287 rport->nport = nport;
11101288 rport->lport = nport->lport;
11111289 nport->rport = rport;
1290
+ spin_lock_init(&rport->lock);
1291
+ INIT_WORK(&rport->ls_work, fcloop_rport_lsrqst_work);
1292
+ INIT_LIST_HEAD(&rport->ls_list);
11121293
11131294 return count;
11141295 }
....@@ -1204,6 +1385,9 @@
12041385 tport->nport = nport;
12051386 tport->lport = nport->lport;
12061387 nport->tport = tport;
1388
+ spin_lock_init(&tport->lock);
1389
+ INIT_WORK(&tport->ls_work, fcloop_tport_lsrqst_work);
1390
+ INIT_LIST_HEAD(&tport->ls_list);
12071391
12081392 return count;
12091393 }