[PATCH 3/3 2.6.28] cxgb3i - add host_set_param() and fixed ddp tag generation.

From: Karen Xie <[EMAIL PROTECTED]>

- added host_set_param() to set private ipv4 address for iscsi traffic.
- fixed ddp tag generation when upper 16 bits are used.

This patch is based on the cxgb3 branch of the git tree.

Signed-off-by: Karen Xie <[EMAIL PROTECTED]>
---

 drivers/scsi/cxgb3i/cxgb3i.h         |    4 -
 drivers/scsi/cxgb3i/cxgb3i_iscsi.c   |   62 +++++++++
 drivers/scsi/cxgb3i/cxgb3i_offload.c |  222 ++++++++++++++++++++++------------
 drivers/scsi/cxgb3i/cxgb3i_offload.h |   21 ++-
 drivers/scsi/cxgb3i/cxgb3i_ulp2.c    |   61 ++++++---
 5 files changed, 261 insertions(+), 109 deletions(-)


diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h
index a65995d..e8eca78 100644
--- a/drivers/scsi/cxgb3i/cxgb3i.h
+++ b/drivers/scsi/cxgb3i/cxgb3i.h
@@ -47,6 +47,7 @@ struct cxgb3i_endpoint;
  * @rsvd_bits: # of bits used by h/w
  * @rsvd_shift:        shift left
  * @rsvd_mask:  bit mask
+ * @rsvd_tag_mask:  h/w tag bit mask
  *
  */
 struct cxgb3i_tag_format {
@@ -55,6 +56,7 @@ struct cxgb3i_tag_format {
        unsigned char rsvd_bits;
        unsigned char rsvd_shift;
        u32 rsvd_mask;
+       u32 rsvd_tag_mask;
 };
 
 /**
@@ -172,6 +174,4 @@ u32 cxgb3i_ddp_tag_reserve(struct cxgb3i_adapter *, 
unsigned int,
                           u32, unsigned int, struct scatterlist *,
                           unsigned int);
 int cxgb3i_conn_ulp2_xmit(struct iscsi_conn *);
-
-void cxgb3i_display_byte_string(char *, unsigned char *, int, int);
 #endif
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c 
b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index e3a7443..c2324fe 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -9,6 +9,7 @@
  * Written by: Karen Xie ([EMAIL PROTECTED])
  */
 
+#include <linux/inet.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -253,9 +254,6 @@ static int cxgb3i_ep_poll(struct iscsi_endpoint *ep, int 
timeout_ms)
        struct cxgb3i_endpoint *cep = ep->dd_data;
        struct s3_conn *c3cn = cep->c3cn;
 
-       cxgb3i_log_debug("ep 0x%p, timeout %d, c3cn 0x%p, state 0x%x.\n",
-                        ep, timeout_ms, c3cn, c3cn->state);
-
        if (!c3cn_in_state(c3cn, C3CN_STATE_ESTABLISHED)) {
                cxgb3i_log_info("not in established state.\n");
                return 0;
@@ -409,12 +407,11 @@ static int cxgb3i_conn_xmit_segment(struct iscsi_conn 
*conn)
        struct iscsi_segment *segment = &tcp_conn->out.segment;
 
        if (segment->total_copied < segment->total_size)
-                       return cxgb3i_conn_ulp2_xmit(conn);
+               return cxgb3i_conn_ulp2_xmit(conn);
        return 0;
 }
 
 
