aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_iscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_transport_iscsi.c')
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c97
1 files changed, 68 insertions, 29 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index c0ec502835ee..f39da0cf5f18 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -287,20 +287,11 @@ void iscsi_block_session(struct iscsi_cls_session *session)
287} 287}
288EXPORT_SYMBOL_GPL(iscsi_block_session); 288EXPORT_SYMBOL_GPL(iscsi_block_session);
289 289
290/**
291 * iscsi_create_session - create iscsi class session
292 * @shost: scsi host
293 * @transport: iscsi transport
294 *
295 * This can be called from a LLD or iscsi_transport.
296 **/
297struct iscsi_cls_session * 290struct iscsi_cls_session *
298iscsi_create_session(struct Scsi_Host *shost, 291iscsi_alloc_session(struct Scsi_Host *shost,
299 struct iscsi_transport *transport) 292 struct iscsi_transport *transport)
300{ 293{
301 struct iscsi_host *ihost;
302 struct iscsi_cls_session *session; 294 struct iscsi_cls_session *session;
303 int err;
304 295
305 session = kzalloc(sizeof(*session) + transport->sessiondata_size, 296 session = kzalloc(sizeof(*session) + transport->sessiondata_size,
306 GFP_KERNEL); 297 GFP_KERNEL);
@@ -313,8 +304,20 @@ iscsi_create_session(struct Scsi_Host *shost,
313 INIT_LIST_HEAD(&session->host_list); 304 INIT_LIST_HEAD(&session->host_list);
314 INIT_LIST_HEAD(&session->sess_list); 305 INIT_LIST_HEAD(&session->sess_list);
315 306
307 session->dev.parent = &shost->shost_gendev;
308 session->dev.release = iscsi_session_release;
309 device_initialize(&session->dev);
316 if (transport->sessiondata_size) 310 if (transport->sessiondata_size)
317 session->dd_data = &session[1]; 311 session->dd_data = &session[1];
312 return session;
313}
314EXPORT_SYMBOL_GPL(iscsi_alloc_session);
315
316int iscsi_add_session(struct iscsi_cls_session *session)
317{
318 struct Scsi_Host *shost = iscsi_session_to_shost(session);
319 struct iscsi_host *ihost;
320 int err;
318 321
319 /* this is released in the dev's release function */ 322 /* this is released in the dev's release function */
320 scsi_host_get(shost); 323 scsi_host_get(shost);
@@ -325,37 +328,51 @@ iscsi_create_session(struct Scsi_Host *shost,
325 328
326 snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", 329 snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
327 session->sid); 330 session->sid);
328 session->dev.parent = &shost->shost_gendev; 331 err = device_add(&session->dev);
329 session->dev.release = iscsi_session_release;
330 err = device_register(&session->dev);
331 if (err) { 332 if (err) {
332 dev_printk(KERN_ERR, &session->dev, "iscsi: could not " 333 dev_printk(KERN_ERR, &session->dev, "iscsi: could not "
333 "register session's dev\n"); 334 "register session's dev\n");
334 goto free_session; 335 goto release_host;
335 } 336 }
336 transport_register_device(&session->dev); 337 transport_register_device(&session->dev);
337 338
338 mutex_lock(&ihost->mutex); 339 mutex_lock(&ihost->mutex);
339 list_add(&session->host_list, &ihost->sessions); 340 list_add(&session->host_list, &ihost->sessions);
340 mutex_unlock(&ihost->mutex); 341 mutex_unlock(&ihost->mutex);
342 return 0;
341 343
342 return session; 344release_host:
343 345 scsi_host_put(shost);
344free_session: 346 return err;
345 kfree(session);
346 return NULL;
347} 347}
348 348EXPORT_SYMBOL_GPL(iscsi_add_session);
349EXPORT_SYMBOL_GPL(iscsi_create_session);
350 349
351/** 350/**
352 * iscsi_destroy_session - destroy iscsi session 351 * iscsi_create_session - create iscsi class session
353 * @session: iscsi_session 352 * @shost: scsi host
353 * @transport: iscsi transport
354 * 354 *
355 * Can be called by a LLD or iscsi_transport. There must not be 355 * This can be called from a LLD or iscsi_transport.
356 * any running connections.
357 **/ 356 **/
358int iscsi_destroy_session(struct iscsi_cls_session *session) 357struct iscsi_cls_session *
358iscsi_create_session(struct Scsi_Host *shost,
359 struct iscsi_transport *transport)
360{
361 struct iscsi_cls_session *session;
362
363 session = iscsi_alloc_session(shost, transport);
364 if (!session)
365 return NULL;
366
367 if (iscsi_add_session(session)) {
368 iscsi_free_session(session);
369 return NULL;
370 }
371 return session;
372}
373EXPORT_SYMBOL_GPL(iscsi_create_session);
374
375void iscsi_remove_session(struct iscsi_cls_session *session)
359{ 376{
360 struct Scsi_Host *shost = iscsi_session_to_shost(session); 377 struct Scsi_Host *shost = iscsi_session_to_shost(session);
361 struct iscsi_host *ihost = shost->shost_data; 378 struct iscsi_host *ihost = shost->shost_data;
@@ -367,11 +384,33 @@ int iscsi_destroy_session(struct iscsi_cls_session *session)
367 list_del(&session->host_list); 384 list_del(&session->host_list);
368 mutex_unlock(&ihost->mutex); 385 mutex_unlock(&ihost->mutex);
369 386
387 scsi_remove_target(&session->dev);
388
370 transport_unregister_device(&session->dev); 389 transport_unregister_device(&session->dev);
371 device_unregister(&session->dev); 390 device_del(&session->dev);
372 return 0;
373} 391}
392EXPORT_SYMBOL_GPL(iscsi_remove_session);
374 393
394void iscsi_free_session(struct iscsi_cls_session *session)
395{
396 put_device(&session->dev);
397}
398
399EXPORT_SYMBOL_GPL(iscsi_free_session);
400
401/**
402 * iscsi_destroy_session - destroy iscsi session
403 * @session: iscsi_session
404 *
405 * Can be called by a LLD or iscsi_transport. There must not be
406 * any running connections.
407 **/
408int iscsi_destroy_session(struct iscsi_cls_session *session)
409{
410 iscsi_remove_session(session);
411 iscsi_free_session(session);
412 return 0;
413}
375EXPORT_SYMBOL_GPL(iscsi_destroy_session); 414EXPORT_SYMBOL_GPL(iscsi_destroy_session);
376 415
377static void iscsi_conn_release(struct device *dev) 416static void iscsi_conn_release(struct device *dev)