qla_rscn.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439
  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. if (fcport->rport)
  287. fc_remote_port_unblock(fcport->rport);
  288. }
  289. /**
  290. * Mailbox IOCB commands.
  291. **/
  292. /**
  293. * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
  294. * @ha: HA context
  295. * @handle: handle to io descriptor
  296. *
  297. * Returns a pointer to the reqest entry, or NULL, if none were available.
  298. */
  299. static inline struct mbx_entry *
  300. qla2x00_get_mbx_iocb_entry(scsi_qla_host_t *ha, uint32_t handle)
  301. {
  302. uint16_t cnt;
  303. struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
  304. struct mbx_entry *mbxentry;
  305. mbxentry = NULL;
  306. if (ha->req_q_cnt < 3) {
  307. cnt = qla2x00_debounce_register(ISP_REQ_Q_OUT(ha, reg));
  308. if (ha->req_ring_index < cnt)
  309. ha->req_q_cnt = cnt - ha->req_ring_index;
  310. else
  311. ha->req_q_cnt = ha->request_q_length -
  312. (ha->req_ring_index - cnt);
  313. }
  314. if (ha->req_q_cnt >= 3) {
  315. mbxentry = (struct mbx_entry *)ha->request_ring_ptr;
  316. memset(mbxentry, 0, sizeof(struct mbx_entry));
  317. mbxentry->entry_type = MBX_IOCB_TYPE;
  318. mbxentry->entry_count = 1;
  319. mbxentry->sys_define1 = SOURCE_ASYNC_IOCB;
  320. mbxentry->handle = handle;
  321. }
  322. return (mbxentry);
  323. }
  324. /**
  325. * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
  326. * @ha: HA context
  327. * @iodesc: io descriptor
  328. * @handle_to_abort: firmware handle to abort
  329. * @ha_locked: is function called with the hardware lock
  330. *
  331. * Returns QLA_SUCCESS if the IOCB was issued.
  332. */
  333. static int
  334. qla2x00_send_abort_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  335. uint32_t handle_to_abort, int ha_locked)
  336. {
  337. unsigned long flags = 0;
  338. struct mbx_entry *mbxentry;
  339. /* Send marker if required. */
  340. if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
  341. return (QLA_FUNCTION_FAILED);
  342. if (!ha_locked)
  343. spin_lock_irqsave(&ha->hardware_lock, flags);
  344. /* Build abort mailbox IOCB. */
  345. mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
  346. if (mbxentry == NULL) {
  347. if (!ha_locked)
  348. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  349. return (QLA_FUNCTION_FAILED);
  350. }
  351. mbxentry->mb0 = __constant_cpu_to_le16(MBC_ABORT_COMMAND);
  352. mbxentry->mb1 = mbxentry->loop_id.extended =
  353. cpu_to_le16(iodesc->remote_fcport->loop_id);
  354. mbxentry->mb2 = LSW(handle_to_abort);
  355. mbxentry->mb3 = MSW(handle_to_abort);
  356. wmb();
  357. qla2x00_add_iodesc_timer(iodesc);
  358. /* Issue command to ISP. */
  359. qla2x00_isp_cmd(ha);
  360. if (!ha_locked)
  361. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  362. DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
  363. "%08x.\n", ha->host_no, iodesc->signature,
  364. iodesc->remote_fcport->loop_id, handle_to_abort));
  365. return (QLA_SUCCESS);
  366. }
  367. /**
  368. * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
  369. * @ha: HA context
  370. * @iodesc: io descriptor
  371. * @mbxstat: mailbox status IOCB
  372. *
  373. * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
  374. * will be used for a retry.
  375. */
  376. static int
  377. qla2x00_send_abort_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  378. struct mbx_entry *mbxstat)
  379. {
  380. DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
  381. "status=%x mb0=%x.\n", ha->host_no, iodesc->remote_fcport->loop_id,
  382. iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa,
  383. le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
  384. return (QLA_SUCCESS);
  385. }
  386. /**
  387. * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
  388. * @ha: HA context
  389. * @iodesc: io descriptor
  390. * @ha_locked: is function called with the hardware lock
  391. *
  392. * Returns QLA_SUCCESS if the IOCB was issued.
  393. */
  394. static int
  395. qla2x00_send_adisc_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  396. int ha_locked)
  397. {
  398. unsigned long flags = 0;
  399. struct mbx_entry *mbxentry;
  400. /* Send marker if required. */
  401. if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
  402. return (QLA_FUNCTION_FAILED);
  403. if (!ha_locked)
  404. spin_lock_irqsave(&ha->hardware_lock, flags);
  405. /* Build Get Port Database IOCB. */
  406. mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
  407. if (mbxentry == NULL) {
  408. if (!ha_locked)
  409. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  410. return (QLA_FUNCTION_FAILED);
  411. }
  412. mbxentry->mb0 = __constant_cpu_to_le16(MBC_GET_PORT_DATABASE);
  413. mbxentry->mb1 = mbxentry->loop_id.extended =
  414. cpu_to_le16(iodesc->remote_fcport->loop_id);
  415. mbxentry->mb2 = cpu_to_le16(MSW(LSD(ha->iodesc_pd_dma)));
  416. mbxentry->mb3 = cpu_to_le16(LSW(LSD(ha->iodesc_pd_dma)));
  417. mbxentry->mb6 = cpu_to_le16(MSW(MSD(ha->iodesc_pd_dma)));
  418. mbxentry->mb7 = cpu_to_le16(LSW(MSD(ha->iodesc_pd_dma)));
  419. mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
  420. wmb();
  421. qla2x00_add_iodesc_timer(iodesc);
  422. /* Issue command to ISP. */
  423. qla2x00_isp_cmd(ha);
  424. if (!ha_locked)
  425. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  426. DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
  427. ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));
  428. return (QLA_SUCCESS);
  429. }
  430. /**
  431. * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
  432. * @ha: HA context
  433. * @iodesc: io descriptor
  434. * @mbxstat: mailbox status IOCB
  435. *
  436. * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
  437. * will be used for a retry.
  438. */
  439. static int
  440. qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  441. struct mbx_entry *mbxstat)
  442. {
  443. fc_port_t *remote_fcport;
  444. remote_fcport = iodesc->remote_fcport;
  445. /* Ensure the port IDs are consistent. */
  446. if (remote_fcport->d_id.b24 != iodesc->d_id.b24) {
  447. DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
  448. "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
  449. ha->host_no, remote_fcport->d_id.b.domain,
  450. remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
  451. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  452. iodesc->d_id.b.al_pa));
  453. return (QLA_SUCCESS);
  454. }
  455. /* Only process the last command. */
  456. if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
  457. DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
  458. "[%02x%02x%02x], expected %x, received %x.\n", ha->host_no,
  459. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  460. iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
  461. iodesc->idx));
  462. return (QLA_SUCCESS);
  463. }
  464. if (le16_to_cpu(mbxstat->status) == CS_COMPLETE) {
  465. DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
  466. "[%x/%02x%02x%02x] online.\n", ha->host_no,
  467. remote_fcport->loop_id, remote_fcport->d_id.b.domain,
  468. remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
  469. atomic_set(&remote_fcport->state, FCS_ONLINE);
  470. } else {
  471. DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
  472. "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha->host_no,
  473. remote_fcport->loop_id, remote_fcport->d_id.b.domain,
  474. remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
  475. le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
  476. if (atomic_read(&remote_fcport->state) != FCS_DEVICE_DEAD)
  477. atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
  478. }
  479. remote_fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
  480. return (QLA_SUCCESS);
  481. }
  482. /**
  483. * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
  484. * @ha: HA context
  485. * @iodesc: io descriptor
  486. * @ha_locked: is function called with the hardware lock
  487. *
  488. * Returns QLA_SUCCESS if the IOCB was issued.
  489. */
  490. static int
  491. qla2x00_send_logout_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  492. int ha_locked)
  493. {
  494. unsigned long flags = 0;
  495. struct mbx_entry *mbxentry;
  496. /* Send marker if required. */
  497. if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
  498. return (QLA_FUNCTION_FAILED);
  499. if (!ha_locked)
  500. spin_lock_irqsave(&ha->hardware_lock, flags);
  501. /* Build fabric port logout mailbox IOCB. */
  502. mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
  503. if (mbxentry == NULL) {
  504. if (!ha_locked)
  505. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  506. return (QLA_FUNCTION_FAILED);
  507. }
  508. mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
  509. mbxentry->mb1 = mbxentry->loop_id.extended =
  510. cpu_to_le16(iodesc->remote_fcport->loop_id);
  511. wmb();
  512. qla2x00_add_iodesc_timer(iodesc);
  513. /* Issue command to ISP. */
  514. qla2x00_isp_cmd(ha);
  515. if (!ha_locked)
  516. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  517. DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",
  518. ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));
  519. return (QLA_SUCCESS);
  520. }
  521. /**
  522. * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback.
  523. * @ha: HA context
  524. * @iodesc: io descriptor
  525. * @mbxstat: mailbox status IOCB
  526. *
  527. * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
  528. * will be used for a retry.
  529. */
  530. static int
  531. qla2x00_send_logout_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  532. struct mbx_entry *mbxstat)
  533. {
  534. DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "
  535. "status=%x mb0=%x mb1=%x.\n", ha->host_no,
  536. iodesc->remote_fcport->loop_id,
  537. iodesc->remote_fcport->d_id.b.domain,
  538. iodesc->remote_fcport->d_id.b.area,
  539. iodesc->remote_fcport->d_id.b.al_pa, le16_to_cpu(mbxstat->status),
  540. le16_to_cpu(mbxstat->mb0), le16_to_cpu(mbxstat->mb1)));
  541. return (QLA_SUCCESS);
  542. }
  543. /**
  544. * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware.
  545. * @ha: HA context
  546. * @iodesc: io descriptor
  547. * @d_id: port id for device
  548. * @ha_locked: is function called with the hardware lock
  549. *
  550. * Returns QLA_SUCCESS if the IOCB was issued.
  551. */
  552. static int
  553. qla2x00_send_login_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  554. port_id_t *d_id, int ha_locked)
  555. {
  556. unsigned long flags = 0;
  557. struct mbx_entry *mbxentry;
  558. /* Send marker if required. */
  559. if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
  560. return (QLA_FUNCTION_FAILED);
  561. if (!ha_locked)
  562. spin_lock_irqsave(&ha->hardware_lock, flags);
  563. /* Build fabric port login mailbox IOCB. */
  564. mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
  565. if (mbxentry == NULL) {
  566. if (!ha_locked)
  567. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  568. return (QLA_FUNCTION_FAILED);
  569. }
  570. mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT);
  571. mbxentry->mb1 = mbxentry->loop_id.extended =
  572. cpu_to_le16(iodesc->remote_fcport->loop_id);
  573. mbxentry->mb2 = cpu_to_le16(d_id->b.domain);
  574. mbxentry->mb3 = cpu_to_le16(d_id->b.area << 8 | d_id->b.al_pa);
  575. mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
  576. wmb();
  577. qla2x00_add_iodesc_timer(iodesc);
  578. /* Issue command to ISP. */
  579. qla2x00_isp_cmd(ha);
  580. if (!ha_locked)
  581. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  582. DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
  583. "[%x/%02x%02x%02x].\n", ha->host_no, iodesc->signature,
  584. iodesc->remote_fcport->loop_id, d_id->b.domain, d_id->b.area,
  585. d_id->b.al_pa));
  586. return (QLA_SUCCESS);
  587. }
  588. /**
  589. * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
  590. * @ha: HA context
  591. * @iodesc: io descriptor
  592. * @mbxstat: mailbox status IOCB
  593. *
  594. * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
  595. * will be used for a retry.
  596. */
  597. static int
  598. qla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
  599. struct mbx_entry *mbxstat)
  600. {
  601. int rval;
  602. fc_port_t *fcport, *remote_fcport, *exist_fcport;
  603. struct io_descriptor *abort_iodesc, *login_iodesc;
  604. uint16_t status, mb[8];
  605. uint16_t reuse;
  606. uint16_t remote_loopid;
  607. port_id_t remote_did, inuse_did;
  608. remote_fcport = iodesc->remote_fcport;
  609. /* Only process the last command. */
  610. if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
  611. DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
  612. "[%02x%02x%02x], expected %x, received %x.\n",
  613. ha->host_no, iodesc->d_id.b.domain, iodesc->d_id.b.area,
  614. iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
  615. iodesc->idx));
  616. /* Free RSCN fcport resources. */
  617. if (remote_fcport->port_type == FCT_RSCN) {
  618. DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
  619. "fcport %p [%x/%02x%02x%02x] given ignored Login "
  620. "IOCB.\n", ha->host_no, remote_fcport,
  621. remote_fcport->loop_id,
  622. remote_fcport->d_id.b.domain,
  623. remote_fcport->d_id.b.area,
  624. remote_fcport->d_id.b.al_pa));
  625. list_del(&remote_fcport->list);
  626. kfree(remote_fcport);
  627. }
  628. return (QLA_SUCCESS);
  629. }
  630. status = le16_to_cpu(mbxstat->status);
  631. mb[0] = le16_to_cpu(mbxstat->mb0);
  632. mb[1] = le16_to_cpu(mbxstat->mb1);
  633. mb[2] = le16_to_cpu(mbxstat->mb2);
  634. mb[6] = le16_to_cpu(mbxstat->mb6);
  635. mb[7] = le16_to_cpu(mbxstat->mb7);
  636. /* Good status? */
  637. if ((status == CS_COMPLETE || status == CS_COMPLETE_CHKCOND) &&
  638. mb[0] == MBS_COMMAND_COMPLETE) {
  639. DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
  640. "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha->host_no, status,
  641. mb[1], mbxstat->port_name[0], mbxstat->port_name[1],
  642. mbxstat->port_name[2], mbxstat->port_name[3],
  643. mbxstat->port_name[4], mbxstat->port_name[5],
  644. mbxstat->port_name[6], mbxstat->port_name[7]));
  645. memcpy(remote_fcport->node_name, mbxstat->node_name, WWN_SIZE);
  646. memcpy(remote_fcport->port_name, mbxstat->port_name, WWN_SIZE);
  647. /* Is the device already in our fcports list? */
  648. if (remote_fcport->port_type != FCT_RSCN) {
  649. DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
  650. "[%x/%02x%02x%02x] online.\n", ha->host_no,
  651. remote_fcport->loop_id,
  652. remote_fcport->d_id.b.domain,
  653. remote_fcport->d_id.b.area,
  654. remote_fcport->d_id.b.al_pa));
  655. qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
  656. return (QLA_SUCCESS);
  657. }
  658. /* Does the RSCN portname already exist in our fcports list? */
  659. exist_fcport = NULL;
  660. list_for_each_entry(fcport, &ha->fcports, list) {
  661. if (memcmp(remote_fcport->port_name, fcport->port_name,
  662. WWN_SIZE) == 0) {
  663. exist_fcport = fcport;
  664. break;
  665. }
  666. }
  667. if (exist_fcport != NULL) {
  668. DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
  669. "fcport in fcports list [%p].\n", ha->host_no,
  670. exist_fcport));
  671. /* Abort any ADISC that could have been sent. */
  672. if (exist_fcport->iodesc_idx_sent != iodesc->idx &&
  673. exist_fcport->iodesc_idx_sent <
  674. MAX_IO_DESCRIPTORS &&
  675. ha->io_descriptors[exist_fcport->iodesc_idx_sent].
  676. cb_idx == ADISC_PORT_IOCB_CB) {
  677. abort_iodesc = qla2x00_alloc_iodesc(ha);
  678. if (abort_iodesc) {
  679. DEBUG14(printk("scsi(%ld): Login IOCB "
  680. "-- issuing abort to outstanding "
  681. "Adisc [%x/%02x%02x%02x].\n",
  682. ha->host_no, remote_fcport->loop_id,
  683. exist_fcport->d_id.b.domain,
  684. exist_fcport->d_id.b.area,
  685. exist_fcport->d_id.b.al_pa));
  686. abort_iodesc->cb_idx = ABORT_IOCB_CB;
  687. abort_iodesc->d_id.b24 =
  688. exist_fcport->d_id.b24;
  689. abort_iodesc->remote_fcport =
  690. exist_fcport;
  691. exist_fcport->iodesc_idx_sent =
  692. abort_iodesc->idx;
  693. qla2x00_send_abort_iocb(ha,
  694. abort_iodesc, ha->io_descriptors[
  695. exist_fcport->iodesc_idx_sent].
  696. signature, 1);
  697. } else {
  698. DEBUG14(printk("scsi(%ld): Login IOCB "
  699. "-- unable to abort outstanding "
  700. "Adisc [%x/%02x%02x%02x].\n",
  701. ha->host_no, remote_fcport->loop_id,
  702. exist_fcport->d_id.b.domain,
  703. exist_fcport->d_id.b.area,
  704. exist_fcport->d_id.b.al_pa));
  705. }
  706. }
  707. /*
  708. * If the existing fcport is waiting to send an ADISC
  709. * or LOGIN, then reuse remote fcport (RSCN) to
  710. * continue waiting.
  711. */
  712. reuse = 0;
  713. remote_loopid = remote_fcport->loop_id;
  714. remote_did.b24 = remote_fcport->d_id.b24;
  715. if (exist_fcport->iodesc_idx_sent ==
  716. IODESC_ADISC_NEEDED ||
  717. exist_fcport->iodesc_idx_sent ==
  718. IODESC_LOGIN_NEEDED) {
  719. DEBUG14(printk("scsi(%ld): Login IOCB -- "
  720. "existing fcport [%x/%02x%02x%02x] "
  721. "waiting for IO descriptor, reuse RSCN "
  722. "fcport.\n", ha->host_no,
  723. exist_fcport->loop_id,
  724. exist_fcport->d_id.b.domain,
  725. exist_fcport->d_id.b.area,
  726. exist_fcport->d_id.b.al_pa));
  727. reuse++;
  728. remote_fcport->iodesc_idx_sent =
  729. exist_fcport->iodesc_idx_sent;
  730. exist_fcport->iodesc_idx_sent =
  731. IODESC_INVALID_INDEX;
  732. remote_fcport->loop_id = exist_fcport->loop_id;
  733. remote_fcport->d_id.b24 =
  734. exist_fcport->d_id.b24;
  735. }
  736. /* Logout the old loopid. */
  737. if (!reuse &&
  738. exist_fcport->loop_id != remote_fcport->loop_id &&
  739. exist_fcport->loop_id != FC_NO_LOOP_ID) {
  740. login_iodesc = qla2x00_alloc_iodesc(ha);
  741. if (login_iodesc) {
  742. DEBUG14(printk("scsi(%ld): Login IOCB "
  743. "-- issuing logout to free old "
  744. "loop id [%x/%02x%02x%02x].\n",
  745. ha->host_no, exist_fcport->loop_id,
  746. exist_fcport->d_id.b.domain,
  747. exist_fcport->d_id.b.area,
  748. exist_fcport->d_id.b.al_pa));
  749. login_iodesc->cb_idx =
  750. LOGOUT_PORT_IOCB_CB;
  751. login_iodesc->d_id.b24 =
  752. exist_fcport->d_id.b24;
  753. login_iodesc->remote_fcport =
  754. exist_fcport;
  755. exist_fcport->iodesc_idx_sent =
  756. login_iodesc->idx;
  757. qla2x00_send_logout_iocb(ha,
  758. login_iodesc, 1);
  759. } else {
  760. /* Ran out of IO descriptiors. */
  761. DEBUG14(printk("scsi(%ld): Login IOCB "
  762. "-- unable to logout to free old "
  763. "loop id [%x/%02x%02x%02x].\n",
  764. ha->host_no, exist_fcport->loop_id,
  765. exist_fcport->d_id.b.domain,
  766. exist_fcport->d_id.b.area,
  767. exist_fcport->d_id.b.al_pa));
  768. exist_fcport->iodesc_idx_sent =
  769. IODESC_INVALID_INDEX;
  770. }
  771. }
  772. /* Update existing fcport with remote fcport info. */
  773. DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
  774. "existing fcport [%x/%02x%02x%02x] online.\n",
  775. ha->host_no, remote_loopid, remote_did.b.domain,
  776. remote_did.b.area, remote_did.b.al_pa));
  777. memcpy(exist_fcport->node_name,
  778. remote_fcport->node_name, WWN_SIZE);
  779. exist_fcport->loop_id = remote_loopid;
  780. exist_fcport->d_id.b24 = remote_did.b24;
  781. qla2x00_update_login_fcport(ha, mbxstat, exist_fcport);
  782. /* Finally, free the remote (RSCN) fcport. */
  783. if (!reuse) {
  784. DEBUG14(printk("scsi(%ld): Login IOCB -- "
  785. "Freeing RSCN fcport %p "
  786. "[%x/%02x%02x%02x].\n", ha->host_no,
  787. remote_fcport, remote_fcport->loop_id,
  788. remote_fcport->d_id.b.domain,
  789. remote_fcport->d_id.b.area,
  790. remote_fcport->d_id.b.al_pa));
  791. list_del(&remote_fcport->list);
  792. kfree(remote_fcport);
  793. }
  794. return (QLA_SUCCESS);
  795. }
  796. /*
  797. * A new device has been added, move the RSCN fcport to our
  798. * fcports list.
  799. */
  800. DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
  801. "[%x/%02x%02x%02x] to fcports list.\n", ha->host_no,
  802. remote_fcport->loop_id, remote_fcport->d_id.b.domain,
  803. remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
  804. list_del(&remote_fcport->list);
  805. remote_fcport->flags = (FCF_RLC_SUPPORT | FCF_RESCAN_NEEDED);
  806. qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
  807. list_add_tail(&remote_fcport->list, &ha->fcports);
  808. set_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags);
  809. } else {
  810. /* Handle login failure. */
  811. if (remote_fcport->login_retry != 0) {
  812. if (mb[0] == MBS_LOOP_ID_USED) {
  813. inuse_did.b.domain = LSB(mb[1]);
  814. inuse_did.b.area = MSB(mb[2]);
  815. inuse_did.b.al_pa = LSB(mb[2]);
  816. DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
  817. "id [%x] used by port id [%02x%02x%02x].\n",
  818. ha->host_no, remote_fcport->loop_id,
  819. inuse_did.b.domain, inuse_did.b.area,
  820. inuse_did.b.al_pa));
  821. if (remote_fcport->d_id.b24 ==
  822. INVALID_PORT_ID) {
  823. /*
  824. * Invalid port id means we are trying
  825. * to login to a remote port with just
  826. * a loop id without knowing about the
  827. * port id. Copy the port id and try
  828. * again.
  829. */
  830. remote_fcport->d_id.b24 = inuse_did.b24;
  831. iodesc->d_id.b24 = inuse_did.b24;
  832. } else {
  833. remote_fcport->loop_id++;
  834. rval = qla2x00_find_new_loop_id(ha,
  835. remote_fcport);
  836. if (rval == QLA_FUNCTION_FAILED) {
  837. /* No more loop ids. */
  838. return (QLA_SUCCESS);
  839. }
  840. }
  841. } else if (mb[0] == MBS_PORT_ID_USED) {
  842. /*
  843. * Device has another loop ID. The firmware
  844. * group recommends the driver perform an
  845. * implicit login with the specified ID.
  846. */
  847. DEBUG14(printk("scsi(%ld): Login IOCB -- port "
  848. "id [%02x%02x%02x] already assigned to "
  849. "loop id [%x].\n", ha->host_no,
  850. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  851. iodesc->d_id.b.al_pa, mb[1]));
  852. remote_fcport->loop_id = mb[1];
  853. } else {
  854. /* Unable to perform login, try again. */
  855. DEBUG14(printk("scsi(%ld): Login IOCB -- "
  856. "failed login [%x/%02x%02x%02x], status=%x "
  857. "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
  858. ha->host_no, remote_fcport->loop_id,
  859. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  860. iodesc->d_id.b.al_pa, status, mb[0], mb[1],
  861. mb[2], mb[6], mb[7]));
  862. }
  863. /* Reissue Login with the same IO descriptor. */
  864. iodesc->signature =
  865. qla2x00_iodesc_to_handle(iodesc);
  866. iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
  867. iodesc->d_id.b24 = remote_fcport->d_id.b24;
  868. remote_fcport->iodesc_idx_sent = iodesc->idx;
  869. remote_fcport->login_retry--;
  870. DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
  871. "login to [%x/%02x%02x%02x] (%d).\n", ha->host_no,
  872. remote_fcport->loop_id,
  873. remote_fcport->d_id.b.domain,
  874. remote_fcport->d_id.b.area,
  875. remote_fcport->d_id.b.al_pa,
  876. remote_fcport->login_retry));
  877. qla2x00_send_login_iocb(ha, iodesc,
  878. &remote_fcport->d_id, 1);
  879. return (QLA_FUNCTION_FAILED);
  880. } else {
  881. /* No more logins, mark device dead. */
  882. DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
  883. "login [%x/%02x%02x%02x] after retries, status=%x "
  884. "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
  885. ha->host_no, remote_fcport->loop_id,
  886. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  887. iodesc->d_id.b.al_pa, status, mb[0], mb[1],
  888. mb[2], mb[6], mb[7]));
  889. atomic_set(&remote_fcport->state, FCS_DEVICE_DEAD);
  890. if (remote_fcport->port_type == FCT_RSCN) {
  891. DEBUG14(printk("scsi(%ld): Login IOCB -- "
  892. "Freeing dead RSCN fcport %p "
  893. "[%x/%02x%02x%02x].\n", ha->host_no,
  894. remote_fcport, remote_fcport->loop_id,
  895. remote_fcport->d_id.b.domain,
  896. remote_fcport->d_id.b.area,
  897. remote_fcport->d_id.b.al_pa));
  898. list_del(&remote_fcport->list);
  899. kfree(remote_fcport);
  900. }
  901. }
  902. }
  903. return (QLA_SUCCESS);
  904. }
  905. /**
  906. * IO descriptor processing routines.
  907. **/
  908. /**
  909. * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
  910. * @ha: HA context
  911. * @flags: allocation flags
  912. *
  913. * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
  914. */
  915. fc_port_t *
  916. qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, gfp_t flags)
  917. {
  918. fc_port_t *fcport;
  919. fcport = qla2x00_alloc_fcport(ha, flags);
  920. if (fcport == NULL)
  921. return (fcport);
  922. /* Setup RSCN fcport structure. */
  923. fcport->port_type = FCT_RSCN;
  924. return (fcport);
  925. }
  926. /**
  927. * qla2x00_handle_port_rscn() - Handle port RSCN.
  928. * @ha: HA context
  929. * @rscn_entry: RSCN entry
  930. * @fcport: fcport entry to updated
  931. *
  932. * Returns QLA_SUCCESS if the port RSCN was handled.
  933. */
  934. int
  935. qla2x00_handle_port_rscn(scsi_qla_host_t *ha, uint32_t rscn_entry,
  936. fc_port_t *known_fcport, int ha_locked)
  937. {
  938. int rval;
  939. port_id_t rscn_pid;
  940. fc_port_t *fcport, *remote_fcport, *rscn_fcport;
  941. struct io_descriptor *iodesc;
  942. remote_fcport = NULL;
  943. rscn_fcport = NULL;
  944. /* Prepare port id based on incoming entries. */
  945. if (known_fcport) {
  946. rscn_pid.b24 = known_fcport->d_id.b24;
  947. remote_fcport = known_fcport;
  948. DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
  949. "fcport [%02x%02x%02x].\n", ha->host_no,
  950. remote_fcport->d_id.b.domain, remote_fcport->d_id.b.area,
  951. remote_fcport->d_id.b.al_pa));
  952. } else {
  953. rscn_pid.b.domain = LSB(MSW(rscn_entry));
  954. rscn_pid.b.area = MSB(LSW(rscn_entry));
  955. rscn_pid.b.al_pa = LSB(LSW(rscn_entry));
  956. DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
  957. "port id [%02x%02x%02x].\n", ha->host_no,
  958. rscn_pid.b.domain, rscn_pid.b.area, rscn_pid.b.al_pa));
  959. /*
  960. * Search fcport lists for a known entry at the specified port
  961. * ID.
  962. */
  963. list_for_each_entry(fcport, &ha->fcports, list) {
  964. if (rscn_pid.b24 == fcport->d_id.b24) {
  965. remote_fcport = fcport;
  966. break;
  967. }
  968. }
  969. list_for_each_entry(fcport, &ha->rscn_fcports, list) {
  970. if (rscn_pid.b24 == fcport->d_id.b24) {
  971. rscn_fcport = fcport;
  972. break;
  973. }
  974. }
  975. if (remote_fcport == NULL)
  976. remote_fcport = rscn_fcport;
  977. }
  978. /*
  979. * If the port is already in our fcport list and online, send an ADISC
  980. * to see if it's still alive. Issue login if a new fcport or the known
  981. * fcport is currently offline.
  982. */
  983. if (remote_fcport) {
  984. /*
  985. * No need to send request if the remote fcport is currently
  986. * waiting for an available io descriptor.
  987. */
  988. if (known_fcport == NULL &&
  989. (remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
  990. remote_fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED)) {
  991. /*
  992. * If previous waiting io descriptor is an ADISC, then
  993. * the new RSCN may come from a new remote fcport being
  994. * plugged into the same location.
  995. */
  996. if (remote_fcport->port_type == FCT_RSCN) {
  997. remote_fcport->iodesc_idx_sent =
  998. IODESC_LOGIN_NEEDED;
  999. } else if (remote_fcport->iodesc_idx_sent ==
  1000. IODESC_ADISC_NEEDED) {
  1001. fc_port_t *new_fcport;
  1002. remote_fcport->iodesc_idx_sent =
  1003. IODESC_INVALID_INDEX;
  1004. /* Create new fcport for later login. */
  1005. new_fcport = qla2x00_alloc_rscn_fcport(ha,
  1006. ha_locked ? GFP_ATOMIC: GFP_KERNEL);
  1007. if (new_fcport) {
  1008. DEBUG14(printk("scsi(%ld): Handle RSCN "
  1009. "-- creating RSCN fcport %p for "
  1010. "future login.\n", ha->host_no,
  1011. new_fcport));
  1012. new_fcport->d_id.b24 =
  1013. remote_fcport->d_id.b24;
  1014. new_fcport->iodesc_idx_sent =
  1015. IODESC_LOGIN_NEEDED;
  1016. list_add_tail(&new_fcport->list,
  1017. &ha->rscn_fcports);
  1018. set_bit(IODESC_PROCESS_NEEDED,
  1019. &ha->dpc_flags);
  1020. } else {
  1021. DEBUG14(printk("scsi(%ld): Handle RSCN "
  1022. "-- unable to allocate RSCN fcport "
  1023. "for future login.\n",
  1024. ha->host_no));
  1025. }
  1026. }
  1027. return (QLA_SUCCESS);
  1028. }
  1029. /* Send ADISC if the fcport is online */
  1030. if (atomic_read(&remote_fcport->state) == FCS_ONLINE ||
  1031. remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED) {
  1032. atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
  1033. iodesc = qla2x00_alloc_iodesc(ha);
  1034. if (iodesc == NULL) {
  1035. /* Mark fcport for later adisc processing */
  1036. DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
  1037. "enough IO descriptors for Adisc, flag "
  1038. "for later processing.\n", ha->host_no));
  1039. remote_fcport->iodesc_idx_sent =
  1040. IODESC_ADISC_NEEDED;
  1041. set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
  1042. return (QLA_SUCCESS);
  1043. }
  1044. iodesc->cb_idx = ADISC_PORT_IOCB_CB;
  1045. iodesc->d_id.b24 = rscn_pid.b24;
  1046. iodesc->remote_fcport = remote_fcport;
  1047. remote_fcport->iodesc_idx_sent = iodesc->idx;
  1048. qla2x00_send_adisc_iocb(ha, iodesc, ha_locked);
  1049. return (QLA_SUCCESS);
  1050. } else if (remote_fcport->iodesc_idx_sent <
  1051. MAX_IO_DESCRIPTORS &&
  1052. ha->io_descriptors[remote_fcport->iodesc_idx_sent].cb_idx ==
  1053. ADISC_PORT_IOCB_CB) {
  1054. /*
  1055. * Receiving another RSCN while an ADISC is pending,
  1056. * abort the IOCB. Use the same descriptor for the
  1057. * abort.
  1058. */
  1059. uint32_t handle_to_abort;
  1060. iodesc = &ha->io_descriptors[
  1061. remote_fcport->iodesc_idx_sent];
  1062. qla2x00_remove_iodesc_timer(iodesc);
  1063. handle_to_abort = iodesc->signature;
  1064. iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
  1065. iodesc->cb_idx = ABORT_IOCB_CB;
  1066. iodesc->d_id.b24 = remote_fcport->d_id.b24;
  1067. iodesc->remote_fcport = remote_fcport;
  1068. remote_fcport->iodesc_idx_sent = iodesc->idx;
  1069. DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
  1070. "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
  1071. ha->host_no, remote_fcport->loop_id,
  1072. iodesc->d_id.b.domain, iodesc->d_id.b.area,
  1073. iodesc->d_id.b.al_pa));
  1074. qla2x00_send_abort_iocb(ha, iodesc, handle_to_abort,
  1075. ha_locked);
  1076. }
  1077. }
  1078. /* We need to login to the remote port, find it. */
  1079. if (known_fcport) {
  1080. remote_fcport = known_fcport;
  1081. } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
  1082. rscn_fcport->iodesc_idx_sent < MAX_IO_DESCRIPTORS &&
  1083. ha->io_descriptors[rscn_fcport->iodesc_idx_sent].cb_idx ==
  1084. LOGIN_PORT_IOCB_CB) {
  1085. /*
  1086. * Ignore duplicate RSCN on fcport which has already
  1087. * initiated a login IOCB.
  1088. */
  1089. DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
  1090. "already sent to [%02x%02x%02x].\n", ha->host_no,
  1091. rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
  1092. rscn_fcport->d_id.b.al_pa));
  1093. return (QLA_SUCCESS);
  1094. } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
  1095. rscn_fcport != remote_fcport) {
  1096. /* Reuse same rscn fcport. */
  1097. DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
  1098. "[%02x%02x%02x].\n", ha->host_no,
  1099. rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
  1100. rscn_fcport->d_id.b.al_pa));
  1101. remote_fcport = rscn_fcport;
  1102. } else {
  1103. /* Create new fcport for later login. */
  1104. remote_fcport = qla2x00_alloc_rscn_fcport(ha,
  1105. ha_locked ? GFP_ATOMIC: GFP_KERNEL);
  1106. list_add_tail(&remote_fcport->list, &ha->rscn_fcports);
  1107. }
  1108. if (remote_fcport == NULL)
  1109. return (QLA_SUCCESS);
  1110. /* Prepare fcport for login. */
  1111. atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
  1112. remote_fcport->login_retry = 3; /* ha->login_retry_count; */
  1113. remote_fcport->d_id.b24 = rscn_pid.b24;
  1114. iodesc = qla2x00_alloc_iodesc(ha);
  1115. if (iodesc == NULL) {
  1116. /* Mark fcport for later adisc processing. */
  1117. DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
  1118. "descriptors for Login, flag for later processing.\n",
  1119. ha->host_no));
  1120. remote_fcport->iodesc_idx_sent = IODESC_LOGIN_NEEDED;
  1121. set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
  1122. return (QLA_SUCCESS);
  1123. }
  1124. if (known_fcport == NULL || rscn_pid.b24 != INVALID_PORT_ID) {
  1125. remote_fcport->loop_id = ha->min_external_loopid;
  1126. rval = qla2x00_find_new_loop_id(ha, remote_fcport);
  1127. if (rval == QLA_FUNCTION_FAILED) {
  1128. /* No more loop ids, failed. */
  1129. DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
  1130. "loop id to perform Login, failed.\n",
  1131. ha->host_no));
  1132. return (rval);
  1133. }
  1134. }
  1135. iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
  1136. iodesc->d_id.b24 = rscn_pid.b24;
  1137. iodesc->remote_fcport = remote_fcport;
  1138. remote_fcport->iodesc_idx_sent = iodesc->idx;
  1139. DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
  1140. "[%x/%02x%02x%02x].\n", ha->host_no, remote_fcport->loop_id,
  1141. iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa));
  1142. qla2x00_send_login_iocb(ha, iodesc, &rscn_pid, ha_locked);
  1143. return (QLA_SUCCESS);
  1144. }
  1145. /**
  1146. * qla2x00_process_iodesc() - Complete IO descriptor processing.
  1147. * @ha: HA context
  1148. * @mbxstat: Mailbox IOCB status
  1149. */
  1150. void
  1151. qla2x00_process_iodesc(scsi_qla_host_t *ha, struct mbx_entry *mbxstat)
  1152. {
  1153. int rval;
  1154. uint32_t signature;
  1155. fc_port_t *fcport;
  1156. struct io_descriptor *iodesc;
  1157. signature = mbxstat->handle;
  1158. DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
  1159. ha->host_no, signature));
  1160. /* Retrieve proper IO descriptor. */
  1161. iodesc = qla2x00_handle_to_iodesc(ha, signature);
  1162. if (iodesc == NULL) {
  1163. DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
  1164. "incorrect signature %08x.\n", ha->host_no, signature));
  1165. return;
  1166. }
  1167. /* Stop IO descriptor timer. */
  1168. qla2x00_remove_iodesc_timer(iodesc);
  1169. /* Verify signature match. */
  1170. if (iodesc->signature != signature) {
  1171. DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
  1172. "signature mismatch, sent %08x, received %08x.\n",
  1173. ha->host_no, iodesc->signature, signature));
  1174. return;
  1175. }
  1176. /* Go with IOCB callback. */
  1177. rval = iocb_function_cb_list[iodesc->cb_idx](ha, iodesc, mbxstat);
  1178. if (rval != QLA_SUCCESS) {
  1179. /* IO descriptor reused by callback. */
  1180. return;
  1181. }
  1182. qla2x00_free_iodesc(iodesc);
  1183. if (test_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags)) {
  1184. /* Scan our fcports list for any RSCN requests. */
  1185. list_for_each_entry(fcport, &ha->fcports, list) {
  1186. if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
  1187. fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
  1188. qla2x00_handle_port_rscn(ha, 0, fcport, 1);
  1189. return;
  1190. }
  1191. }
  1192. /* Scan our RSCN fcports list for any RSCN requests. */
  1193. list_for_each_entry(fcport, &ha->rscn_fcports, list) {
  1194. if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
  1195. fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
  1196. qla2x00_handle_port_rscn(ha, 0, fcport, 1);
  1197. return;
  1198. }
  1199. }
  1200. }
  1201. clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
  1202. }
  1203. /**
  1204. * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
  1205. * @ha: HA context
  1206. *
  1207. * This routine will also delete any RSCN entries related to the outstanding
  1208. * IO descriptors.
  1209. */
  1210. void
  1211. qla2x00_cancel_io_descriptors(scsi_qla_host_t *ha)
  1212. {
  1213. fc_port_t *fcport, *fcptemp;
  1214. clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
  1215. /* Abort all IO descriptors. */
  1216. qla2x00_init_io_descriptors(ha);
  1217. /* Reset all pending IO descriptors in fcports list. */
  1218. list_for_each_entry(fcport, &ha->fcports, list) {
  1219. fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
  1220. }
  1221. /* Reset all pending IO descriptors in rscn fcports list. */
  1222. list_for_each_entry_safe(fcport, fcptemp, &ha->rscn_fcports, list) {
  1223. DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
  1224. "%p [%x/%02x%02x%02x].\n", ha->host_no, fcport,
  1225. fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
  1226. fcport->d_id.b.al_pa));
  1227. list_del(&fcport->list);
  1228. kfree(fcport);
  1229. }
  1230. }