diff options
Diffstat (limited to 'drivers/target/tcm_fc/tfc_conf.c')
-rw-r--r-- | drivers/target/tcm_fc/tfc_conf.c | 76 |
1 files changed, 39 insertions, 37 deletions
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index e879da81ad93..efdcb9663a1a 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c | |||
@@ -50,7 +50,7 @@ | |||
50 | 50 | ||
51 | struct target_fabric_configfs *ft_configfs; | 51 | struct target_fabric_configfs *ft_configfs; |
52 | 52 | ||
53 | LIST_HEAD(ft_lport_list); | 53 | static LIST_HEAD(ft_wwn_list); |
54 | DEFINE_MUTEX(ft_lport_lock); | 54 | DEFINE_MUTEX(ft_lport_lock); |
55 | 55 | ||
56 | unsigned int ft_debug_logging; | 56 | unsigned int ft_debug_logging; |
@@ -298,7 +298,7 @@ static struct se_portal_group *ft_add_tpg( | |||
298 | struct config_group *group, | 298 | struct config_group *group, |
299 | const char *name) | 299 | const char *name) |
300 | { | 300 | { |
301 | struct ft_lport_acl *lacl; | 301 | struct ft_lport_wwn *ft_wwn; |
302 | struct ft_tpg *tpg; | 302 | struct ft_tpg *tpg; |
303 | struct workqueue_struct *wq; | 303 | struct workqueue_struct *wq; |
304 | unsigned long index; | 304 | unsigned long index; |
@@ -318,12 +318,17 @@ static struct se_portal_group *ft_add_tpg( | |||
318 | if (index > UINT_MAX) | 318 | if (index > UINT_MAX) |
319 | return NULL; | 319 | return NULL; |
320 | 320 | ||
321 | lacl = container_of(wwn, struct ft_lport_acl, fc_lport_wwn); | 321 | if ((index != 1)) { |
322 | pr_err("Error, a single TPG=1 is used for HW port mappings\n"); | ||
323 | return ERR_PTR(-ENOSYS); | ||
324 | } | ||
325 | |||
326 | ft_wwn = container_of(wwn, struct ft_lport_wwn, se_wwn); | ||
322 | tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); | 327 | tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); |
323 | if (!tpg) | 328 | if (!tpg) |
324 | return NULL; | 329 | return NULL; |
325 | tpg->index = index; | 330 | tpg->index = index; |
326 | tpg->lport_acl = lacl; | 331 | tpg->lport_wwn = ft_wwn; |
327 | INIT_LIST_HEAD(&tpg->lun_list); | 332 | INIT_LIST_HEAD(&tpg->lun_list); |
328 | 333 | ||
329 | wq = alloc_workqueue("tcm_fc", 0, 1); | 334 | wq = alloc_workqueue("tcm_fc", 0, 1); |
@@ -342,7 +347,7 @@ static struct se_portal_group *ft_add_tpg( | |||
342 | tpg->workqueue = wq; | 347 | tpg->workqueue = wq; |
343 | 348 | ||
344 | mutex_lock(&ft_lport_lock); | 349 | mutex_lock(&ft_lport_lock); |
345 | list_add_tail(&tpg->list, &lacl->tpg_list); | 350 | ft_wwn->tpg = tpg; |
346 | mutex_unlock(&ft_lport_lock); | 351 | mutex_unlock(&ft_lport_lock); |
347 | 352 | ||
348 | return &tpg->se_tpg; | 353 | return &tpg->se_tpg; |
@@ -351,6 +356,7 @@ static struct se_portal_group *ft_add_tpg( | |||
351 | static void ft_del_tpg(struct se_portal_group *se_tpg) | 356 | static void ft_del_tpg(struct se_portal_group *se_tpg) |
352 | { | 357 | { |
353 | struct ft_tpg *tpg = container_of(se_tpg, struct ft_tpg, se_tpg); | 358 | struct ft_tpg *tpg = container_of(se_tpg, struct ft_tpg, se_tpg); |
359 | struct ft_lport_wwn *ft_wwn = tpg->lport_wwn; | ||
354 | 360 | ||
355 | pr_debug("del tpg %s\n", | 361 | pr_debug("del tpg %s\n", |
356 | config_item_name(&tpg->se_tpg.tpg_group.cg_item)); | 362 | config_item_name(&tpg->se_tpg.tpg_group.cg_item)); |
@@ -361,7 +367,7 @@ static void ft_del_tpg(struct se_portal_group *se_tpg) | |||
361 | synchronize_rcu(); | 367 | synchronize_rcu(); |
362 | 368 | ||
363 | mutex_lock(&ft_lport_lock); | 369 | mutex_lock(&ft_lport_lock); |
364 | list_del(&tpg->list); | 370 | ft_wwn->tpg = NULL; |
365 | if (tpg->tport) { | 371 | if (tpg->tport) { |
366 | tpg->tport->tpg = NULL; | 372 | tpg->tport->tpg = NULL; |
367 | tpg->tport = NULL; | 373 | tpg->tport = NULL; |
@@ -380,15 +386,11 @@ static void ft_del_tpg(struct se_portal_group *se_tpg) | |||
380 | */ | 386 | */ |
381 | struct ft_tpg *ft_lport_find_tpg(struct fc_lport *lport) | 387 | struct ft_tpg *ft_lport_find_tpg(struct fc_lport *lport) |
382 | { | 388 | { |
383 | struct ft_lport_acl *lacl; | 389 | struct ft_lport_wwn *ft_wwn; |
384 | struct ft_tpg *tpg; | ||
385 | 390 | ||
386 | list_for_each_entry(lacl, &ft_lport_list, list) { | 391 | list_for_each_entry(ft_wwn, &ft_wwn_list, ft_wwn_node) { |
387 | if (lacl->wwpn == lport->wwpn) { | 392 | if (ft_wwn->wwpn == lport->wwpn) |
388 | list_for_each_entry(tpg, &lacl->tpg_list, list) | 393 | return ft_wwn->tpg; |
389 | return tpg; /* XXX for now return first entry */ | ||
390 | return NULL; | ||
391 | } | ||
392 | } | 394 | } |
393 | return NULL; | 395 | return NULL; |
394 | } | 396 | } |
@@ -401,50 +403,49 @@ struct ft_tpg *ft_lport_find_tpg(struct fc_lport *lport) | |||
401 | * Add lport to allowed config. | 403 | * Add lport to allowed config. |
402 | * The name is the WWPN in lower-case ASCII, colon-separated bytes. | 404 | * The name is the WWPN in lower-case ASCII, colon-separated bytes. |
403 | */ | 405 | */ |
404 | static struct se_wwn *ft_add_lport( | 406 | static struct se_wwn *ft_add_wwn( |
405 | struct target_fabric_configfs *tf, | 407 | struct target_fabric_configfs *tf, |
406 | struct config_group *group, | 408 | struct config_group *group, |
407 | const char *name) | 409 | const char *name) |
408 | { | 410 | { |
409 | struct ft_lport_acl *lacl; | 411 | struct ft_lport_wwn *ft_wwn; |
410 | struct ft_lport_acl *old_lacl; | 412 | struct ft_lport_wwn *old_ft_wwn; |
411 | u64 wwpn; | 413 | u64 wwpn; |
412 | 414 | ||
413 | pr_debug("add lport %s\n", name); | 415 | pr_debug("add wwn %s\n", name); |
414 | if (ft_parse_wwn(name, &wwpn, 1) < 0) | 416 | if (ft_parse_wwn(name, &wwpn, 1) < 0) |
415 | return NULL; | 417 | return NULL; |
416 | lacl = kzalloc(sizeof(*lacl), GFP_KERNEL); | 418 | ft_wwn = kzalloc(sizeof(*ft_wwn), GFP_KERNEL); |
417 | if (!lacl) | 419 | if (!ft_wwn) |
418 | return NULL; | 420 | return NULL; |
419 | lacl->wwpn = wwpn; | 421 | ft_wwn->wwpn = wwpn; |
420 | INIT_LIST_HEAD(&lacl->tpg_list); | ||
421 | 422 | ||
422 | mutex_lock(&ft_lport_lock); | 423 | mutex_lock(&ft_lport_lock); |
423 | list_for_each_entry(old_lacl, &ft_lport_list, list) { | 424 | list_for_each_entry(old_ft_wwn, &ft_wwn_list, ft_wwn_node) { |
424 | if (old_lacl->wwpn == wwpn) { | 425 | if (old_ft_wwn->wwpn == wwpn) { |
425 | mutex_unlock(&ft_lport_lock); | 426 | mutex_unlock(&ft_lport_lock); |
426 | kfree(lacl); | 427 | kfree(ft_wwn); |
427 | return NULL; | 428 | return NULL; |
428 | } | 429 | } |
429 | } | 430 | } |
430 | list_add_tail(&lacl->list, &ft_lport_list); | 431 | list_add_tail(&ft_wwn->ft_wwn_node, &ft_wwn_list); |
431 | ft_format_wwn(lacl->name, sizeof(lacl->name), wwpn); | 432 | ft_format_wwn(ft_wwn->name, sizeof(ft_wwn->name), wwpn); |
432 | mutex_unlock(&ft_lport_lock); | 433 | mutex_unlock(&ft_lport_lock); |
433 | 434 | ||
434 | return &lacl->fc_lport_wwn; | 435 | return &ft_wwn->se_wwn; |
435 | } | 436 | } |
436 | 437 | ||
437 | static void ft_del_lport(struct se_wwn *wwn) | 438 | static void ft_del_wwn(struct se_wwn *wwn) |
438 | { | 439 | { |
439 | struct ft_lport_acl *lacl = container_of(wwn, | 440 | struct ft_lport_wwn *ft_wwn = container_of(wwn, |
440 | struct ft_lport_acl, fc_lport_wwn); | 441 | struct ft_lport_wwn, se_wwn); |
441 | 442 | ||
442 | pr_debug("del lport %s\n", lacl->name); | 443 | pr_debug("del wwn %s\n", ft_wwn->name); |
443 | mutex_lock(&ft_lport_lock); | 444 | mutex_lock(&ft_lport_lock); |
444 | list_del(&lacl->list); | 445 | list_del(&ft_wwn->ft_wwn_node); |
445 | mutex_unlock(&ft_lport_lock); | 446 | mutex_unlock(&ft_lport_lock); |
446 | 447 | ||
447 | kfree(lacl); | 448 | kfree(ft_wwn); |
448 | } | 449 | } |
449 | 450 | ||
450 | static ssize_t ft_wwn_show_attr_version( | 451 | static ssize_t ft_wwn_show_attr_version( |
@@ -471,7 +472,7 @@ static char *ft_get_fabric_wwn(struct se_portal_group *se_tpg) | |||
471 | { | 472 | { |
472 | struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr; | 473 | struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr; |
473 | 474 | ||
474 | return tpg->lport_acl->name; | 475 | return tpg->lport_wwn->name; |
475 | } | 476 | } |
476 | 477 | ||
477 | static u16 ft_get_tag(struct se_portal_group *se_tpg) | 478 | static u16 ft_get_tag(struct se_portal_group *se_tpg) |
@@ -536,12 +537,13 @@ static struct target_core_fabric_ops ft_fabric_ops = { | |||
536 | .queue_data_in = ft_queue_data_in, | 537 | .queue_data_in = ft_queue_data_in, |
537 | .queue_status = ft_queue_status, | 538 | .queue_status = ft_queue_status, |
538 | .queue_tm_rsp = ft_queue_tm_resp, | 539 | .queue_tm_rsp = ft_queue_tm_resp, |
540 | .aborted_task = ft_aborted_task, | ||
539 | /* | 541 | /* |
540 | * Setup function pointers for generic logic in | 542 | * Setup function pointers for generic logic in |
541 | * target_core_fabric_configfs.c | 543 | * target_core_fabric_configfs.c |
542 | */ | 544 | */ |
543 | .fabric_make_wwn = &ft_add_lport, | 545 | .fabric_make_wwn = &ft_add_wwn, |
544 | .fabric_drop_wwn = &ft_del_lport, | 546 | .fabric_drop_wwn = &ft_del_wwn, |
545 | .fabric_make_tpg = &ft_add_tpg, | 547 | .fabric_make_tpg = &ft_add_tpg, |
546 | .fabric_drop_tpg = &ft_del_tpg, | 548 | .fabric_drop_tpg = &ft_del_tpg, |
547 | .fabric_post_link = NULL, | 549 | .fabric_post_link = NULL, |