aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_lport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libfc/fc_lport.c')
-rw-r--r--drivers/scsi/libfc/fc_lport.c864
1 files changed, 605 insertions, 259 deletions
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index bd2f77197447..d126ecfff704 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -56,7 +56,7 @@
56 * at the same time. 56 * at the same time.
57 * 57 *
58 * When discovery succeeds or fails a callback is made to the lport as 58 * When discovery succeeds or fails a callback is made to the lport as
59 * notification. Currently, succesful discovery causes the lport to take no 59 * notification. Currently, successful discovery causes the lport to take no
60 * action. A failure will cause the lport to reset. There is likely a circular 60 * action. A failure will cause the lport to reset. There is likely a circular
61 * locking problem with this implementation. 61 * locking problem with this implementation.
62 */ 62 */
@@ -88,12 +88,16 @@
88 */ 88 */
89 89
90#include <linux/timer.h> 90#include <linux/timer.h>
91#include <linux/slab.h>
91#include <asm/unaligned.h> 92#include <asm/unaligned.h>
92 93
93#include <scsi/fc/fc_gs.h> 94#include <scsi/fc/fc_gs.h>
94 95
95#include <scsi/libfc.h> 96#include <scsi/libfc.h>
96#include <scsi/fc_encode.h> 97#include <scsi/fc_encode.h>
98#include <linux/scatterlist.h>
99
100#include "fc_libfc.h"
97 101
98/* Fabric IDs to use for point-to-point mode, chosen on whims. */ 102/* Fabric IDs to use for point-to-point mode, chosen on whims. */
99#define FC_LOCAL_PTP_FID_LO 0x010101 103#define FC_LOCAL_PTP_FID_LO 0x010101
@@ -106,8 +110,7 @@ static void fc_lport_error(struct fc_lport *, struct fc_frame *);
106static void fc_lport_enter_reset(struct fc_lport *); 110static void fc_lport_enter_reset(struct fc_lport *);
107static void fc_lport_enter_flogi(struct fc_lport *); 111static void fc_lport_enter_flogi(struct fc_lport *);
108static void fc_lport_enter_dns(struct fc_lport *); 112static void fc_lport_enter_dns(struct fc_lport *);
109static void fc_lport_enter_rpn_id(struct fc_lport *); 113static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state);
110static void fc_lport_enter_rft_id(struct fc_lport *);
111static void fc_lport_enter_scr(struct fc_lport *); 114static void fc_lport_enter_scr(struct fc_lport *);
112static void fc_lport_enter_ready(struct fc_lport *); 115static void fc_lport_enter_ready(struct fc_lport *);
113static void fc_lport_enter_logo(struct fc_lport *); 116static void fc_lport_enter_logo(struct fc_lport *);
@@ -116,14 +119,40 @@ static const char *fc_lport_state_names[] = {
116 [LPORT_ST_DISABLED] = "disabled", 119 [LPORT_ST_DISABLED] = "disabled",
117 [LPORT_ST_FLOGI] = "FLOGI", 120 [LPORT_ST_FLOGI] = "FLOGI",
118 [LPORT_ST_DNS] = "dNS", 121 [LPORT_ST_DNS] = "dNS",
119 [LPORT_ST_RPN_ID] = "RPN_ID", 122 [LPORT_ST_RNN_ID] = "RNN_ID",
123 [LPORT_ST_RSNN_NN] = "RSNN_NN",
124 [LPORT_ST_RSPN_ID] = "RSPN_ID",
120 [LPORT_ST_RFT_ID] = "RFT_ID", 125 [LPORT_ST_RFT_ID] = "RFT_ID",
126 [LPORT_ST_RFF_ID] = "RFF_ID",
121 [LPORT_ST_SCR] = "SCR", 127 [LPORT_ST_SCR] = "SCR",
122 [LPORT_ST_READY] = "Ready", 128 [LPORT_ST_READY] = "Ready",
123 [LPORT_ST_LOGO] = "LOGO", 129 [LPORT_ST_LOGO] = "LOGO",
124 [LPORT_ST_RESET] = "reset", 130 [LPORT_ST_RESET] = "reset",
125}; 131};
126 132
133/**
134 * struct fc_bsg_info - FC Passthrough managemet structure
135 * @job: The passthrough job
136 * @lport: The local port to pass through a command
137 * @rsp_code: The expected response code
138 * @sg: job->reply_payload.sg_list
139 * @nents: job->reply_payload.sg_cnt
140 * @offset: The offset into the response data
141 */
142struct fc_bsg_info {
143 struct fc_bsg_job *job;
144 struct fc_lport *lport;
145 u16 rsp_code;
146 struct scatterlist *sg;
147 u32 nents;
148 size_t offset;
149};
150
151/**
152 * fc_frame_drop() - Dummy frame handler
153 * @lport: The local port the frame was received on
154 * @fp: The received frame
155 */
127static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp) 156static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
128{ 157{
129 fc_frame_free(fp); 158 fc_frame_free(fp);
@@ -150,8 +179,8 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
150 switch (event) { 179 switch (event) {
151 case RPORT_EV_READY: 180 case RPORT_EV_READY:
152 if (lport->state == LPORT_ST_DNS) { 181 if (lport->state == LPORT_ST_DNS) {
153 lport->dns_rp = rdata; 182 lport->dns_rdata = rdata;
154 fc_lport_enter_rpn_id(lport); 183 fc_lport_enter_ns(lport, LPORT_ST_RNN_ID);
155 } else { 184 } else {
156 FC_LPORT_DBG(lport, "Received an READY event " 185 FC_LPORT_DBG(lport, "Received an READY event "
157 "on port (%6x) for the directory " 186 "on port (%6x) for the directory "
@@ -165,7 +194,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
165 case RPORT_EV_LOGO: 194 case RPORT_EV_LOGO:
166 case RPORT_EV_FAILED: 195 case RPORT_EV_FAILED:
167 case RPORT_EV_STOP: 196 case RPORT_EV_STOP:
168 lport->dns_rp = NULL; 197 lport->dns_rdata = NULL;
169 break; 198 break;
170 case RPORT_EV_NONE: 199 case RPORT_EV_NONE:
171 break; 200 break;
@@ -189,8 +218,8 @@ static const char *fc_lport_state(struct fc_lport *lport)
189 218
190/** 219/**
191 * fc_lport_ptp_setup() - Create an rport for point-to-point mode 220 * fc_lport_ptp_setup() - Create an rport for point-to-point mode
192 * @lport: The lport to attach the ptp rport to 221 * @lport: The lport to attach the ptp rport to
193 * @fid: The FID of the ptp rport 222 * @remote_fid: The FID of the ptp rport
194 * @remote_wwpn: The WWPN of the ptp rport 223 * @remote_wwpn: The WWPN of the ptp rport
195 * @remote_wwnn: The WWNN of the ptp rport 224 * @remote_wwnn: The WWNN of the ptp rport
196 */ 225 */
@@ -199,18 +228,22 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
199 u64 remote_wwnn) 228 u64 remote_wwnn)
200{ 229{
201 mutex_lock(&lport->disc.disc_mutex); 230 mutex_lock(&lport->disc.disc_mutex);
202 if (lport->ptp_rp) 231 if (lport->ptp_rdata)
203 lport->tt.rport_logoff(lport->ptp_rp); 232 lport->tt.rport_logoff(lport->ptp_rdata);
204 lport->ptp_rp = lport->tt.rport_create(lport, remote_fid); 233 lport->ptp_rdata = lport->tt.rport_create(lport, remote_fid);
205 lport->ptp_rp->ids.port_name = remote_wwpn; 234 lport->ptp_rdata->ids.port_name = remote_wwpn;
206 lport->ptp_rp->ids.node_name = remote_wwnn; 235 lport->ptp_rdata->ids.node_name = remote_wwnn;
207 mutex_unlock(&lport->disc.disc_mutex); 236 mutex_unlock(&lport->disc.disc_mutex);
208 237
209 lport->tt.rport_login(lport->ptp_rp); 238 lport->tt.rport_login(lport->ptp_rdata);
210 239
211 fc_lport_enter_ready(lport); 240 fc_lport_enter_ready(lport);
212} 241}
213 242
243/**
244 * fc_get_host_port_type() - Return the port type of the given Scsi_Host
245 * @shost: The SCSI host whose port type is to be determined
246 */
214void fc_get_host_port_type(struct Scsi_Host *shost) 247void fc_get_host_port_type(struct Scsi_Host *shost)
215{ 248{
216 /* TODO - currently just NPORT */ 249 /* TODO - currently just NPORT */
@@ -218,17 +251,33 @@ void fc_get_host_port_type(struct Scsi_Host *shost)
218} 251}
219EXPORT_SYMBOL(fc_get_host_port_type); 252EXPORT_SYMBOL(fc_get_host_port_type);
220 253
254/**
255 * fc_get_host_port_state() - Return the port state of the given Scsi_Host
256 * @shost: The SCSI host whose port state is to be determined
257 */
221void fc_get_host_port_state(struct Scsi_Host *shost) 258void fc_get_host_port_state(struct Scsi_Host *shost)
222{ 259{
223 struct fc_lport *lp = shost_priv(shost); 260 struct fc_lport *lport = shost_priv(shost);
224 261
225 if (lp->link_up) 262 mutex_lock(&lport->lp_mutex);
226 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; 263 if (!lport->link_up)
264 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
227 else 265 else
228 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; 266 switch (lport->state) {
267 case LPORT_ST_READY:
268 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
269 break;
270 default:
271 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
272 }
273 mutex_unlock(&lport->lp_mutex);
229} 274}
230EXPORT_SYMBOL(fc_get_host_port_state); 275EXPORT_SYMBOL(fc_get_host_port_state);
231 276
277/**
278 * fc_get_host_speed() - Return the speed of the given Scsi_Host
279 * @shost: The SCSI host whose port speed is to be determined
280 */
232void fc_get_host_speed(struct Scsi_Host *shost) 281void fc_get_host_speed(struct Scsi_Host *shost)
233{ 282{
234 struct fc_lport *lport = shost_priv(shost); 283 struct fc_lport *lport = shost_priv(shost);
@@ -237,24 +286,28 @@ void fc_get_host_speed(struct Scsi_Host *shost)
237} 286}
238EXPORT_SYMBOL(fc_get_host_speed); 287EXPORT_SYMBOL(fc_get_host_speed);
239 288
289/**
290 * fc_get_host_stats() - Return the Scsi_Host's statistics
291 * @shost: The SCSI host whose statistics are to be returned
292 */
240struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost) 293struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
241{ 294{
242 struct fc_host_statistics *fcoe_stats; 295 struct fc_host_statistics *fcoe_stats;
243 struct fc_lport *lp = shost_priv(shost); 296 struct fc_lport *lport = shost_priv(shost);
244 struct timespec v0, v1; 297 struct timespec v0, v1;
245 unsigned int cpu; 298 unsigned int cpu;
246 299
247 fcoe_stats = &lp->host_stats; 300 fcoe_stats = &lport->host_stats;
248 memset(fcoe_stats, 0, sizeof(struct fc_host_statistics)); 301 memset(fcoe_stats, 0, sizeof(struct fc_host_statistics));
249 302
250 jiffies_to_timespec(jiffies, &v0); 303 jiffies_to_timespec(jiffies, &v0);
251 jiffies_to_timespec(lp->boot_time, &v1); 304 jiffies_to_timespec(lport->boot_time, &v1);
252 fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec); 305 fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec);
253 306
254 for_each_possible_cpu(cpu) { 307 for_each_possible_cpu(cpu) {
255 struct fcoe_dev_stats *stats; 308 struct fcoe_dev_stats *stats;
256 309
257 stats = per_cpu_ptr(lp->dev_stats, cpu); 310 stats = per_cpu_ptr(lport->dev_stats, cpu);
258 311
259 fcoe_stats->tx_frames += stats->TxFrames; 312 fcoe_stats->tx_frames += stats->TxFrames;
260 fcoe_stats->tx_words += stats->TxWords; 313 fcoe_stats->tx_words += stats->TxWords;
@@ -279,12 +332,15 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
279} 332}
280EXPORT_SYMBOL(fc_get_host_stats); 333EXPORT_SYMBOL(fc_get_host_stats);
281 334
282/* 335/**
283 * Fill in FLOGI command for request. 336 * fc_lport_flogi_fill() - Fill in FLOGI command for request
337 * @lport: The local port the FLOGI is for
338 * @flogi: The FLOGI command
339 * @op: The opcode
284 */ 340 */
285static void 341static void fc_lport_flogi_fill(struct fc_lport *lport,
286fc_lport_flogi_fill(struct fc_lport *lport, struct fc_els_flogi *flogi, 342 struct fc_els_flogi *flogi,
287 unsigned int op) 343 unsigned int op)
288{ 344{
289 struct fc_els_csp *sp; 345 struct fc_els_csp *sp;
290 struct fc_els_cssp *cp; 346 struct fc_els_cssp *cp;
@@ -312,8 +368,10 @@ fc_lport_flogi_fill(struct fc_lport *lport, struct fc_els_flogi *flogi,
312 } 368 }
313} 369}
314 370
315/* 371/**
316 * Add a supported FC-4 type. 372 * fc_lport_add_fc4_type() - Add a supported FC-4 type to a local port
373 * @lport: The local port to add a new FC-4 type to
374 * @type: The new FC-4 type
317 */ 375 */
318static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type) 376static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
319{ 377{
@@ -325,11 +383,11 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
325 383
326/** 384/**
327 * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report. 385 * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report.
386 * @sp: The sequence in the RLIR exchange
387 * @fp: The RLIR request frame
328 * @lport: Fibre Channel local port recieving the RLIR 388 * @lport: Fibre Channel local port recieving the RLIR
329 * @sp: current sequence in the RLIR exchange
330 * @fp: RLIR request frame
331 * 389 *
332 * Locking Note: The lport lock is exected to be held before calling 390 * Locking Note: The lport lock is expected to be held before calling
333 * this function. 391 * this function.
334 */ 392 */
335static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp, 393static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
@@ -344,11 +402,11 @@ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
344 402
345/** 403/**
346 * fc_lport_recv_echo_req() - Handle received ECHO request 404 * fc_lport_recv_echo_req() - Handle received ECHO request
347 * @lport: Fibre Channel local port recieving the ECHO 405 * @sp: The sequence in the ECHO exchange
348 * @sp: current sequence in the ECHO exchange 406 * @fp: ECHO request frame
349 * @fp: ECHO request frame 407 * @lport: The local port recieving the ECHO
350 * 408 *
351 * Locking Note: The lport lock is exected to be held before calling 409 * Locking Note: The lport lock is expected to be held before calling
352 * this function. 410 * this function.
353 */ 411 */
354static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, 412static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
@@ -361,7 +419,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
361 void *dp; 419 void *dp;
362 u32 f_ctl; 420 u32 f_ctl;
363 421
364 FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n", 422 FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
365 fc_lport_state(lport)); 423 fc_lport_state(lport));
366 424
367 len = fr_len(in_fp) - sizeof(struct fc_frame_header); 425 len = fr_len(in_fp) - sizeof(struct fc_frame_header);
@@ -374,7 +432,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
374 if (fp) { 432 if (fp) {
375 dp = fc_frame_payload_get(fp, len); 433 dp = fc_frame_payload_get(fp, len);
376 memcpy(dp, pp, len); 434 memcpy(dp, pp, len);
377 *((u32 *)dp) = htonl(ELS_LS_ACC << 24); 435 *((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
378 sp = lport->tt.seq_start_next(sp); 436 sp = lport->tt.seq_start_next(sp);
379 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 437 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
380 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 438 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
@@ -385,12 +443,12 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
385} 443}
386 444
387/** 445/**
388 * fc_lport_recv_echo_req() - Handle received Request Node ID data request 446 * fc_lport_recv_rnid_req() - Handle received Request Node ID data request
389 * @lport: Fibre Channel local port recieving the RNID 447 * @sp: The sequence in the RNID exchange
390 * @sp: current sequence in the RNID exchange 448 * @fp: The RNID request frame
391 * @fp: RNID request frame 449 * @lport: The local port recieving the RNID
392 * 450 *
393 * Locking Note: The lport lock is exected to be held before calling 451 * Locking Note: The lport lock is expected to be held before calling
394 * this function. 452 * this function.
395 */ 453 */
396static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp, 454static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
@@ -453,9 +511,9 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
453 511
454/** 512/**
455 * fc_lport_recv_logo_req() - Handle received fabric LOGO request 513 * fc_lport_recv_logo_req() - Handle received fabric LOGO request
456 * @lport: Fibre Channel local port recieving the LOGO 514 * @sp: The sequence in the LOGO exchange
457 * @sp: current sequence in the LOGO exchange 515 * @fp: The LOGO request frame
458 * @fp: LOGO request frame 516 * @lport: The local port recieving the LOGO
459 * 517 *
460 * Locking Note: The lport lock is exected to be held before calling 518 * Locking Note: The lport lock is exected to be held before calling
461 * this function. 519 * this function.
@@ -470,7 +528,7 @@ static void fc_lport_recv_logo_req(struct fc_seq *sp, struct fc_frame *fp,
470 528
471/** 529/**
472 * fc_fabric_login() - Start the lport state machine 530 * fc_fabric_login() - Start the lport state machine
473 * @lport: The lport that should log into the fabric 531 * @lport: The local port that should log into the fabric
474 * 532 *
475 * Locking Note: This function should not be called 533 * Locking Note: This function should not be called
476 * with the lport lock held. 534 * with the lport lock held.
@@ -480,7 +538,9 @@ int fc_fabric_login(struct fc_lport *lport)
480 int rc = -1; 538 int rc = -1;
481 539
482 mutex_lock(&lport->lp_mutex); 540 mutex_lock(&lport->lp_mutex);
483 if (lport->state == LPORT_ST_DISABLED) { 541 if (lport->state == LPORT_ST_DISABLED ||
542 lport->state == LPORT_ST_LOGO) {
543 fc_lport_state_enter(lport, LPORT_ST_RESET);
484 fc_lport_enter_reset(lport); 544 fc_lport_enter_reset(lport);
485 rc = 0; 545 rc = 0;
486 } 546 }
@@ -491,47 +551,69 @@ int fc_fabric_login(struct fc_lport *lport)
491EXPORT_SYMBOL(fc_fabric_login); 551EXPORT_SYMBOL(fc_fabric_login);
492 552
493/** 553/**
494 * fc_linkup() - Handler for transport linkup events 554 * __fc_linkup() - Handler for transport linkup events
495 * @lport: The lport whose link is up 555 * @lport: The lport whose link is up
556 *
557 * Locking: must be called with the lp_mutex held
496 */ 558 */
497void fc_linkup(struct fc_lport *lport) 559void __fc_linkup(struct fc_lport *lport)
498{ 560{
499 printk(KERN_INFO "libfc: Link up on port (%6x)\n",
500 fc_host_port_id(lport->host));
501
502 mutex_lock(&lport->lp_mutex);
503 if (!lport->link_up) { 561 if (!lport->link_up) {
504 lport->link_up = 1; 562 lport->link_up = 1;
505 563
506 if (lport->state == LPORT_ST_RESET) 564 if (lport->state == LPORT_ST_RESET)
507 fc_lport_enter_flogi(lport); 565 fc_lport_enter_flogi(lport);
508 } 566 }
567}
568
569/**
570 * fc_linkup() - Handler for transport linkup events
571 * @lport: The local port whose link is up
572 */
573void fc_linkup(struct fc_lport *lport)
574{
575 printk(KERN_INFO "host%d: libfc: Link up on port (%6x)\n",
576 lport->host->host_no, fc_host_port_id(lport->host));
577
578 mutex_lock(&lport->lp_mutex);
579 __fc_linkup(lport);
509 mutex_unlock(&lport->lp_mutex); 580 mutex_unlock(&lport->lp_mutex);
510} 581}
511EXPORT_SYMBOL(fc_linkup); 582EXPORT_SYMBOL(fc_linkup);
512 583
513/** 584/**
514 * fc_linkdown() - Handler for transport linkdown events 585 * __fc_linkdown() - Handler for transport linkdown events
515 * @lport: The lport whose link is down 586 * @lport: The lport whose link is down
587 *
588 * Locking: must be called with the lp_mutex held
516 */ 589 */
517void fc_linkdown(struct fc_lport *lport) 590void __fc_linkdown(struct fc_lport *lport)
518{ 591{
519 mutex_lock(&lport->lp_mutex);
520 printk(KERN_INFO "libfc: Link down on port (%6x)\n",
521 fc_host_port_id(lport->host));
522
523 if (lport->link_up) { 592 if (lport->link_up) {
524 lport->link_up = 0; 593 lport->link_up = 0;
525 fc_lport_enter_reset(lport); 594 fc_lport_enter_reset(lport);
526 lport->tt.fcp_cleanup(lport); 595 lport->tt.fcp_cleanup(lport);
527 } 596 }
597}
598
599/**
600 * fc_linkdown() - Handler for transport linkdown events
601 * @lport: The local port whose link is down
602 */
603void fc_linkdown(struct fc_lport *lport)
604{
605 printk(KERN_INFO "host%d: libfc: Link down on port (%6x)\n",
606 lport->host->host_no, fc_host_port_id(lport->host));
607
608 mutex_lock(&lport->lp_mutex);
609 __fc_linkdown(lport);
528 mutex_unlock(&lport->lp_mutex); 610 mutex_unlock(&lport->lp_mutex);
529} 611}
530EXPORT_SYMBOL(fc_linkdown); 612EXPORT_SYMBOL(fc_linkdown);
531 613
532/** 614/**
533 * fc_fabric_logoff() - Logout of the fabric 615 * fc_fabric_logoff() - Logout of the fabric
534 * @lport: fc_lport pointer to logoff the fabric 616 * @lport: The local port to logoff the fabric
535 * 617 *
536 * Return value: 618 * Return value:
537 * 0 for success, -1 for failure 619 * 0 for success, -1 for failure
@@ -540,8 +622,8 @@ int fc_fabric_logoff(struct fc_lport *lport)
540{ 622{
541 lport->tt.disc_stop_final(lport); 623 lport->tt.disc_stop_final(lport);
542 mutex_lock(&lport->lp_mutex); 624 mutex_lock(&lport->lp_mutex);
543 if (lport->dns_rp) 625 if (lport->dns_rdata)
544 lport->tt.rport_logoff(lport->dns_rp); 626 lport->tt.rport_logoff(lport->dns_rdata);
545 mutex_unlock(&lport->lp_mutex); 627 mutex_unlock(&lport->lp_mutex);
546 lport->tt.rport_flush_queue(); 628 lport->tt.rport_flush_queue();
547 mutex_lock(&lport->lp_mutex); 629 mutex_lock(&lport->lp_mutex);
@@ -553,11 +635,9 @@ int fc_fabric_logoff(struct fc_lport *lport)
553EXPORT_SYMBOL(fc_fabric_logoff); 635EXPORT_SYMBOL(fc_fabric_logoff);
554 636
555/** 637/**
556 * fc_lport_destroy() - unregister a fc_lport 638 * fc_lport_destroy() - Unregister a fc_lport
557 * @lport: fc_lport pointer to unregister 639 * @lport: The local port to unregister
558 * 640 *
559 * Return value:
560 * None
561 * Note: 641 * Note:
562 * exit routine for fc_lport instance 642 * exit routine for fc_lport instance
563 * clean-up all the allocated memory 643 * clean-up all the allocated memory
@@ -580,13 +660,9 @@ int fc_lport_destroy(struct fc_lport *lport)
580EXPORT_SYMBOL(fc_lport_destroy); 660EXPORT_SYMBOL(fc_lport_destroy);
581 661
582/** 662/**
583 * fc_set_mfs() - sets up the mfs for the corresponding fc_lport 663 * fc_set_mfs() - Set the maximum frame size for a local port
584 * @lport: fc_lport pointer to unregister 664 * @lport: The local port to set the MFS for
585 * @mfs: the new mfs for fc_lport 665 * @mfs: The new MFS
586 *
587 * Set mfs for the given fc_lport to the new mfs.
588 *
589 * Return: 0 for success
590 */ 666 */
591int fc_set_mfs(struct fc_lport *lport, u32 mfs) 667int fc_set_mfs(struct fc_lport *lport, u32 mfs)
592{ 668{
@@ -617,7 +693,7 @@ EXPORT_SYMBOL(fc_set_mfs);
617 693
618/** 694/**
619 * fc_lport_disc_callback() - Callback for discovery events 695 * fc_lport_disc_callback() - Callback for discovery events
620 * @lport: FC local port 696 * @lport: The local port receiving the event
621 * @event: The discovery event 697 * @event: The discovery event
622 */ 698 */
623void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event) 699void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
@@ -627,8 +703,9 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
627 FC_LPORT_DBG(lport, "Discovery succeeded\n"); 703 FC_LPORT_DBG(lport, "Discovery succeeded\n");
628 break; 704 break;
629 case DISC_EV_FAILED: 705 case DISC_EV_FAILED:
630 printk(KERN_ERR "libfc: Discovery failed for port (%6x)\n", 706 printk(KERN_ERR "host%d: libfc: "
631 fc_host_port_id(lport->host)); 707 "Discovery failed for port (%6x)\n",
708 lport->host->host_no, fc_host_port_id(lport->host));
632 mutex_lock(&lport->lp_mutex); 709 mutex_lock(&lport->lp_mutex);
633 fc_lport_enter_reset(lport); 710 fc_lport_enter_reset(lport);
634 mutex_unlock(&lport->lp_mutex); 711 mutex_unlock(&lport->lp_mutex);
@@ -641,7 +718,7 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
641 718
642/** 719/**
643 * fc_rport_enter_ready() - Enter the ready state and start discovery 720 * fc_rport_enter_ready() - Enter the ready state and start discovery
644 * @lport: Fibre Channel local port that is ready 721 * @lport: The local port that is ready
645 * 722 *
646 * Locking Note: The lport lock is expected to be held before calling 723 * Locking Note: The lport lock is expected to be held before calling
647 * this routine. 724 * this routine.
@@ -652,22 +729,46 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
652 fc_lport_state(lport)); 729 fc_lport_state(lport));
653 730
654 fc_lport_state_enter(lport, LPORT_ST_READY); 731 fc_lport_state_enter(lport, LPORT_ST_READY);
732 if (lport->vport)
733 fc_vport_set_state(lport->vport, FC_VPORT_ACTIVE);
734 fc_vports_linkchange(lport);
655 735
656 if (!lport->ptp_rp) 736 if (!lport->ptp_rdata)
657 lport->tt.disc_start(fc_lport_disc_callback, lport); 737 lport->tt.disc_start(fc_lport_disc_callback, lport);
658} 738}
659 739
660/** 740/**
741 * fc_lport_set_port_id() - set the local port Port ID
742 * @lport: The local port which will have its Port ID set.
743 * @port_id: The new port ID.
744 * @fp: The frame containing the incoming request, or NULL.
745 *
746 * Locking Note: The lport lock is expected to be held before calling
747 * this function.
748 */
749static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id,
750 struct fc_frame *fp)
751{
752 if (port_id)
753 printk(KERN_INFO "host%d: Assigned Port ID %6x\n",
754 lport->host->host_no, port_id);
755
756 fc_host_port_id(lport->host) = port_id;
757 if (lport->tt.lport_set_port_id)
758 lport->tt.lport_set_port_id(lport, port_id, fp);
759}
760
761/**
661 * fc_lport_recv_flogi_req() - Receive a FLOGI request 762 * fc_lport_recv_flogi_req() - Receive a FLOGI request
662 * @sp_in: The sequence the FLOGI is on 763 * @sp_in: The sequence the FLOGI is on
663 * @rx_fp: The frame the FLOGI is in 764 * @rx_fp: The FLOGI frame
664 * @lport: The lport that recieved the request 765 * @lport: The local port that recieved the request
665 * 766 *
666 * A received FLOGI request indicates a point-to-point connection. 767 * A received FLOGI request indicates a point-to-point connection.
667 * Accept it with the common service parameters indicating our N port. 768 * Accept it with the common service parameters indicating our N port.
668 * Set up to do a PLOGI if we have the higher-number WWPN. 769 * Set up to do a PLOGI if we have the higher-number WWPN.
669 * 770 *
670 * Locking Note: The lport lock is exected to be held before calling 771 * Locking Note: The lport lock is expected to be held before calling
671 * this function. 772 * this function.
672 */ 773 */
673static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, 774static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
@@ -695,8 +796,9 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
695 goto out; 796 goto out;
696 remote_wwpn = get_unaligned_be64(&flp->fl_wwpn); 797 remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
697 if (remote_wwpn == lport->wwpn) { 798 if (remote_wwpn == lport->wwpn) {
698 printk(KERN_WARNING "libfc: Received FLOGI from port " 799 printk(KERN_WARNING "host%d: libfc: Received FLOGI from port "
699 "with same WWPN %llx\n", remote_wwpn); 800 "with same WWPN %llx\n",
801 lport->host->host_no, remote_wwpn);
700 goto out; 802 goto out;
701 } 803 }
702 FC_LPORT_DBG(lport, "FLOGI from port WWPN %llx\n", remote_wwpn); 804 FC_LPORT_DBG(lport, "FLOGI from port WWPN %llx\n", remote_wwpn);
@@ -715,7 +817,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
715 remote_fid = FC_LOCAL_PTP_FID_HI; 817 remote_fid = FC_LOCAL_PTP_FID_HI;
716 } 818 }
717 819
718 fc_host_port_id(lport->host) = local_fid; 820 fc_lport_set_port_id(lport, local_fid, rx_fp);
719 821
720 fp = fc_frame_alloc(lport, sizeof(*flp)); 822 fp = fc_frame_alloc(lport, sizeof(*flp));
721 if (fp) { 823 if (fp) {
@@ -747,9 +849,9 @@ out:
747 849
748/** 850/**
749 * fc_lport_recv_req() - The generic lport request handler 851 * fc_lport_recv_req() - The generic lport request handler
750 * @lport: The lport that received the request 852 * @lport: The local port that received the request
751 * @sp: The sequence the request is on 853 * @sp: The sequence the request is on
752 * @fp: The frame the request is in 854 * @fp: The request frame
753 * 855 *
754 * This function will see if the lport handles the request or 856 * This function will see if the lport handles the request or
755 * if an rport should handle the request. 857 * if an rport should handle the request.
@@ -817,8 +919,8 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
817} 919}
818 920
819/** 921/**
820 * fc_lport_reset() - Reset an lport 922 * fc_lport_reset() - Reset a local port
821 * @lport: The lport which should be reset 923 * @lport: The local port which should be reset
822 * 924 *
823 * Locking Note: This functions should not be called with the 925 * Locking Note: This functions should not be called with the
824 * lport lock held. 926 * lport lock held.
@@ -834,29 +936,31 @@ int fc_lport_reset(struct fc_lport *lport)
834EXPORT_SYMBOL(fc_lport_reset); 936EXPORT_SYMBOL(fc_lport_reset);
835 937
836/** 938/**
837 * fc_lport_reset_locked() - Reset the local port 939 * fc_lport_reset_locked() - Reset the local port w/ the lport lock held
838 * @lport: Fibre Channel local port to be reset 940 * @lport: The local port to be reset
839 * 941 *
840 * Locking Note: The lport lock is expected to be held before calling 942 * Locking Note: The lport lock is expected to be held before calling
841 * this routine. 943 * this routine.
842 */ 944 */
843static void fc_lport_reset_locked(struct fc_lport *lport) 945static void fc_lport_reset_locked(struct fc_lport *lport)
844{ 946{
845 if (lport->dns_rp) 947 if (lport->dns_rdata)
846 lport->tt.rport_logoff(lport->dns_rp); 948 lport->tt.rport_logoff(lport->dns_rdata);
847 949
848 lport->ptp_rp = NULL; 950 lport->ptp_rdata = NULL;
849 951
850 lport->tt.disc_stop(lport); 952 lport->tt.disc_stop(lport);
851 953
852 lport->tt.exch_mgr_reset(lport, 0, 0); 954 lport->tt.exch_mgr_reset(lport, 0, 0);
853 fc_host_fabric_name(lport->host) = 0; 955 fc_host_fabric_name(lport->host) = 0;
854 fc_host_port_id(lport->host) = 0; 956
957 if (fc_host_port_id(lport->host))
958 fc_lport_set_port_id(lport, 0, NULL);
855} 959}
856 960
857/** 961/**
858 * fc_lport_enter_reset() - Reset the local port 962 * fc_lport_enter_reset() - Reset the local port
859 * @lport: Fibre Channel local port to be reset 963 * @lport: The local port to be reset
860 * 964 *
861 * Locking Note: The lport lock is expected to be held before calling 965 * Locking Note: The lport lock is expected to be held before calling
862 * this routine. 966 * this routine.
@@ -866,15 +970,25 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
866 FC_LPORT_DBG(lport, "Entered RESET state from %s state\n", 970 FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
867 fc_lport_state(lport)); 971 fc_lport_state(lport));
868 972
973 if (lport->state == LPORT_ST_DISABLED || lport->state == LPORT_ST_LOGO)
974 return;
975
976 if (lport->vport) {
977 if (lport->link_up)
978 fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING);
979 else
980 fc_vport_set_state(lport->vport, FC_VPORT_LINKDOWN);
981 }
869 fc_lport_state_enter(lport, LPORT_ST_RESET); 982 fc_lport_state_enter(lport, LPORT_ST_RESET);
983 fc_vports_linkchange(lport);
870 fc_lport_reset_locked(lport); 984 fc_lport_reset_locked(lport);
871 if (lport->link_up) 985 if (lport->link_up)
872 fc_lport_enter_flogi(lport); 986 fc_lport_enter_flogi(lport);
873} 987}
874 988
875/** 989/**
876 * fc_lport_enter_disabled() - disable the local port 990 * fc_lport_enter_disabled() - Disable the local port
877 * @lport: Fibre Channel local port to be reset 991 * @lport: The local port to be reset
878 * 992 *
879 * Locking Note: The lport lock is expected to be held before calling 993 * Locking Note: The lport lock is expected to be held before calling
880 * this routine. 994 * this routine.
@@ -885,13 +999,14 @@ static void fc_lport_enter_disabled(struct fc_lport *lport)
885 fc_lport_state(lport)); 999 fc_lport_state(lport));
886 1000
887 fc_lport_state_enter(lport, LPORT_ST_DISABLED); 1001 fc_lport_state_enter(lport, LPORT_ST_DISABLED);
1002 fc_vports_linkchange(lport);
888 fc_lport_reset_locked(lport); 1003 fc_lport_reset_locked(lport);
889} 1004}
890 1005
891/** 1006/**
892 * fc_lport_error() - Handler for any errors 1007 * fc_lport_error() - Handler for any errors
893 * @lport: The fc_lport object 1008 * @lport: The local port that the error was on
894 * @fp: The frame pointer 1009 * @fp: The error code encoded in a frame pointer
895 * 1010 *
896 * If the error was caused by a resource allocation failure 1011 * If the error was caused by a resource allocation failure
897 * then wait for half a second and retry, otherwise retry 1012 * then wait for half a second and retry, otherwise retry
@@ -922,8 +1037,11 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
922 case LPORT_ST_DISABLED: 1037 case LPORT_ST_DISABLED:
923 case LPORT_ST_READY: 1038 case LPORT_ST_READY:
924 case LPORT_ST_RESET: 1039 case LPORT_ST_RESET:
925 case LPORT_ST_RPN_ID: 1040 case LPORT_ST_RNN_ID:
1041 case LPORT_ST_RSNN_NN:
1042 case LPORT_ST_RSPN_ID:
926 case LPORT_ST_RFT_ID: 1043 case LPORT_ST_RFT_ID:
1044 case LPORT_ST_RFF_ID:
927 case LPORT_ST_SCR: 1045 case LPORT_ST_SCR:
928 case LPORT_ST_DNS: 1046 case LPORT_ST_DNS:
929 case LPORT_ST_FLOGI: 1047 case LPORT_ST_FLOGI:
@@ -936,33 +1054,33 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
936} 1054}
937 1055
938/** 1056/**
939 * fc_lport_rft_id_resp() - Handle response to Register Fibre 1057 * fc_lport_ns_resp() - Handle response to a name server
940 * Channel Types by ID (RPN_ID) request 1058 * registration exchange
941 * @sp: current sequence in RPN_ID exchange 1059 * @sp: current sequence in exchange
942 * @fp: response frame 1060 * @fp: response frame
943 * @lp_arg: Fibre Channel host port instance 1061 * @lp_arg: Fibre Channel host port instance
944 * 1062 *
945 * Locking Note: This function will be called without the lport lock 1063 * Locking Note: This function will be called without the lport lock
946 * held, but it will lock, call an _enter_* function or fc_lport_error 1064 * held, but it will lock, call an _enter_* function or fc_lport_error()
947 * and then unlock the lport. 1065 * and then unlock the lport.
948 */ 1066 */
949static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, 1067static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
950 void *lp_arg) 1068 void *lp_arg)
951{ 1069{
952 struct fc_lport *lport = lp_arg; 1070 struct fc_lport *lport = lp_arg;
953 struct fc_frame_header *fh; 1071 struct fc_frame_header *fh;
954 struct fc_ct_hdr *ct; 1072 struct fc_ct_hdr *ct;
955 1073
956 FC_LPORT_DBG(lport, "Received a RFT_ID %s\n", fc_els_resp_type(fp)); 1074 FC_LPORT_DBG(lport, "Received a ns %s\n", fc_els_resp_type(fp));
957 1075
958 if (fp == ERR_PTR(-FC_EX_CLOSED)) 1076 if (fp == ERR_PTR(-FC_EX_CLOSED))
959 return; 1077 return;
960 1078
961 mutex_lock(&lport->lp_mutex); 1079 mutex_lock(&lport->lp_mutex);
962 1080
963 if (lport->state != LPORT_ST_RFT_ID) { 1081 if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFF_ID) {
964 FC_LPORT_DBG(lport, "Received a RFT_ID response, but in state " 1082 FC_LPORT_DBG(lport, "Received a name server response, "
965 "%s\n", fc_lport_state(lport)); 1083 "but in state %s\n", fc_lport_state(lport));
966 if (IS_ERR(fp)) 1084 if (IS_ERR(fp))
967 goto err; 1085 goto err;
968 goto out; 1086 goto out;
@@ -980,63 +1098,28 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
980 ct->ct_fs_type == FC_FST_DIR && 1098 ct->ct_fs_type == FC_FST_DIR &&
981 ct->ct_fs_subtype == FC_NS_SUBTYPE && 1099 ct->ct_fs_subtype == FC_NS_SUBTYPE &&
982 ntohs(ct->ct_cmd) == FC_FS_ACC) 1100 ntohs(ct->ct_cmd) == FC_FS_ACC)
983 fc_lport_enter_scr(lport); 1101 switch (lport->state) {
984 else 1102 case LPORT_ST_RNN_ID:
985 fc_lport_error(lport, fp); 1103 fc_lport_enter_ns(lport, LPORT_ST_RSNN_NN);
986out: 1104 break;
987 fc_frame_free(fp); 1105 case LPORT_ST_RSNN_NN:
988err: 1106 fc_lport_enter_ns(lport, LPORT_ST_RSPN_ID);
989 mutex_unlock(&lport->lp_mutex); 1107 break;
990} 1108 case LPORT_ST_RSPN_ID:
991 1109 fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
992/** 1110 break;
993 * fc_lport_rpn_id_resp() - Handle response to Register Port 1111 case LPORT_ST_RFT_ID:
994 * Name by ID (RPN_ID) request 1112 fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
995 * @sp: current sequence in RPN_ID exchange 1113 break;
996 * @fp: response frame 1114 case LPORT_ST_RFF_ID:
997 * @lp_arg: Fibre Channel host port instance 1115 fc_lport_enter_scr(lport);
998 * 1116 break;
999 * Locking Note: This function will be called without the lport lock 1117 default:
1000 * held, but it will lock, call an _enter_* function or fc_lport_error 1118 /* should have already been caught by state checks */
1001 * and then unlock the lport. 1119 break;
1002 */ 1120 }
1003static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
1004 void *lp_arg)
1005{
1006 struct fc_lport *lport = lp_arg;
1007 struct fc_frame_header *fh;
1008 struct fc_ct_hdr *ct;
1009
1010 FC_LPORT_DBG(lport, "Received a RPN_ID %s\n", fc_els_resp_type(fp));
1011
1012 if (fp == ERR_PTR(-FC_EX_CLOSED))
1013 return;
1014
1015 mutex_lock(&lport->lp_mutex);
1016
1017 if (lport->state != LPORT_ST_RPN_ID) {
1018 FC_LPORT_DBG(lport, "Received a RPN_ID response, but in state "
1019 "%s\n", fc_lport_state(lport));
1020 if (IS_ERR(fp))
1021 goto err;
1022 goto out;
1023 }
1024
1025 if (IS_ERR(fp)) {
1026 fc_lport_error(lport, fp);
1027 goto err;
1028 }
1029
1030 fh = fc_frame_header_get(fp);
1031 ct = fc_frame_payload_get(fp, sizeof(*ct));
1032 if (fh && ct && fh->fh_type == FC_TYPE_CT &&
1033 ct->ct_fs_type == FC_FST_DIR &&
1034 ct->ct_fs_subtype == FC_NS_SUBTYPE &&
1035 ntohs(ct->ct_cmd) == FC_FS_ACC)
1036 fc_lport_enter_rft_id(lport);
1037 else 1121 else
1038 fc_lport_error(lport, fp); 1122 fc_lport_error(lport, fp);
1039
1040out: 1123out:
1041 fc_frame_free(fp); 1124 fc_frame_free(fp);
1042err: 1125err:
@@ -1045,8 +1128,8 @@ err:
1045 1128
1046/** 1129/**
1047 * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request 1130 * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request
1048 * @sp: current sequence in SCR exchange 1131 * @sp: current sequence in SCR exchange
1049 * @fp: response frame 1132 * @fp: response frame
1050 * @lp_arg: Fibre Channel lport port instance that sent the registration request 1133 * @lp_arg: Fibre Channel lport port instance that sent the registration request
1051 * 1134 *
1052 * Locking Note: This function will be called without the lport lock 1135 * Locking Note: This function will be called without the lport lock
@@ -1092,8 +1175,8 @@ err:
1092} 1175}
1093 1176
1094/** 1177/**
1095 * fc_lport_enter_scr() - Send a State Change Register (SCR) request 1178 * fc_lport_enter_scr() - Send a SCR (State Change Register) request
1096 * @lport: Fibre Channel local port to register for state changes 1179 * @lport: The local port to register for state changes
1097 * 1180 *
1098 * Locking Note: The lport lock is expected to be held before calling 1181 * Locking Note: The lport lock is expected to be held before calling
1099 * this routine. 1182 * this routine.
@@ -1114,78 +1197,74 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
1114 } 1197 }
1115 1198
1116 if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR, 1199 if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
1117 fc_lport_scr_resp, lport, lport->e_d_tov)) 1200 fc_lport_scr_resp, lport,
1118 fc_lport_error(lport, fp); 1201 2 * lport->r_a_tov))
1202 fc_lport_error(lport, NULL);
1119} 1203}
1120 1204
1121/** 1205/**
1122 * fc_lport_enter_rft_id() - Register FC4-types with the name server 1206 * fc_lport_enter_ns() - register some object with the name server
1123 * @lport: Fibre Channel local port to register 1207 * @lport: Fibre Channel local port to register
1124 * 1208 *
1125 * Locking Note: The lport lock is expected to be held before calling 1209 * Locking Note: The lport lock is expected to be held before calling
1126 * this routine. 1210 * this routine.
1127 */ 1211 */
1128static void fc_lport_enter_rft_id(struct fc_lport *lport) 1212static void fc_lport_enter_ns(struct fc_lport *lport, enum fc_lport_state state)
1129{ 1213{
1130 struct fc_frame *fp; 1214 struct fc_frame *fp;
1131 struct fc_ns_fts *lps; 1215 enum fc_ns_req cmd;
1132 int i; 1216 int size = sizeof(struct fc_ct_hdr);
1217 size_t len;
1133 1218
1134 FC_LPORT_DBG(lport, "Entered RFT_ID state from %s state\n", 1219 FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
1220 fc_lport_state_names[state],
1135 fc_lport_state(lport)); 1221 fc_lport_state(lport));
1136 1222
1137 fc_lport_state_enter(lport, LPORT_ST_RFT_ID); 1223 fc_lport_state_enter(lport, state);
1138 1224
1139 lps = &lport->fcts; 1225 switch (state) {
1140 i = sizeof(lps->ff_type_map) / sizeof(lps->ff_type_map[0]); 1226 case LPORT_ST_RNN_ID:
1141 while (--i >= 0) 1227 cmd = FC_NS_RNN_ID;
1142 if (ntohl(lps->ff_type_map[i]) != 0) 1228 size += sizeof(struct fc_ns_rn_id);
1143 break; 1229 break;
1144 if (i < 0) { 1230 case LPORT_ST_RSNN_NN:
1145 /* nothing to register, move on to SCR */ 1231 len = strnlen(fc_host_symbolic_name(lport->host), 255);
1146 fc_lport_enter_scr(lport); 1232 /* if there is no symbolic name, skip to RFT_ID */
1147 return; 1233 if (!len)
1148 } 1234 return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1149 1235 cmd = FC_NS_RSNN_NN;
1150 fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) + 1236 size += sizeof(struct fc_ns_rsnn) + len;
1151 sizeof(struct fc_ns_rft)); 1237 break;
1152 if (!fp) { 1238 case LPORT_ST_RSPN_ID:
1153 fc_lport_error(lport, fp); 1239 len = strnlen(fc_host_symbolic_name(lport->host), 255);
1240 /* if there is no symbolic name, skip to RFT_ID */
1241 if (!len)
1242 return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1243 cmd = FC_NS_RSPN_ID;
1244 size += sizeof(struct fc_ns_rspn) + len;
1245 break;
1246 case LPORT_ST_RFT_ID:
1247 cmd = FC_NS_RFT_ID;
1248 size += sizeof(struct fc_ns_rft);
1249 break;
1250 case LPORT_ST_RFF_ID:
1251 cmd = FC_NS_RFF_ID;
1252 size += sizeof(struct fc_ns_rff_id);
1253 break;
1254 default:
1255 fc_lport_error(lport, NULL);
1154 return; 1256 return;
1155 } 1257 }
1156 1258
1157 if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RFT_ID, 1259 fp = fc_frame_alloc(lport, size);
1158 fc_lport_rft_id_resp,
1159 lport, lport->e_d_tov))
1160 fc_lport_error(lport, fp);
1161}
1162
1163/**
1164 * fc_rport_enter_rft_id() - Register port name with the name server
1165 * @lport: Fibre Channel local port to register
1166 *
1167 * Locking Note: The lport lock is expected to be held before calling
1168 * this routine.
1169 */
1170static void fc_lport_enter_rpn_id(struct fc_lport *lport)
1171{
1172 struct fc_frame *fp;
1173
1174 FC_LPORT_DBG(lport, "Entered RPN_ID state from %s state\n",
1175 fc_lport_state(lport));
1176
1177 fc_lport_state_enter(lport, LPORT_ST_RPN_ID);
1178
1179 fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
1180 sizeof(struct fc_ns_rn_id));
1181 if (!fp) { 1260 if (!fp) {
1182 fc_lport_error(lport, fp); 1261 fc_lport_error(lport, fp);
1183 return; 1262 return;
1184 } 1263 }
1185 1264
1186 if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RPN_ID, 1265 if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, cmd,
1187 fc_lport_rpn_id_resp, 1266 fc_lport_ns_resp,
1188 lport, lport->e_d_tov)) 1267 lport, 3 * lport->r_a_tov))
1189 fc_lport_error(lport, fp); 1268 fc_lport_error(lport, fp);
1190} 1269}
1191 1270
@@ -1194,8 +1273,8 @@ static struct fc_rport_operations fc_lport_rport_ops = {
1194}; 1273};
1195 1274
1196/** 1275/**
1197 * fc_rport_enter_dns() - Create a rport to the name server 1276 * fc_rport_enter_dns() - Create a fc_rport for the name server
1198 * @lport: Fibre Channel local port requesting a rport for the name server 1277 * @lport: The local port requesting a remote port for the name server
1199 * 1278 *
1200 * Locking Note: The lport lock is expected to be held before calling 1279 * Locking Note: The lport lock is expected to be held before calling
1201 * this routine. 1280 * this routine.
@@ -1224,8 +1303,8 @@ err:
1224} 1303}
1225 1304
1226/** 1305/**
1227 * fc_lport_timeout() - Handler for the retry_work timer. 1306 * fc_lport_timeout() - Handler for the retry_work timer
1228 * @work: The work struct of the fc_lport 1307 * @work: The work struct of the local port
1229 */ 1308 */
1230static void fc_lport_timeout(struct work_struct *work) 1309static void fc_lport_timeout(struct work_struct *work)
1231{ 1310{
@@ -1237,21 +1316,25 @@ static void fc_lport_timeout(struct work_struct *work)
1237 1316
1238 switch (lport->state) { 1317 switch (lport->state) {
1239 case LPORT_ST_DISABLED: 1318 case LPORT_ST_DISABLED:
1319 WARN_ON(1);
1320 break;
1240 case LPORT_ST_READY: 1321 case LPORT_ST_READY:
1241 case LPORT_ST_RESET:
1242 WARN_ON(1); 1322 WARN_ON(1);
1243 break; 1323 break;
1324 case LPORT_ST_RESET:
1325 break;
1244 case LPORT_ST_FLOGI: 1326 case LPORT_ST_FLOGI:
1245 fc_lport_enter_flogi(lport); 1327 fc_lport_enter_flogi(lport);
1246 break; 1328 break;
1247 case LPORT_ST_DNS: 1329 case LPORT_ST_DNS:
1248 fc_lport_enter_dns(lport); 1330 fc_lport_enter_dns(lport);
1249 break; 1331 break;
1250 case LPORT_ST_RPN_ID: 1332 case LPORT_ST_RNN_ID:
1251 fc_lport_enter_rpn_id(lport); 1333 case LPORT_ST_RSNN_NN:
1252 break; 1334 case LPORT_ST_RSPN_ID:
1253 case LPORT_ST_RFT_ID: 1335 case LPORT_ST_RFT_ID:
1254 fc_lport_enter_rft_id(lport); 1336 case LPORT_ST_RFF_ID:
1337 fc_lport_enter_ns(lport, lport->state);
1255 break; 1338 break;
1256 case LPORT_ST_SCR: 1339 case LPORT_ST_SCR:
1257 fc_lport_enter_scr(lport); 1340 fc_lport_enter_scr(lport);
@@ -1266,16 +1349,16 @@ static void fc_lport_timeout(struct work_struct *work)
1266 1349
1267/** 1350/**
1268 * fc_lport_logo_resp() - Handle response to LOGO request 1351 * fc_lport_logo_resp() - Handle response to LOGO request
1269 * @sp: current sequence in LOGO exchange 1352 * @sp: The sequence that the LOGO was on
1270 * @fp: response frame 1353 * @fp: The LOGO frame
1271 * @lp_arg: Fibre Channel lport port instance that sent the LOGO request 1354 * @lp_arg: The lport port that received the LOGO request
1272 * 1355 *
1273 * Locking Note: This function will be called without the lport lock 1356 * Locking Note: This function will be called without the lport lock
1274 * held, but it will lock, call an _enter_* function or fc_lport_error 1357 * held, but it will lock, call an _enter_* function or fc_lport_error()
1275 * and then unlock the lport. 1358 * and then unlock the lport.
1276 */ 1359 */
1277static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, 1360void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
1278 void *lp_arg) 1361 void *lp_arg)
1279{ 1362{
1280 struct fc_lport *lport = lp_arg; 1363 struct fc_lport *lport = lp_arg;
1281 u8 op; 1364 u8 op;
@@ -1311,10 +1394,11 @@ out:
1311err: 1394err:
1312 mutex_unlock(&lport->lp_mutex); 1395 mutex_unlock(&lport->lp_mutex);
1313} 1396}
1397EXPORT_SYMBOL(fc_lport_logo_resp);
1314 1398
1315/** 1399/**
1316 * fc_rport_enter_logo() - Logout of the fabric 1400 * fc_rport_enter_logo() - Logout of the fabric
1317 * @lport: Fibre Channel local port to be logged out 1401 * @lport: The local port to be logged out
1318 * 1402 *
1319 * Locking Note: The lport lock is expected to be held before calling 1403 * Locking Note: The lport lock is expected to be held before calling
1320 * this routine. 1404 * this routine.
@@ -1328,6 +1412,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
1328 fc_lport_state(lport)); 1412 fc_lport_state(lport));
1329 1413
1330 fc_lport_state_enter(lport, LPORT_ST_LOGO); 1414 fc_lport_state_enter(lport, LPORT_ST_LOGO);
1415 fc_vports_linkchange(lport);
1331 1416
1332 fp = fc_frame_alloc(lport, sizeof(*logo)); 1417 fp = fc_frame_alloc(lport, sizeof(*logo));
1333 if (!fp) { 1418 if (!fp) {
@@ -1336,22 +1421,23 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
1336 } 1421 }
1337 1422
1338 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO, 1423 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
1339 fc_lport_logo_resp, lport, lport->e_d_tov)) 1424 fc_lport_logo_resp, lport,
1340 fc_lport_error(lport, fp); 1425 2 * lport->r_a_tov))
1426 fc_lport_error(lport, NULL);
1341} 1427}
1342 1428
1343/** 1429/**
1344 * fc_lport_flogi_resp() - Handle response to FLOGI request 1430 * fc_lport_flogi_resp() - Handle response to FLOGI request
1345 * @sp: current sequence in FLOGI exchange 1431 * @sp: The sequence that the FLOGI was on
1346 * @fp: response frame 1432 * @fp: The FLOGI response frame
1347 * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request 1433 * @lp_arg: The lport port that received the FLOGI response
1348 * 1434 *
1349 * Locking Note: This function will be called without the lport lock 1435 * Locking Note: This function will be called without the lport lock
1350 * held, but it will lock, call an _enter_* function or fc_lport_error 1436 * held, but it will lock, call an _enter_* function or fc_lport_error()
1351 * and then unlock the lport. 1437 * and then unlock the lport.
1352 */ 1438 */
1353static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, 1439void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1354 void *lp_arg) 1440 void *lp_arg)
1355{ 1441{
1356 struct fc_lport *lport = lp_arg; 1442 struct fc_lport *lport = lp_arg;
1357 struct fc_frame_header *fh; 1443 struct fc_frame_header *fh;
@@ -1385,11 +1471,6 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1385 fh = fc_frame_header_get(fp); 1471 fh = fc_frame_header_get(fp);
1386 did = ntoh24(fh->fh_d_id); 1472 did = ntoh24(fh->fh_d_id);
1387 if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { 1473 if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {
1388
1389 printk(KERN_INFO "libfc: Assigned FID (%6x) in FLOGI response\n",
1390 did);
1391 fc_host_port_id(lport->host) = did;
1392
1393 flp = fc_frame_payload_get(fp, sizeof(*flp)); 1474 flp = fc_frame_payload_get(fp, sizeof(*flp));
1394 if (flp) { 1475 if (flp) {
1395 mfs = ntohs(flp->fl_csp.sp_bb_data) & 1476 mfs = ntohs(flp->fl_csp.sp_bb_data) &
@@ -1402,12 +1483,18 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1402 e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); 1483 e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
1403 if (csp_flags & FC_SP_FT_EDTR) 1484 if (csp_flags & FC_SP_FT_EDTR)
1404 e_d_tov /= 1000000; 1485 e_d_tov /= 1000000;
1486
1487 lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
1488
1405 if ((csp_flags & FC_SP_FT_FPORT) == 0) { 1489 if ((csp_flags & FC_SP_FT_FPORT) == 0) {
1406 if (e_d_tov > lport->e_d_tov) 1490 if (e_d_tov > lport->e_d_tov)
1407 lport->e_d_tov = e_d_tov; 1491 lport->e_d_tov = e_d_tov;
1408 lport->r_a_tov = 2 * e_d_tov; 1492 lport->r_a_tov = 2 * e_d_tov;
1409 printk(KERN_INFO "libfc: Port (%6x) entered " 1493 fc_lport_set_port_id(lport, did, fp);
1410 "point to point mode\n", did); 1494 printk(KERN_INFO "host%d: libfc: "
1495 "Port (%6x) entered "
1496 "point-to-point mode\n",
1497 lport->host->host_no, did);
1411 fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id), 1498 fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id),
1412 get_unaligned_be64( 1499 get_unaligned_be64(
1413 &flp->fl_wwpn), 1500 &flp->fl_wwpn),
@@ -1418,6 +1505,7 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1418 lport->r_a_tov = r_a_tov; 1505 lport->r_a_tov = r_a_tov;
1419 fc_host_fabric_name(lport->host) = 1506 fc_host_fabric_name(lport->host) =
1420 get_unaligned_be64(&flp->fl_wwnn); 1507 get_unaligned_be64(&flp->fl_wwnn);
1508 fc_lport_set_port_id(lport, did, fp);
1421 fc_lport_enter_dns(lport); 1509 fc_lport_enter_dns(lport);
1422 } 1510 }
1423 } 1511 }
@@ -1430,6 +1518,7 @@ out:
1430err: 1518err:
1431 mutex_unlock(&lport->lp_mutex); 1519 mutex_unlock(&lport->lp_mutex);
1432} 1520}
1521EXPORT_SYMBOL(fc_lport_flogi_resp);
1433 1522
1434/** 1523/**
1435 * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager 1524 * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager
@@ -1451,12 +1540,18 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
1451 if (!fp) 1540 if (!fp)
1452 return fc_lport_error(lport, fp); 1541 return fc_lport_error(lport, fp);
1453 1542
1454 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI, 1543 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp,
1455 fc_lport_flogi_resp, lport, lport->e_d_tov)) 1544 lport->vport ? ELS_FDISC : ELS_FLOGI,
1456 fc_lport_error(lport, fp); 1545 fc_lport_flogi_resp, lport,
1546 lport->vport ? 2 * lport->r_a_tov :
1547 lport->e_d_tov))
1548 fc_lport_error(lport, NULL);
1457} 1549}
1458 1550
1459/* Configure a fc_lport */ 1551/**
1552 * fc_lport_config() - Configure a fc_lport
1553 * @lport: The local port to be configured
1554 */
1460int fc_lport_config(struct fc_lport *lport) 1555int fc_lport_config(struct fc_lport *lport)
1461{ 1556{
1462 INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout); 1557 INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
@@ -1471,6 +1566,10 @@ int fc_lport_config(struct fc_lport *lport)
1471} 1566}
1472EXPORT_SYMBOL(fc_lport_config); 1567EXPORT_SYMBOL(fc_lport_config);
1473 1568
1569/**
1570 * fc_lport_init() - Initialize the lport layer for a local port
1571 * @lport: The local port to initialize the exchange layer for
1572 */
1474int fc_lport_init(struct fc_lport *lport) 1573int fc_lport_init(struct fc_lport *lport)
1475{ 1574{
1476 if (!lport->tt.lport_recv) 1575 if (!lport->tt.lport_recv)
@@ -1500,7 +1599,254 @@ int fc_lport_init(struct fc_lport *lport)
1500 if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT) 1599 if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
1501 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT; 1600 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
1502 1601
1503 INIT_LIST_HEAD(&lport->ema_list);
1504 return 0; 1602 return 0;
1505} 1603}
1506EXPORT_SYMBOL(fc_lport_init); 1604EXPORT_SYMBOL(fc_lport_init);
1605
1606/**
1607 * fc_lport_bsg_resp() - The common response handler for FC Passthrough requests
1608 * @sp: The sequence for the FC Passthrough response
1609 * @fp: The response frame
1610 * @info_arg: The BSG info that the response is for
1611 */
1612static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
1613 void *info_arg)
1614{
1615 struct fc_bsg_info *info = info_arg;
1616 struct fc_bsg_job *job = info->job;
1617 struct fc_lport *lport = info->lport;
1618 struct fc_frame_header *fh;
1619 size_t len;
1620 void *buf;
1621
1622 if (IS_ERR(fp)) {
1623 job->reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
1624 -ECONNABORTED : -ETIMEDOUT;
1625 job->reply_len = sizeof(uint32_t);
1626 job->state_flags |= FC_RQST_STATE_DONE;
1627 job->job_done(job);
1628 kfree(info);
1629 return;
1630 }
1631
1632 mutex_lock(&lport->lp_mutex);
1633 fh = fc_frame_header_get(fp);
1634 len = fr_len(fp) - sizeof(*fh);
1635 buf = fc_frame_payload_get(fp, 0);
1636
1637 if (fr_sof(fp) == FC_SOF_I3 && !ntohs(fh->fh_seq_cnt)) {
1638 /* Get the response code from the first frame payload */
1639 unsigned short cmd = (info->rsp_code == FC_FS_ACC) ?
1640 ntohs(((struct fc_ct_hdr *)buf)->ct_cmd) :
1641 (unsigned short)fc_frame_payload_op(fp);
1642
1643 /* Save the reply status of the job */
1644 job->reply->reply_data.ctels_reply.status =
1645 (cmd == info->rsp_code) ?
1646 FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
1647 }
1648
1649 job->reply->reply_payload_rcv_len +=
1650 fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
1651 &info->offset, KM_BIO_SRC_IRQ, NULL);
1652
1653 if (fr_eof(fp) == FC_EOF_T &&
1654 (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
1655 (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
1656 if (job->reply->reply_payload_rcv_len >
1657 job->reply_payload.payload_len)
1658 job->reply->reply_payload_rcv_len =
1659 job->reply_payload.payload_len;
1660 job->reply->result = 0;
1661 job->state_flags |= FC_RQST_STATE_DONE;
1662 job->job_done(job);
1663 kfree(info);
1664 }
1665 fc_frame_free(fp);
1666 mutex_unlock(&lport->lp_mutex);
1667}
1668
1669/**
1670 * fc_lport_els_request() - Send ELS passthrough request
1671 * @job: The BSG Passthrough job
1672 * @lport: The local port sending the request
1673 * @did: The destination port id
1674 *
1675 * Locking Note: The lport lock is expected to be held before calling
1676 * this routine.
1677 */
1678static int fc_lport_els_request(struct fc_bsg_job *job,
1679 struct fc_lport *lport,
1680 u32 did, u32 tov)
1681{
1682 struct fc_bsg_info *info;
1683 struct fc_frame *fp;
1684 struct fc_frame_header *fh;
1685 char *pp;
1686 int len;
1687
1688 fp = fc_frame_alloc(lport, job->request_payload.payload_len);
1689 if (!fp)
1690 return -ENOMEM;
1691
1692 len = job->request_payload.payload_len;
1693 pp = fc_frame_payload_get(fp, len);
1694
1695 sg_copy_to_buffer(job->request_payload.sg_list,
1696 job->request_payload.sg_cnt,
1697 pp, len);
1698
1699 fh = fc_frame_header_get(fp);
1700 fh->fh_r_ctl = FC_RCTL_ELS_REQ;
1701 hton24(fh->fh_d_id, did);
1702 hton24(fh->fh_s_id, fc_host_port_id(lport->host));
1703 fh->fh_type = FC_TYPE_ELS;
1704 hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
1705 FC_FC_END_SEQ | FC_FC_SEQ_INIT);
1706 fh->fh_cs_ctl = 0;
1707 fh->fh_df_ctl = 0;
1708 fh->fh_parm_offset = 0;
1709
1710 info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
1711 if (!info) {
1712 fc_frame_free(fp);
1713 return -ENOMEM;
1714 }
1715
1716 info->job = job;
1717 info->lport = lport;
1718 info->rsp_code = ELS_LS_ACC;
1719 info->nents = job->reply_payload.sg_cnt;
1720 info->sg = job->reply_payload.sg_list;
1721
1722 if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
1723 NULL, info, tov))
1724 return -ECOMM;
1725 return 0;
1726}
1727
1728/**
1729 * fc_lport_ct_request() - Send CT Passthrough request
1730 * @job: The BSG Passthrough job
1731 * @lport: The local port sending the request
1732 * @did: The destination FC-ID
1733 * @tov: The timeout period to wait for the response
1734 *
1735 * Locking Note: The lport lock is expected to be held before calling
1736 * this routine.
1737 */
1738static int fc_lport_ct_request(struct fc_bsg_job *job,
1739 struct fc_lport *lport, u32 did, u32 tov)
1740{
1741 struct fc_bsg_info *info;
1742 struct fc_frame *fp;
1743 struct fc_frame_header *fh;
1744 struct fc_ct_req *ct;
1745 size_t len;
1746
1747 fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
1748 job->request_payload.payload_len);
1749 if (!fp)
1750 return -ENOMEM;
1751
1752 len = job->request_payload.payload_len;
1753 ct = fc_frame_payload_get(fp, len);
1754
1755 sg_copy_to_buffer(job->request_payload.sg_list,
1756 job->request_payload.sg_cnt,
1757 ct, len);
1758
1759 fh = fc_frame_header_get(fp);
1760 fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL;
1761 hton24(fh->fh_d_id, did);
1762 hton24(fh->fh_s_id, fc_host_port_id(lport->host));
1763 fh->fh_type = FC_TYPE_CT;
1764 hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
1765 FC_FC_END_SEQ | FC_FC_SEQ_INIT);
1766 fh->fh_cs_ctl = 0;
1767 fh->fh_df_ctl = 0;
1768 fh->fh_parm_offset = 0;
1769
1770 info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
1771 if (!info) {
1772 fc_frame_free(fp);
1773 return -ENOMEM;
1774 }
1775
1776 info->job = job;
1777 info->lport = lport;
1778 info->rsp_code = FC_FS_ACC;
1779 info->nents = job->reply_payload.sg_cnt;
1780 info->sg = job->reply_payload.sg_list;
1781
1782 if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
1783 NULL, info, tov))
1784 return -ECOMM;
1785 return 0;
1786}
1787
1788/**
1789 * fc_lport_bsg_request() - The common entry point for sending
1790 * FC Passthrough requests
1791 * @job: The BSG passthrough job
1792 */
1793int fc_lport_bsg_request(struct fc_bsg_job *job)
1794{
1795 struct request *rsp = job->req->next_rq;
1796 struct Scsi_Host *shost = job->shost;
1797 struct fc_lport *lport = shost_priv(shost);
1798 struct fc_rport *rport;
1799 struct fc_rport_priv *rdata;
1800 int rc = -EINVAL;
1801 u32 did;
1802
1803 job->reply->reply_payload_rcv_len = 0;
1804 if (rsp)
1805 rsp->resid_len = job->reply_payload.payload_len;
1806
1807 mutex_lock(&lport->lp_mutex);
1808
1809 switch (job->request->msgcode) {
1810 case FC_BSG_RPT_ELS:
1811 rport = job->rport;
1812 if (!rport)
1813 break;
1814
1815 rdata = rport->dd_data;
1816 rc = fc_lport_els_request(job, lport, rport->port_id,
1817 rdata->e_d_tov);
1818 break;
1819
1820 case FC_BSG_RPT_CT:
1821 rport = job->rport;
1822 if (!rport)
1823 break;
1824
1825 rdata = rport->dd_data;
1826 rc = fc_lport_ct_request(job, lport, rport->port_id,
1827 rdata->e_d_tov);
1828 break;
1829
1830 case FC_BSG_HST_CT:
1831 did = ntoh24(job->request->rqst_data.h_ct.port_id);
1832 if (did == FC_FID_DIR_SERV)
1833 rdata = lport->dns_rdata;
1834 else
1835 rdata = lport->tt.rport_lookup(lport, did);
1836
1837 if (!rdata)
1838 break;
1839
1840 rc = fc_lport_ct_request(job, lport, did, rdata->e_d_tov);
1841 break;
1842
1843 case FC_BSG_HST_ELS_NOLOGIN:
1844 did = ntoh24(job->request->rqst_data.h_els.port_id);
1845 rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
1846 break;
1847 }
1848
1849 mutex_unlock(&lport->lp_mutex);
1850 return rc;
1851}
1852EXPORT_SYMBOL(fc_lport_bsg_request);