// SPDX-License-Identifier: GPL-2.0-only /* * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. * * Maintained at www.Open-FCoE.org */ /* * Target Discovery * * This block discovers all FC-4 remote ports, including FCP initiators. It * also handles RSCN events and re-discovery if necessary. */ /* * DISC LOCKING * * The disc mutex is can be locked when acquiring rport locks, but may not * be held when acquiring the lport lock. Refer to fc_lport.c for more * details. */ #include <linux/timer.h> #include <linux/slab.h> #include <linux/err.h> #include <linux/export.h> #include <linux/list.h> #include <linux/unaligned.h> #include <scsi/fc/fc_gs.h> #include <scsi/libfc.h> #include "fc_libfc.h" #define FC_DISC_RETRY_LIMIT … #define FC_DISC_RETRY_DELAY … static void fc_disc_gpn_ft_req(struct fc_disc *); static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); static void fc_disc_done(struct fc_disc *, enum fc_disc_event); static void fc_disc_timeout(struct work_struct *); static int fc_disc_single(struct fc_lport *, struct fc_disc_port *); static void fc_disc_restart(struct fc_disc *); /** * fc_disc_stop_rports() - Delete all the remote ports associated with the lport * @disc: The discovery job to stop remote ports on */ static void fc_disc_stop_rports(struct fc_disc *disc) { … } /** * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN) * @disc: The discovery object to which the RSCN applies * @fp: The RSCN frame */ static void fc_disc_recv_rscn_req(struct fc_disc *disc, struct fc_frame *fp) { … } /** * fc_disc_recv_req() - Handle incoming requests * @lport: The local port receiving the request * @fp: The request frame * * Locking Note: This function is called from the EM and will lock * the disc_mutex before calling the handler for the * request. */ static void fc_disc_recv_req(struct fc_lport *lport, struct fc_frame *fp) { … } /** * fc_disc_restart() - Restart discovery * @disc: The discovery object to be restarted */ static void fc_disc_restart(struct fc_disc *disc) { … } /** * fc_disc_start() - Start discovery on a local port * @lport: The local port to have discovery started on * @disc_callback: Callback function to be called when discovery is complete */ static void fc_disc_start(void (*disc_callback)(struct fc_lport *, enum fc_disc_event), struct fc_lport *lport) { … } /** * fc_disc_done() - Discovery has been completed * @disc: The discovery context * @event: The discovery completion status */ static void fc_disc_done(struct fc_disc *disc, enum fc_disc_event event) { … } /** * fc_disc_error() - Handle error on dNS request * @disc: The discovery context * @fp: The error code encoded as a frame pointer */ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp) { … } /** * fc_disc_gpn_ft_req() - Send Get Port Names by FC-4 type (GPN_FT) request * @disc: The discovery context */ static void fc_disc_gpn_ft_req(struct fc_disc *disc) { … } /** * fc_disc_gpn_ft_parse() - Parse the body of the dNS GPN_FT response. * @disc: The discovery context * @buf: The GPN_FT response buffer * @len: The size of response buffer * * Goes through the list of IDs and names resulting from a request. */ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) { … } /** * fc_disc_timeout() - Handler for discovery timeouts * @work: Structure holding discovery context that needs to retry discovery */ static void fc_disc_timeout(struct work_struct *work) { … } /** * fc_disc_gpn_ft_resp() - Handle a response frame from Get Port Names (GPN_FT) * @sp: The sequence that the GPN_FT response was received on * @fp: The GPN_FT response frame * @disc_arg: The discovery context * * Locking Note: This function is called without disc mutex held, and * should do all its processing with the mutex held */ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, void *disc_arg) { … } /** * fc_disc_gpn_id_resp() - Handle a response frame from Get Port Names (GPN_ID) * @sp: The sequence the GPN_ID is on * @fp: The response frame * @rdata_arg: The remote port that sent the GPN_ID response * * Locking Note: This function is called without disc mutex held. */ static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, void *rdata_arg) { … } /** * fc_disc_gpn_id_req() - Send Get Port Names by ID (GPN_ID) request * @lport: The local port to initiate discovery on * @rdata: remote port private data * * On failure, an error code is returned. */ static int fc_disc_gpn_id_req(struct fc_lport *lport, struct fc_rport_priv *rdata) { … } /** * fc_disc_single() - Discover the directory information for a single target * @lport: The local port the remote port is associated with * @dp: The port to rediscover */ static int fc_disc_single(struct fc_lport *lport, struct fc_disc_port *dp) { … } /** * fc_disc_stop() - Stop discovery for a given lport * @lport: The local port that discovery should stop on */ static void fc_disc_stop(struct fc_lport *lport) { … } /** * fc_disc_stop_final() - Stop discovery for a given lport * @lport: The lport that discovery should stop on * * This function will block until discovery has been * completely stopped and all rports have been deleted. */ static void fc_disc_stop_final(struct fc_lport *lport) { … } /** * fc_disc_config() - Configure the discovery layer for a local port * @lport: The local port that needs the discovery layer to be configured * @priv: Private data structre for users of the discovery layer */ void fc_disc_config(struct fc_lport *lport, void *priv) { … } EXPORT_SYMBOL(…); /** * fc_disc_init() - Initialize the discovery layer for a local port * @lport: The local port that needs the discovery layer to be initialized */ void fc_disc_init(struct fc_lport *lport) { … } EXPORT_SYMBOL(…);