diff options
Diffstat (limited to 'drivers/scsi/libfc/fc_disc.c')
-rw-r--r-- | drivers/scsi/libfc/fc_disc.c | 84 |
1 files changed, 2 insertions, 82 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index a2410dc7444..428421842f3 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c | |||
@@ -45,8 +45,6 @@ | |||
45 | 45 | ||
46 | static void fc_disc_gpn_ft_req(struct fc_disc *); | 46 | static void fc_disc_gpn_ft_req(struct fc_disc *); |
47 | static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); | 47 | static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); |
48 | static int fc_disc_new_target(struct fc_disc *, struct fc_rport_priv *, | ||
49 | struct fc_rport_identifiers *); | ||
50 | static void fc_disc_done(struct fc_disc *, enum fc_disc_event); | 48 | static void fc_disc_done(struct fc_disc *, enum fc_disc_event); |
51 | static void fc_disc_timeout(struct work_struct *); | 49 | static void fc_disc_timeout(struct work_struct *); |
52 | static void fc_disc_single(struct fc_disc *, struct fc_disc_port *); | 50 | static 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 | */ |
246 | static void fc_disc_start(void (*disc_callback)(struct fc_lport *, | 243 | static 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 | */ | ||
300 | static 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 |