qla_rscn.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437
  1. /*
  2. * QLOGIC LINUX SOFTWARE
  3. *
  4. * QLogic ISP2x00 device driver for Linux 2.6.x
  5. * Copyright (C) 2003-2005 QLogic Corporation
  6. * (www.qlogic.com)
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2, or (at your option) any
  11. * later version.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. */
  19. #include "qla_def.h"
  20. /**
  21. * IO descriptor handle definitions.
  22. *
  23. * Signature form:
  24. *
  25. * |31------28|27-------------------12|11-------0|
  26. * | Type | Rolling Signature | Index |
  27. * |----------|-----------------------|----------|
  28. *
  29. **/
  30. #define HDL_TYPE_SCSI 0
  31. #define HDL_TYPE_ASYNC_IOCB 0x0A
  32. #define HDL_INDEX_BITS 12
  33. #define HDL_ITER_BITS 16
  34. #define HDL_TYPE_BITS 4
  35. #define HDL_INDEX_MASK ((1UL << HDL_INDEX_BITS) - 1)
  36. #define HDL_ITER_MASK ((1UL << HDL_ITER_BITS) - 1)
  37. #define HDL_TYPE_MASK ((1UL << HDL_TYPE_BITS) - 1)
  38. #define HDL_INDEX_SHIFT 0
  39. #define HDL_ITER_SHIFT (HDL_INDEX_SHIFT + HDL_INDEX_BITS)
  40. #define HDL_TYPE_SHIFT (HDL_ITER_SHIFT + HDL_ITER_BITS)
  41. /* Local Prototypes. */
  42. static inline uint32_t qla2x00_to_handle(uint16_t, uint16_t, uint16_t);
  43. static inline uint16_t qla2x00_handle_to_idx(uint32_t);
  44. static inline uint32_t qla2x00_iodesc_to_handle(struct io_descriptor *);
  45. static inline struct io_descriptor *qla2x00_handle_to_iodesc(scsi_qla_host_t *,
  46. uint32_t);
  47. static inline struct io_descriptor *qla2x00_alloc_iodesc(scsi_qla_host_t *);
  48. static inline void qla2x00_free_iodesc(struct io_descriptor *);
  49. static inline void qla2x00_init_io_descriptors(scsi_qla_host_t *);
  50. static void qla2x00_iodesc_timeout(unsigned long);
  51. static inline void qla2x00_add_iodesc_timer(struct io_descriptor *);
  52. static inline void qla2x00_remove_iodesc_timer(struct io_descriptor *);
  53. static inline void qla2x00_update_login_fcport(scsi_qla_host_t *,
  54. struct mbx_entry *, fc_port_t *);
  55. static int qla2x00_send_abort_iocb(scsi_qla_host_t *, struct io_descriptor *,
  56. uint32_t, int);
  57. static int qla2x00_send_abort_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
  58. struct mbx_entry *);
  59. static int qla2x00_send_adisc_iocb(scsi_qla_host_t *, struct io_descriptor *,
  60. int);
  61. static int qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
  62. struct mbx_entry *);
  63. static int qla2x00_send_logout_iocb(scsi_qla_host_t *, struct io_descriptor *,
  64. int);
  65. static int qla2x00_send_logout_iocb_cb(scsi_qla_host_t *,
  66. struct io_descriptor *, struct mbx_entry *);
  67. static int qla2x00_send_login_iocb(scsi_qla_host_t *, struct io_descriptor *,
  68. port_id_t *, int);
  69. static int qla2x00_send_login_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
  70. struct mbx_entry *);
  71. /**
  72. * Mailbox IOCB callback array.
  73. **/
  74. static int (*iocb_function_cb_list[LAST_IOCB_CB])
  75. (scsi_qla_host_t *, struct io_descriptor *, struct mbx_entry *) = {
  76. qla2x00_send_abort_iocb_cb,
  77. qla2x00_send_adisc_iocb_cb,
  78. qla2x00_send_logout_iocb_cb,
  79. qla2x00_send_login_iocb_cb,
  80. };
  81. /**
  82. * Generic IO descriptor handle routines.
  83. **/
  84. /**
  85. * qla2x00_to_handle() - Create a descriptor handle.
  86. * @type: descriptor type
  87. * @iter: descriptor rolling signature
  88. * @idx: index to the descriptor array
  89. *
  90. * Returns a composite handle based in the @type, @iter, and @idx.
  91. */
  92. static inline uint32_t
  93. qla2x00_to_handle(uint16_t type, uint16_t iter, uint16_t idx)
  94. {
  95. return ((uint32_t)(((uint32_t)type << HDL_TYPE_SHIFT) |
  96. ((uint32_t)iter << HDL_ITER_SHIFT) |
  97. ((uint32_t)idx << HDL_INDEX_SHIFT)));
  98. }
  99. /**
  100. * qla2x00_handle_to_idx() - Retrive the index for a given handle.
  101. * @handle: descriptor handle
  102. *
  103. * Returns the index specified by the @handle.
  104. */
  105. static inline uint16_t
  106. qla2x00_handle_to_idx(uint32_t handle)
  107. {
  108. return ((uint16_t)(((handle) >> HDL_INDEX_SHIFT) & HDL_INDEX_MASK));
  109. }
  110. /**
  111. * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle.
  112. * @iodesc: io descriptor
  113. *
  114. * Returns a unique handle for @iodesc.
  115. */
  116. static inline uint32_t
  117. qla2x00_iodesc_to_handle(struct io_descriptor *iodesc)
  118. {
  119. uint32_t handle;
  120. handle = qla2x00_to_handle(HDL_TYPE_ASYNC_IOCB,
  121. ++iodesc->ha->iodesc_signature, iodesc->idx);
  122. iodesc->signature = handle;
  123. return (handle);
  124. }
  125. /**
  126. * qla2x00_handle_to_iodesc() - Retrieve an IO descriptor given a unique handle.
  127. * @ha: HA context
  128. * @handle: handle to io descriptor
  129. *
  130. * Returns a pointer to the io descriptor, or NULL, if the io descriptor does
  131. * not exist or the io descriptors signature does not @handle.
  132. */
  133. static inline struct io_descriptor *
  134. qla2x00_handle_to_iodesc(scsi_qla_host_t *ha, uint32_t handle)
  135. {
  136. uint16_t idx;
  137. struct io_descriptor *iodesc;
  138. idx = qla2x00_handle_to_idx(handle);
  139. iodesc = &ha->io_descriptors[idx];
  140. if (iodesc)
  141. if (iodesc->signature != handle)
  142. iodesc = NULL;
  143. return (iodesc);
  144. }
  145. /**
  146. * IO descriptor allocation routines.
  147. **/
  148. /**
  149. * qla2x00_alloc_iodesc() - Allocate an IO descriptor from the pool.
  150. * @ha: HA context
  151. *
  152. * Returns a pointer to the allocated io descriptor, or NULL, if none available.
  153. */
  154. static inline struct io_descriptor *
  155. qla2x00_alloc_iodesc(scsi_qla_host_t *ha)
  156. {
  157. uint16_t iter;
  158. struct io_descriptor *iodesc;
  159. iodesc = NULL;
  160. for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
  161. if (ha->io_descriptors[iter].used)
  162. continue;
  163. iodesc = &ha->io_descriptors[iter];
  164. iodesc->used = 1;
  165. iodesc->idx = iter;
  166. init_timer(&iodesc->timer);
  167. iodesc->ha = ha;
  168. iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
  169. break;
  170. }
  171. return (iodesc);
  172. }
  173. /**
  174. * qla2x00_free_iodesc() - Free an IO descriptor.
  175. * @iodesc: io descriptor
  176. *
  177. * NOTE: The io descriptors timer *must* be stopped before it can be free'd.
  178. */
  179. static inline void
  180. qla2x00_free_iodesc(struct io_descriptor *iodesc)
  181. {
  182. iodesc->used = 0;
  183. iodesc->signature = 0;
  184. }
  185. /**
  186. * qla2x00_remove_iodesc_timer() - Remove an active timer from an IO descriptor.
  187. * @iodesc: io descriptor
  188. */
  189. static inline void
  190. qla2x00_remove_iodesc_timer(struct io_descriptor *iodesc)
  191. {
  192. if (iodesc->timer.function != NULL) {
  193. del_timer_sync(&iodesc->timer);
  194. iodesc->timer.data = (unsigned long) NULL;
  195. iodesc->timer.function = NULL;
  196. }
  197. }
  198. /**
  199. * qla2x00_init_io_descriptors() - Initialize the pool of IO descriptors.
  200. * @ha: HA context
  201. */
  202. static inline void
  203. qla2x00_init_io_descriptors(scsi_qla_host_t *ha)
  204. {
  205. uint16_t iter;
  206. for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
  207. if (!ha->io_descriptors[iter].used)
  208. continue;
  209. qla2x00_remove_iodesc_timer(&ha->io_descriptors[iter]);
  210. qla2x00_free_iodesc(&ha->io_descriptors[iter]);
  211. }
  212. }
  213. /**
  214. * IO descriptor timer routines.
  215. **/
  216. /**
  217. * qla2x00_iodesc_timeout() - Timeout IO descriptor handler.
  218. * @data: io descriptor
  219. */
  220. static void
  221. qla2x00_iodesc_timeout(unsigned long data)
  222. {
  223. struct io_descriptor *iodesc;
  224. iodesc = (struct io_descriptor *) data;
  225. DEBUG14(printk("scsi(%ld): IO descriptor timeout, index=%x "
  226. "signature=%08x, scheduling ISP abort.\n", iodesc->ha->host_no,
  227. iodesc->idx, iodesc->signature));
  228. qla2x00_free_iodesc(iodesc);
  229. qla_printk(KERN_WARNING, iodesc->ha,
  230. "IO descriptor timeout. Scheduling ISP abort.\n");
  231. set_bit(ISP_ABORT_NEEDED, &iodesc->ha->dpc_flags);
  232. }
  233. /**
  234. * qla2x00_add_iodesc_timer() - Add and start a timer for an IO descriptor.
  235. * @iodesc: io descriptor
  236. *
  237. * NOTE:
  238. * The firmware shall timeout an outstanding mailbox IOCB in 2 * R_A_TOV (in
  239. * tenths of a second) after it hits the wire. But, if there are any request
  240. * resource contraints (i.e. during heavy I/O), exchanges can be held off for
  241. * at most R_A_TOV. Therefore, the driver will wait 4 * R_A_TOV before
  242. * scheduling a recovery (big hammer).
  243. */
  244. static inline void
  245. qla2x00_add_iodesc_timer(struct io_descriptor *iodesc)
  246. {
  247. unsigned long timeout;
  248. timeout = (iodesc->ha->r_a_tov * 4) / 10;
  249. init_timer(&iodesc->timer);
  250. iodesc->timer.data = (unsigned long) iodesc;
  251. iodesc->timer.expires = jiffies + (timeout * HZ);
  252. iodesc->timer.function =
  253. (void (*) (unsigned long)) qla2x00_iodesc_timeout;
  254. add_timer(&iodesc->timer);
  255. }
  256. /**
  257. * IO descriptor support routines.
  258. **/
  259. /**
  260. * qla2x00_update_login_fcport() - Update fcport data after login processing.
  261. * @ha: HA context
  262. * @mbxstat: Mailbox command status IOCB
  263. * @fcport: port to update
  264. */
  265. static inline void
  266. qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
  267. fc_port_t *fcport)
  268. {
  269. if (le16_to_cpu(mbxstat->mb1) & BIT_0) {
  270. fcport->port_type = FCT_INITIATOR;
  271. } else {
  272. fcport->port_type = FCT_TARGET;
  273. if (le16_to_cpu(mbxstat->mb1) & BIT_1) {
  274. fcport->flags |= FCF_TAPE_PRESENT;
  275. }
  276. }
  277. fcport->login_retry = 0;
  278. fcport->port_login_retry_count = ha->port_down_retry_count *
  279. PORT_RETRY_TIME;
  280. atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
  281. PORT_RETRY_TIME);
  282. fcport->flags |= FCF_FABRIC_DEVICE;
  283. fcport->flags &= ~FCF_FAILOVER_NEEDED;
  284. fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
  285. atomic_set(&fcport->state, FCS_ONLINE);
  286. }
  287. /**
  288. * Mailbox IOCB commands.
  289. **/
  290. /**
  291. * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
  292. * @ha: HA context
  293. * @handle: handle to io descriptor
  294. *
  295. * Returns a pointer to the reqest entry, or NULL, if none were available.
  296. */
  297. static inline struct mbx_entry *
  298. qla2x00_get_mbx_iocb_entry(scsi_qla_host_t *ha, uint32_t handle)
  299. {
  300. uint16_t cnt;
  301. struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
  302. struct mbx_entry *mbxentry;
  303. mbxentry = NULL;
  304. if (ha->req_q_cnt < 3) {
  305. cnt = qla2x00_debounce_register(ISP_REQ_Q_OUT(ha, reg));
  306. if (ha->req_ring_index < cnt)
  307. ha->req_q_cnt = cnt - ha->req_ring_index;
  308. else
  309. ha->req_q_cnt = ha->request_q_length -
  310. (ha->req_ring_index - cnt);
  311. }
  312. if (ha->req_q_cnt >= 3) {
  313. mbxentry = (struct mbx_entry *)ha->request_ring_ptr;
  314. memset(mbxentry, 0, sizeof(struct mbx_entry));
  315. mbxentry->entry_type = MBX_IOCB_TYPE;
  316. mbxentry->entry_count = 1;
  317. mbxentry->sys_define1 = SOURCE_ASYNC_IOCB;
  318. mbxentry->handle = handle;
  319. }
  320. return (mbxentry);
  321. }
  322. /**
  323. * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
  324. * @ha: HA context
  325. * @iodesc: io descriptor
  326. * @handle_to_abort: firmware handle to abort
  327. * @ha_locked: is function called with the hardware lock
  328. *
  329. * Returns QLA_SUCCESS if the IOCB was issued.
  330. */
  331. static int
  332. qla2x00_send_abort_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  333. uint32_t handle_to_abort, int ha_locked)
  334. {
  335. unsigned long flags = 0;
  336. struct mbx_entry *mbxentry;
  337. /* Send marker if required. */
  338. if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
  339. return (QLA_FUNCTION_FAILED);
  340. if (!ha_locked)
  341. spin_lock_irqsave(&ha->hardware_lock, flags);
  342. /* Build abort mailbox IOCB. */
  343. mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
  344. if (mbxentry == NULL) {
  345. if (!ha_locked)
  346. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  347. return (QLA_FUNCTION_FAILED);
  348. }
  349. mbxentry->mb0 = __constant_cpu_to_le16(MBC_ABORT_COMMAND);
  350. mbxentry->mb1 = mbxentry->loop_id.extended =
  351. cpu_to_le16(iodesc->remote_fcport->loop_id);
  352. mbxentry->mb2 = LSW(handle_to_abort);
  353. mbxentry->mb3 = MSW(handle_to_abort);
  354. wmb();
  355. qla2x00_add_iodesc_timer(iodesc);
  356. /* Issue command to ISP. */
  357. qla2x00_isp_cmd(ha);
  358. if (!ha_locked)
  359. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  360. DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
  361. "%08x.\n", ha->host_no, iodesc->signature,
  362. iodesc->remote_fcport->loop_id, handle_to_abort));
  363. return (QLA_SUCCESS);
  364. }
  365. /**
  366. * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
  367. * @ha: HA context
  368. * @iodesc: io descriptor
  369. * @mbxstat: mailbox status IOCB
  370. *
  371. * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
  372. * will be used for a retry.
  373. */
  374. static int
  375. qla2x00_send_abort_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  376. struct mbx_entry *mbxstat)
  377. {
  378. DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
  379. "status=%x mb0=%x.\n", ha->host_no, iodesc->remote_fcport->loop_id,
  380. iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa,
  381. le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
  382. return (QLA_SUCCESS);
  383. }
  384. /**
  385. * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
  386. * @ha: HA context
  387. * @iodesc: io descriptor
  388. * @ha_locked: is function called with the hardware lock
  389. *
  390. * Returns QLA_SUCCESS if the IOCB was issued.
  391. */
  392. static int
  393. qla2x00_send_adisc_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  394. int ha_locked)
  395. {
  396. unsigned long flags = 0;
  397. struct mbx_entry *mbxentry;
  398. /* Send marker if required. */
  399. if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
  400. return (QLA_FUNCTION_FAILED);
  401. if (!ha_locked)
  402. spin_lock_irqsave(&ha->hardware_lock, flags);
  403. /* Build Get Port Database IOCB. */
  404. mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
  405. if (mbxentry == NULL) {
  406. if (!ha_locked)
  407. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  408. return (QLA_FUNCTION_FAILED);
  409. }
  410. mbxentry->mb0 = __constant_cpu_to_le16(MBC_GET_PORT_DATABASE);
  411. mbxentry->mb1 = mbxentry->loop_id.extended =
  412. cpu_to_le16(iodesc->remote_fcport->loop_id);
  413. mbxentry->mb2 = cpu_to_le16(MSW(LSD(ha->iodesc_pd_dma)));
  414. mbxentry->mb3 = cpu_to_le16(LSW(LSD(ha->iodesc_pd_dma)));
  415. mbxentry->mb6 = cpu_to_le16(MSW(MSD(ha->iodesc_pd_dma)));
  416. mbxentry->mb7 = cpu_to_le16(LSW(MSD(ha->iodesc_pd_dma)));
  417. mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
  418. wmb();
  419. qla2x00_add_iodesc_timer(iodesc);
  420. /* Issue command to ISP. */
  421. qla2x00_isp_cmd(ha);
  422. if (!ha_locked)
  423. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  424. DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
  425. ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));
  426. return (QLA_SUCCESS);
  427. }
  428. /**
  429. * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
  430. * @ha: HA context
  431. * @iodesc: io descriptor
  432. * @mbxstat: mailbox status IOCB
  433. *
  434. * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
  435. * will be used for a retry.
  436. */
  437. static int
  438. qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  439. struct mbx_entry *mbxstat)
  440. {
  441. fc_port_t *remote_fcport;
  442. remote_fcport = iodesc->remote_fcport;
  443. /* Ensure the port IDs are consistent. */
  444. if (remote_fcport->d_id.b24 != iodesc->d_id.b24) {
  445. DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
  446. "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
  447. ha->host_no, remote_fcport->d_id.b.domain,
  448. remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
  449. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  450. iodesc->d_id.b.al_pa));
  451. return (QLA_SUCCESS);
  452. }
  453. /* Only process the last command. */
  454. if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
  455. DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
  456. "[%02x%02x%02x], expected %x, received %x.\n", ha->host_no,
  457. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  458. iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
  459. iodesc->idx));
  460. return (QLA_SUCCESS);
  461. }
  462. if (le16_to_cpu(mbxstat->status) == CS_COMPLETE) {
  463. DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
  464. "[%x/%02x%02x%02x] online.\n", ha->host_no,
  465. remote_fcport->loop_id, remote_fcport->d_id.b.domain,
  466. remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
  467. atomic_set(&remote_fcport->state, FCS_ONLINE);
  468. } else {
  469. DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
  470. "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha->host_no,
  471. remote_fcport->loop_id, remote_fcport->d_id.b.domain,
  472. remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
  473. le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
  474. if (atomic_read(&remote_fcport->state) != FCS_DEVICE_DEAD)
  475. atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
  476. }
  477. remote_fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
  478. return (QLA_SUCCESS);
  479. }
  480. /**
  481. * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
  482. * @ha: HA context
  483. * @iodesc: io descriptor
  484. * @ha_locked: is function called with the hardware lock
  485. *
  486. * Returns QLA_SUCCESS if the IOCB was issued.
  487. */
  488. static int
  489. qla2x00_send_logout_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  490. int ha_locked)
  491. {
  492. unsigned long flags = 0;
  493. struct mbx_entry *mbxentry;
  494. /* Send marker if required. */
  495. if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
  496. return (QLA_FUNCTION_FAILED);
  497. if (!ha_locked)
  498. spin_lock_irqsave(&ha->hardware_lock, flags);
  499. /* Build fabric port logout mailbox IOCB. */
  500. mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
  501. if (mbxentry == NULL) {
  502. if (!ha_locked)
  503. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  504. return (QLA_FUNCTION_FAILED);
  505. }
  506. mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
  507. mbxentry->mb1 = mbxentry->loop_id.extended =
  508. cpu_to_le16(iodesc->remote_fcport->loop_id);
  509. wmb();
  510. qla2x00_add_iodesc_timer(iodesc);
  511. /* Issue command to ISP. */
  512. qla2x00_isp_cmd(ha);
  513. if (!ha_locked)
  514. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  515. DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",
  516. ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));
  517. return (QLA_SUCCESS);
  518. }
  519. /**
  520. * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback.
  521. * @ha: HA context
  522. * @iodesc: io descriptor
  523. * @mbxstat: mailbox status IOCB
  524. *
  525. * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
  526. * will be used for a retry.
  527. */
  528. static int
  529. qla2x00_send_logout_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  530. struct mbx_entry *mbxstat)
  531. {
  532. DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "
  533. "status=%x mb0=%x mb1=%x.\n", ha->host_no,
  534. iodesc->remote_fcport->loop_id,
  535. iodesc->remote_fcport->d_id.b.domain,
  536. iodesc->remote_fcport->d_id.b.area,
  537. iodesc->remote_fcport->d_id.b.al_pa, le16_to_cpu(mbxstat->status),
  538. le16_to_cpu(mbxstat->mb0), le16_to_cpu(mbxstat->mb1)));
  539. return (QLA_SUCCESS);
  540. }
  541. /**
  542. * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware.
  543. * @ha: HA context
  544. * @iodesc: io descriptor
  545. * @d_id: port id for device
  546. * @ha_locked: is function called with the hardware lock
  547. *
  548. * Returns QLA_SUCCESS if the IOCB was issued.
  549. */
  550. static int
  551. qla2x00_send_login_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  552. port_id_t *d_id, int ha_locked)
  553. {
  554. unsigned long flags = 0;
  555. struct mbx_entry *mbxentry;
  556. /* Send marker if required. */
  557. if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
  558. return (QLA_FUNCTION_FAILED);
  559. if (!ha_locked)
  560. spin_lock_irqsave(&ha->hardware_lock, flags);
  561. /* Build fabric port login mailbox IOCB. */
  562. mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
  563. if (mbxentry == NULL) {
  564. if (!ha_locked)
  565. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  566. return (QLA_FUNCTION_FAILED);
  567. }
  568. mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT);
  569. mbxentry->mb1 = mbxentry->loop_id.extended =
  570. cpu_to_le16(iodesc->remote_fcport->loop_id);
  571. mbxentry->mb2 = cpu_to_le16(d_id->b.domain);
  572. mbxentry->mb3 = cpu_to_le16(d_id->b.area << 8 | d_id->b.al_pa);
  573. mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
  574. wmb();
  575. qla2x00_add_iodesc_timer(iodesc);
  576. /* Issue command to ISP. */
  577. qla2x00_isp_cmd(ha);
  578. if (!ha_locked)
  579. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  580. DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
  581. "[%x/%02x%02x%02x].\n", ha->host_no, iodesc->signature,
  582. iodesc->remote_fcport->loop_id, d_id->b.domain, d_id->b.area,
  583. d_id->b.al_pa));
  584. return (QLA_SUCCESS);
  585. }
  586. /**
  587. * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
  588. * @ha: HA context
  589. * @iodesc: io descriptor
  590. * @mbxstat: mailbox status IOCB
  591. *
  592. * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
  593. * will be used for a retry.
  594. */
  595. static int
  596. qla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  597. struct mbx_entry *mbxstat)
  598. {
  599. int rval;
  600. fc_port_t *fcport, *remote_fcport, *exist_fcport;
  601. struct io_descriptor *abort_iodesc, *login_iodesc;
  602. uint16_t status, mb[8];
  603. uint16_t reuse;
  604. uint16_t remote_loopid;
  605. port_id_t remote_did, inuse_did;
  606. remote_fcport = iodesc->remote_fcport;
  607. /* Only process the last command. */
  608. if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
  609. DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
  610. "[%02x%02x%02x], expected %x, received %x.\n",
  611. ha->host_no, iodesc->d_id.b.domain, iodesc->d_id.b.area,
  612. iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
  613. iodesc->idx));
  614. /* Free RSCN fcport resources. */
  615. if (remote_fcport->port_type == FCT_RSCN) {
  616. DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
  617. "fcport %p [%x/%02x%02x%02x] given ignored Login "
  618. "IOCB.\n", ha->host_no, remote_fcport,
  619. remote_fcport->loop_id,
  620. remote_fcport->d_id.b.domain,
  621. remote_fcport->d_id.b.area,
  622. remote_fcport->d_id.b.al_pa));
  623. list_del(&remote_fcport->list);
  624. kfree(remote_fcport);
  625. }
  626. return (QLA_SUCCESS);
  627. }
  628. status = le16_to_cpu(mbxstat->status);
  629. mb[0] = le16_to_cpu(mbxstat->mb0);
  630. mb[1] = le16_to_cpu(mbxstat->mb1);
  631. mb[2] = le16_to_cpu(mbxstat->mb2);
  632. mb[6] = le16_to_cpu(mbxstat->mb6);
  633. mb[7] = le16_to_cpu(mbxstat->mb7);
  634. /* Good status? */
  635. if ((status == CS_COMPLETE || status == CS_COMPLETE_CHKCOND) &&
  636. mb[0] == MBS_COMMAND_COMPLETE) {
  637. DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
  638. "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha->host_no, status,
  639. mb[1], mbxstat->port_name[0], mbxstat->port_name[1],
  640. mbxstat->port_name[2], mbxstat->port_name[3],
  641. mbxstat->port_name[4], mbxstat->port_name[5],
  642. mbxstat->port_name[6], mbxstat->port_name[7]));
  643. memcpy(remote_fcport->node_name, mbxstat->node_name, WWN_SIZE);
  644. memcpy(remote_fcport->port_name, mbxstat->port_name, WWN_SIZE);
  645. /* Is the device already in our fcports list? */
  646. if (remote_fcport->port_type != FCT_RSCN) {
  647. DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
  648. "[%x/%02x%02x%02x] online.\n", ha->host_no,
  649. remote_fcport->loop_id,
  650. remote_fcport->d_id.b.domain,
  651. remote_fcport->d_id.b.area,
  652. remote_fcport->d_id.b.al_pa));
  653. qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
  654. return (QLA_SUCCESS);
  655. }
  656. /* Does the RSCN portname already exist in our fcports list? */
  657. exist_fcport = NULL;
  658. list_for_each_entry(fcport, &ha->fcports, list) {
  659. if (memcmp(remote_fcport->port_name, fcport->port_name,
  660. WWN_SIZE) == 0) {
  661. exist_fcport = fcport;
  662. break;
  663. }
  664. }
  665. if (exist_fcport != NULL) {
  666. DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
  667. "fcport in fcports list [%p].\n", ha->host_no,
  668. exist_fcport));
  669. /* Abort any ADISC that could have been sent. */
  670. if (exist_fcport->iodesc_idx_sent != iodesc->idx &&
  671. exist_fcport->iodesc_idx_sent <
  672. MAX_IO_DESCRIPTORS &&
  673. ha->io_descriptors[exist_fcport->iodesc_idx_sent].
  674. cb_idx == ADISC_PORT_IOCB_CB) {
  675. abort_iodesc = qla2x00_alloc_iodesc(ha);
  676. if (abort_iodesc) {
  677. DEBUG14(printk("scsi(%ld): Login IOCB "
  678. "-- issuing abort to outstanding "
  679. "Adisc [%x/%02x%02x%02x].\n",
  680. ha->host_no, remote_fcport->loop_id,
  681. exist_fcport->d_id.b.domain,
  682. exist_fcport->d_id.b.area,
  683. exist_fcport->d_id.b.al_pa));
  684. abort_iodesc->cb_idx = ABORT_IOCB_CB;
  685. abort_iodesc->d_id.b24 =
  686. exist_fcport->d_id.b24;
  687. abort_iodesc->remote_fcport =
  688. exist_fcport;
  689. exist_fcport->iodesc_idx_sent =
  690. abort_iodesc->idx;
  691. qla2x00_send_abort_iocb(ha,
  692. abort_iodesc, ha->io_descriptors[
  693. exist_fcport->iodesc_idx_sent].
  694. signature, 1);
  695. } else {
  696. DEBUG14(printk("scsi(%ld): Login IOCB "
  697. "-- unable to abort outstanding "
  698. "Adisc [%x/%02x%02x%02x].\n",
  699. ha->host_no, remote_fcport->loop_id,
  700. exist_fcport->d_id.b.domain,
  701. exist_fcport->d_id.b.area,
  702. exist_fcport->d_id.b.al_pa));
  703. }
  704. }
  705. /*
  706. * If the existing fcport is waiting to send an ADISC
  707. * or LOGIN, then reuse remote fcport (RSCN) to
  708. * continue waiting.
  709. */
  710. reuse = 0;
  711. remote_loopid = remote_fcport->loop_id;
  712. remote_did.b24 = remote_fcport->d_id.b24;
  713. if (exist_fcport->iodesc_idx_sent ==
  714. IODESC_ADISC_NEEDED ||
  715. exist_fcport->iodesc_idx_sent ==
  716. IODESC_LOGIN_NEEDED) {
  717. DEBUG14(printk("scsi(%ld): Login IOCB -- "
  718. "existing fcport [%x/%02x%02x%02x] "
  719. "waiting for IO descriptor, reuse RSCN "
  720. "fcport.\n", ha->host_no,
  721. exist_fcport->loop_id,
  722. exist_fcport->d_id.b.domain,
  723. exist_fcport->d_id.b.area,
  724. exist_fcport->d_id.b.al_pa));
  725. reuse++;
  726. remote_fcport->iodesc_idx_sent =
  727. exist_fcport->iodesc_idx_sent;
  728. exist_fcport->iodesc_idx_sent =
  729. IODESC_INVALID_INDEX;
  730. remote_fcport->loop_id = exist_fcport->loop_id;
  731. remote_fcport->d_id.b24 =
  732. exist_fcport->d_id.b24;
  733. }
  734. /* Logout the old loopid. */
  735. if (!reuse &&
  736. exist_fcport->loop_id != remote_fcport->loop_id &&
  737. exist_fcport->loop_id != FC_NO_LOOP_ID) {
  738. login_iodesc = qla2x00_alloc_iodesc(ha);
  739. if (login_iodesc) {
  740. DEBUG14(printk("scsi(%ld): Login IOCB "
  741. "-- issuing logout to free old "
  742. "loop id [%x/%02x%02x%02x].\n",
  743. ha->host_no, exist_fcport->loop_id,
  744. exist_fcport->d_id.b.domain,
  745. exist_fcport->d_id.b.area,
  746. exist_fcport->d_id.b.al_pa));
  747. login_iodesc->cb_idx =
  748. LOGOUT_PORT_IOCB_CB;
  749. login_iodesc->d_id.b24 =
  750. exist_fcport->d_id.b24;
  751. login_iodesc->remote_fcport =
  752. exist_fcport;
  753. exist_fcport->iodesc_idx_sent =
  754. login_iodesc->idx;
  755. qla2x00_send_logout_iocb(ha,
  756. login_iodesc, 1);
  757. } else {
  758. /* Ran out of IO descriptiors. */
  759. DEBUG14(printk("scsi(%ld): Login IOCB "
  760. "-- unable to logout to free old "
  761. "loop id [%x/%02x%02x%02x].\n",
  762. ha->host_no, exist_fcport->loop_id,
  763. exist_fcport->d_id.b.domain,
  764. exist_fcport->d_id.b.area,
  765. exist_fcport->d_id.b.al_pa));
  766. exist_fcport->iodesc_idx_sent =
  767. IODESC_INVALID_INDEX;
  768. }
  769. }
  770. /* Update existing fcport with remote fcport info. */
  771. DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
  772. "existing fcport [%x/%02x%02x%02x] online.\n",
  773. ha->host_no, remote_loopid, remote_did.b.domain,
  774. remote_did.b.area, remote_did.b.al_pa));
  775. memcpy(exist_fcport->node_name,
  776. remote_fcport->node_name, WWN_SIZE);
  777. exist_fcport->loop_id = remote_loopid;
  778. exist_fcport->d_id.b24 = remote_did.b24;
  779. qla2x00_update_login_fcport(ha, mbxstat, exist_fcport);
  780. /* Finally, free the remote (RSCN) fcport. */
  781. if (!reuse) {
  782. DEBUG14(printk("scsi(%ld): Login IOCB -- "
  783. "Freeing RSCN fcport %p "
  784. "[%x/%02x%02x%02x].\n", ha->host_no,
  785. remote_fcport, remote_fcport->loop_id,
  786. remote_fcport->d_id.b.domain,
  787. remote_fcport->d_id.b.area,
  788. remote_fcport->d_id.b.al_pa));
  789. list_del(&remote_fcport->list);
  790. kfree(remote_fcport);
  791. }
  792. return (QLA_SUCCESS);
  793. }
  794. /*
  795. * A new device has been added, move the RSCN fcport to our
  796. * fcports list.
  797. */
  798. DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
  799. "[%x/%02x%02x%02x] to fcports list.\n", ha->host_no,
  800. remote_fcport->loop_id, remote_fcport->d_id.b.domain,
  801. remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
  802. list_del(&remote_fcport->list);
  803. remote_fcport->flags = (FCF_RLC_SUPPORT | FCF_RESCAN_NEEDED);
  804. qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
  805. list_add_tail(&remote_fcport->list, &ha->fcports);
  806. set_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags);
  807. } else {
  808. /* Handle login failure. */
  809. if (remote_fcport->login_retry != 0) {
  810. if (mb[0] == MBS_LOOP_ID_USED) {
  811. inuse_did.b.domain = LSB(mb[1]);
  812. inuse_did.b.area = MSB(mb[2]);
  813. inuse_did.b.al_pa = LSB(mb[2]);
  814. DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
  815. "id [%x] used by port id [%02x%02x%02x].\n",
  816. ha->host_no, remote_fcport->loop_id,
  817. inuse_did.b.domain, inuse_did.b.area,
  818. inuse_did.b.al_pa));
  819. if (remote_fcport->d_id.b24 ==
  820. INVALID_PORT_ID) {
  821. /*
  822. * Invalid port id means we are trying
  823. * to login to a remote port with just
  824. * a loop id without knowing about the
  825. * port id. Copy the port id and try
  826. * again.
  827. */
  828. remote_fcport->d_id.b24 = inuse_did.b24;
  829. iodesc->d_id.b24 = inuse_did.b24;
  830. } else {
  831. remote_fcport->loop_id++;
  832. rval = qla2x00_find_new_loop_id(ha,
  833. remote_fcport);
  834. if (rval == QLA_FUNCTION_FAILED) {
  835. /* No more loop ids. */
  836. return (QLA_SUCCESS);
  837. }
  838. }
  839. } else if (mb[0] == MBS_PORT_ID_USED) {
  840. /*
  841. * Device has another loop ID. The firmware
  842. * group recommends the driver perform an
  843. * implicit login with the specified ID.
  844. */
  845. DEBUG14(printk("scsi(%ld): Login IOCB -- port "
  846. "id [%02x%02x%02x] already assigned to "
  847. "loop id [%x].\n", ha->host_no,
  848. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  849. iodesc->d_id.b.al_pa, mb[1]));
  850. remote_fcport->loop_id = mb[1];
  851. } else {
  852. /* Unable to perform login, try again. */
  853. DEBUG14(printk("scsi(%ld): Login IOCB -- "
  854. "failed login [%x/%02x%02x%02x], status=%x "
  855. "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
  856. ha->host_no, remote_fcport->loop_id,
  857. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  858. iodesc->d_id.b.al_pa, status, mb[0], mb[1],
  859. mb[2], mb[6], mb[7]));
  860. }
  861. /* Reissue Login with the same IO descriptor. */
  862. iodesc->signature =
  863. qla2x00_iodesc_to_handle(iodesc);
  864. iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
  865. iodesc->d_id.b24 = remote_fcport->d_id.b24;
  866. remote_fcport->iodesc_idx_sent = iodesc->idx;
  867. remote_fcport->login_retry--;
  868. DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
  869. "login to [%x/%02x%02x%02x] (%d).\n", ha->host_no,
  870. remote_fcport->loop_id,
  871. remote_fcport->d_id.b.domain,
  872. remote_fcport->d_id.b.area,
  873. remote_fcport->d_id.b.al_pa,
  874. remote_fcport->login_retry));
  875. qla2x00_send_login_iocb(ha, iodesc,
  876. &remote_fcport->d_id, 1);
  877. return (QLA_FUNCTION_FAILED);
  878. } else {
  879. /* No more logins, mark device dead. */
  880. DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
  881. "login [%x/%02x%02x%02x] after retries, status=%x "
  882. "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
  883. ha->host_no, remote_fcport->loop_id,
  884. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  885. iodesc->d_id.b.al_pa, status, mb[0], mb[1],
  886. mb[2], mb[6], mb[7]));
  887. atomic_set(&remote_fcport->state, FCS_DEVICE_DEAD);
  888. if (remote_fcport->port_type == FCT_RSCN) {
  889. DEBUG14(printk("scsi(%ld): Login IOCB -- "
  890. "Freeing dead RSCN fcport %p "
  891. "[%x/%02x%02x%02x].\n", ha->host_no,
  892. remote_fcport, remote_fcport->loop_id,
  893. remote_fcport->d_id.b.domain,
  894. remote_fcport->d_id.b.area,
  895. remote_fcport->d_id.b.al_pa));
  896. list_del(&remote_fcport->list);
  897. kfree(remote_fcport);
  898. }
  899. }
  900. }
  901. return (QLA_SUCCESS);
  902. }
  903. /**
  904. * IO descriptor processing routines.
  905. **/
  906. /**
  907. * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
  908. * @ha: HA context
  909. * @flags: allocation flags
  910. *
  911. * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
  912. */
  913. fc_port_t *
  914. qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, int flags)
  915. {
  916. fc_port_t *fcport;
  917. fcport = qla2x00_alloc_fcport(ha, flags);
  918. if (fcport == NULL)
  919. return (fcport);
  920. /* Setup RSCN fcport structure. */
  921. fcport->port_type = FCT_RSCN;
  922. return (fcport);
  923. }
  924. /**
  925. * qla2x00_handle_port_rscn() - Handle port RSCN.
  926. * @ha: HA context
  927. * @rscn_entry: RSCN entry
  928. * @fcport: fcport entry to updated
  929. *
  930. * Returns QLA_SUCCESS if the port RSCN was handled.
  931. */
  932. int
  933. qla2x00_handle_port_rscn(scsi_qla_host_t *ha, uint32_t rscn_entry,
  934. fc_port_t *known_fcport, int ha_locked)
  935. {
  936. int rval;
  937. port_id_t rscn_pid;
  938. fc_port_t *fcport, *remote_fcport, *rscn_fcport;
  939. struct io_descriptor *iodesc;
  940. remote_fcport = NULL;
  941. rscn_fcport = NULL;
  942. /* Prepare port id based on incoming entries. */
  943. if (known_fcport) {
  944. rscn_pid.b24 = known_fcport->d_id.b24;
  945. remote_fcport = known_fcport;
  946. DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
  947. "fcport [%02x%02x%02x].\n", ha->host_no,
  948. remote_fcport->d_id.b.domain, remote_fcport->d_id.b.area,
  949. remote_fcport->d_id.b.al_pa));
  950. } else {
  951. rscn_pid.b.domain = LSB(MSW(rscn_entry));
  952. rscn_pid.b.area = MSB(LSW(rscn_entry));
  953. rscn_pid.b.al_pa = LSB(LSW(rscn_entry));
  954. DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
  955. "port id [%02x%02x%02x].\n", ha->host_no,
  956. rscn_pid.b.domain, rscn_pid.b.area, rscn_pid.b.al_pa));
  957. /*
  958. * Search fcport lists for a known entry at the specified port
  959. * ID.
  960. */
  961. list_for_each_entry(fcport, &ha->fcports, list) {
  962. if (rscn_pid.b24 == fcport->d_id.b24) {
  963. remote_fcport = fcport;
  964. break;
  965. }
  966. }
  967. list_for_each_entry(fcport, &ha->rscn_fcports, list) {
  968. if (rscn_pid.b24 == fcport->d_id.b24) {
  969. rscn_fcport = fcport;
  970. break;
  971. }
  972. }
  973. if (remote_fcport == NULL)
  974. remote_fcport = rscn_fcport;
  975. }
  976. /*
  977. * If the port is already in our fcport list and online, send an ADISC
  978. * to see if it's still alive. Issue login if a new fcport or the known
  979. * fcport is currently offline.
  980. */
  981. if (remote_fcport) {
  982. /*
  983. * No need to send request if the remote fcport is currently
  984. * waiting for an available io descriptor.
  985. */
  986. if (known_fcport == NULL &&
  987. (remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
  988. remote_fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED)) {
  989. /*
  990. * If previous waiting io descriptor is an ADISC, then
  991. * the new RSCN may come from a new remote fcport being
  992. * plugged into the same location.
  993. */
  994. if (remote_fcport->port_type == FCT_RSCN) {
  995. remote_fcport->iodesc_idx_sent =
  996. IODESC_LOGIN_NEEDED;
  997. } else if (remote_fcport->iodesc_idx_sent ==
  998. IODESC_ADISC_NEEDED) {
  999. fc_port_t *new_fcport;
  1000. remote_fcport->iodesc_idx_sent =
  1001. IODESC_INVALID_INDEX;
  1002. /* Create new fcport for later login. */
  1003. new_fcport = qla2x00_alloc_rscn_fcport(ha,
  1004. ha_locked ? GFP_ATOMIC: GFP_KERNEL);
  1005. if (new_fcport) {
  1006. DEBUG14(printk("scsi(%ld): Handle RSCN "
  1007. "-- creating RSCN fcport %p for "
  1008. "future login.\n", ha->host_no,
  1009. new_fcport));
  1010. new_fcport->d_id.b24 =
  1011. remote_fcport->d_id.b24;
  1012. new_fcport->iodesc_idx_sent =
  1013. IODESC_LOGIN_NEEDED;
  1014. list_add_tail(&new_fcport->list,
  1015. &ha->rscn_fcports);
  1016. set_bit(IODESC_PROCESS_NEEDED,
  1017. &ha->dpc_flags);
  1018. } else {
  1019. DEBUG14(printk("scsi(%ld): Handle RSCN "
  1020. "-- unable to allocate RSCN fcport "
  1021. "for future login.\n",
  1022. ha->host_no));
  1023. }
  1024. }
  1025. return (QLA_SUCCESS);
  1026. }
  1027. /* Send ADISC if the fcport is online */
  1028. if (atomic_read(&remote_fcport->state) == FCS_ONLINE ||
  1029. remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED) {
  1030. atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
  1031. iodesc = qla2x00_alloc_iodesc(ha);
  1032. if (iodesc == NULL) {
  1033. /* Mark fcport for later adisc processing */
  1034. DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
  1035. "enough IO descriptors for Adisc, flag "
  1036. "for later processing.\n", ha->host_no));
  1037. remote_fcport->iodesc_idx_sent =
  1038. IODESC_ADISC_NEEDED;
  1039. set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
  1040. return (QLA_SUCCESS);
  1041. }
  1042. iodesc->cb_idx = ADISC_PORT_IOCB_CB;
  1043. iodesc->d_id.b24 = rscn_pid.b24;
  1044. iodesc->remote_fcport = remote_fcport;
  1045. remote_fcport->iodesc_idx_sent = iodesc->idx;
  1046. qla2x00_send_adisc_iocb(ha, iodesc, ha_locked);
  1047. return (QLA_SUCCESS);
  1048. } else if (remote_fcport->iodesc_idx_sent <
  1049. MAX_IO_DESCRIPTORS &&
  1050. ha->io_descriptors[remote_fcport->iodesc_idx_sent].cb_idx ==
  1051. ADISC_PORT_IOCB_CB) {
  1052. /*
  1053. * Receiving another RSCN while an ADISC is pending,
  1054. * abort the IOCB. Use the same descriptor for the
  1055. * abort.
  1056. */
  1057. uint32_t handle_to_abort;
  1058. iodesc = &ha->io_descriptors[
  1059. remote_fcport->iodesc_idx_sent];
  1060. qla2x00_remove_iodesc_timer(iodesc);
  1061. handle_to_abort = iodesc->signature;
  1062. iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
  1063. iodesc->cb_idx = ABORT_IOCB_CB;
  1064. iodesc->d_id.b24 = remote_fcport->d_id.b24;
  1065. iodesc->remote_fcport = remote_fcport;
  1066. remote_fcport->iodesc_idx_sent = iodesc->idx;
  1067. DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
  1068. "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
  1069. ha->host_no, remote_fcport->loop_id,
  1070. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  1071. iodesc->d_id.b.al_pa));
  1072. qla2x00_send_abort_iocb(ha, iodesc, handle_to_abort,
  1073. ha_locked);
  1074. }
  1075. }
  1076. /* We need to login to the remote port, find it. */
  1077. if (known_fcport) {
  1078. remote_fcport = known_fcport;
  1079. } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
  1080. rscn_fcport->iodesc_idx_sent < MAX_IO_DESCRIPTORS &&
  1081. ha->io_descriptors[rscn_fcport->iodesc_idx_sent].cb_idx ==
  1082. LOGIN_PORT_IOCB_CB) {
  1083. /*
  1084. * Ignore duplicate RSCN on fcport which has already
  1085. * initiated a login IOCB.
  1086. */
  1087. DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
  1088. "already sent to [%02x%02x%02x].\n", ha->host_no,
  1089. rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
  1090. rscn_fcport->d_id.b.al_pa));
  1091. return (QLA_SUCCESS);
  1092. } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
  1093. rscn_fcport != remote_fcport) {
  1094. /* Reuse same rscn fcport. */
  1095. DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
  1096. "[%02x%02x%02x].\n", ha->host_no,
  1097. rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
  1098. rscn_fcport->d_id.b.al_pa));
  1099. remote_fcport = rscn_fcport;
  1100. } else {
  1101. /* Create new fcport for later login. */
  1102. remote_fcport = qla2x00_alloc_rscn_fcport(ha,
  1103. ha_locked ? GFP_ATOMIC: GFP_KERNEL);
  1104. list_add_tail(&remote_fcport->list, &ha->rscn_fcports);
  1105. }
  1106. if (remote_fcport == NULL)
  1107. return (QLA_SUCCESS);
  1108. /* Prepare fcport for login. */
  1109. atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
  1110. remote_fcport->login_retry = 3; /* ha->login_retry_count; */
  1111. remote_fcport->d_id.b24 = rscn_pid.b24;
  1112. iodesc = qla2x00_alloc_iodesc(ha);
  1113. if (iodesc == NULL) {
  1114. /* Mark fcport for later adisc processing. */
  1115. DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
  1116. "descriptors for Login, flag for later processing.\n",
  1117. ha->host_no));
  1118. remote_fcport->iodesc_idx_sent = IODESC_LOGIN_NEEDED;
  1119. set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
  1120. return (QLA_SUCCESS);
  1121. }
  1122. if (known_fcport == NULL || rscn_pid.b24 != INVALID_PORT_ID) {
  1123. remote_fcport->loop_id = ha->min_external_loopid;
  1124. rval = qla2x00_find_new_loop_id(ha, remote_fcport);
  1125. if (rval == QLA_FUNCTION_FAILED) {
  1126. /* No more loop ids, failed. */
  1127. DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
  1128. "loop id to perform Login, failed.\n",
  1129. ha->host_no));
  1130. return (rval);
  1131. }
  1132. }
  1133. iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
  1134. iodesc->d_id.b24 = rscn_pid.b24;
  1135. iodesc->remote_fcport = remote_fcport;
  1136. remote_fcport->iodesc_idx_sent = iodesc->idx;
  1137. DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
  1138. "[%x/%02x%02x%02x].\n", ha->host_no, remote_fcport->loop_id,
  1139. iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa));
  1140. qla2x00_send_login_iocb(ha, iodesc, &rscn_pid, ha_locked);
  1141. return (QLA_SUCCESS);
  1142. }
  1143. /**
  1144. * qla2x00_process_iodesc() - Complete IO descriptor processing.
  1145. * @ha: HA context
  1146. * @mbxstat: Mailbox IOCB status
  1147. */
  1148. void
  1149. qla2x00_process_iodesc(scsi_qla_host_t *ha, struct mbx_entry *mbxstat)
  1150. {
  1151. int rval;
  1152. uint32_t signature;
  1153. fc_port_t *fcport;
  1154. struct io_descriptor *iodesc;
  1155. signature = mbxstat->handle;
  1156. DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
  1157. ha->host_no, signature));
  1158. /* Retrieve proper IO descriptor. */
  1159. iodesc = qla2x00_handle_to_iodesc(ha, signature);
  1160. if (iodesc == NULL) {
  1161. DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
  1162. "incorrect signature %08x.\n", ha->host_no, signature));
  1163. return;
  1164. }
  1165. /* Stop IO descriptor timer. */
  1166. qla2x00_remove_iodesc_timer(iodesc);
  1167. /* Verify signature match. */
  1168. if (iodesc->signature != signature) {
  1169. DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
  1170. "signature mismatch, sent %08x, received %08x.\n",
  1171. ha->host_no, iodesc->signature, signature));
  1172. return;
  1173. }
  1174. /* Go with IOCB callback. */
  1175. rval = iocb_function_cb_list[iodesc->cb_idx](ha, iodesc, mbxstat);
  1176. if (rval != QLA_SUCCESS) {
  1177. /* IO descriptor reused by callback. */
  1178. return;
  1179. }
  1180. qla2x00_free_iodesc(iodesc);
  1181. if (test_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags)) {
  1182. /* Scan our fcports list for any RSCN requests. */
  1183. list_for_each_entry(fcport, &ha->fcports, list) {
  1184. if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
  1185. fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
  1186. qla2x00_handle_port_rscn(ha, 0, fcport, 1);
  1187. return;
  1188. }
  1189. }
  1190. /* Scan our RSCN fcports list for any RSCN requests. */
  1191. list_for_each_entry(fcport, &ha->rscn_fcports, list) {
  1192. if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
  1193. fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
  1194. qla2x00_handle_port_rscn(ha, 0, fcport, 1);
  1195. return;
  1196. }
  1197. }
  1198. }
  1199. clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
  1200. }
  1201. /**
  1202. * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
  1203. * @ha: HA context
  1204. *
  1205. * This routine will also delete any RSCN entries related to the outstanding
  1206. * IO descriptors.
  1207. */
  1208. void
  1209. qla2x00_cancel_io_descriptors(scsi_qla_host_t *ha)
  1210. {
  1211. fc_port_t *fcport, *fcptemp;
  1212. clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
  1213. /* Abort all IO descriptors. */
  1214. qla2x00_init_io_descriptors(ha);
  1215. /* Reset all pending IO descriptors in fcports list. */
  1216. list_for_each_entry(fcport, &ha->fcports, list) {
  1217. fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
  1218. }
  1219. /* Reset all pending IO descriptors in rscn fcports list. */
  1220. list_for_each_entry_safe(fcport, fcptemp, &ha->rscn_fcports, list) {
  1221. DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
  1222. "%p [%x/%02x%02x%02x].\n", ha->host_no, fcport,
  1223. fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
  1224. fcport->d_id.b.al_pa));
  1225. list_del(&fcport->list);
  1226. kfree(fcport);
  1227. }
  1228. }