-
 /**
  * cxgb3i_conn_bind - binds iscsi sess, conn and endpoint together
  * @cls_session:       pointer to iscsi cls session
@@ -559,6 +556,48 @@ static int cxgb3i_conn_set_param(struct iscsi_cls_conn 
*cls_conn,
 }
 
 /**
+ * cxgb3i_host_set_param - configure host (adapter) related parameters
+ * @shost:     scsi host pointer
+ * @param:     parameter type identifier
+ * @buf:       buffer pointer
+ */
+static int cxgb3i_host_set_param(struct Scsi_Host *shost,
+                                enum iscsi_host_param param,
+                                char *buf, int buflen)
+{
+       static struct cxgb3i_hba *hba;
+       int rc = -EINVAL;
+
+       cxgb3i_log_debug("param %d, buf %s.\n", param, buf);
+
+       switch (param) {
+       case ISCSI_HOST_PARAM_NETDEV_NAME:
+       {
+               struct net_device *ndev = dev_get_by_name(&init_net, buf);
+
+               if (ndev) {
+                       hba = cxgb3i_hba_find_by_netdev(ndev);
+                       if (hba)
+                               rc = 0;
+                       else
+                               cxgb3i_log_info("%s not a cxgb3i device.\n",
+                                               buf);
+               }
+               break;
+       }
+       case ISCSI_HOST_PARAM_IPADDRESS:
+               if (hba) {
+                       __be32 addr = in_aton(buf);
+                       rc = cxgb3i_set_private_ipv4addr(hba->ndev, addr);
+               }
+               break;
+       default:
+               return iscsi_host_get_param(shost, param, buf);
+       }
+       return rc;
+}
+
+/**
  * cxgb3i_host_get_param - returns host (adapter) related parameters
  * @shost:     scsi host pointer
  * @param:     parameter type identifier
@@ -571,6 +610,8 @@ static int cxgb3i_host_get_param(struct Scsi_Host *shost,
        int i;
        int len = 0;
 
+       cxgb3i_log_debug("hba %s, param %d.\n", hba->ndev->name, param);
+
        switch (param) {
        case ISCSI_HOST_PARAM_HWADDRESS:
                for (i = 0; i < 6; i++)
@@ -583,6 +624,16 @@ static int cxgb3i_host_get_param(struct Scsi_Host *shost,
        case ISCSI_HOST_PARAM_NETDEV_NAME:
                len = sprintf(buf, "%s\n", hba->ndev->name);
                break;
+       case ISCSI_HOST_PARAM_IPADDRESS:
+       {
+               int rc;
+               __be32 addr;
+
+               rc = cxgb3i_get_private_ipv4addr(hba->ndev, &addr);
+               if (!rc)
+                       len = sprintf(buf, "%u.%u.%u.%u", NIPQUAD(addr));
+               break;
+       }
        default:
                return iscsi_host_get_param(shost, param, buf);
        }
@@ -746,6 +797,7 @@ static struct iscsi_transport cxgb3i_iscsi_transport = {
        .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
            ISCSI_HOST_INITIATOR_NAME | ISCSI_HOST_NETDEV_NAME,
        .get_host_param = cxgb3i_host_get_param,
+       .set_host_param = cxgb3i_host_set_param,
        /* session management */
        .create_session = cxgb3i_session_create,
        .destroy_session = cxgb3i_session_destroy,
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c 
b/drivers/scsi/cxgb3i/cxgb3i_offload.c
index bb968ae..fbc0e8a 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c
@@ -39,12 +39,6 @@ static unsigned int sport_base = 20000;
 module_param(sport_base, uint, 0644);
 MODULE_PARM_DESC(sport_start, "starting port number (default=20000)");
 
-#ifdef __DEBUG_C3CN_CONN__
-#define c3cn_conn_debug         cxgb3i_log_debug
-#else
-#define c3cn_conn_debug(fmt...)
-#endif
-
 #ifdef __DEBUG_C3CN_TX__
 #define c3cn_tx_debug         cxgb3i_log_debug
 #else
@@ -197,7 +191,7 @@ static void s3_init_wr_tab(unsigned int wr_len)
 }
 
 /*
- * Initialization/cleanup cxgb3 API operations.
+ * cxgb3i API operations.
  */
 /*
  * large memory chunk allocation/release
@@ -306,6 +300,36 @@ void cxgb3i_sdev_remove(struct t3cdev *cdev)
 }
 
 /*
+ * set/get iscsi private address
+ */
+int cxgb3i_set_private_ipv4addr(struct net_device *ndev, __be32 addr)
+{
+       struct t3cdev *tdev = dev2t3cdev(ndev);
+       struct iscsi_ipv4addr ii;
+       int rc;
+
+       ii.dev = ndev;
+       ii.ipv4addr = addr;
+       rc = tdev->ctl(tdev, SET_ISCSI_IPV4ADDR, &ii);
+       if (!rc)
+               cxgb3i_log_info("%s -> iscsi IPV4 %u.%u.%u.%u.\n",
+                               ndev->name, NIPQUAD(addr));
+       return rc;
+}
+
+int cxgb3i_get_private_ipv4addr(struct net_device *ndev, __be32 *addrp)
+{
+       struct t3cdev *tdev = dev2t3cdev(ndev);
+       struct iscsi_ipv4addr ii;
+       int rc;
+
+       ii.dev = ndev;
+       rc = tdev->ctl(tdev, GET_ISCSI_IPV4ADDR, &ii);
+       *addrp = rc ? 0 : ii.ipv4addr;
+       return rc;
+}
+
+/*
  * Return TRUE if the specified net device is for a port on one of our
  * registered adapters.
  */
@@ -410,11 +434,15 @@ void c3cn_close(struct s3_conn *c3cn)
                /* Nothing if we are already closed */
                ;
        else if (data_lost || c3cn->state == C3CN_STATE_SYN_SENT) {
+               c3cn_conn_debug("c3cn 0x%p, 0x%x -> closing, send reset.\n",
+                               c3cn, c3cn->state);
                /* Unread data was tossed, zap the connection. */
                s3_send_reset(c3cn, CPL_ABORT_SEND_RST, NULL);
                release_port(c3cn);
                goto unlock;
        } else if (c3cn->state == C3CN_STATE_ESTABLISHED) {
+               c3cn_conn_debug("c3cn 0x%p, est. -> closing, send close_req.\n",
+                               c3cn);
                c3cn_set_state(c3cn, C3CN_STATE_CLOSING);
                mk_close_req(c3cn);
        }
@@ -454,8 +482,8 @@ out:
  * ======================================================================
  */
 
