aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_disc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libfc/fc_disc.c')
-rw-r--r--drivers/scsi/libfc/fc_disc.c84
1 files changed, 2 insertions, 82 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index a2410dc74441..428421842f3a 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -45,8 +45,6 @@
45 45
46static void fc_disc_gpn_ft_req(struct fc_disc *); 46static void fc_disc_gpn_ft_req(struct fc_disc *);
47static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); 47static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *);
48static int fc_disc_new_target(struct fc_disc *, struct fc_rport_priv *,
49 struct fc_rport_identifiers *);
50static void fc_disc_done(struct fc_disc *, enum fc_disc_event); 48static void fc_disc_done(struct fc_disc *, enum fc_disc_event);
51static void fc_disc_timeout(struct work_struct *); 49static void fc_disc_timeout(struct work_struct *);
52static void fc_disc_single(struct fc_disc *, struct fc_disc_port *); 50static void fc_disc_single(struct fc_disc *, struct fc_disc_port *);
@@ -240,14 +238,12 @@ static void fc_disc_restart(struct fc_disc *disc)
240/** 238/**
241 * fc_disc_start() - Fibre Channel Target discovery 239 * fc_disc_start() - Fibre Channel Target discovery
242 * @lport: FC local port 240 * @lport: FC local port
243 * 241 * @disc_callback: function to be called when discovery is complete
244 * Returns non-zero if discovery cannot be started.
245 */ 242 */
246static void fc_disc_start(void (*disc_callback)(struct fc_lport *, 243static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
247 enum fc_disc_event), 244 enum fc_disc_event),
248 struct fc_lport *lport) 245 struct fc_lport *lport)
249{ 246{
250 struct fc_rport_priv *rdata;
251 struct fc_disc *disc = &lport->disc; 247 struct fc_disc *disc = &lport->disc;
252 248
253 /* 249 /*
@@ -256,88 +252,12 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
256 * and send the GPN_FT request. 252 * and send the GPN_FT request.
257 */ 253 */
258 mutex_lock(&disc->disc_mutex); 254 mutex_lock(&disc->disc_mutex);
259
260 disc->disc_callback = disc_callback; 255 disc->disc_callback = disc_callback;
261 256 fc_disc_restart(disc);
262 /*
263 * If not ready, or already running discovery, just set request flag.
264 */
265 disc->requested = 1;
266
267 if (disc->pending) {
268 mutex_unlock(&disc->disc_mutex);
269 return;
270 }
271
272 /*
273 * Handle point-to-point mode as a simple discovery
274 * of the remote port. Yucky, yucky, yuck, yuck!
275 */
276 rdata = disc->lport->ptp_rp;
277 if (rdata) {
278 kref_get(&rdata->kref);
279 if (!fc_disc_new_target(disc, rdata, &rdata->ids)) {
280 fc_disc_done(disc, DISC_EV_SUCCESS);
281 }
282 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
283 } else {
284 disc->disc_id = (disc->disc_id + 2) | 1;
285 fc_disc_gpn_ft_req(disc); /* get ports by FC-4 type */
286 }
287
288 mutex_unlock(&disc->disc_mutex); 257 mutex_unlock(&disc->disc_mutex);
289} 258}
290 259
291/** 260/**
292 * fc_disc_new_target() - Handle new target found by discovery
293 * @lport: FC local port
294 * @rdata: The previous FC remote port priv (NULL if new remote port)
295 * @ids: Identifiers for the new FC remote port
296 *
297 * Locking Note: This function expects that the disc_mutex is locked
298 * before it is called.
299 */
300static int fc_disc_new_target(struct fc_disc *disc,
301 struct fc_rport_priv *rdata,
302 struct fc_rport_identifiers *ids)
303{
304 struct fc_lport *lport = disc->lport;
305 int error = 0;
306
307 if (rdata && ids->port_name) {
308 if (rdata->ids.port_name == -1) {
309 /*
310 * Set WWN and fall through to notify of create.
311 */
312 rdata->ids.port_name = ids->port_name;
313 rdata->ids.node_name = ids->node_name;
314 } else if (rdata->ids.port_name != ids->port_name) {
315 /*
316 * This is a new port with the same FCID as
317 * a previously-discovered port. Presumably the old
318 * port logged out and a new port logged in and was
319 * assigned the same FCID. This should be rare.
320 * Delete the old one and fall thru to re-create.
321 */
322 lport->tt.rport_logoff(rdata);
323 rdata = NULL;
324 }
325 }
326 if (((ids->port_name != -1) || (ids->port_id != -1)) &&
327 ids->port_id != fc_host_port_id(lport->host) &&
328 ids->port_name != lport->wwpn) {
329 if (!rdata) {
330 rdata = lport->tt.rport_create(lport, ids);
331 if (!rdata)
332 error = -ENOMEM;
333 }
334 if (rdata)
335 lport->tt.rport_login(rdata);
336 }
337 return error;
338}
339
340/**
341 * fc_disc_done() - Discovery has been completed 261 * fc_disc_done() - Discovery has been completed
342 * @disc: FC discovery context 262 * @disc: FC discovery context
343 * @event: discovery completion status 263 * @event: discovery completion status