]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/scsi/libfc/fc_lport.c
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[mirror_ubuntu-artful-kernel.git] / drivers / scsi / libfc / fc_lport.c
index 50c71678a156e8f32d833575de49379e5cd3a151..919736a74ffa6e8b46e1f87b042968f42eae71b8 100644 (file)
@@ -149,7 +149,7 @@ static const char *fc_lport_state_names[] = {
  * @offset:   The offset into the response data
  */
 struct fc_bsg_info {
-       struct fc_bsg_job *job;
+       struct bsg_job *job;
        struct fc_lport *lport;
        u16 rsp_code;
        struct scatterlist *sg;
@@ -200,7 +200,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
                                     "in the DNS or FDMI state, it's in the "
                                     "%d state", rdata->ids.port_id,
                                     lport->state);
-                       lport->tt.rport_logoff(rdata);
+                       fc_rport_logoff(rdata);
                }
                break;
        case RPORT_EV_LOGO:
@@ -237,23 +237,26 @@ static const char *fc_lport_state(struct fc_lport *lport)
  * @remote_fid:         The FID of the ptp rport
  * @remote_wwpn: The WWPN of the ptp rport
  * @remote_wwnn: The WWNN of the ptp rport
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
  */
 static void fc_lport_ptp_setup(struct fc_lport *lport,
                               u32 remote_fid, u64 remote_wwpn,
                               u64 remote_wwnn)
 {
-       mutex_lock(&lport->disc.disc_mutex);
        if (lport->ptp_rdata) {
-               lport->tt.rport_logoff(lport->ptp_rdata);
-               kref_put(&lport->ptp_rdata->kref, lport->tt.rport_destroy);
+               fc_rport_logoff(lport->ptp_rdata);
+               kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
        }
-       lport->ptp_rdata = lport->tt.rport_create(lport, remote_fid);
+       mutex_lock(&lport->disc.disc_mutex);
+       lport->ptp_rdata = fc_rport_create(lport, remote_fid);
        kref_get(&lport->ptp_rdata->kref);
        lport->ptp_rdata->ids.port_name = remote_wwpn;
        lport->ptp_rdata->ids.node_name = remote_wwnn;
        mutex_unlock(&lport->disc.disc_mutex);
 
-       lport->tt.rport_login(lport->ptp_rdata);
+       fc_rport_login(lport->ptp_rdata);
 
        fc_lport_enter_ready(lport);
 }
@@ -409,7 +412,7 @@ static void fc_lport_recv_rlir_req(struct fc_lport *lport, struct fc_frame *fp)
        FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
                     fc_lport_state(lport));
 
-       lport->tt.seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
+       fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
        fc_frame_free(fp);
 }
 
