1 /* 2 * Copyright(c) 2008 Intel Corporation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program; if not, write to the Free Software Foundation, Inc., 15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 * 17 * Maintained at www.Open-FCoE.org 18 */ 19 20 /* 21 * Provide interface to send ELS/CT FC frames 22 */ 23 24 #include <asm/unaligned.h> 25 #include <scsi/fc/fc_gs.h> 26 #include <scsi/fc/fc_ns.h> 27 #include <scsi/fc/fc_els.h> 28 #include <scsi/libfc.h> 29 #include <scsi/fc_encode.h> 30 31 /* 32 * fc_elsct_send - sends ELS/CT frame 33 */ 34 static struct fc_seq *fc_elsct_send(struct fc_lport *lport, 35 u32 did, 36 struct fc_frame *fp, 37 unsigned int op, 38 void (*resp)(struct fc_seq *, 39 struct fc_frame *fp, 40 void *arg), 41 void *arg, u32 timer_msec) 42 { 43 enum fc_rctl r_ctl; 44 enum fc_fh_type fh_type; 45 int rc; 46 47 /* ELS requests */ 48 if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS)) 49 rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type); 50 else { 51 /* CT requests */ 52 rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type); 53 did = FC_FID_DIR_SERV; 54 } 55 56 if (rc) 57 return NULL; 58 59 fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type, 60 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 61 62 return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec); 63 } 64 65 int fc_elsct_init(struct fc_lport *lport) 66 { 67 if (!lport->tt.elsct_send) 68 lport->tt.elsct_send = fc_elsct_send; 69 70 return 0; 71 } 72 EXPORT_SYMBOL(fc_elsct_init); 73 74 /** 75 * fc_els_resp_type() - return string describing ELS response for debug. 76 * @fp: frame pointer with possible error code. 77 */ 78 const char *fc_els_resp_type(struct fc_frame *fp) 79 { 80 const char *msg; 81 if (IS_ERR(fp)) { 82 switch (-PTR_ERR(fp)) { 83 case FC_NO_ERR: 84 msg = "response no error"; 85 break; 86 case FC_EX_TIMEOUT: 87 msg = "response timeout"; 88 break; 89 case FC_EX_CLOSED: 90 msg = "response closed"; 91 break; 92 default: 93 msg = "response unknown error"; 94 break; 95 } 96 } else { 97 switch (fc_frame_payload_op(fp)) { 98 case ELS_LS_ACC: 99 msg = "accept"; 100 break; 101 case ELS_LS_RJT: 102 msg = "reject"; 103 break; 104 default: 105 msg = "response unknown ELS"; 106 break; 107 } 108 } 109 return msg; 110 } 111