fc_rport.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296
  1. /*
  2. * Copyright(c) 2007 - 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. * RPORT GENERAL INFO
  21. *
  22. * This file contains all processing regarding fc_rports. It contains the
  23. * rport state machine and does all rport interaction with the transport class.
  24. * There should be no other places in libfc that interact directly with the
  25. * transport class in regards to adding and deleting rports.
  26. *
  27. * fc_rport's represent N_Port's within the fabric.
  28. */
  29. /*
  30. * RPORT LOCKING
  31. *
  32. * The rport should never hold the rport mutex and then attempt to acquire
  33. * either the lport or disc mutexes. The rport's mutex is considered lesser
  34. * than both the lport's mutex and the disc mutex. Refer to fc_lport.c for
  35. * more comments on the heirarchy.
  36. *
  37. * The locking strategy is similar to the lport's strategy. The lock protects
  38. * the rport's states and is held and released by the entry points to the rport
  39. * block. All _enter_* functions correspond to rport states and expect the rport
  40. * mutex to be locked before calling them. This means that rports only handle
  41. * one request or response at a time, since they're not critical for the I/O
  42. * path this potential over-use of the mutex is acceptable.
  43. */
  44. #include <linux/kernel.h>
  45. #include <linux/spinlock.h>
  46. #include <linux/interrupt.h>
  47. #include <linux/rcupdate.h>
  48. #include <linux/timer.h>
  49. #include <linux/workqueue.h>
  50. #include <asm/unaligned.h>
  51. #include <scsi/libfc.h>
  52. #include <scsi/fc_encode.h>
  53. static int fc_rport_debug;
  54. #define FC_DEBUG_RPORT(fmt...) \
  55. do { \
  56. if (fc_rport_debug) \
  57. FC_DBG(fmt); \
  58. } while (0)
  59. struct workqueue_struct *rport_event_queue;
  60. static void fc_rport_enter_plogi(struct fc_rport *);
  61. static void fc_rport_enter_prli(struct fc_rport *);
  62. static void fc_rport_enter_rtv(struct fc_rport *);
  63. static void fc_rport_enter_ready(struct fc_rport *);
  64. static void fc_rport_enter_logo(struct fc_rport *);
  65. static void fc_rport_recv_plogi_req(struct fc_rport *,
  66. struct fc_seq *, struct fc_frame *);
  67. static void fc_rport_recv_prli_req(struct fc_rport *,
  68. struct fc_seq *, struct fc_frame *);
  69. static void fc_rport_recv_prlo_req(struct fc_rport *,
  70. struct fc_seq *, struct fc_frame *);
  71. static void fc_rport_recv_logo_req(struct fc_rport *,
  72. struct fc_seq *, struct fc_frame *);
  73. static void fc_rport_timeout(struct work_struct *);
  74. static void fc_rport_error(struct fc_rport *, struct fc_frame *);
  75. static void fc_rport_work(struct work_struct *);
  76. static const char *fc_rport_state_names[] = {
  77. [RPORT_ST_NONE] = "None",
  78. [RPORT_ST_INIT] = "Init",
  79. [RPORT_ST_PLOGI] = "PLOGI",
  80. [RPORT_ST_PRLI] = "PRLI",
  81. [RPORT_ST_RTV] = "RTV",
  82. [RPORT_ST_READY] = "Ready",
  83. [RPORT_ST_LOGO] = "LOGO",
  84. };
  85. static void fc_rport_rogue_destroy(struct device *dev)
  86. {
  87. struct fc_rport *rport = dev_to_rport(dev);
  88. FC_DEBUG_RPORT("Destroying rogue rport (%6x)\n", rport->port_id);
  89. kfree(rport);
  90. }
  91. struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp)
  92. {
  93. struct fc_rport *rport;
  94. struct fc_rport_libfc_priv *rdata;
  95. rport = kzalloc(sizeof(*rport) + sizeof(*rdata), GFP_KERNEL);
  96. if (!rport)
  97. return NULL;
  98. rdata = RPORT_TO_PRIV(rport);
  99. rport->dd_data = rdata;
  100. rport->port_id = dp->ids.port_id;
  101. rport->port_name = dp->ids.port_name;
  102. rport->node_name = dp->ids.node_name;
  103. rport->roles = dp->ids.roles;
  104. rport->maxframe_size = FC_MIN_MAX_PAYLOAD;
  105. /*
  106. * Note: all this libfc rogue rport code will be removed for
  107. * upstream so it fine that this is really ugly and hacky right now.
  108. */
  109. device_initialize(&rport->dev);
  110. rport->dev.release = fc_rport_rogue_destroy;
  111. mutex_init(&rdata->rp_mutex);
  112. rdata->local_port = dp->lp;
  113. rdata->trans_state = FC_PORTSTATE_ROGUE;
  114. rdata->rp_state = RPORT_ST_INIT;
  115. rdata->event = RPORT_EV_NONE;
  116. rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;
  117. rdata->ops = NULL;
  118. rdata->e_d_tov = dp->lp->e_d_tov;
  119. rdata->r_a_tov = dp->lp->r_a_tov;
  120. INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
  121. INIT_WORK(&rdata->event_work, fc_rport_work);
  122. /*
  123. * For good measure, but not necessary as we should only
  124. * add REAL rport to the lport list.
  125. */
  126. INIT_LIST_HEAD(&rdata->peers);
  127. return rport;
  128. }
  129. /**
  130. * fc_rport_state - return a string for the state the rport is in
  131. * @rport: The rport whose state we want to get a string for
  132. */
  133. static const char *fc_rport_state(struct fc_rport *rport)
  134. {
  135. const char *cp;
  136. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  137. cp = fc_rport_state_names[rdata->rp_state];
  138. if (!cp)
  139. cp = "Unknown";
  140. return cp;
  141. }
  142. /**
  143. * fc_set_rport_loss_tmo - Set the remote port loss timeout in seconds.
  144. * @rport: Pointer to Fibre Channel remote port structure
  145. * @timeout: timeout in seconds
  146. */
  147. void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
  148. {
  149. if (timeout)
  150. rport->dev_loss_tmo = timeout + 5;
  151. else
  152. rport->dev_loss_tmo = 30;
  153. }
  154. EXPORT_SYMBOL(fc_set_rport_loss_tmo);
  155. /**
  156. * fc_plogi_get_maxframe - Get max payload from the common service parameters
  157. * @flp: FLOGI payload structure
  158. * @maxval: upper limit, may be less than what is in the service parameters
  159. */
  160. static unsigned int
  161. fc_plogi_get_maxframe(struct fc_els_flogi *flp, unsigned int maxval)
  162. {
  163. unsigned int mfs;
  164. /*
  165. * Get max payload from the common service parameters and the
  166. * class 3 receive data field size.
  167. */
  168. mfs = ntohs(flp->fl_csp.sp_bb_data) & FC_SP_BB_DATA_MASK;
  169. if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval)
  170. maxval = mfs;
  171. mfs = ntohs(flp->fl_cssp[3 - 1].cp_rdfs);
  172. if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval)
  173. maxval = mfs;
  174. return maxval;
  175. }
  176. /**
  177. * fc_rport_state_enter - Change the rport's state
  178. * @rport: The rport whose state should change
  179. * @new: The new state of the rport
  180. *
  181. * Locking Note: Called with the rport lock held
  182. */
  183. static void fc_rport_state_enter(struct fc_rport *rport,
  184. enum fc_rport_state new)
  185. {
  186. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  187. if (rdata->rp_state != new)
  188. rdata->retries = 0;
  189. rdata->rp_state = new;
  190. }
  191. static void fc_rport_work(struct work_struct *work)
  192. {
  193. u32 port_id;
  194. struct fc_rport_libfc_priv *rdata =
  195. container_of(work, struct fc_rport_libfc_priv, event_work);
  196. enum fc_rport_event event;
  197. enum fc_rport_trans_state trans_state;
  198. struct fc_lport *lport = rdata->local_port;
  199. struct fc_rport_operations *rport_ops;
  200. struct fc_rport *rport = PRIV_TO_RPORT(rdata);
  201. mutex_lock(&rdata->rp_mutex);
  202. event = rdata->event;
  203. rport_ops = rdata->ops;
  204. if (event == RPORT_EV_CREATED) {
  205. struct fc_rport *new_rport;
  206. struct fc_rport_libfc_priv *new_rdata;
  207. struct fc_rport_identifiers ids;
  208. ids.port_id = rport->port_id;
  209. ids.roles = rport->roles;
  210. ids.port_name = rport->port_name;
  211. ids.node_name = rport->node_name;
  212. mutex_unlock(&rdata->rp_mutex);
  213. new_rport = fc_remote_port_add(lport->host, 0, &ids);
  214. if (new_rport) {
  215. /*
  216. * Switch from the rogue rport to the rport
  217. * returned by the FC class.
  218. */
  219. new_rport->maxframe_size = rport->maxframe_size;
  220. new_rdata = new_rport->dd_data;
  221. new_rdata->e_d_tov = rdata->e_d_tov;
  222. new_rdata->r_a_tov = rdata->r_a_tov;
  223. new_rdata->ops = rdata->ops;
  224. new_rdata->local_port = rdata->local_port;
  225. new_rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;
  226. new_rdata->trans_state = FC_PORTSTATE_REAL;
  227. mutex_init(&new_rdata->rp_mutex);
  228. INIT_DELAYED_WORK(&new_rdata->retry_work,
  229. fc_rport_timeout);
  230. INIT_LIST_HEAD(&new_rdata->peers);
  231. INIT_WORK(&new_rdata->event_work, fc_rport_work);
  232. fc_rport_state_enter(new_rport, RPORT_ST_READY);
  233. } else {
  234. FC_DBG("Failed to create the rport for port "
  235. "(%6x).\n", ids.port_id);
  236. event = RPORT_EV_FAILED;
  237. }
  238. put_device(&rport->dev);
  239. rport = new_rport;
  240. rdata = new_rport->dd_data;
  241. if (rport_ops->event_callback)
  242. rport_ops->event_callback(lport, rport, event);
  243. } else if ((event == RPORT_EV_FAILED) ||
  244. (event == RPORT_EV_LOGO) ||
  245. (event == RPORT_EV_STOP)) {
  246. trans_state = rdata->trans_state;
  247. mutex_unlock(&rdata->rp_mutex);
  248. if (rport_ops->event_callback)
  249. rport_ops->event_callback(lport, rport, event);
  250. if (trans_state == FC_PORTSTATE_ROGUE)
  251. put_device(&rport->dev);
  252. else {
  253. port_id = rport->port_id;
  254. fc_remote_port_delete(rport);
  255. lport->tt.exch_mgr_reset(lport, 0, port_id);
  256. lport->tt.exch_mgr_reset(lport, port_id, 0);
  257. }
  258. } else
  259. mutex_unlock(&rdata->rp_mutex);
  260. }
  261. /**
  262. * fc_rport_login - Start the remote port login state machine
  263. * @rport: Fibre Channel remote port
  264. *
  265. * Locking Note: Called without the rport lock held. This
  266. * function will hold the rport lock, call an _enter_*
  267. * function and then unlock the rport.
  268. */
  269. int fc_rport_login(struct fc_rport *rport)
  270. {
  271. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  272. mutex_lock(&rdata->rp_mutex);
  273. FC_DEBUG_RPORT("Login to port (%6x)\n", rport->port_id);
  274. fc_rport_enter_plogi(rport);
  275. mutex_unlock(&rdata->rp_mutex);
  276. return 0;
  277. }
  278. /**
  279. * fc_rport_logoff - Logoff and remove an rport
  280. * @rport: Fibre Channel remote port to be removed
  281. *
  282. * Locking Note: Called without the rport lock held. This
  283. * function will hold the rport lock, call an _enter_*
  284. * function and then unlock the rport.
  285. */
  286. int fc_rport_logoff(struct fc_rport *rport)
  287. {
  288. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  289. mutex_lock(&rdata->rp_mutex);
  290. FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id);
  291. fc_rport_enter_logo(rport);
  292. /*
  293. * Change the state to NONE so that we discard
  294. * the response.
  295. */
  296. fc_rport_state_enter(rport, RPORT_ST_NONE);
  297. mutex_unlock(&rdata->rp_mutex);
  298. cancel_delayed_work_sync(&rdata->retry_work);
  299. mutex_lock(&rdata->rp_mutex);
  300. rdata->event = RPORT_EV_STOP;
  301. queue_work(rport_event_queue, &rdata->event_work);
  302. mutex_unlock(&rdata->rp_mutex);
  303. return 0;
  304. }
  305. /**
  306. * fc_rport_enter_ready - The rport is ready
  307. * @rport: Fibre Channel remote port that is ready
  308. *
  309. * Locking Note: The rport lock is expected to be held before calling
  310. * this routine.
  311. */
  312. static void fc_rport_enter_ready(struct fc_rport *rport)
  313. {
  314. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  315. fc_rport_state_enter(rport, RPORT_ST_READY);
  316. FC_DEBUG_RPORT("Port (%6x) is Ready\n", rport->port_id);
  317. rdata->event = RPORT_EV_CREATED;
  318. queue_work(rport_event_queue, &rdata->event_work);
  319. }
  320. /**
  321. * fc_rport_timeout - Handler for the retry_work timer.
  322. * @work: The work struct of the fc_rport_libfc_priv
  323. *
  324. * Locking Note: Called without the rport lock held. This
  325. * function will hold the rport lock, call an _enter_*
  326. * function and then unlock the rport.
  327. */
  328. static void fc_rport_timeout(struct work_struct *work)
  329. {
  330. struct fc_rport_libfc_priv *rdata =
  331. container_of(work, struct fc_rport_libfc_priv, retry_work.work);
  332. struct fc_rport *rport = PRIV_TO_RPORT(rdata);
  333. mutex_lock(&rdata->rp_mutex);
  334. switch (rdata->rp_state) {
  335. case RPORT_ST_PLOGI:
  336. fc_rport_enter_plogi(rport);
  337. break;
  338. case RPORT_ST_PRLI:
  339. fc_rport_enter_prli(rport);
  340. break;
  341. case RPORT_ST_RTV:
  342. fc_rport_enter_rtv(rport);
  343. break;
  344. case RPORT_ST_LOGO:
  345. fc_rport_enter_logo(rport);
  346. break;
  347. case RPORT_ST_READY:
  348. case RPORT_ST_INIT:
  349. case RPORT_ST_NONE:
  350. break;
  351. }
  352. mutex_unlock(&rdata->rp_mutex);
  353. put_device(&rport->dev);
  354. }
  355. /**
  356. * fc_rport_error - Handler for any errors
  357. * @rport: The fc_rport object
  358. * @fp: The frame pointer
  359. *
  360. * If the error was caused by a resource allocation failure
  361. * then wait for half a second and retry, otherwise retry
  362. * immediately.
  363. *
  364. * Locking Note: The rport lock is expected to be held before
  365. * calling this routine
  366. */
  367. static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
  368. {
  369. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  370. unsigned long delay = 0;
  371. FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n",
  372. PTR_ERR(fp), fc_rport_state(rport), rdata->retries);
  373. if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) {
  374. /*
  375. * Memory allocation failure, or the exchange timed out.
  376. * Retry after delay
  377. */
  378. if (rdata->retries < rdata->local_port->max_retry_count) {
  379. rdata->retries++;
  380. if (!fp)
  381. delay = msecs_to_jiffies(500);
  382. get_device(&rport->dev);
  383. schedule_delayed_work(&rdata->retry_work, delay);
  384. } else {
  385. switch (rdata->rp_state) {
  386. case RPORT_ST_PLOGI:
  387. case RPORT_ST_PRLI:
  388. case RPORT_ST_LOGO:
  389. rdata->event = RPORT_EV_FAILED;
  390. queue_work(rport_event_queue,
  391. &rdata->event_work);
  392. break;
  393. case RPORT_ST_RTV:
  394. fc_rport_enter_ready(rport);
  395. break;
  396. case RPORT_ST_NONE:
  397. case RPORT_ST_READY:
  398. case RPORT_ST_INIT:
  399. break;
  400. }
  401. }
  402. }
  403. }
  404. /**
  405. * fc_rport_plogi_recv_resp - Handle incoming ELS PLOGI response
  406. * @sp: current sequence in the PLOGI exchange
  407. * @fp: response frame
  408. * @rp_arg: Fibre Channel remote port
  409. *
  410. * Locking Note: This function will be called without the rport lock
  411. * held, but it will lock, call an _enter_* function or fc_rport_error
  412. * and then unlock the rport.
  413. */
  414. static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
  415. void *rp_arg)
  416. {
  417. struct fc_rport *rport = rp_arg;
  418. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  419. struct fc_lport *lport = rdata->local_port;
  420. struct fc_els_flogi *plp;
  421. unsigned int tov;
  422. u16 csp_seq;
  423. u16 cssp_seq;
  424. u8 op;
  425. mutex_lock(&rdata->rp_mutex);
  426. FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n",
  427. rport->port_id);
  428. if (rdata->rp_state != RPORT_ST_PLOGI) {
  429. FC_DBG("Received a PLOGI response, but in state %s\n",
  430. fc_rport_state(rport));
  431. goto out;
  432. }
  433. if (IS_ERR(fp)) {
  434. fc_rport_error(rport, fp);
  435. goto err;
  436. }
  437. op = fc_frame_payload_op(fp);
  438. if (op == ELS_LS_ACC &&
  439. (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {
  440. rport->port_name = get_unaligned_be64(&plp->fl_wwpn);
  441. rport->node_name = get_unaligned_be64(&plp->fl_wwnn);
  442. tov = ntohl(plp->fl_csp.sp_e_d_tov);
  443. if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR)
  444. tov /= 1000;
  445. if (tov > rdata->e_d_tov)
  446. rdata->e_d_tov = tov;
  447. csp_seq = ntohs(plp->fl_csp.sp_tot_seq);
  448. cssp_seq = ntohs(plp->fl_cssp[3 - 1].cp_con_seq);
  449. if (cssp_seq < csp_seq)
  450. csp_seq = cssp_seq;
  451. rdata->max_seq = csp_seq;
  452. rport->maxframe_size =
  453. fc_plogi_get_maxframe(plp, lport->mfs);
  454. /*
  455. * If the rport is one of the well known addresses
  456. * we skip PRLI and RTV and go straight to READY.
  457. */
  458. if (rport->port_id >= FC_FID_DOM_MGR)
  459. fc_rport_enter_ready(rport);
  460. else
  461. fc_rport_enter_prli(rport);
  462. } else
  463. fc_rport_error(rport, fp);
  464. out:
  465. fc_frame_free(fp);
  466. err:
  467. mutex_unlock(&rdata->rp_mutex);
  468. put_device(&rport->dev);
  469. }
  470. /**
  471. * fc_rport_enter_plogi - Send Port Login (PLOGI) request to peer
  472. * @rport: Fibre Channel remote port to send PLOGI to
  473. *
  474. * Locking Note: The rport lock is expected to be held before calling
  475. * this routine.
  476. */
  477. static void fc_rport_enter_plogi(struct fc_rport *rport)
  478. {
  479. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  480. struct fc_lport *lport = rdata->local_port;
  481. struct fc_frame *fp;
  482. FC_DEBUG_RPORT("Port (%6x) entered PLOGI state from %s state\n",
  483. rport->port_id, fc_rport_state(rport));
  484. fc_rport_state_enter(rport, RPORT_ST_PLOGI);
  485. rport->maxframe_size = FC_MIN_MAX_PAYLOAD;
  486. fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
  487. if (!fp) {
  488. fc_rport_error(rport, fp);
  489. return;
  490. }
  491. rdata->e_d_tov = lport->e_d_tov;
  492. if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI,
  493. fc_rport_plogi_resp, rport, lport->e_d_tov))
  494. fc_rport_error(rport, fp);
  495. else
  496. get_device(&rport->dev);
  497. }
  498. /**
  499. * fc_rport_prli_resp - Process Login (PRLI) response handler
  500. * @sp: current sequence in the PRLI exchange
  501. * @fp: response frame
  502. * @rp_arg: Fibre Channel remote port
  503. *
  504. * Locking Note: This function will be called without the rport lock
  505. * held, but it will lock, call an _enter_* function or fc_rport_error
  506. * and then unlock the rport.
  507. */
  508. static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
  509. void *rp_arg)
  510. {
  511. struct fc_rport *rport = rp_arg;
  512. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  513. struct {
  514. struct fc_els_prli prli;
  515. struct fc_els_spp spp;
  516. } *pp;
  517. u32 roles = FC_RPORT_ROLE_UNKNOWN;
  518. u32 fcp_parm = 0;
  519. u8 op;
  520. mutex_lock(&rdata->rp_mutex);
  521. FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n",
  522. rport->port_id);
  523. if (rdata->rp_state != RPORT_ST_PRLI) {
  524. FC_DBG("Received a PRLI response, but in state %s\n",
  525. fc_rport_state(rport));
  526. goto out;
  527. }
  528. if (IS_ERR(fp)) {
  529. fc_rport_error(rport, fp);
  530. goto err;
  531. }
  532. op = fc_frame_payload_op(fp);
  533. if (op == ELS_LS_ACC) {
  534. pp = fc_frame_payload_get(fp, sizeof(*pp));
  535. if (pp && pp->prli.prli_spp_len >= sizeof(pp->spp)) {
  536. fcp_parm = ntohl(pp->spp.spp_params);
  537. if (fcp_parm & FCP_SPPF_RETRY)
  538. rdata->flags |= FC_RP_FLAGS_RETRY;
  539. }
  540. rport->supported_classes = FC_COS_CLASS3;
  541. if (fcp_parm & FCP_SPPF_INIT_FCN)
  542. roles |= FC_RPORT_ROLE_FCP_INITIATOR;
  543. if (fcp_parm & FCP_SPPF_TARG_FCN)
  544. roles |= FC_RPORT_ROLE_FCP_TARGET;
  545. rport->roles = roles;
  546. fc_rport_enter_rtv(rport);
  547. } else {
  548. FC_DBG("Bad ELS response\n");
  549. rdata->event = RPORT_EV_FAILED;
  550. queue_work(rport_event_queue, &rdata->event_work);
  551. }
  552. out:
  553. fc_frame_free(fp);
  554. err:
  555. mutex_unlock(&rdata->rp_mutex);
  556. put_device(&rport->dev);
  557. }
  558. /**
  559. * fc_rport_logo_resp - Logout (LOGO) response handler
  560. * @sp: current sequence in the LOGO exchange
  561. * @fp: response frame
  562. * @rp_arg: Fibre Channel remote port
  563. *
  564. * Locking Note: This function will be called without the rport lock
  565. * held, but it will lock, call an _enter_* function or fc_rport_error
  566. * and then unlock the rport.
  567. */
  568. static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
  569. void *rp_arg)
  570. {
  571. struct fc_rport *rport = rp_arg;
  572. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  573. u8 op;
  574. mutex_lock(&rdata->rp_mutex);
  575. FC_DEBUG_RPORT("Received a LOGO response from port (%6x)\n",
  576. rport->port_id);
  577. if (IS_ERR(fp)) {
  578. fc_rport_error(rport, fp);
  579. goto err;
  580. }
  581. if (rdata->rp_state != RPORT_ST_LOGO) {
  582. FC_DEBUG_RPORT("Received a LOGO response, but in state %s\n",
  583. fc_rport_state(rport));
  584. goto out;
  585. }
  586. op = fc_frame_payload_op(fp);
  587. if (op == ELS_LS_ACC) {
  588. fc_rport_enter_rtv(rport);
  589. } else {
  590. FC_DBG("Bad ELS response\n");
  591. rdata->event = RPORT_EV_LOGO;
  592. queue_work(rport_event_queue, &rdata->event_work);
  593. }
  594. out:
  595. fc_frame_free(fp);
  596. err:
  597. mutex_unlock(&rdata->rp_mutex);
  598. put_device(&rport->dev);
  599. }
  600. /**
  601. * fc_rport_enter_prli - Send Process Login (PRLI) request to peer
  602. * @rport: Fibre Channel remote port to send PRLI to
  603. *
  604. * Locking Note: The rport lock is expected to be held before calling
  605. * this routine.
  606. */
  607. static void fc_rport_enter_prli(struct fc_rport *rport)
  608. {
  609. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  610. struct fc_lport *lport = rdata->local_port;
  611. struct {
  612. struct fc_els_prli prli;
  613. struct fc_els_spp spp;
  614. } *pp;
  615. struct fc_frame *fp;
  616. FC_DEBUG_RPORT("Port (%6x) entered PRLI state from %s state\n",
  617. rport->port_id, fc_rport_state(rport));
  618. fc_rport_state_enter(rport, RPORT_ST_PRLI);
  619. fp = fc_frame_alloc(lport, sizeof(*pp));
  620. if (!fp) {
  621. fc_rport_error(rport, fp);
  622. return;
  623. }
  624. if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI,
  625. fc_rport_prli_resp, rport, lport->e_d_tov))
  626. fc_rport_error(rport, fp);
  627. else
  628. get_device(&rport->dev);
  629. }
  630. /**
  631. * fc_rport_els_rtv_resp - Request Timeout Value response handler
  632. * @sp: current sequence in the RTV exchange
  633. * @fp: response frame
  634. * @rp_arg: Fibre Channel remote port
  635. *
  636. * Many targets don't seem to support this.
  637. *
  638. * Locking Note: This function will be called without the rport lock
  639. * held, but it will lock, call an _enter_* function or fc_rport_error
  640. * and then unlock the rport.
  641. */
  642. static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
  643. void *rp_arg)
  644. {
  645. struct fc_rport *rport = rp_arg;
  646. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  647. u8 op;
  648. mutex_lock(&rdata->rp_mutex);
  649. FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n",
  650. rport->port_id);
  651. if (rdata->rp_state != RPORT_ST_RTV) {
  652. FC_DBG("Received a RTV response, but in state %s\n",
  653. fc_rport_state(rport));
  654. goto out;
  655. }
  656. if (IS_ERR(fp)) {
  657. fc_rport_error(rport, fp);
  658. goto err;
  659. }
  660. op = fc_frame_payload_op(fp);
  661. if (op == ELS_LS_ACC) {
  662. struct fc_els_rtv_acc *rtv;
  663. u32 toq;
  664. u32 tov;
  665. rtv = fc_frame_payload_get(fp, sizeof(*rtv));
  666. if (rtv) {
  667. toq = ntohl(rtv->rtv_toq);
  668. tov = ntohl(rtv->rtv_r_a_tov);
  669. if (tov == 0)
  670. tov = 1;
  671. rdata->r_a_tov = tov;
  672. tov = ntohl(rtv->rtv_e_d_tov);
  673. if (toq & FC_ELS_RTV_EDRES)
  674. tov /= 1000000;
  675. if (tov == 0)
  676. tov = 1;
  677. rdata->e_d_tov = tov;
  678. }
  679. }
  680. fc_rport_enter_ready(rport);
  681. out:
  682. fc_frame_free(fp);
  683. err:
  684. mutex_unlock(&rdata->rp_mutex);
  685. put_device(&rport->dev);
  686. }
  687. /**
  688. * fc_rport_enter_rtv - Send Request Timeout Value (RTV) request to peer
  689. * @rport: Fibre Channel remote port to send RTV to
  690. *
  691. * Locking Note: The rport lock is expected to be held before calling
  692. * this routine.
  693. */
  694. static void fc_rport_enter_rtv(struct fc_rport *rport)
  695. {
  696. struct fc_frame *fp;
  697. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  698. struct fc_lport *lport = rdata->local_port;
  699. FC_DEBUG_RPORT("Port (%6x) entered RTV state from %s state\n",
  700. rport->port_id, fc_rport_state(rport));
  701. fc_rport_state_enter(rport, RPORT_ST_RTV);
  702. fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv));
  703. if (!fp) {
  704. fc_rport_error(rport, fp);
  705. return;
  706. }
  707. if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV,
  708. fc_rport_rtv_resp, rport, lport->e_d_tov))
  709. fc_rport_error(rport, fp);
  710. else
  711. get_device(&rport->dev);
  712. }
  713. /**
  714. * fc_rport_enter_logo - Send Logout (LOGO) request to peer
  715. * @rport: Fibre Channel remote port to send LOGO to
  716. *
  717. * Locking Note: The rport lock is expected to be held before calling
  718. * this routine.
  719. */
  720. static void fc_rport_enter_logo(struct fc_rport *rport)
  721. {
  722. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  723. struct fc_lport *lport = rdata->local_port;
  724. struct fc_frame *fp;
  725. FC_DEBUG_RPORT("Port (%6x) entered LOGO state from %s state\n",
  726. rport->port_id, fc_rport_state(rport));
  727. fc_rport_state_enter(rport, RPORT_ST_LOGO);
  728. fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo));
  729. if (!fp) {
  730. fc_rport_error(rport, fp);
  731. return;
  732. }
  733. if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO,
  734. fc_rport_logo_resp, rport, lport->e_d_tov))
  735. fc_rport_error(rport, fp);
  736. else
  737. get_device(&rport->dev);
  738. }
  739. /**
  740. * fc_rport_recv_req - Receive a request from a rport
  741. * @sp: current sequence in the PLOGI exchange
  742. * @fp: response frame
  743. * @rp_arg: Fibre Channel remote port
  744. *
  745. * Locking Note: Called without the rport lock held. This
  746. * function will hold the rport lock, call an _enter_*
  747. * function and then unlock the rport.
  748. */
  749. void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
  750. struct fc_rport *rport)
  751. {
  752. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  753. struct fc_lport *lport = rdata->local_port;
  754. struct fc_frame_header *fh;
  755. struct fc_seq_els_data els_data;
  756. u8 op;
  757. mutex_lock(&rdata->rp_mutex);
  758. els_data.fp = NULL;
  759. els_data.explan = ELS_EXPL_NONE;
  760. els_data.reason = ELS_RJT_NONE;
  761. fh = fc_frame_header_get(fp);
  762. if (fh->fh_r_ctl == FC_RCTL_ELS_REQ && fh->fh_type == FC_TYPE_ELS) {
  763. op = fc_frame_payload_op(fp);
  764. switch (op) {
  765. case ELS_PLOGI:
  766. fc_rport_recv_plogi_req(rport, sp, fp);
  767. break;
  768. case ELS_PRLI:
  769. fc_rport_recv_prli_req(rport, sp, fp);
  770. break;
  771. case ELS_PRLO:
  772. fc_rport_recv_prlo_req(rport, sp, fp);
  773. break;
  774. case ELS_LOGO:
  775. fc_rport_recv_logo_req(rport, sp, fp);
  776. break;
  777. case ELS_RRQ:
  778. els_data.fp = fp;
  779. lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data);
  780. break;
  781. case ELS_REC:
  782. els_data.fp = fp;
  783. lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data);
  784. break;
  785. default:
  786. els_data.reason = ELS_RJT_UNSUP;
  787. lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data);
  788. break;
  789. }
  790. }
  791. mutex_unlock(&rdata->rp_mutex);
  792. }
  793. /**
  794. * fc_rport_recv_plogi_req - Handle incoming Port Login (PLOGI) request
  795. * @rport: Fibre Channel remote port that initiated PLOGI
  796. * @sp: current sequence in the PLOGI exchange
  797. * @fp: PLOGI request frame
  798. *
  799. * Locking Note: The rport lock is exected to be held before calling
  800. * this function.
  801. */
  802. static void fc_rport_recv_plogi_req(struct fc_rport *rport,
  803. struct fc_seq *sp, struct fc_frame *rx_fp)
  804. {
  805. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  806. struct fc_lport *lport = rdata->local_port;
  807. struct fc_frame *fp = rx_fp;
  808. struct fc_exch *ep;
  809. struct fc_frame_header *fh;
  810. struct fc_els_flogi *pl;
  811. struct fc_seq_els_data rjt_data;
  812. u32 sid;
  813. u64 wwpn;
  814. u64 wwnn;
  815. enum fc_els_rjt_reason reject = 0;
  816. u32 f_ctl;
  817. rjt_data.fp = NULL;
  818. fh = fc_frame_header_get(fp);
  819. FC_DEBUG_RPORT("Received PLOGI request from port (%6x) "
  820. "while in state %s\n", ntoh24(fh->fh_s_id),
  821. fc_rport_state(rport));
  822. sid = ntoh24(fh->fh_s_id);
  823. pl = fc_frame_payload_get(fp, sizeof(*pl));
  824. if (!pl) {
  825. FC_DBG("incoming PLOGI from %x too short\n", sid);
  826. WARN_ON(1);
  827. /* XXX TBD: send reject? */
  828. fc_frame_free(fp);
  829. return;
  830. }
  831. wwpn = get_unaligned_be64(&pl->fl_wwpn);
  832. wwnn = get_unaligned_be64(&pl->fl_wwnn);
  833. /*
  834. * If the session was just created, possibly due to the incoming PLOGI,
  835. * set the state appropriately and accept the PLOGI.
  836. *
  837. * If we had also sent a PLOGI, and if the received PLOGI is from a
  838. * higher WWPN, we accept it, otherwise an LS_RJT is sent with reason
  839. * "command already in progress".
  840. *
  841. * XXX TBD: If the session was ready before, the PLOGI should result in
  842. * all outstanding exchanges being reset.
  843. */
  844. switch (rdata->rp_state) {
  845. case RPORT_ST_INIT:
  846. FC_DEBUG_RPORT("incoming PLOGI from %6x wwpn %llx state INIT "
  847. "- reject\n", sid, wwpn);
  848. reject = ELS_RJT_UNSUP;
  849. break;
  850. case RPORT_ST_PLOGI:
  851. FC_DEBUG_RPORT("incoming PLOGI from %x in PLOGI state %d\n",
  852. sid, rdata->rp_state);
  853. if (wwpn < lport->wwpn)
  854. reject = ELS_RJT_INPROG;
  855. break;
  856. case RPORT_ST_PRLI:
  857. case RPORT_ST_READY:
  858. FC_DEBUG_RPORT("incoming PLOGI from %x in logged-in state %d "
  859. "- ignored for now\n", sid, rdata->rp_state);
  860. /* XXX TBD - should reset */
  861. break;
  862. case RPORT_ST_NONE:
  863. default:
  864. FC_DEBUG_RPORT("incoming PLOGI from %x in unexpected "
  865. "state %d\n", sid, rdata->rp_state);
  866. break;
  867. }
  868. if (reject) {
  869. rjt_data.reason = reject;
  870. rjt_data.explan = ELS_EXPL_NONE;
  871. lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
  872. fc_frame_free(fp);
  873. } else {
  874. fp = fc_frame_alloc(lport, sizeof(*pl));
  875. if (fp == NULL) {
  876. fp = rx_fp;
  877. rjt_data.reason = ELS_RJT_UNAB;
  878. rjt_data.explan = ELS_EXPL_NONE;
  879. lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
  880. fc_frame_free(fp);
  881. } else {
  882. sp = lport->tt.seq_start_next(sp);
  883. WARN_ON(!sp);
  884. fc_rport_set_name(rport, wwpn, wwnn);
  885. /*
  886. * Get session payload size from incoming PLOGI.
  887. */
  888. rport->maxframe_size =
  889. fc_plogi_get_maxframe(pl, lport->mfs);
  890. fc_frame_free(rx_fp);
  891. fc_plogi_fill(lport, fp, ELS_LS_ACC);
  892. /*
  893. * Send LS_ACC. If this fails,
  894. * the originator should retry.
  895. */
  896. f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
  897. f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
  898. ep = fc_seq_exch(sp);
  899. fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
  900. FC_TYPE_ELS, f_ctl, 0);
  901. lport->tt.seq_send(lport, sp, fp);
  902. if (rdata->rp_state == RPORT_ST_PLOGI)
  903. fc_rport_enter_prli(rport);
  904. }
  905. }
  906. }
  907. /**
  908. * fc_rport_recv_prli_req - Handle incoming Process Login (PRLI) request
  909. * @rport: Fibre Channel remote port that initiated PRLI
  910. * @sp: current sequence in the PRLI exchange
  911. * @fp: PRLI request frame
  912. *
  913. * Locking Note: The rport lock is exected to be held before calling
  914. * this function.
  915. */
  916. static void fc_rport_recv_prli_req(struct fc_rport *rport,
  917. struct fc_seq *sp, struct fc_frame *rx_fp)
  918. {
  919. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  920. struct fc_lport *lport = rdata->local_port;
  921. struct fc_exch *ep;
  922. struct fc_frame *fp;
  923. struct fc_frame_header *fh;
  924. struct {
  925. struct fc_els_prli prli;
  926. struct fc_els_spp spp;
  927. } *pp;
  928. struct fc_els_spp *rspp; /* request service param page */
  929. struct fc_els_spp *spp; /* response spp */
  930. unsigned int len;
  931. unsigned int plen;
  932. enum fc_els_rjt_reason reason = ELS_RJT_UNAB;
  933. enum fc_els_rjt_explan explan = ELS_EXPL_NONE;
  934. enum fc_els_spp_resp resp;
  935. struct fc_seq_els_data rjt_data;
  936. u32 f_ctl;
  937. u32 fcp_parm;
  938. u32 roles = FC_RPORT_ROLE_UNKNOWN;
  939. rjt_data.fp = NULL;
  940. fh = fc_frame_header_get(rx_fp);
  941. FC_DEBUG_RPORT("Received PRLI request from port (%6x) "
  942. "while in state %s\n", ntoh24(fh->fh_s_id),
  943. fc_rport_state(rport));
  944. switch (rdata->rp_state) {
  945. case RPORT_ST_PRLI:
  946. case RPORT_ST_READY:
  947. reason = ELS_RJT_NONE;
  948. break;
  949. default:
  950. break;
  951. }
  952. len = fr_len(rx_fp) - sizeof(*fh);
  953. pp = fc_frame_payload_get(rx_fp, sizeof(*pp));
  954. if (pp == NULL) {
  955. reason = ELS_RJT_PROT;
  956. explan = ELS_EXPL_INV_LEN;
  957. } else {
  958. plen = ntohs(pp->prli.prli_len);
  959. if ((plen % 4) != 0 || plen > len) {
  960. reason = ELS_RJT_PROT;
  961. explan = ELS_EXPL_INV_LEN;
  962. } else if (plen < len) {
  963. len = plen;
  964. }
  965. plen = pp->prli.prli_spp_len;
  966. if ((plen % 4) != 0 || plen < sizeof(*spp) ||
  967. plen > len || len < sizeof(*pp)) {
  968. reason = ELS_RJT_PROT;
  969. explan = ELS_EXPL_INV_LEN;
  970. }
  971. rspp = &pp->spp;
  972. }
  973. if (reason != ELS_RJT_NONE ||
  974. (fp = fc_frame_alloc(lport, len)) == NULL) {
  975. rjt_data.reason = reason;
  976. rjt_data.explan = explan;
  977. lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
  978. } else {
  979. sp = lport->tt.seq_start_next(sp);
  980. WARN_ON(!sp);
  981. pp = fc_frame_payload_get(fp, len);
  982. WARN_ON(!pp);
  983. memset(pp, 0, len);
  984. pp->prli.prli_cmd = ELS_LS_ACC;
  985. pp->prli.prli_spp_len = plen;
  986. pp->prli.prli_len = htons(len);
  987. len -= sizeof(struct fc_els_prli);
  988. /*
  989. * Go through all the service parameter pages and build
  990. * response. If plen indicates longer SPP than standard,
  991. * use that. The entire response has been pre-cleared above.
  992. */
  993. spp = &pp->spp;
  994. while (len >= plen) {
  995. spp->spp_type = rspp->spp_type;
  996. spp->spp_type_ext = rspp->spp_type_ext;
  997. spp->spp_flags = rspp->spp_flags & FC_SPP_EST_IMG_PAIR;
  998. resp = FC_SPP_RESP_ACK;
  999. if (rspp->spp_flags & FC_SPP_RPA_VAL)
  1000. resp = FC_SPP_RESP_NO_PA;
  1001. switch (rspp->spp_type) {
  1002. case 0: /* common to all FC-4 types */
  1003. break;
  1004. case FC_TYPE_FCP:
  1005. fcp_parm = ntohl(rspp->spp_params);
  1006. if (fcp_parm * FCP_SPPF_RETRY)
  1007. rdata->flags |= FC_RP_FLAGS_RETRY;
  1008. rport->supported_classes = FC_COS_CLASS3;
  1009. if (fcp_parm & FCP_SPPF_INIT_FCN)
  1010. roles |= FC_RPORT_ROLE_FCP_INITIATOR;
  1011. if (fcp_parm & FCP_SPPF_TARG_FCN)
  1012. roles |= FC_RPORT_ROLE_FCP_TARGET;
  1013. rport->roles = roles;
  1014. spp->spp_params =
  1015. htonl(lport->service_params);
  1016. break;
  1017. default:
  1018. resp = FC_SPP_RESP_INVL;
  1019. break;
  1020. }
  1021. spp->spp_flags |= resp;
  1022. len -= plen;
  1023. rspp = (struct fc_els_spp *)((char *)rspp + plen);
  1024. spp = (struct fc_els_spp *)((char *)spp + plen);
  1025. }
  1026. /*
  1027. * Send LS_ACC. If this fails, the originator should retry.
  1028. */
  1029. f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
  1030. f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
  1031. ep = fc_seq_exch(sp);
  1032. fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
  1033. FC_TYPE_ELS, f_ctl, 0);
  1034. lport->tt.seq_send(lport, sp, fp);
  1035. /*
  1036. * Get lock and re-check state.
  1037. */
  1038. switch (rdata->rp_state) {
  1039. case RPORT_ST_PRLI:
  1040. fc_rport_enter_ready(rport);
  1041. break;
  1042. case RPORT_ST_READY:
  1043. break;
  1044. default:
  1045. break;
  1046. }
  1047. }
  1048. fc_frame_free(rx_fp);
  1049. }
  1050. /**
  1051. * fc_rport_recv_prlo_req - Handle incoming Process Logout (PRLO) request
  1052. * @rport: Fibre Channel remote port that initiated PRLO
  1053. * @sp: current sequence in the PRLO exchange
  1054. * @fp: PRLO request frame
  1055. *
  1056. * Locking Note: The rport lock is exected to be held before calling
  1057. * this function.
  1058. */
  1059. static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp,
  1060. struct fc_frame *fp)
  1061. {
  1062. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  1063. struct fc_lport *lport = rdata->local_port;
  1064. struct fc_frame_header *fh;
  1065. struct fc_seq_els_data rjt_data;
  1066. fh = fc_frame_header_get(fp);
  1067. FC_DEBUG_RPORT("Received PRLO request from port (%6x) "
  1068. "while in state %s\n", ntoh24(fh->fh_s_id),
  1069. fc_rport_state(rport));
  1070. rjt_data.fp = NULL;
  1071. rjt_data.reason = ELS_RJT_UNAB;
  1072. rjt_data.explan = ELS_EXPL_NONE;
  1073. lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
  1074. fc_frame_free(fp);
  1075. }
  1076. /**
  1077. * fc_rport_recv_logo_req - Handle incoming Logout (LOGO) request
  1078. * @rport: Fibre Channel remote port that initiated LOGO
  1079. * @sp: current sequence in the LOGO exchange
  1080. * @fp: LOGO request frame
  1081. *
  1082. * Locking Note: The rport lock is exected to be held before calling
  1083. * this function.
  1084. */
  1085. static void fc_rport_recv_logo_req(struct fc_rport *rport, struct fc_seq *sp,
  1086. struct fc_frame *fp)
  1087. {
  1088. struct fc_frame_header *fh;
  1089. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  1090. struct fc_lport *lport = rdata->local_port;
  1091. fh = fc_frame_header_get(fp);
  1092. FC_DEBUG_RPORT("Received LOGO request from port (%6x) "
  1093. "while in state %s\n", ntoh24(fh->fh_s_id),
  1094. fc_rport_state(rport));
  1095. rdata->event = RPORT_EV_LOGO;
  1096. queue_work(rport_event_queue, &rdata->event_work);
  1097. lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
  1098. fc_frame_free(fp);
  1099. }
  1100. static void fc_rport_flush_queue(void)
  1101. {
  1102. flush_workqueue(rport_event_queue);
  1103. }
  1104. int fc_rport_init(struct fc_lport *lport)
  1105. {
  1106. if (!lport->tt.rport_login)
  1107. lport->tt.rport_login = fc_rport_login;
  1108. if (!lport->tt.rport_logoff)
  1109. lport->tt.rport_logoff = fc_rport_logoff;
  1110. if (!lport->tt.rport_recv_req)
  1111. lport->tt.rport_recv_req = fc_rport_recv_req;
  1112. if (!lport->tt.rport_flush_queue)
  1113. lport->tt.rport_flush_queue = fc_rport_flush_queue;
  1114. return 0;
  1115. }
  1116. EXPORT_SYMBOL(fc_rport_init);
  1117. int fc_setup_rport()
  1118. {
  1119. rport_event_queue = create_singlethread_workqueue("fc_rport_eq");
  1120. if (!rport_event_queue)
  1121. return -ENOMEM;
  1122. return 0;
  1123. }
  1124. EXPORT_SYMBOL(fc_setup_rport);
  1125. void fc_destroy_rport()
  1126. {
  1127. destroy_workqueue(rport_event_queue);
  1128. }
  1129. EXPORT_SYMBOL(fc_destroy_rport);
  1130. void fc_rport_terminate_io(struct fc_rport *rport)
  1131. {
  1132. struct fc_rport_libfc_priv *rdata = rport->dd_data;
  1133. struct fc_lport *lport = rdata->local_port;
  1134. lport->tt.exch_mgr_reset(lport, 0, rport->port_id);
  1135. lport->tt.exch_mgr_reset(lport, rport->port_id, 0);
  1136. }
  1137. EXPORT_SYMBOL(fc_rport_terminate_io);