aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_iscsi.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-04-06 22:13:41 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-04-14 15:09:00 -0400
commit7996a778ff8c717cb1a7a294475c59cc8f1e9fb8 (patch)
tree3d7ee67ad547a65ad10f5c7e41e20f6124ee249b /drivers/scsi/scsi_transport_iscsi.c
parent30a6c65236f9d26e3325cae468f330b833a3878c (diff)
[SCSI] iscsi: add libiscsi
There is a lot of code duplcited between iscsi_tcp and the upcoming iscsi_iser driver. This patch puts the duplicated code in a lib. There is more code to move around but this takes care of the basics. For iscsi_offload if they use the lib we will probably move some things around. For example in the queuecommand we will not assume that the LLD wants to do queue_work, but it is better to handle that later when we know for sure what iscsi_offload looks like (we could probably do this for iscsi_iser though to). Ideally I would like to get the iscsi_transports modules to a place where all they really have to do is put data on the wire, but how to do that will hopefully be more clear when we see other modules like iscsi_offload. Or maybe iscsi_offload will not use the lib and it will just be iscsi_iser and iscsi_tcp and maybe the iscsi_tcp_tgt if that is allowed in mainline. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_transport_iscsi.c')
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c116
1 files changed, 13 insertions, 103 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index e2b67e34d92e..bc9071d2d212 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -472,106 +472,6 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
472EXPORT_SYMBOL_GPL(iscsi_destroy_conn); 472EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
473 473
474/* 474/*
475 * These functions are used only by software iscsi_transports
476 * which do not allocate and more their scsi_hosts since this
477 * is initiated from userspace.
478 */
479
480/*
481 * iSCSI Session's hostdata organization:
482 *
483 * *------------------* <== hostdata_session(host->hostdata)
484 * | ptr to class sess|
485 * |------------------| <== iscsi_hostdata(host->hostdata)
486 * | transport's data |
487 * *------------------*
488 */
489
490#define hostdata_privsize(_t) (sizeof(unsigned long) + _t->hostdata_size + \
491 _t->hostdata_size % sizeof(unsigned long))
492
493#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
494
495/**
496 * iscsi_transport_create_session - create iscsi cls session and host
497 * scsit: scsi transport template
498 * transport: iscsi transport template
499 *
500 * This can be used by software iscsi_transports that allocate
501 * a session per scsi host.
502 **/
503struct Scsi_Host *
504iscsi_transport_create_session(struct scsi_transport_template *scsit,
505 struct iscsi_transport *transport)
506{
507 struct iscsi_cls_session *session;
508 struct Scsi_Host *shost;
509 unsigned long flags;
510
511 shost = scsi_host_alloc(transport->host_template,
512 hostdata_privsize(transport));
513 if (!shost) {
514 printk(KERN_ERR "iscsi: can not allocate SCSI host for "
515 "session\n");
516 return NULL;
517 }
518
519 shost->max_id = 1;
520 shost->max_channel = 0;
521 shost->max_lun = transport->max_lun;
522 shost->max_cmd_len = transport->max_cmd_len;
523 shost->transportt = scsit;
524 shost->transportt->create_work_queue = 1;
525
526 if (scsi_add_host(shost, NULL))
527 goto free_host;
528
529 session = iscsi_create_session(shost, transport, 0);
530 if (!session)
531 goto remove_host;
532
533 *(unsigned long*)shost->hostdata = (unsigned long)session;
534 spin_lock_irqsave(&sesslock, flags);
535 list_add(&session->sess_list, &sesslist);
536 spin_unlock_irqrestore(&sesslock, flags);
537 return shost;
538
539remove_host:
540 scsi_remove_host(shost);
541free_host:
542 scsi_host_put(shost);
543 return NULL;
544}
545
546EXPORT_SYMBOL_GPL(iscsi_transport_create_session);
547
548/**
549 * iscsi_transport_destroy_session - destroy session and scsi host
550 * shost: scsi host
551 *
552 * This can be used by software iscsi_transports that allocate
553 * a session per scsi host.
554 **/
555int iscsi_transport_destroy_session(struct Scsi_Host *shost)
556{
557 struct iscsi_cls_session *session;
558 unsigned long flags;
559
560 session = hostdata_session(shost->hostdata);
561 spin_lock_irqsave(&sesslock, flags);
562 list_del(&session->sess_list);
563 spin_unlock_irqrestore(&sesslock, flags);
564 iscsi_destroy_session(session);
565
566 scsi_remove_host(shost);
567 /* ref from host alloc */
568 scsi_host_put(shost);
569 return 0;
570}
571
572EXPORT_SYMBOL_GPL(iscsi_transport_destroy_session);
573
574/*
575 * iscsi interface functions 475 * iscsi interface functions
576 */ 476 */
577static struct iscsi_internal * 477static struct iscsi_internal *
@@ -857,14 +757,19 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
857{ 757{
858 struct iscsi_transport *transport = priv->iscsi_transport; 758 struct iscsi_transport *transport = priv->iscsi_transport;
859 struct iscsi_cls_session *session; 759 struct iscsi_cls_session *session;
760 unsigned long flags;
860 uint32_t hostno; 761 uint32_t hostno;
861 762
862 session = transport->create_session(&priv->t, 763 session = transport->create_session(transport, &priv->t,
863 ev->u.c_session.initial_cmdsn, 764 ev->u.c_session.initial_cmdsn,
864 &hostno); 765 &hostno);
865 if (!session) 766 if (!session)
866 return -ENOMEM; 767 return -ENOMEM;
867 768
769 spin_lock_irqsave(&sesslock, flags);
770 list_add(&session->sess_list, &sesslist);
771 spin_unlock_irqrestore(&sesslock, flags);
772
868 ev->r.c_session_ret.host_no = hostno; 773 ev->r.c_session_ret.host_no = hostno;
869 ev->r.c_session_ret.sid = session->sid; 774 ev->r.c_session_ret.sid = session->sid;
870 return 0; 775 return 0;
@@ -1032,6 +937,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1032 struct iscsi_internal *priv; 937 struct iscsi_internal *priv;
1033 struct iscsi_cls_session *session; 938 struct iscsi_cls_session *session;
1034 struct iscsi_cls_conn *conn; 939 struct iscsi_cls_conn *conn;
940 unsigned long flags;
1035 941
1036 priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); 942 priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
1037 if (!priv) 943 if (!priv)
@@ -1047,9 +953,13 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1047 break; 953 break;
1048 case ISCSI_UEVENT_DESTROY_SESSION: 954 case ISCSI_UEVENT_DESTROY_SESSION:
1049 session = iscsi_session_lookup(ev->u.d_session.sid); 955 session = iscsi_session_lookup(ev->u.d_session.sid);
1050 if (session) 956 if (session) {
957 spin_lock_irqsave(&sesslock, flags);
958 list_del(&session->sess_list);
959 spin_unlock_irqrestore(&sesslock, flags);
960
1051 transport->destroy_session(session); 961 transport->destroy_session(session);
1052 else 962 } else
1053 err = -EINVAL; 963 err = -EINVAL;
1054 break; 964 break;
1055 case ISCSI_UEVENT_CREATE_CONN: 965 case ISCSI_UEVENT_CREATE_CONN: