diff options
| -rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 97 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 8 |
2 files changed, 76 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 | } |
| 288 | EXPORT_SYMBOL_GPL(iscsi_block_session); | 288 | EXPORT_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 | **/ | ||
| 297 | struct iscsi_cls_session * | 290 | struct iscsi_cls_session * |
| 298 | iscsi_create_session(struct Scsi_Host *shost, | 291 | iscsi_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 | } | ||
| 314 | EXPORT_SYMBOL_GPL(iscsi_alloc_session); | ||
| 315 | |||
| 316 | int 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; | 344 | release_host: |
| 343 | 345 | scsi_host_put(shost); | |
| 344 | free_session: | 346 | return err; |
| 345 | kfree(session); | ||
| 346 | return NULL; | ||
| 347 | } | 347 | } |
| 348 | 348 | EXPORT_SYMBOL_GPL(iscsi_add_session); | |
| 349 | EXPORT_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 | **/ |
| 358 | int iscsi_destroy_session(struct iscsi_cls_session *session) | 357 | struct iscsi_cls_session * |
| 358 | iscsi_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 | } | ||
| 373 | EXPORT_SYMBOL_GPL(iscsi_create_session); | ||
| 374 | |||
| 375 | void 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 | } |
| 392 | EXPORT_SYMBOL_GPL(iscsi_remove_session); | ||
| 374 | 393 | ||
| 394 | void iscsi_free_session(struct iscsi_cls_session *session) | ||
| 395 | { | ||
| 396 | put_device(&session->dev); | ||
| 397 | } | ||
| 398 | |||
| 399 | EXPORT_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 | **/ | ||
| 408 | int iscsi_destroy_session(struct iscsi_cls_session *session) | ||
| 409 | { | ||
| 410 | iscsi_remove_session(session); | ||
| 411 | iscsi_free_session(session); | ||
| 412 | return 0; | ||
| 413 | } | ||
| 375 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); | 414 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); |
| 376 | 415 | ||
| 377 | static void iscsi_conn_release(struct device *dev) | 416 | static void iscsi_conn_release(struct device *dev) |
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 2e3cb37af047..53493d591355 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h | |||
| @@ -199,6 +199,9 @@ struct iscsi_cls_session { | |||
| 199 | #define iscsi_session_to_shost(_session) \ | 199 | #define iscsi_session_to_shost(_session) \ |
| 200 | dev_to_shost(_session->dev.parent) | 200 | dev_to_shost(_session->dev.parent) |
| 201 | 201 | ||
| 202 | #define starget_to_session(_stgt) \ | ||
| 203 | iscsi_dev_to_session(_stgt->dev.parent) | ||
| 204 | |||
| 202 | struct iscsi_host { | 205 | struct iscsi_host { |
| 203 | int next_target_id; | 206 | int next_target_id; |
| 204 | struct list_head sessions; | 207 | struct list_head sessions; |
| @@ -208,8 +211,13 @@ struct iscsi_host { | |||
| 208 | /* | 211 | /* |
| 209 | * session and connection functions that can be used by HW iSCSI LLDs | 212 | * session and connection functions that can be used by HW iSCSI LLDs |
| 210 | */ | 213 | */ |
| 214 | extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost, | ||
| 215 | struct iscsi_transport *transport); | ||
| 216 | extern int iscsi_add_session(struct iscsi_cls_session *session); | ||
| 211 | extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, | 217 | extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, |
| 212 | struct iscsi_transport *t); | 218 | struct iscsi_transport *t); |
| 219 | extern void iscsi_remove_session(struct iscsi_cls_session *session); | ||
| 220 | extern void iscsi_free_session(struct iscsi_cls_session *session); | ||
| 213 | extern int iscsi_destroy_session(struct iscsi_cls_session *session); | 221 | extern int iscsi_destroy_session(struct iscsi_cls_session *session); |
| 214 | extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, | 222 | extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, |
| 215 | uint32_t cid); | 223 | uint32_t cid); |