-static int s3_connect(struct s3_conn *);
 static u32 s3_send_rx_credits(struct s3_conn *, u32, u32, int);
+static int act_open(struct s3_conn *, struct net_device *);
 static void mk_act_open_req(struct s3_conn *, struct sk_buff *,
                            unsigned int, const struct l2t_entry *);
 static void skb_entail(struct s3_conn *, struct sk_buff *, int);
@@ -545,6 +573,36 @@ static inline void make_tx_data_wr(struct s3_conn *c3cn,
        }
 }
 
+/**
+ * cxgb3_egress_dev - return the cxgb3 egress device or NULL if the egress
+ *     device isn't one of our ports.
+ *
+ * @root_dev: the root device anchoring the search
+ * @c3cn: the connection used to determine egress port in bonding mode
+ * @context: in bonding mode, indicates a connection set up or failover
+ *
+ * Given a root network device it returns the physical egress device that is a
+ * descendant of the root device.  The root device may be either a physical
+ * device, in which case it is the device returned, or a virtual device, such
+ * as a VLAN or bonding device.  In case of a bonding device the search
+ * considers the decisions of the bonding device given its mode to locate the
+ * correct egress device.
+ */
+static struct net_device *cxgb3_egress_dev(struct net_device *root_dev,
+                                          struct s3_conn *c3cn,
+                                          int context)
+{
+       while (root_dev) {
+               if (root_dev->priv_flags & IFF_802_1Q_VLAN)
+                       root_dev = vlan_dev_real_dev(root_dev);
+               else if (is_cxgb3_dev(root_dev))
+                       return root_dev;
+               else
+                       return NULL;
+       }
+       return NULL;
+}
+
 static struct rtable *find_route(__be32 saddr, __be32 daddr,
                                 __be16 sport, __be16 dport)
 {
@@ -570,6 +628,10 @@ static struct rtable *find_route(__be32 saddr, __be32 
daddr,
 int cxgb3i_c3cn_connect(struct s3_conn *c3cn, struct sockaddr_in *usin)
 {
        struct rtable *rt;
+       struct net_device *dev;
+       struct cxgb3i_sdev_data *cdata;
+       struct t3cdev *cdev;
+       __be32 sipv4;
        int err;
 
        if (usin->sin_family != AF_INET)
@@ -608,14 +670,42 @@ int cxgb3i_c3cn_connect(struct s3_conn *c3cn, struct 
sockaddr_in *usin)
        if (!c3cn->saddr.sin_addr.s_addr)
                c3cn->saddr.sin_addr.s_addr = rt->rt_src;
 
-       c3cn_conn_debug("c3cn 0x%p -> SYN_SENT.\n", c3cn);
-       c3cn_set_state(c3cn, C3CN_STATE_SYN_SENT);
-
        /* now commit destination to connection */
        c3cn->dst_cache = &rt->u.dst;
 
-       if (s3_connect(c3cn))
+       /* try to establish an offloaded connection */
+       dev = cxgb3_egress_dev(c3cn->dst_cache->dev, c3cn, 0);
+       if (dev == NULL) {
+               c3cn_conn_debug("c3cn 0x%p, egress dev NULL.\n", c3cn);
+               return -ENETUNREACH;
+       }
+       cdata = NDEV2CDATA(dev);
+       cdev = cdata->cdev;
+
+       err = cxgb3i_get_private_ipv4addr(dev, &sipv4);
+       if (err)
+               return err;
+
+       if (!sipv4) {
+               c3cn_conn_debug("c3cn 0x%p, iscsi ip not configured.\n", c3cn);
+               sipv4 = c3cn->saddr.sin_addr.s_addr + 0x1000000;
+               err = cxgb3i_set_private_ipv4addr(dev, sipv4);
+               if (err)
+                       return err;
+       }
+       c3cn->saddr.sin_addr.s_addr = sipv4;
+
+       c3cn_conn_debug("c3cn 0x%p, %u.%u.%u.%u,%u-%u.%u.%u.%u,%u SYN_SENT.\n",
+                       c3cn, NIPQUAD(c3cn->saddr.sin_addr.s_addr),
+                       ntohs(c3cn->saddr.sin_port),
+                       NIPQUAD(c3cn->daddr.sin_addr.s_addr),
+                       ntohs(c3cn->daddr.sin_port));
+
+       c3cn_set_state(c3cn, C3CN_STATE_SYN_SENT);
+
+       if (!act_open(c3cn, dev))
                return 0;
+
        /*
         * If we get here, we don't have an offload connection so simply
         * return a failure.
@@ -763,6 +853,8 @@ static void abort_arp_failure(struct t3cdev *cdev, struct 
sk_buff *skb)
 {
        struct cpl_abort_req *req = cplhdr(skb);
 
+       c3cn_conn_debug("tdev 0x%p.\n", cdev);
+
        req->cmd = CPL_ABORT_NO_RST;
        cxgb3_ofld_send(cdev, skb);
 }
@@ -785,7 +877,8 @@ static int s3_send_reset(struct s3_conn *c3cn, int mode,
                return 1;
        }
 
-       c3cn_conn_debug("c3cn 0x%p, mode %d.\n", c3cn, mode);
+       c3cn_conn_debug("c3cn 0x%p, mode %d, flag ABORT_RPL + ABORT_SHUT.\n",
+                       c3cn, mode);
 
        c3cn_set_flag(c3cn, C3CN_ABORT_RPL_PENDING);
        c3cn_set_flag(c3cn, C3CN_ABORT_SHUTDOWN);
@@ -873,7 +966,6 @@ static void process_rx_iscsi_hdr(struct s3_conn *, struct 
sk_buff *);
 
 static struct sk_buff *__get_cpl_reply_skb(struct sk_buff *, size_t, gfp_t);
 
-static int act_open(struct s3_conn *, struct net_device *);
 static void fail_act_open(struct s3_conn *, int);
 static void init_offload_conn(struct s3_conn *, struct t3cdev *,
                              struct dst_entry *);
@@ -919,51 +1011,6 @@ static struct sk_buff *alloc_ctrl_skb(const struct 
s3_conn *c3cn,
        return skb;
 }
 
-/**
- * cxgb3_egress_dev - return the cxgb3 egress device or NULL if the egress
- *     device isn't one of our ports.
- *
- * @root_dev: the root device anchoring the search
- * @c3cn: the connection used to determine egress port in bonding mode
- * @context: in bonding mode, indicates a connection set up or failover
- *
- * Given a root network device it returns the physical egress device that is a
- * descendant of the root device.  The root device may be either a physical
- * device, in which case it is the device returned, or a virtual device, such
- * as a VLAN or bonding device.  In case of a bonding device the search
- * considers the decisions of the bonding device given its mode to locate the
- * correct egress device.
- */
-static struct net_device *cxgb3_egress_dev(struct net_device *root_dev,
-                                          struct s3_conn *c3cn,
-                                          int context)
-{
-       while (root_dev) {
-               if (root_dev->priv_flags & IFF_802_1Q_VLAN)
-                       root_dev = vlan_dev_real_dev(root_dev);
-               else if (is_cxgb3_dev(root_dev))
-                       return root_dev;
-               else
-                       return NULL;
-       }
-       return NULL;
-}
-
-/*
- * Return TRUE if we're able to establish an offload connection; otherwise
- * return FALSE.
- */
-static int s3_connect(struct s3_conn *c3cn)
-{
-       struct net_device *dev = cxgb3_egress_dev(c3cn->dst_cache->dev,
-                                                 c3cn, 0);
-       if (dev == NULL) {
-               c3cn_conn_debug("c3cn 0x%p, egress dev NULL.\n", c3cn);
-               return 0;
-       }
-       return act_open(c3cn, dev) == 0;
-}
-
 /*
  * Handle an ARP failure for an active open.
  */
@@ -971,6 +1018,8 @@ static void act_open_req_arp_failure(struct t3cdev *dev, 
struct sk_buff *skb)
 {
        struct s3_conn *c3cn = (struct s3_conn *)skb->sk;
 
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        c3cn_hold(c3cn);
        spin_lock(&c3cn->lock);
        if (c3cn->state == C3CN_STATE_SYN_SENT) {
@@ -1097,10 +1146,6 @@ static void mk_act_open_req(struct s3_conn *c3cn, struct 
sk_buff *skb,
                            unsigned int atid, const struct l2t_entry *e)
 {
        struct cpl_act_open_req *req;
-       struct iscsi_ipv4addr ii;
-
-       ii.dev = c3cn->dev;
-       c3cn->cdev->ctl(c3cn->cdev, GET_ISCSI_IPV4ADDR, &ii);
 
        c3cn_conn_debug("c3cn 0x%p, atid 0x%x.\n", c3cn, atid);
 
@@ -1110,7 +1155,7 @@ static void mk_act_open_req(struct s3_conn *c3cn, struct 
sk_buff *skb,
        OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, atid));
        req->local_port = c3cn->saddr.sin_port;
        req->peer_port = c3cn->daddr.sin_port;
-       req->local_ip = ii.ipv4addr;
+       req->local_ip = c3cn->saddr.sin_addr.s_addr;
        req->peer_ip = c3cn->daddr.sin_addr.s_addr;
        req->opt0h = htonl(calc_opt0h(c3cn) | V_L2T_IDX(e->idx) |
                           V_TX_CHANNEL(e->smt_idx));
@@ -1165,6 +1210,8 @@ static inline void abort_conn(struct s3_conn *c3cn,
 {
        struct sk_buff *abort_skb;
 
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        abort_skb = __get_cpl_reply_skb(skb, sizeof(struct cpl_abort_req),
                                        GFP_ATOMIC);
        if (abort_skb)
@@ -1197,7 +1244,8 @@ static int do_act_establish(struct t3cdev *cdev, struct 
sk_buff *skb,
        struct s3_conn *c3cn = ctx;
        struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(cdev);
 
-       c3cn_conn_debug("c3cn 0x%p, tid 0x%x.\n", c3cn, tid);
+       c3cn_conn_debug("rcv, tid 0x%x, c3cn 0x%p, 0x%x, 0x%lx.\n",
+                       tid, c3cn, c3cn->state, c3cn->flags);
        /*
         * It's OK if the TID is currently in use, the owning connection may
         * have backlogged its last CPL message(s).  Just take it away.
@@ -1220,7 +1268,8 @@ static int do_act_open_rpl(struct t3cdev *cdev, struct 
sk_buff *skb, void *ctx)
        struct s3_conn *c3cn = ctx;
        struct cpl_act_open_rpl *rpl = cplhdr(skb);
 
-       c3cn_conn_debug("c3cn 0x%p, status 0x%x.\n", c3cn, rpl->status);
+       c3cn_conn_debug("rcv, status 0x%x, c3cn 0x%p, 0x%x, 0x%lx.\n",
+                       rpl->status, c3cn, c3cn->state, c3cn->flags);
 
        if (act_open_has_tid(rpl->status))
                cxgb3_queue_tid_release(cdev, GET_TID(rpl));
@@ -1257,8 +1306,8 @@ static int do_peer_close(struct t3cdev *cdev, struct 
sk_buff *skb, void *ctx)
 {
        struct s3_conn *c3cn = ctx;
 
-       c3cn_conn_debug("c3cn 0x%p, state 0x%x, flag 0x%lx.\n",
-                        c3cn, c3cn->state, c3cn->flags);
+       c3cn_conn_debug("rcv, c3cn 0x%p, 0x%x, 0x%lx.\n",
+                       c3cn, c3cn->state, c3cn->flags);
        process_cpl_msg_ref(do_peer_fin, c3cn, skb);
        return 0;
 }
@@ -1271,14 +1320,14 @@ static int do_abort_req(struct t3cdev *cdev, struct 
sk_buff *skb, void *ctx)
        const struct cpl_abort_req_rss *req = cplhdr(skb);
        struct s3_conn *c3cn = ctx;
 
+       c3cn_conn_debug("rcv, c3cn 0x%p, 0x%x, 0x%lx.\n",
+                       c3cn, c3cn->state, c3cn->flags);
+
        if (is_neg_adv_abort(req->status)) {
                __kfree_skb(skb);
                return 0;
        }
 
-       c3cn_conn_debug("c3cn 0x%p, state 0x%x, flag 0x%lx.\n",
-                        c3cn, c3cn->state, c3cn->flags);
-
        process_cpl_msg_ref(process_abort_req, c3cn, skb);
        return 0;
 }
@@ -1289,7 +1338,11 @@ static int do_abort_req(struct t3cdev *cdev, struct 
sk_buff *skb, void *ctx)
 static int do_abort_rpl(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
 {
        struct cpl_abort_rpl_rss *rpl = cplhdr(skb);
-       struct s3_conn *c3cn;
+       struct s3_conn *c3cn = ctx;
+
+       c3cn_conn_debug("rcv, status 0x%x, c3cn 0x%p, 0x%x, 0x%lx.\n",
+                       rpl->status, c3cn, c3cn ? c3cn->state : 0,
+                       c3cn ? c3cn->flags : 0UL);
 
        /*
         * Ignore replies to post-close aborts indicating that the abort was
@@ -1300,10 +1353,6 @@ static int do_abort_rpl(struct t3cdev *cdev, struct 
sk_buff *skb, void *ctx)
        if (rpl->status == CPL_ERR_ABORT_FAILED)
                goto discard;
 
-       c3cn = ctx;
-       c3cn_conn_debug("c3cn 0x%p, state 0x%x, flag 0x%lx.\n",
-                        c3cn, c3cn->state, c3cn->flags);
-
        /*
         * Sometimes we've already closed the connection, e.g., a post-close
         * abort races with ABORT_REQ_RSS, the latter frees the connection
@@ -1330,7 +1379,7 @@ static int do_close_con_rpl(struct t3cdev *cdev, struct 
sk_buff *skb,
 {
        struct s3_conn *c3cn = ctx;
 
-       c3cn_conn_debug("c3cn 0x%p, state 0x%x, flag 0x%lx.\n",
+       c3cn_conn_debug("rcv, c3cn 0x%p, 0x%x, 0x%lx.\n",
                         c3cn, c3cn->state, c3cn->flags);
 
        process_cpl_msg_ref(process_close_con_rpl, c3cn, skb);
@@ -1415,6 +1464,8 @@ static void c3cn_act_establish(struct s3_conn *c3cn,
        struct cpl_act_establish *req = cplhdr(skb);
        u32 rcv_isn = ntohl(req->rcv_isn);      /* real RCV_ISN + 1 */
 
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        if (unlikely(c3cn->state != C3CN_STATE_SYN_SENT))
                printk(KERN_ERR "TID %u expected SYN_SENT, found %d\n",
                       c3cn->tid, c3cn->state);
@@ -1436,6 +1487,8 @@ static void active_open_failed(struct s3_conn *c3cn,
 {
        struct cpl_act_open_rpl *rpl = cplhdr(skb);
 
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        if (rpl->status == CPL_ERR_CONN_EXIST &&
            c3cn->retry_timer.function != act_open_retry_timer) {
                c3cn->retry_timer.function = act_open_retry_timer;
@@ -1572,6 +1625,9 @@ static void do_peer_fin(struct s3_conn *c3cn, struct 
sk_buff *skb)
 {
        int keep = 0;
 
+       c3cn_conn_debug("rcv, c3cn 0x%p, 0x%x, 0x%lx.\n",
+                        c3cn, c3cn->state, c3cn->flags);
+
        if (c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING))
                goto out;
 
@@ -1607,6 +1663,8 @@ static void process_abort_req(struct s3_conn *c3cn,
        int rst_status = CPL_ABORT_NO_RST;
        const struct cpl_abort_req_rss *req = cplhdr(skb);
 
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        if (!c3cn_flag(c3cn, C3CN_ABORT_REQ_RCVD)) {
                c3cn_set_flag(c3cn, C3CN_ABORT_REQ_RCVD);
                c3cn_set_flag(c3cn, C3CN_ABORT_SHUTDOWN);
@@ -1644,6 +1702,8 @@ static void process_abort_req(struct s3_conn *c3cn,
 static void process_abort_rpl(struct s3_conn *c3cn,
                              struct sk_buff *skb)
 {
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        if (c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING)) {
                if (!c3cn_flag(c3cn, C3CN_ABORT_RPL_RCVD))
                        c3cn_set_flag(c3cn, C3CN_ABORT_RPL_RCVD);
@@ -1666,6 +1726,8 @@ static void process_close_con_rpl(struct s3_conn *c3cn,
 {
        struct cpl_close_con_rpl *rpl = cplhdr(skb);
 
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        c3cn->snd_una = ntohl(rpl->snd_nxt) - 1;        /* exclude FIN */
 
        if (c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING))
@@ -1722,6 +1784,8 @@ static unsigned int select_mss(struct s3_conn *c3cn, 
unsigned int pmtu)
 
 static void fail_act_open(struct s3_conn *c3cn, int errno)
 {
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        c3cn->err = errno;
        t3_release_offload_resources(c3cn);
        c3cn_done(c3cn);
@@ -1748,6 +1812,8 @@ static void act_open_retry_timer(unsigned long data)
        struct sk_buff *skb;
        struct s3_conn *c3cn = (struct s3_conn *)data;
 
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        spin_lock(&c3cn->lock);
        skb = alloc_skb(sizeof(struct cpl_act_open_req), GFP_ATOMIC);
        if (!skb)
@@ -1913,6 +1979,8 @@ static struct sk_buff *__get_cpl_reply_skb(struct sk_buff 
*skb, size_t len,
 static void make_established(struct s3_conn *c3cn, u32 snd_isn,
                             unsigned int opt)
 {
+       c3cn_conn_debug("c3cn 0x%p, state 0x%x.\n", c3cn, c3cn->state);
+
        c3cn->write_seq = c3cn->snd_nxt = c3cn->snd_una = snd_isn;
 
        /*
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h 
b/drivers/scsi/cxgb3i/cxgb3i_offload.h
index 0c17abd..42ed6c3 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h
@@ -29,6 +29,12 @@
 #define cxgb3i_log_debug(fmt...)
 #endif
 
+#ifdef __DEBUG_C3CN_CONN__
+#define c3cn_conn_debug         cxgb3i_log_debug
+#else
+#define c3cn_conn_debug(fmt...)
+#endif
+
 /*
  * Data structure to keep track of cxgb3 connection.
  */
@@ -95,7 +101,6 @@ static inline unsigned int c3cn_in_state(const struct 
s3_conn *c3cn,
        return states & c3cn->state;
 }
 
-
 /*
  * Connection flags -- many to track some close related events.
  */
@@ -115,12 +120,16 @@ static inline void c3cn_set_flag(struct s3_conn *c3cn,
                                 enum c3cn_flags flag)
 {
        __set_bit(flag, &c3cn->flags);
+       c3cn_conn_debug("c3cn 0x%p, %d, 0x%x, 0x%lx.\n",
+                        c3cn, flag, c3cn->state, c3cn->flags);
 }
 
 static inline void c3cn_reset_flag(struct s3_conn *c3cn,
                                   enum c3cn_flags flag)
 {
        __clear_bit(flag, &c3cn->flags);
+       c3cn_conn_debug("c3cn 0x%p, %d, 0x%x, 0x%lx.\n",
+                        c3cn, flag, c3cn->state, c3cn->flags);
 }
 
 static inline int c3cn_flag(struct s3_conn *c3cn, enum c3cn_flags flag)
@@ -155,8 +164,11 @@ static inline void c3cn_hold(struct s3_conn *c3cn)
 
 static inline void c3cn_put(struct s3_conn *c3cn)
 {
-       if (atomic_dec_and_test(&c3cn->refcnt))
+       if (atomic_dec_and_test(&c3cn->refcnt)) {
+               c3cn_conn_debug("c3cn 0x%p, 0x%x, 0x%lx.\n",
+                               c3cn, c3cn->state, c3cn->flags);
                kfree(c3cn);
+       }
 }
 
 void c3cn_close(struct s3_conn *);
@@ -169,6 +181,8 @@ static inline void c3cn_release(struct s3_conn *c3cn)
 /*
  * Primary API routines.
  */
+int cxgb3i_set_private_ipv4addr(struct net_device *, __be32);
+int cxgb3i_get_private_ipv4addr(struct net_device *, __be32 *);
 
 void cxgb3i_sdev_cleanup(void);
 int cxgb3i_sdev_init(cxgb3_cpl_handler_func *);
@@ -216,11 +230,8 @@ static inline void process_cpl_msg(void (*fn)(struct 
s3_conn *,
                                   struct s3_conn *c3cn,
                                   struct sk_buff *skb)
 {
-cxgb3i_log_debug("c3cn 0x%p, locking ....\n", c3cn);
        spin_lock(&c3cn->lock);
-cxgb3i_log_debug("c3cn 0x%p, locked.\n", c3cn);
        fn(c3cn, skb);
-cxgb3i_log_debug("c3cn 0x%p, unlock.\n", c3cn);
        spin_unlock(&c3cn->lock);
 }
 
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ulp2.c 
b/drivers/scsi/cxgb3i/cxgb3i_ulp2.c
index ef85401..f11ec43 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ulp2.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_ulp2.c
@@ -1,5 +1,5 @@
 /*
- * cxgb3i_ddp.c: Chelsio S3xx iSCSI driver.
+ * cxgb3i_ulp2.c: Chelsio S3xx iSCSI driver.
  *
  * Copyright (c) 2008 Chelsio Communications, Inc.
  *
@@ -59,7 +59,7 @@ static void cxgb3i_ddp_page_init(void)
        unsigned long n = PAGE_SIZE >> ULP2_4K_PAGE_SHIFT;
 
        if (PAGE_SIZE & (~ULP2_4K_PAGE_MASK)) {
-               cxgb3i_log_warn("PAGE_SIZE 0x%lx is not multiple of 4K, "
+               cxgb3i_log_debug("PAGE_SIZE 0x%lx is not multiple of 4K, "
                                "ddp disabled.\n", PAGE_SIZE);
                return;
        }
@@ -105,8 +105,10 @@ static int set_ddp_map(struct cxgb3i_adapter *snic, struct 
pagepod_hdr *hdr,
                skb =
                    alloc_skb(sizeof(struct ulp_mem_io) + PPOD_SIZE,
                              GFP_ATOMIC);
-               if (!skb)
+               if (!skb) {
+                       cxgb3i_log_debug("skb OMM.\n");
                        return -ENOMEM;
+               }
                skb_put(skb, sizeof(struct ulp_mem_io) + PPOD_SIZE);
 
                ulp_mem_io_set_hdr(skb, pm_addr);
@@ -164,8 +166,11 @@ static int cxgb3i_ddp_sgl_check(struct scatterlist *sgl, 
unsigned int sgcnt)
        for_each_sg(sgl, sg, sgcnt, i) {
                if ((i && sg->offset) ||
                    ((i != sgcnt - 1) &&
-                    (sg->length + sg->offset) != PAGE_SIZE))
+                    (sg->length + sg->offset) != PAGE_SIZE)) {
+                       cxgb3i_tag_debug("sg %u/%u, off %u, len %u.\n",
+                                        i, sgcnt, sg->offset, sg->length);
                        return -EINVAL;
+               }
        }
 
        return 0;
@@ -212,12 +217,18 @@ u32 cxgb3i_ddp_tag_reserve(struct cxgb3i_adapter *snic, 
unsigned int tid,
        u32 tag;
        int err;
 
-       if (!ddp || !sgcnt || xferlen < PAGE_SIZE)
+       if (!ddp || !sgcnt || xferlen < PAGE_SIZE) {
+               cxgb3i_tag_debug("sgcnt %u, xferlen %u < %lu, NO DDP.\n",
+                                sgcnt, xferlen, PAGE_SIZE);
                return RESERVED_ITT;
+       }
 
        err = cxgb3i_ddp_sgl_check(sgl, sgcnt);
-       if (err < 0)
+       if (err < 0) {
+               cxgb3i_tag_debug("sgcnt %u, xferlen %u, SGL check fail.\n",
+                                sgcnt, xferlen);
                return RESERVED_ITT;
+       }
 
        npods = (sgcnt + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
        idx_max = ddp->nppods - npods + 1;
@@ -232,17 +243,23 @@ u32 cxgb3i_ddp_tag_reserve(struct cxgb3i_adapter *snic, 
unsigned int tid,
                                                      ddp->idx_last - npods + 1,
                                                      npods);
        }
-       if (idx < 0)
+       if (idx < 0) {
+               cxgb3i_tag_debug("sgcnt %u, xferlen %u, npods %u NO DDP.\n",
+                                sgcnt, xferlen, npods);
                return RESERVED_ITT;
+       }
 
-       if (pci_map_sg(snic->pdev, sgl, sgcnt, PCI_DMA_FROMDEVICE) <= 0)
+       if (pci_map_sg(snic->pdev, sgl, sgcnt, PCI_DMA_FROMDEVICE) <= 0) {
+               cxgb3i_tag_debug("sgcnt %u, xferlen %u, pci map failed.\n",
+                                sgcnt, xferlen);
                goto unmark_entries;
+       }
 
        tag = sw_tag | (idx << snic->tag_format.rsvd_shift);
 
        hdr.rsvd = 0;
        hdr.vld_tid = htonl(F_PPOD_VALID | V_PPOD_TID(tid));
-       hdr.pgsz_tag_clr = htonl(tag);
+       hdr.pgsz_tag_clr = htonl(tag & snic->tag_format.rsvd_tag_mask);
        hdr.maxoffset = htonl(xferlen);
        hdr.pgoffset = htonl(sgl->offset);
 
@@ -250,7 +267,7 @@ u32 cxgb3i_ddp_tag_reserve(struct cxgb3i_adapter *snic, 
unsigned int tid,
                goto unmap_sgl;
 
        ddp->idx_last = idx;
-       cxgb3i_tag_debug("tid 0x%x, xfer %u, 0x%x -> ddp tag 0x%x (%u, %u).\n",
+       cxgb3i_tag_debug("tid 0x%x, xfer %u, 0x%x -> ddp 0x%x (0x%x, %u).\n",
                         tid, xferlen, sw_tag, tag, idx, npods);
        return tag;
 
@@ -358,12 +375,9 @@ static int cxgb3i_conn_read_pdu_skb(struct iscsi_conn 
*conn,
                                         hdr->opcode & ISCSI_OPCODE_MASK,
                                         tcp_conn->in.datalen);
                        segment->total_copied = segment->total_size;
-               } else {
-                       cxgb3i_ddp_debug("opcode 0x%x, data %u, not ddp'ed.\n",
-                                        hdr->opcode & ISCSI_OPCODE_MASK,
-                                        tcp_conn->in.datalen);
+               } else
                        offset += sizeof(struct cpl_iscsi_hdr_norss);
-               }
+
                while (segment->total_copied < segment->total_size) {
                        iscsi_tcp_segment_map(segment, 1);
                        err = skb_copy_bits(skb, offset, segment->data,
@@ -643,11 +657,8 @@ int cxgb3i_adapter_ulp_init(struct cxgb3i_adapter *snic)
        snic->tag_format.rsvd_bits = bits;
        snic->tag_format.rsvd_shift = PPOD_IDX_SHIFT;
        snic->tag_format.rsvd_mask = (1 << snic->tag_format.rsvd_bits) - 1;
-
-       cxgb3i_log_debug("snic nppods %u, rsvd shift %u, bits %u, mask 0x%x.\n",
-                        ppmax, snic->tag_format.rsvd_shift,
-                        snic->tag_format.rsvd_bits,
-                        snic->tag_format.rsvd_mask);
+       snic->tag_format.rsvd_tag_mask =
+               (1 << (snic->tag_format.rsvd_bits + PPOD_IDX_SHIFT)) - 1;
 
        ddp->map = cxgb3i_alloc_big_mem(ppmax);
        if (!ddp->map) {
@@ -663,6 +674,8 @@ int cxgb3i_adapter_ulp_init(struct cxgb3i_adapter *snic)
        for (i = 0; i < ULP2_PGIDX_MAX; i++)
                uinfo.pgsz_factor[i] = ddp_page_order[i];
 
+       uinfo.ulimit = uinfo.llimit + (ppmax << PPOD_SIZE_SHIFT);
+
        err = tdev->ctl(tdev, ULP_ISCSI_SET_PARAMS, &uinfo);
        if (err < 0) {
                cxgb3i_log_warn("snic unable to set iscsi param err=%d, "
@@ -675,6 +688,14 @@ int cxgb3i_adapter_ulp_init(struct cxgb3i_adapter *snic)
 
        tdev->ulp_iscsi = ddp;
 
+       cxgb3i_log_info("snic nppods %u (0x%x ~ 0x%x), rsvd shift %u, "
+                       "bits %u, mask 0x%x, 0x%x.\n",
+                        ppmax, ddp->llimit, ddp->ulimit,
+                        snic->tag_format.rsvd_shift,
+                        snic->tag_format.rsvd_bits,
+                        snic->tag_format.rsvd_mask,
+                        uinfo.tagmask);
+
        return 0;
 
 free_ppod_map:

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To post to this group, send email to open-iscsi@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/open-iscsi
-~----------~----~----~----~------~----~------~--~---

Reply via email to