aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-17 01:09:29 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-17 01:09:29 -0500
commit2bb4646fce8d09916b351d1a62f98db7cec6fc41 (patch)
treec1f0d002e69868606eca9d1b919835f422892063 /drivers/s390/scsi
parent6836b9bdd98e3b500cd49512484df68f46e14659 (diff)
parentb0483e78e5c4c9871fc5541875b3bc006846d46b (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r--drivers/s390/scsi/zfcp_cfdc.c9
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c2
-rw-r--r--drivers/s390/scsi/zfcp_ext.h5
-rw-r--r--drivers/s390/scsi/zfcp_fc.c93
-rw-r--r--drivers/s390/scsi/zfcp_fc.h2
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c19
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c1
7 files changed, 85 insertions, 46 deletions
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index f932400e980a..0eb6eefd2c1a 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/miscdevice.h> 14#include <linux/miscdevice.h>
15#include <asm/compat.h>
15#include <asm/ccwdev.h> 16#include <asm/ccwdev.h>
16#include "zfcp_def.h" 17#include "zfcp_def.h"
17#include "zfcp_ext.h" 18#include "zfcp_ext.h"
@@ -163,7 +164,7 @@ static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data,
163} 164}
164 165
165static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, 166static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
166 unsigned long buffer) 167 unsigned long arg)
167{ 168{
168 struct zfcp_cfdc_data *data; 169 struct zfcp_cfdc_data *data;
169 struct zfcp_cfdc_data __user *data_user; 170 struct zfcp_cfdc_data __user *data_user;
@@ -175,7 +176,11 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
175 if (command != ZFCP_CFDC_IOC) 176 if (command != ZFCP_CFDC_IOC)
176 return -ENOTTY; 177 return -ENOTTY;
177 178
178 data_user = (void __user *) buffer; 179 if (is_compat_task())
180 data_user = compat_ptr(arg);
181 else
182 data_user = (void __user *)arg;
183
179 if (!data_user) 184 if (!data_user)
180 return -EINVAL; 185 return -EINVAL;
181 186
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 84450955ae11..7369c8911bcf 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -327,7 +327,7 @@ static void zfcp_dbf_hba_view_response(char **p,
327 break; 327 break;
328 zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); 328 zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
329 zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); 329 zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
330 p += sprintf(*p, "\n"); 330 *p += sprintf(*p, "\n");
331 break; 331 break;
332 332
333 case FSF_QTCB_OPEN_PORT_WITH_DID: 333 case FSF_QTCB_OPEN_PORT_WITH_DID:
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 03dec832b465..66bdb34143cb 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -108,6 +108,7 @@ extern void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *);
108extern int zfcp_fc_gs_setup(struct zfcp_adapter *); 108extern int zfcp_fc_gs_setup(struct zfcp_adapter *);
109extern void zfcp_fc_gs_destroy(struct zfcp_adapter *); 109extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
110extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *); 110extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
111extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
111 112
112/* zfcp_fsf.c */ 113/* zfcp_fsf.c */
113extern int zfcp_fsf_open_port(struct zfcp_erp_action *); 114extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
@@ -129,9 +130,9 @@ extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
129extern int zfcp_fsf_status_read(struct zfcp_qdio *); 130extern int zfcp_fsf_status_read(struct zfcp_qdio *);
130extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); 131extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
131extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *, 132extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *,
132 mempool_t *); 133 mempool_t *, unsigned int);
133extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32, 134extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
134 struct zfcp_fsf_ct_els *); 135 struct zfcp_fsf_ct_els *, unsigned int);
135extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *, 136extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
136 struct scsi_cmnd *); 137 struct scsi_cmnd *);
137extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); 138extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index ac5e3b7a3576..271399f62f1b 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -258,7 +258,8 @@ static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port,
258 gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn; 258 gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn;
259 259
260 ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct, 260 ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct,
261 adapter->pool.gid_pn_req); 261 adapter->pool.gid_pn_req,
262 ZFCP_FC_CTELS_TMO);
262 if (!ret) { 263 if (!ret) {
263 wait_for_completion(&completion); 264 wait_for_completion(&completion);
264 zfcp_fc_ns_gid_pn_eval(gid_pn); 265 zfcp_fc_ns_gid_pn_eval(gid_pn);
@@ -421,7 +422,8 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
421 hton24(adisc->adisc_req.adisc_port_id, 422 hton24(adisc->adisc_req.adisc_port_id,
422 fc_host_port_id(adapter->scsi_host)); 423 fc_host_port_id(adapter->scsi_host));
423 424
424 ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els); 425 ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els,
426 ZFCP_FC_CTELS_TMO);
425 if (ret) 427 if (ret)
426 kmem_cache_free(zfcp_data.adisc_cache, adisc); 428 kmem_cache_free(zfcp_data.adisc_cache, adisc);
427 429
@@ -532,7 +534,8 @@ static int zfcp_fc_send_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
532 ct->req = &gpn_ft->sg_req; 534 ct->req = &gpn_ft->sg_req;
533 ct->resp = gpn_ft->sg_resp; 535 ct->resp = gpn_ft->sg_resp;
534 536
535 ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL); 537 ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL,
538 ZFCP_FC_CTELS_TMO);
536 if (!ret) 539 if (!ret)
537 wait_for_completion(&completion); 540 wait_for_completion(&completion);
538 return ret; 541 return ret;
@@ -668,15 +671,52 @@ static void zfcp_fc_ct_els_job_handler(void *data)
668{ 671{
669 struct fc_bsg_job *job = data; 672 struct fc_bsg_job *job = data;
670 struct zfcp_fsf_ct_els *zfcp_ct_els = job->dd_data; 673 struct zfcp_fsf_ct_els *zfcp_ct_els = job->dd_data;
671 int status = zfcp_ct_els->status; 674 struct fc_bsg_reply *jr = job->reply;
672 int reply_status;
673 675
674 reply_status = status ? FC_CTELS_STATUS_REJECT : FC_CTELS_STATUS_OK; 676 jr->reply_payload_rcv_len = job->reply_payload.payload_len;
675 job->reply->reply_data.ctels_reply.status = reply_status; 677 jr->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
676 job->reply->reply_payload_rcv_len = job->reply_payload.payload_len; 678 jr->result = zfcp_ct_els->status ? -EIO : 0;
677 job->job_done(job); 679 job->job_done(job);
678} 680}
679 681
682static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
683{
684 u32 preamble_word1;
685 u8 gs_type;
686 struct zfcp_adapter *adapter;
687
688 preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
689 gs_type = (preamble_word1 & 0xff000000) >> 24;
690
691 adapter = (struct zfcp_adapter *) job->shost->hostdata[0];
692
693 switch (gs_type) {
694 case FC_FST_ALIAS:
695 return &adapter->gs->as;
696 case FC_FST_MGMT:
697 return &adapter->gs->ms;
698 case FC_FST_TIME:
699 return &adapter->gs->ts;
700 break;
701 case FC_FST_DIR:
702 return &adapter->gs->ds;
703 break;
704 default:
705 return NULL;
706 }
707}
708
709static void zfcp_fc_ct_job_handler(void *data)
710{
711 struct fc_bsg_job *job = data;
712 struct zfcp_fc_wka_port *wka_port;
713
714 wka_port = zfcp_fc_job_wka_port(job);
715 zfcp_fc_wka_port_put(wka_port);
716
717 zfcp_fc_ct_els_job_handler(data);
718}
719
680static int zfcp_fc_exec_els_job(struct fc_bsg_job *job, 720static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
681 struct zfcp_adapter *adapter) 721 struct zfcp_adapter *adapter)
682{ 722{
@@ -695,43 +735,27 @@ static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
695 } else 735 } else
696 d_id = ntoh24(job->request->rqst_data.h_els.port_id); 736 d_id = ntoh24(job->request->rqst_data.h_els.port_id);
697 737
698 return zfcp_fsf_send_els(adapter, d_id, els); 738 els->handler = zfcp_fc_ct_els_job_handler;
739 return zfcp_fsf_send_els(adapter, d_id, els, job->req->timeout / HZ);
699} 740}
700 741
701static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job, 742static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job,
702 struct zfcp_adapter *adapter) 743 struct zfcp_adapter *adapter)
703{ 744{
704 int ret; 745 int ret;
705 u8 gs_type;
706 struct zfcp_fsf_ct_els *ct = job->dd_data; 746 struct zfcp_fsf_ct_els *ct = job->dd_data;
707 struct zfcp_fc_wka_port *wka_port; 747 struct zfcp_fc_wka_port *wka_port;
708 u32 preamble_word1;
709 748
710 preamble_word1 = job->request->rqst_data.r_ct.preamble_word1; 749 wka_port = zfcp_fc_job_wka_port(job);
711 gs_type = (preamble_word1 & 0xff000000) >> 24; 750 if (!wka_port)
712 751 return -EINVAL;
713 switch (gs_type) {
714 case FC_FST_ALIAS:
715 wka_port = &adapter->gs->as;
716 break;
717 case FC_FST_MGMT:
718 wka_port = &adapter->gs->ms;
719 break;
720 case FC_FST_TIME:
721 wka_port = &adapter->gs->ts;
722 break;
723 case FC_FST_DIR:
724 wka_port = &adapter->gs->ds;
725 break;
726 default:
727 return -EINVAL; /* no such service */
728 }
729 752
730 ret = zfcp_fc_wka_port_get(wka_port); 753 ret = zfcp_fc_wka_port_get(wka_port);
731 if (ret) 754 if (ret)
732 return ret; 755 return ret;
733 756
734 ret = zfcp_fsf_send_ct(wka_port, ct, NULL); 757 ct->handler = zfcp_fc_ct_job_handler;
758 ret = zfcp_fsf_send_ct(wka_port, ct, NULL, job->req->timeout / HZ);
735 if (ret) 759 if (ret)
736 zfcp_fc_wka_port_put(wka_port); 760 zfcp_fc_wka_port_put(wka_port);
737 761
@@ -752,7 +776,6 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
752 776
753 ct_els->req = job->request_payload.sg_list; 777 ct_els->req = job->request_payload.sg_list;
754 ct_els->resp = job->reply_payload.sg_list; 778 ct_els->resp = job->reply_payload.sg_list;
755 ct_els->handler = zfcp_fc_ct_els_job_handler;
756 ct_els->handler_data = job; 779 ct_els->handler_data = job;
757 780
758 switch (job->request->msgcode) { 781 switch (job->request->msgcode) {
@@ -767,6 +790,12 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
767 } 790 }
768} 791}
769 792
793int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *job)
794{
795 /* hardware tracks timeout, reset bsg timeout to not interfere */
796 return -EAGAIN;
797}
798
770int zfcp_fc_gs_setup(struct zfcp_adapter *adapter) 799int zfcp_fc_gs_setup(struct zfcp_adapter *adapter)
771{ 800{
772 struct zfcp_fc_wka_ports *wka_ports; 801 struct zfcp_fc_wka_ports *wka_ports;
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
index cb2a3669a384..0747b087390d 100644
--- a/drivers/s390/scsi/zfcp_fc.h
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -27,6 +27,8 @@
27#define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \ 27#define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \
28 (ZFCP_FC_GPN_FT_ENT_PAGE + 1)) 28 (ZFCP_FC_GPN_FT_ENT_PAGE + 1))
29 29
30#define ZFCP_FC_CTELS_TMO (2 * FC_DEF_R_A_TOV / 1000)
31
30/** 32/**
31 * struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request 33 * struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
32 * @ct_hdr: FC GS common transport header 34 * @ct_hdr: FC GS common transport header
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 482dcd97aa5d..e8fb4d9baa8b 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1068,20 +1068,20 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
1068static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, 1068static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
1069 struct scatterlist *sg_req, 1069 struct scatterlist *sg_req,
1070 struct scatterlist *sg_resp, 1070 struct scatterlist *sg_resp,
1071 int max_sbals) 1071 int max_sbals, unsigned int timeout)
1072{ 1072{
1073 int ret; 1073 int ret;
1074 unsigned int fcp_chan_timeout;
1075 1074
1076 ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); 1075 ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
1077 if (ret) 1076 if (ret)
1078 return ret; 1077 return ret;
1079 1078
1080 /* common settings for ct/gs and els requests */ 1079 /* common settings for ct/gs and els requests */
1081 fcp_chan_timeout = 2 * FC_DEF_R_A_TOV / 1000; 1080 if (timeout > 255)
1081 timeout = 255; /* max value accepted by hardware */
1082 req->qtcb->bottom.support.service_class = FSF_CLASS_3; 1082 req->qtcb->bottom.support.service_class = FSF_CLASS_3;
1083 req->qtcb->bottom.support.timeout = fcp_chan_timeout; 1083 req->qtcb->bottom.support.timeout = timeout;
1084 zfcp_fsf_start_timer(req, (fcp_chan_timeout + 10) * HZ); 1084 zfcp_fsf_start_timer(req, (timeout + 10) * HZ);
1085 1085
1086 return 0; 1086 return 0;
1087} 1087}
@@ -1092,7 +1092,8 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
1092 * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req 1092 * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req
1093 */ 1093 */
1094int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, 1094int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
1095 struct zfcp_fsf_ct_els *ct, mempool_t *pool) 1095 struct zfcp_fsf_ct_els *ct, mempool_t *pool,
1096 unsigned int timeout)
1096{ 1097{
1097 struct zfcp_qdio *qdio = wka_port->adapter->qdio; 1098 struct zfcp_qdio *qdio = wka_port->adapter->qdio;
1098 struct zfcp_fsf_req *req; 1099 struct zfcp_fsf_req *req;
@@ -1111,7 +1112,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
1111 1112
1112 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; 1113 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1113 ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, 1114 ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp,
1114 FSF_MAX_SBALS_PER_REQ); 1115 FSF_MAX_SBALS_PER_REQ, timeout);
1115 if (ret) 1116 if (ret)
1116 goto failed_send; 1117 goto failed_send;
1117 1118
@@ -1188,7 +1189,7 @@ skip_fsfstatus:
1188 * @els: pointer to struct zfcp_send_els with data for the command 1189 * @els: pointer to struct zfcp_send_els with data for the command
1189 */ 1190 */
1190int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, 1191int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
1191 struct zfcp_fsf_ct_els *els) 1192 struct zfcp_fsf_ct_els *els, unsigned int timeout)
1192{ 1193{
1193 struct zfcp_fsf_req *req; 1194 struct zfcp_fsf_req *req;
1194 struct zfcp_qdio *qdio = adapter->qdio; 1195 struct zfcp_qdio *qdio = adapter->qdio;
@@ -1206,7 +1207,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
1206 } 1207 }
1207 1208
1208 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; 1209 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1209 ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2); 1210 ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2, timeout);
1210 1211
1211 if (ret) 1212 if (ret)
1212 goto failed_send; 1213 goto failed_send;
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 771cc536a989..8e6fc68d6bd4 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -652,6 +652,7 @@ struct fc_function_template zfcp_transport_functions = {
652 .show_host_port_state = 1, 652 .show_host_port_state = 1,
653 .show_host_active_fc4s = 1, 653 .show_host_active_fc4s = 1,
654 .bsg_request = zfcp_fc_exec_bsg_job, 654 .bsg_request = zfcp_fc_exec_bsg_job,
655 .bsg_timeout = zfcp_fc_timeout_bsg_job,
655 /* no functions registered for following dynamic attributes but 656 /* no functions registered for following dynamic attributes but
656 directly set by LLDD */ 657 directly set by LLDD */
657 .show_host_port_type = 1, 658 .show_host_port_type = 1,