@@ -478,7 +481,7 @@ static void fc_lport_recv_rnid_req(struct fc_lport *lport,
        if (!req) {
                rjt_data.reason = ELS_RJT_LOGIC;
                rjt_data.explan = ELS_EXPL_NONE;
-               lport->tt.seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);
+               fc_seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);
        } else {
                fmt = req->rnid_fmt;
                len = sizeof(*rp);
@@ -518,7 +521,7 @@ static void fc_lport_recv_rnid_req(struct fc_lport *lport,
  */
 static void fc_lport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
 {
-       lport->tt.seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
+       fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
        fc_lport_enter_reset(lport);
        fc_frame_free(fp);
 }
@@ -620,9 +623,9 @@ int fc_fabric_logoff(struct fc_lport *lport)
        lport->tt.disc_stop_final(lport);
        mutex_lock(&lport->lp_mutex);
        if (lport->dns_rdata)
-               lport->tt.rport_logoff(lport->dns_rdata);
+               fc_rport_logoff(lport->dns_rdata);
        mutex_unlock(&lport->lp_mutex);
-       lport->tt.rport_flush_queue();
+       fc_rport_flush_queue();
        mutex_lock(&lport->lp_mutex);
        fc_lport_enter_logo(lport);
        mutex_unlock(&lport->lp_mutex);
@@ -899,7 +902,7 @@ static void fc_lport_recv_els_req(struct fc_lport *lport,
                /*
                 * Check opcode.
                 */
-               recv = lport->tt.rport_recv_req;
+               recv = fc_rport_recv_req;
                switch (fc_frame_payload_op(fp)) {
                case ELS_FLOGI:
                        if (!lport->point_to_multipoint)
@@ -941,15 +944,14 @@ struct fc4_prov fc_lport_els_prov = {
 };
 
 /**
- * fc_lport_recv_req() - The generic lport request handler
+ * fc_lport_recv() - The generic lport request handler
  * @lport: The lport that received the request
  * @fp: The frame the request is in
  *
  * Locking Note: This function should not be called with the lport
  *              lock held because it may grab the lock.
  */
-static void fc_lport_recv_req(struct fc_lport *lport,
-                             struct fc_frame *fp)
+void fc_lport_recv(struct fc_lport *lport, struct fc_frame *fp)
 {
        struct fc_frame_header *fh = fc_frame_header_get(fp);
        struct fc_seq *sp = fr_seq(fp);
@@ -978,8 +980,9 @@ drop:
        FC_LPORT_DBG(lport, "dropping unexpected frame type %x\n", fh->fh_type);
        fc_frame_free(fp);
        if (sp)
-               lport->tt.exch_done(sp);
+               fc_exch_done(sp);
 }
+EXPORT_SYMBOL(fc_lport_recv);
 
 /**
  * fc_lport_reset() - Reset a local port
@@ -1007,12 +1010,14 @@ EXPORT_SYMBOL(fc_lport_reset);
  */
 static void fc_lport_reset_locked(struct fc_lport *lport)
 {
-       if (lport->dns_rdata)
-               lport->tt.rport_logoff(lport->dns_rdata);
+       if (lport->dns_rdata) {
+               fc_rport_logoff(lport->dns_rdata);
+               lport->dns_rdata = NULL;
+       }
 
        if (lport->ptp_rdata) {
-               lport->tt.rport_logoff(lport->ptp_rdata);
-               kref_put(&lport->ptp_rdata->kref, lport->tt.rport_destroy);
+               fc_rport_logoff(lport->ptp_rdata);
+               kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
                lport->ptp_rdata = NULL;
        }
 
@@ -1426,13 +1431,13 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
        fc_lport_state_enter(lport, LPORT_ST_DNS);
 
        mutex_lock(&lport->disc.disc_mutex);
-       rdata = lport->tt.rport_create(lport, FC_FID_DIR_SERV);
+       rdata = fc_rport_create(lport, FC_FID_DIR_SERV);
        mutex_unlock(&lport->disc.disc_mutex);
        if (!rdata)
                goto err;
 
        rdata->ops = &fc_lport_rport_ops;
-       lport->tt.rport_login(rdata);
+       fc_rport_login(rdata);
        return;
 
 err:
@@ -1543,13 +1548,13 @@ static void fc_lport_enter_fdmi(struct fc_lport *lport)
        fc_lport_state_enter(lport, LPORT_ST_FDMI);
 
        mutex_lock(&lport->disc.disc_mutex);
-       rdata = lport->tt.rport_create(lport, FC_FID_MGMT_SERV);
+       rdata = fc_rport_create(lport, FC_FID_MGMT_SERV);
        mutex_unlock(&lport->disc.disc_mutex);
        if (!rdata)
                goto err;
 
        rdata->ops = &fc_lport_rport_ops;
-       lport->tt.rport_login(rdata);
+       fc_rport_login(rdata);
        return;
 
 err:
@@ -1772,7 +1777,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
        if ((csp_flags & FC_SP_FT_FPORT) == 0) {
                if (e_d_tov > lport->e_d_tov)
                        lport->e_d_tov = e_d_tov;
-               lport->r_a_tov = 2 * e_d_tov;
+               lport->r_a_tov = 2 * lport->e_d_tov;
                fc_lport_set_port_id(lport, did, fp);
                printk(KERN_INFO "host%d: libfc: "
                       "Port (%6.6x) entered "
@@ -1784,8 +1789,10 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
                                   get_unaligned_be64(
                                           &flp->fl_wwnn));
        } else {
-               lport->e_d_tov = e_d_tov;
-               lport->r_a_tov = r_a_tov;
+               if (e_d_tov > lport->e_d_tov)
+                       lport->e_d_tov = e_d_tov;
+               if (r_a_tov > lport->r_a_tov)
+                       lport->r_a_tov = r_a_tov;
                fc_host_fabric_name(lport->host) =
                        get_unaligned_be64(&flp->fl_wwnn);
                fc_lport_set_port_id(lport, did, fp);
@@ -1858,12 +1865,6 @@ EXPORT_SYMBOL(fc_lport_config);
  */
 int fc_lport_init(struct fc_lport *lport)
 {
-       if (!lport->tt.lport_recv)
-               lport->tt.lport_recv = fc_lport_recv_req;
-
-       if (!lport->tt.lport_reset)
-               lport->tt.lport_reset = fc_lport_reset;
-
        fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
        fc_host_node_name(lport->host) = lport->wwnn;
        fc_host_port_name(lport->host) = lport->wwpn;
@@ -1900,18 +1901,19 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
                              void *info_arg)
 {
        struct fc_bsg_info *info = info_arg;
-       struct fc_bsg_job *job = info->job;
+       struct bsg_job *job = info->job;
+       struct fc_bsg_reply *bsg_reply = job->reply;
        struct fc_lport *lport = info->lport;
        struct fc_frame_header *fh;
        size_t len;
        void *buf;
 
        if (IS_ERR(fp)) {
-               job->reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
+               bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
                        -ECONNABORTED : -ETIMEDOUT;
                job->reply_len = sizeof(uint32_t);
-               job->state_flags |= FC_RQST_STATE_DONE;
-               job->job_done(job);
+               bsg_job_done(job, bsg_reply->result,
+                              bsg_reply->reply_payload_rcv_len);
                kfree(info);
                return;
        }
@@ -1928,25 +1930,25 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
                        (unsigned short)fc_frame_payload_op(fp);
 
                /* Save the reply status of the job */
-               job->reply->reply_data.ctels_reply.status =
+               bsg_reply->reply_data.ctels_reply.status =
                        (cmd == info->rsp_code) ?
                        FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
        }
 
-       job->reply->reply_payload_rcv_len +=
+       bsg_reply->reply_payload_rcv_len +=
                fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
                                         &info->offset, NULL);
 
        if (fr_eof(fp) == FC_EOF_T &&
            (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
            (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
-               if (job->reply->reply_payload_rcv_len >
+               if (bsg_reply->reply_payload_rcv_len >
                    job->reply_payload.payload_len)
-                       job->reply->reply_payload_rcv_len =
+                       bsg_reply->reply_payload_rcv_len =
                                job->reply_payload.payload_len;
-               job->reply->result = 0;
-               job->state_flags |= FC_RQST_STATE_DONE;
-               job->job_done(job);
+               bsg_reply->result = 0;
+               bsg_job_done(job, bsg_reply->result,
+                              bsg_reply->reply_payload_rcv_len);
                kfree(info);
        }
        fc_frame_free(fp);
@@ -1962,7 +1964,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
  */
-static int fc_lport_els_request(struct fc_bsg_job *job,
+static int fc_lport_els_request(struct bsg_job *job,
                                struct fc_lport *lport,
                                u32 did, u32 tov)
 {
@@ -2005,8 +2007,8 @@ static int fc_lport_els_request(struct fc_bsg_job *job,
        info->nents = job->reply_payload.sg_cnt;
        info->sg = job->reply_payload.sg_list;
 
-       if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
-                                    NULL, info, tov)) {
+       if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
+                             NULL, info, tov)) {
                kfree(info);
                return -ECOMM;
        }
@@ -2023,7 +2025,7 @@ static int fc_lport_els_request(struct fc_bsg_job *job,
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
  */
-static int fc_lport_ct_request(struct fc_bsg_job *job,
+static int fc_lport_ct_request(struct bsg_job *job,
                               struct fc_lport *lport, u32 did, u32 tov)
 {
        struct fc_bsg_info *info;
@@ -2066,8 +2068,8 @@ static int fc_lport_ct_request(struct fc_bsg_job *job,
        info->nents = job->reply_payload.sg_cnt;
        info->sg = job->reply_payload.sg_list;
 
-       if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
-                                    NULL, info, tov)) {
+       if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
+                             NULL, info, tov)) {
                kfree(info);
                return -ECOMM;
        }
@@ -2079,25 +2081,27 @@ static int fc_lport_ct_request(struct fc_bsg_job *job,
  *                         FC Passthrough requests
  * @job: The BSG passthrough job
  */
-int fc_lport_bsg_request(struct fc_bsg_job *job)
+int fc_lport_bsg_request(struct bsg_job *job)
 {
+       struct fc_bsg_request *bsg_request = job->request;
+       struct fc_bsg_reply *bsg_reply = job->reply;
        struct request *rsp = job->req->next_rq;
-       struct Scsi_Host *shost = job->shost;
+       struct Scsi_Host *shost = fc_bsg_to_shost(job);
        struct fc_lport *lport = shost_priv(shost);
        struct fc_rport *rport;
        struct fc_rport_priv *rdata;
        int rc = -EINVAL;
        u32 did, tov;
 
-       job->reply->reply_payload_rcv_len = 0;
+       bsg_reply->reply_payload_rcv_len = 0;
        if (rsp)
                rsp->resid_len = job->reply_payload.payload_len;
 
        mutex_lock(&lport->lp_mutex);
 
-       switch (job->request->msgcode) {
+       switch (bsg_request->msgcode) {
        case FC_BSG_RPT_ELS:
-               rport = job->rport;
+               rport = fc_bsg_to_rport(job);
                if (!rport)
                        break;
 
@@ -2107,7 +2111,7 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
                break;
 
        case FC_BSG_RPT_CT:
-               rport = job->rport;
+               rport = fc_bsg_to_rport(job);
                if (!rport)
                        break;
 
@@ -2117,25 +2121,25 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
                break;
 
        case FC_BSG_HST_CT:
-               did = ntoh24(job->request->rqst_data.h_ct.port_id);
+               did = ntoh24(bsg_request->rqst_data.h_ct.port_id);
                if (did == FC_FID_DIR_SERV) {
                        rdata = lport->dns_rdata;
                        if (!rdata)
                                break;
                        tov = rdata->e_d_tov;
                } else {
-                       rdata = lport->tt.rport_lookup(lport, did);
+                       rdata = fc_rport_lookup(lport, did);
                        if (!rdata)
                                break;
                        tov = rdata->e_d_tov;
-                       kref_put(&rdata->kref, lport->tt.rport_destroy);
+                       kref_put(&rdata->kref, fc_rport_destroy);
                }
 
                rc = fc_lport_ct_request(job, lport, did, tov);
                break;
 
        case FC_BSG_HST_ELS_NOLOGIN:
-               did = ntoh24(job->request->rqst_data.h_els.port_id);
+               did = ntoh24(bsg_request->rqst_data.h_els.port_id);
                rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
                break;
        }