qla_mbx.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937
  1. /*
  2. * QLOGIC LINUX SOFTWARE
  3. *
  4. * QLogic ISP2x00 device driver for Linux 2.6.x
  5. * Copyright (C) 2003-2004 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. #include <linux/delay.h>
  21. static void
  22. qla2x00_mbx_sem_timeout(unsigned long data)
  23. {
  24. struct semaphore *sem_ptr = (struct semaphore *)data;
  25. DEBUG11(printk("qla2x00_sem_timeout: entered.\n");)
  26. if (sem_ptr != NULL) {
  27. up(sem_ptr);
  28. }
  29. DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n");)
  30. }
  31. /*
  32. * qla2x00_mailbox_command
  33. * Issue mailbox command and waits for completion.
  34. *
  35. * Input:
  36. * ha = adapter block pointer.
  37. * mcp = driver internal mbx struct pointer.
  38. *
  39. * Output:
  40. * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
  41. *
  42. * Returns:
  43. * 0 : QLA_SUCCESS = cmd performed success
  44. * 1 : QLA_FUNCTION_FAILED (error encountered)
  45. * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
  46. *
  47. * Context:
  48. * Kernel context.
  49. */
  50. static int
  51. qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
  52. {
  53. int rval;
  54. unsigned long flags = 0;
  55. device_reg_t __iomem *reg = ha->iobase;
  56. struct timer_list tmp_intr_timer;
  57. uint8_t abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
  58. uint8_t io_lock_on = ha->flags.init_done;
  59. uint16_t command;
  60. uint16_t *iptr;
  61. uint16_t __iomem *optr;
  62. uint32_t cnt;
  63. uint32_t mboxes;
  64. unsigned long mbx_flags = 0;
  65. unsigned long wait_time;
  66. rval = QLA_SUCCESS;
  67. DEBUG11(printk("qla2x00_mailbox_command(%ld): entered.\n",
  68. ha->host_no);)
  69. /*
  70. * Wait for active mailbox commands to finish by waiting at most
  71. * tov seconds. This is to serialize actual issuing of mailbox cmds
  72. * during non ISP abort time.
  73. */
  74. if (!abort_active) {
  75. if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) {
  76. /* Timeout occurred. Return error. */
  77. DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): cmd "
  78. "access timeout. Exiting.\n", ha->host_no);)
  79. return QLA_FUNCTION_TIMEOUT;
  80. }
  81. }
  82. ha->flags.mbox_busy = 1;
  83. /* Save mailbox command for debug */
  84. ha->mcp = mcp;
  85. /* Try to get mailbox register access */
  86. if (!abort_active)
  87. spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
  88. DEBUG11(printk("scsi%d: prepare to issue mbox cmd=0x%x.\n",
  89. (int)ha->host_no, mcp->mb[0]);)
  90. spin_lock_irqsave(&ha->hardware_lock, flags);
  91. /* Load mailbox registers. */
  92. optr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 0);
  93. iptr = mcp->mb;
  94. command = mcp->mb[0];
  95. mboxes = mcp->out_mb;
  96. for (cnt = 0; cnt < ha->mbx_count; cnt++) {
  97. if (IS_QLA2200(ha) && cnt == 8)
  98. optr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
  99. if (mboxes & BIT_0)
  100. WRT_REG_WORD(optr, *iptr);
  101. mboxes >>= 1;
  102. optr++;
  103. iptr++;
  104. }
  105. #if defined(QL_DEBUG_LEVEL_1)
  106. printk("qla2x00_mailbox_command: Loaded MBX registers "
  107. "(displayed in bytes) = \n");
  108. qla2x00_dump_buffer((uint8_t *)mcp->mb, 16);
  109. printk("\n");
  110. qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x10), 16);
  111. printk("\n");
  112. qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x20), 8);
  113. printk("\n");
  114. printk("qla2x00_mailbox_command: I/O address = %lx.\n",
  115. (u_long)optr);
  116. qla2x00_dump_regs(ha);
  117. #endif
  118. /* Issue set host interrupt command to send cmd out. */
  119. ha->flags.mbox_int = 0;
  120. clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
  121. /* Unlock mbx registers and wait for interrupt */
  122. DEBUG11(printk("qla2x00_mailbox_command: going to unlock irq & "
  123. "waiting for interrupt. jiffies=%lx.\n", jiffies);)
  124. /* Wait for mbx cmd completion until timeout */
  125. if (!abort_active && io_lock_on) {
  126. /* sleep on completion semaphore */
  127. DEBUG11(printk("qla2x00_mailbox_command(%ld): "
  128. "INTERRUPT MODE. Initializing timer.\n",
  129. ha->host_no);)
  130. init_timer(&tmp_intr_timer);
  131. tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem;
  132. tmp_intr_timer.expires = jiffies + mcp->tov * HZ;
  133. tmp_intr_timer.function =
  134. (void (*)(unsigned long))qla2x00_mbx_sem_timeout;
  135. DEBUG11(printk("qla2x00_mailbox_command(%ld): "
  136. "Adding timer.\n", ha->host_no);)
  137. add_timer(&tmp_intr_timer);
  138. DEBUG11(printk("qla2x00_mailbox_command: going to "
  139. "unlock & sleep. time=0x%lx.\n", jiffies);)
  140. set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
  141. WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
  142. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  143. if (!abort_active)
  144. spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
  145. /* Wait for either the timer to expire
  146. * or the mbox completion interrupt
  147. */
  148. down(&ha->mbx_intr_sem);
  149. DEBUG11(printk("qla2x00_mailbox_command:"
  150. "waking up."
  151. "time=0x%lx\n", jiffies);)
  152. clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
  153. /* delete the timer */
  154. del_timer(&tmp_intr_timer);
  155. } else {
  156. DEBUG3_11(printk("qla2x00_mailbox_command(%ld): cmd=%x "
  157. "POLLING MODE.\n", ha->host_no, command);)
  158. WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
  159. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  160. if (!abort_active)
  161. spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
  162. wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
  163. while (!ha->flags.mbox_int) {
  164. if (time_after(jiffies, wait_time))
  165. break;
  166. /* Check for pending interrupts. */
  167. qla2x00_poll(ha);
  168. udelay(10); /* v4.27 */
  169. } /* while */
  170. }
  171. if (!abort_active)
  172. spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
  173. /* Check whether we timed out */
  174. if (ha->flags.mbox_int) {
  175. uint16_t *iptr2;
  176. DEBUG3_11(printk("qla2x00_mailbox_cmd: cmd %x completed.\n",
  177. command);)
  178. /* Got interrupt. Clear the flag. */
  179. ha->flags.mbox_int = 0;
  180. clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
  181. if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
  182. rval = QLA_FUNCTION_FAILED;
  183. /* Load return mailbox registers. */
  184. iptr2 = mcp->mb;
  185. iptr = (uint16_t *)&ha->mailbox_out[0];
  186. mboxes = mcp->in_mb;
  187. for (cnt = 0; cnt < ha->mbx_count; cnt++) {
  188. if (mboxes & BIT_0)
  189. *iptr2 = *iptr;
  190. mboxes >>= 1;
  191. iptr2++;
  192. iptr++;
  193. }
  194. } else {
  195. #if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) || \
  196. defined(QL_DEBUG_LEVEL_11)
  197. printk("qla2x00_mailbox_command(%ld): **** MB Command Timeout "
  198. "for cmd %x ****\n", ha->host_no, command);
  199. printk("qla2x00_mailbox_command: icontrol=%x jiffies=%lx\n",
  200. RD_REG_WORD(&reg->ictrl), jiffies);
  201. printk("qla2x00_mailbox_command: *** mailbox[0] = 0x%x ***\n",
  202. RD_REG_WORD(optr));
  203. qla2x00_dump_regs(ha);
  204. #endif
  205. rval = QLA_FUNCTION_TIMEOUT;
  206. }
  207. if (!abort_active)
  208. spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
  209. ha->flags.mbox_busy = 0;
  210. /* Clean up */
  211. ha->mcp = NULL;
  212. if (!abort_active) {
  213. DEBUG11(printk("qla2x00_mailbox_cmd: checking for additional "
  214. "resp interrupt.\n");)
  215. /* polling mode for non isp_abort commands. */
  216. qla2x00_poll(ha);
  217. }
  218. if (rval == QLA_FUNCTION_TIMEOUT) {
  219. if (!io_lock_on || (mcp->flags & IOCTL_CMD)) {
  220. /* not in dpc. schedule it for dpc to take over. */
  221. DEBUG(printk("qla2x00_mailbox_command(%ld): timeout "
  222. "schedule isp_abort_needed.\n",
  223. ha->host_no);)
  224. DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): "
  225. "timeout schedule isp_abort_needed.\n",
  226. ha->host_no);)
  227. qla_printk(KERN_WARNING, ha,
  228. "Mailbox command timeout occured. Scheduling ISP "
  229. "abort.\n");
  230. set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
  231. if (ha->dpc_wait && !ha->dpc_active)
  232. up(ha->dpc_wait);
  233. } else if (!abort_active) {
  234. /* call abort directly since we are in the DPC thread */
  235. DEBUG(printk("qla2x00_mailbox_command(%ld): timeout "
  236. "calling abort_isp\n", ha->host_no);)
  237. DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): "
  238. "timeout calling abort_isp\n", ha->host_no);)
  239. qla_printk(KERN_WARNING, ha,
  240. "Mailbox command timeout occured. Issuing ISP "
  241. "abort.\n");
  242. set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
  243. clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
  244. if (qla2x00_abort_isp(ha)) {
  245. /* failed. retry later. */
  246. set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
  247. }
  248. clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
  249. DEBUG(printk("qla2x00_mailbox_command: finished "
  250. "abort_isp\n");)
  251. DEBUG2_3_11(printk("qla2x00_mailbox_command: finished "
  252. "abort_isp\n");)
  253. }
  254. }
  255. /* Allow next mbx cmd to come in. */
  256. if (!abort_active)
  257. up(&ha->mbx_cmd_sem);
  258. if (rval) {
  259. DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): **** FAILED. "
  260. "mbx0=%x, mbx1=%x, mbx2=%x, cmd=%x ****\n",
  261. ha->host_no, mcp->mb[0], mcp->mb[1], mcp->mb[2], command);)
  262. } else {
  263. DEBUG11(printk("qla2x00_mailbox_command(%ld): done.\n",
  264. ha->host_no);)
  265. }
  266. DEBUG11(printk("qla2x00_mailbox_command(%ld): exiting.\n",
  267. ha->host_no);)
  268. return rval;
  269. }
  270. /*
  271. * qla2x00_load_ram
  272. * Load adapter RAM using DMA.
  273. *
  274. * Input:
  275. * ha = adapter block pointer.
  276. *
  277. * Returns:
  278. * qla2x00 local function return status code.
  279. *
  280. * Context:
  281. * Kernel context.
  282. */
  283. int
  284. qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint16_t risc_addr,
  285. uint16_t risc_code_size)
  286. {
  287. int rval;
  288. mbx_cmd_t mc;
  289. mbx_cmd_t *mcp = &mc;
  290. uint32_t req_len;
  291. dma_addr_t nml_dma;
  292. uint32_t nml_len;
  293. uint32_t normalized;
  294. DEBUG11(printk("qla2x00_load_ram(%ld): entered.\n",
  295. ha->host_no);)
  296. req_len = risc_code_size;
  297. nml_dma = 0;
  298. nml_len = 0;
  299. normalized = qla2x00_normalize_dma_addr(&req_dma, &req_len, &nml_dma,
  300. &nml_len);
  301. /* Load first segment */
  302. mcp->mb[0] = MBC_LOAD_RISC_RAM;
  303. mcp->mb[1] = risc_addr;
  304. mcp->mb[2] = MSW(req_dma);
  305. mcp->mb[3] = LSW(req_dma);
  306. mcp->mb[4] = (uint16_t)req_len;
  307. mcp->mb[6] = MSW(MSD(req_dma));
  308. mcp->mb[7] = LSW(MSD(req_dma));
  309. mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
  310. mcp->in_mb = MBX_0;
  311. mcp->tov = 30;
  312. mcp->flags = 0;
  313. rval = qla2x00_mailbox_command(ha, mcp);
  314. /* Load second segment - if necessary */
  315. if (normalized && (rval == QLA_SUCCESS)) {
  316. mcp->mb[0] = MBC_LOAD_RISC_RAM;
  317. mcp->mb[1] = risc_addr + (uint16_t)req_len;
  318. mcp->mb[2] = MSW(nml_dma);
  319. mcp->mb[3] = LSW(nml_dma);
  320. mcp->mb[4] = (uint16_t)nml_len;
  321. mcp->mb[6] = MSW(MSD(nml_dma));
  322. mcp->mb[7] = LSW(MSD(nml_dma));
  323. mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
  324. mcp->in_mb = MBX_0;
  325. mcp->tov = 30;
  326. mcp->flags = 0;
  327. rval = qla2x00_mailbox_command(ha, mcp);
  328. }
  329. if (rval == QLA_SUCCESS) {
  330. /* Empty */
  331. DEBUG11(printk("qla2x00_load_ram(%ld): done.\n", ha->host_no);)
  332. } else {
  333. /* Empty */
  334. DEBUG2_3_11(printk("qla2x00_load_ram(%ld): failed. rval=%x "
  335. "mb[0]=%x.\n", ha->host_no, rval, mcp->mb[0]);)
  336. }
  337. return rval;
  338. }
  339. /*
  340. * qla2x00_load_ram_ext
  341. * Load adapter extended RAM using DMA.
  342. *
  343. * Input:
  344. * ha = adapter block pointer.
  345. *
  346. * Returns:
  347. * qla2x00 local function return status code.
  348. *
  349. * Context:
  350. * Kernel context.
  351. */
  352. int
  353. qla2x00_load_ram_ext(scsi_qla_host_t *ha, dma_addr_t req_dma,
  354. uint32_t risc_addr, uint16_t risc_code_size)
  355. {
  356. int rval;
  357. mbx_cmd_t mc;
  358. mbx_cmd_t *mcp = &mc;
  359. uint32_t req_len;
  360. dma_addr_t nml_dma;
  361. uint32_t nml_len;
  362. uint32_t normalized;
  363. DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
  364. req_len = risc_code_size;
  365. nml_dma = 0;
  366. nml_len = 0;
  367. normalized = qla2x00_normalize_dma_addr(&req_dma, &req_len, &nml_dma,
  368. &nml_len);
  369. /* Load first segment */
  370. mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
  371. mcp->mb[1] = LSW(risc_addr);
  372. mcp->mb[2] = MSW(req_dma);
  373. mcp->mb[3] = LSW(req_dma);
  374. mcp->mb[4] = (uint16_t)req_len;
  375. mcp->mb[6] = MSW(MSD(req_dma));
  376. mcp->mb[7] = LSW(MSD(req_dma));
  377. mcp->mb[8] = MSW(risc_addr);
  378. mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
  379. mcp->in_mb = MBX_0;
  380. mcp->tov = 30;
  381. mcp->flags = 0;
  382. rval = qla2x00_mailbox_command(ha, mcp);
  383. /* Load second segment - if necessary */
  384. if (normalized && (rval == QLA_SUCCESS)) {
  385. risc_addr += req_len;
  386. mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
  387. mcp->mb[1] = LSW(risc_addr);
  388. mcp->mb[2] = MSW(nml_dma);
  389. mcp->mb[3] = LSW(nml_dma);
  390. mcp->mb[4] = (uint16_t)nml_len;
  391. mcp->mb[6] = MSW(MSD(nml_dma));
  392. mcp->mb[7] = LSW(MSD(nml_dma));
  393. mcp->mb[8] = MSW(risc_addr);
  394. mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
  395. mcp->in_mb = MBX_0;
  396. mcp->tov = 30;
  397. mcp->flags = 0;
  398. rval = qla2x00_mailbox_command(ha, mcp);
  399. }
  400. if (rval != QLA_SUCCESS) {
  401. /*EMPTY*/
  402. DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n",
  403. __func__, ha->host_no, rval, mcp->mb[0]));
  404. } else {
  405. /*EMPTY*/
  406. DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
  407. }
  408. return rval;
  409. }
  410. /*
  411. * qla2x00_execute_fw
  412. * Start adapter firmware.
  413. *
  414. * Input:
  415. * ha = adapter block pointer.
  416. * TARGET_QUEUE_LOCK must be released.
  417. * ADAPTER_STATE_LOCK must be released.
  418. *
  419. * Returns:
  420. * qla2x00 local function return status code.
  421. *
  422. * Context:
  423. * Kernel context.
  424. */
  425. int
  426. qla2x00_execute_fw(scsi_qla_host_t *ha)
  427. {
  428. int rval;
  429. mbx_cmd_t mc;
  430. mbx_cmd_t *mcp = &mc;
  431. DEBUG11(printk("qla2x00_execute_fw(%ld): entered.\n", ha->host_no);)
  432. mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
  433. mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart;
  434. mcp->out_mb = MBX_1|MBX_0;
  435. if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
  436. mcp->mb[2] = 0;
  437. mcp->out_mb |= MBX_2;
  438. }
  439. mcp->in_mb = MBX_0;
  440. mcp->tov = 30;
  441. mcp->flags = 0;
  442. rval = qla2x00_mailbox_command(ha, mcp);
  443. DEBUG11(printk("qla2x00_execute_fw(%ld): done.\n", ha->host_no);)
  444. return rval;
  445. }
  446. /*
  447. * qla2x00_get_fw_version
  448. * Get firmware version.
  449. *
  450. * Input:
  451. * ha: adapter state pointer.
  452. * major: pointer for major number.
  453. * minor: pointer for minor number.
  454. * subminor: pointer for subminor number.
  455. *
  456. * Returns:
  457. * qla2x00 local function return status code.
  458. *
  459. * Context:
  460. * Kernel context.
  461. */
  462. void
  463. qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor,
  464. uint16_t *subminor, uint16_t *attributes, uint32_t *memory)
  465. {
  466. int rval;
  467. mbx_cmd_t mc;
  468. mbx_cmd_t *mcp = &mc;
  469. DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
  470. mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
  471. mcp->out_mb = MBX_0;
  472. mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
  473. mcp->flags = 0;
  474. mcp->tov = 30;
  475. rval = qla2x00_mailbox_command(ha, mcp);
  476. /* Return mailbox data. */
  477. *major = mcp->mb[1];
  478. *minor = mcp->mb[2];
  479. *subminor = mcp->mb[3];
  480. *attributes = mcp->mb[6];
  481. if (IS_QLA2100(ha) || IS_QLA2200(ha))
  482. *memory = 0x1FFFF; /* Defaults to 128KB. */
  483. else
  484. *memory = (mcp->mb[5] << 16) | mcp->mb[4];
  485. if (rval != QLA_SUCCESS) {
  486. /*EMPTY*/
  487. DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
  488. ha->host_no, rval));
  489. } else {
  490. /*EMPTY*/
  491. DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
  492. }
  493. }
  494. /*
  495. * qla2x00_get_fw_options
  496. * Set firmware options.
  497. *
  498. * Input:
  499. * ha = adapter block pointer.
  500. * fwopt = pointer for firmware options.
  501. *
  502. * Returns:
  503. * qla2x00 local function return status code.
  504. *
  505. * Context:
  506. * Kernel context.
  507. */
  508. int
  509. qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
  510. {
  511. int rval;
  512. mbx_cmd_t mc;
  513. mbx_cmd_t *mcp = &mc;
  514. DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
  515. mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
  516. mcp->out_mb = MBX_0;
  517. mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
  518. mcp->tov = 30;
  519. mcp->flags = 0;
  520. rval = qla2x00_mailbox_command(ha, mcp);
  521. if (rval != QLA_SUCCESS) {
  522. /*EMPTY*/
  523. DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
  524. ha->host_no, rval));
  525. } else {
  526. fwopts[1] = mcp->mb[1];
  527. fwopts[2] = mcp->mb[2];
  528. fwopts[3] = mcp->mb[3];
  529. DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
  530. }
  531. return rval;
  532. }
  533. /*
  534. * qla2x00_set_fw_options
  535. * Set firmware options.
  536. *
  537. * Input:
  538. * ha = adapter block pointer.
  539. * fwopt = pointer for firmware options.
  540. *
  541. * Returns:
  542. * qla2x00 local function return status code.
  543. *
  544. * Context:
  545. * Kernel context.
  546. */
  547. int
  548. qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
  549. {
  550. int rval;
  551. mbx_cmd_t mc;
  552. mbx_cmd_t *mcp = &mc;
  553. DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
  554. mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
  555. mcp->mb[1] = fwopts[1];
  556. mcp->mb[2] = fwopts[2];
  557. mcp->mb[3] = fwopts[3];
  558. mcp->mb[10] = fwopts[10];
  559. mcp->mb[11] = fwopts[11];
  560. mcp->mb[12] = 0; /* Undocumented, but used */
  561. mcp->out_mb = MBX_12|MBX_11|MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
  562. mcp->in_mb = MBX_0;
  563. mcp->tov = 30;
  564. mcp->flags = 0;
  565. rval = qla2x00_mailbox_command(ha, mcp);
  566. if (rval != QLA_SUCCESS) {
  567. /*EMPTY*/
  568. DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
  569. ha->host_no, rval));
  570. } else {
  571. /*EMPTY*/
  572. DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
  573. }
  574. return rval;
  575. }
  576. /*
  577. * qla2x00_mbx_reg_test
  578. * Mailbox register wrap test.
  579. *
  580. * Input:
  581. * ha = adapter block pointer.
  582. * TARGET_QUEUE_LOCK must be released.
  583. * ADAPTER_STATE_LOCK must be released.
  584. *
  585. * Returns:
  586. * qla2x00 local function return status code.
  587. *
  588. * Context:
  589. * Kernel context.
  590. */
  591. int
  592. qla2x00_mbx_reg_test(scsi_qla_host_t *ha)
  593. {
  594. int rval;
  595. mbx_cmd_t mc;
  596. mbx_cmd_t *mcp = &mc;
  597. DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no);)
  598. mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
  599. mcp->mb[1] = 0xAAAA;
  600. mcp->mb[2] = 0x5555;
  601. mcp->mb[3] = 0xAA55;
  602. mcp->mb[4] = 0x55AA;
  603. mcp->mb[5] = 0xA5A5;
  604. mcp->mb[6] = 0x5A5A;
  605. mcp->mb[7] = 0x2525;
  606. mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
  607. mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
  608. mcp->tov = 30;
  609. mcp->flags = 0;
  610. rval = qla2x00_mailbox_command(ha, mcp);
  611. if (rval == QLA_SUCCESS) {
  612. if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
  613. mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
  614. rval = QLA_FUNCTION_FAILED;
  615. if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
  616. mcp->mb[7] != 0x2525)
  617. rval = QLA_FUNCTION_FAILED;
  618. }
  619. if (rval != QLA_SUCCESS) {
  620. /*EMPTY*/
  621. DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n",
  622. ha->host_no, rval);)
  623. } else {
  624. /*EMPTY*/
  625. DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n",
  626. ha->host_no);)
  627. }
  628. return rval;
  629. }
  630. /*
  631. * qla2x00_verify_checksum
  632. * Verify firmware checksum.
  633. *
  634. * Input:
  635. * ha = adapter block pointer.
  636. * TARGET_QUEUE_LOCK must be released.
  637. * ADAPTER_STATE_LOCK must be released.
  638. *
  639. * Returns:
  640. * qla2x00 local function return status code.
  641. *
  642. * Context:
  643. * Kernel context.
  644. */
  645. int
  646. qla2x00_verify_checksum(scsi_qla_host_t *ha)
  647. {
  648. int rval;
  649. mbx_cmd_t mc;
  650. mbx_cmd_t *mcp = &mc;
  651. DEBUG11(printk("qla2x00_verify_checksum(%ld): entered.\n",
  652. ha->host_no);)
  653. mcp->mb[0] = MBC_VERIFY_CHECKSUM;
  654. mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart;
  655. mcp->out_mb = MBX_1|MBX_0;
  656. mcp->in_mb = MBX_2|MBX_0;
  657. mcp->tov = 30;
  658. mcp->flags = 0;
  659. rval = qla2x00_mailbox_command(ha, mcp);
  660. if (rval != QLA_SUCCESS) {
  661. /*EMPTY*/
  662. DEBUG2_3_11(printk("qla2x00_verify_checksum(%ld): failed=%x.\n",
  663. ha->host_no, rval);)
  664. } else {
  665. /*EMPTY*/
  666. DEBUG11(printk("qla2x00_verify_checksum(%ld): done.\n",
  667. ha->host_no);)
  668. }
  669. return rval;
  670. }
  671. /*
  672. * qla2x00_issue_iocb
  673. * Issue IOCB using mailbox command
  674. *
  675. * Input:
  676. * ha = adapter state pointer.
  677. * buffer = buffer pointer.
  678. * phys_addr = physical address of buffer.
  679. * size = size of buffer.
  680. * TARGET_QUEUE_LOCK must be released.
  681. * ADAPTER_STATE_LOCK must be released.
  682. *
  683. * Returns:
  684. * qla2x00 local function return status code.
  685. *
  686. * Context:
  687. * Kernel context.
  688. */
  689. int
  690. qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr,
  691. size_t size)
  692. {
  693. int rval;
  694. mbx_cmd_t mc;
  695. mbx_cmd_t *mcp = &mc;
  696. mcp->mb[0] = MBC_IOCB_COMMAND_A64;
  697. mcp->mb[1] = 0;
  698. mcp->mb[2] = MSW(phys_addr);
  699. mcp->mb[3] = LSW(phys_addr);
  700. mcp->mb[6] = MSW(MSD(phys_addr));
  701. mcp->mb[7] = LSW(MSD(phys_addr));
  702. mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
  703. mcp->in_mb = MBX_2|MBX_0;
  704. mcp->tov = 30;
  705. mcp->flags = 0;
  706. rval = qla2x00_mailbox_command(ha, mcp);
  707. if (rval != QLA_SUCCESS) {
  708. /*EMPTY*/
  709. DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x",
  710. ha->host_no,rval);)
  711. DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x",
  712. ha->host_no,rval);)
  713. } else {
  714. /*EMPTY*/
  715. }
  716. return rval;
  717. }
  718. /*
  719. * qla2x00_abort_command
  720. * Abort command aborts a specified IOCB.
  721. *
  722. * Input:
  723. * ha = adapter block pointer.
  724. * sp = SB structure pointer.
  725. *
  726. * Returns:
  727. * qla2x00 local function return status code.
  728. *
  729. * Context:
  730. * Kernel context.
  731. */
  732. int
  733. qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
  734. {
  735. unsigned long flags = 0;
  736. fc_port_t *fcport;
  737. int rval;
  738. uint32_t handle;
  739. mbx_cmd_t mc;
  740. mbx_cmd_t *mcp = &mc;
  741. DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);)
  742. fcport = sp->fcport;
  743. if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
  744. atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
  745. return 1;
  746. }
  747. spin_lock_irqsave(&ha->hardware_lock, flags);
  748. for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
  749. if (ha->outstanding_cmds[handle] == sp)
  750. break;
  751. }
  752. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  753. if (handle == MAX_OUTSTANDING_COMMANDS) {
  754. /* command not found */
  755. return QLA_FUNCTION_FAILED;
  756. }
  757. mcp->mb[0] = MBC_ABORT_COMMAND;
  758. if (HAS_EXTENDED_IDS(ha))
  759. mcp->mb[1] = fcport->loop_id;
  760. else
  761. mcp->mb[1] = fcport->loop_id << 8;
  762. mcp->mb[2] = (uint16_t)handle;
  763. mcp->mb[3] = (uint16_t)(handle >> 16);
  764. mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
  765. mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
  766. mcp->in_mb = MBX_0;
  767. mcp->tov = 30;
  768. mcp->flags = 0;
  769. rval = qla2x00_mailbox_command(ha, mcp);
  770. if (rval != QLA_SUCCESS) {
  771. DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n",
  772. ha->host_no, rval);)
  773. } else {
  774. sp->flags |= SRB_ABORT_PENDING;
  775. DEBUG11(printk("qla2x00_abort_command(%ld): done.\n",
  776. ha->host_no);)
  777. }
  778. return rval;
  779. }
  780. #if USE_ABORT_TGT
  781. /*
  782. * qla2x00_abort_target
  783. * Issue abort target mailbox command.
  784. *
  785. * Input:
  786. * ha = adapter block pointer.
  787. *
  788. * Returns:
  789. * qla2x00 local function return status code.
  790. *
  791. * Context:
  792. * Kernel context.
  793. */
  794. int
  795. qla2x00_abort_target(fc_port_t *fcport)
  796. {
  797. int rval;
  798. mbx_cmd_t mc;
  799. mbx_cmd_t *mcp = &mc;
  800. DEBUG11(printk("qla2x00_abort_target(%ld): entered.\n",
  801. fcport->ha->host_no);)
  802. if (fcport == NULL) {
  803. /* no target to abort */
  804. return 0;
  805. }
  806. mcp->mb[0] = MBC_ABORT_TARGET;
  807. mcp->out_mb = MBX_2|MBX_1|MBX_0;
  808. if (HAS_EXTENDED_IDS(fcport->ha)) {
  809. mcp->mb[1] = fcport->loop_id;
  810. mcp->mb[10] = 0;
  811. mcp->out_mb |= MBX_10;
  812. } else {
  813. mcp->mb[1] = fcport->loop_id << 8;
  814. }
  815. mcp->mb[2] = fcport->ha->loop_reset_delay;
  816. mcp->in_mb = MBX_0;
  817. mcp->tov = 30;
  818. mcp->flags = 0;
  819. rval = qla2x00_mailbox_command(fcport->ha, mcp);
  820. /* Issue marker command. */
  821. fcport->ha->marker_needed = 1;
  822. if (rval != QLA_SUCCESS) {
  823. DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n",
  824. fcport->ha->host_no, rval);)
  825. } else {
  826. /*EMPTY*/
  827. DEBUG11(printk("qla2x00_abort_target(%ld): done.\n",
  828. fcport->ha->host_no);)
  829. }
  830. return rval;
  831. }
  832. #endif
  833. /*
  834. * qla2x00_target_reset
  835. * Issue target reset mailbox command.
  836. *
  837. * Input:
  838. * ha = adapter block pointer.
  839. * TARGET_QUEUE_LOCK must be released.
  840. * ADAPTER_STATE_LOCK must be released.
  841. *
  842. * Returns:
  843. * qla2x00 local function return status code.
  844. *
  845. * Context:
  846. * Kernel context.
  847. */
  848. int
  849. qla2x00_target_reset(scsi_qla_host_t *ha, struct fc_port *fcport)
  850. {
  851. int rval;
  852. mbx_cmd_t mc;
  853. mbx_cmd_t *mcp = &mc;
  854. DEBUG11(printk("qla2x00_target_reset(%ld): entered.\n", ha->host_no);)
  855. if (atomic_read(&fcport->state) != FCS_ONLINE)
  856. return 0;
  857. mcp->mb[0] = MBC_TARGET_RESET;
  858. if (HAS_EXTENDED_IDS(ha))
  859. mcp->mb[1] = fcport->loop_id;
  860. else
  861. mcp->mb[1] = fcport->loop_id << 8;
  862. mcp->mb[2] = ha->loop_reset_delay;
  863. mcp->out_mb = MBX_2|MBX_1|MBX_0;
  864. mcp->in_mb = MBX_0;
  865. mcp->tov = 30;
  866. mcp->flags = 0;
  867. rval = qla2x00_mailbox_command(ha, mcp);
  868. if (rval != QLA_SUCCESS) {
  869. /*EMPTY*/
  870. DEBUG2_3_11(printk("qla2x00_target_reset(%ld): failed=%x.\n",
  871. ha->host_no, rval);)
  872. } else {
  873. /*EMPTY*/
  874. DEBUG11(printk("qla2x00_target_reset(%ld): done.\n",
  875. ha->host_no);)
  876. }
  877. return rval;
  878. }
  879. /*
  880. * qla2x00_get_adapter_id
  881. * Get adapter ID and topology.
  882. *
  883. * Input:
  884. * ha = adapter block pointer.
  885. * id = pointer for loop ID.
  886. * al_pa = pointer for AL_PA.
  887. * area = pointer for area.
  888. * domain = pointer for domain.
  889. * top = pointer for topology.
  890. * TARGET_QUEUE_LOCK must be released.
  891. * ADAPTER_STATE_LOCK must be released.
  892. *
  893. * Returns:
  894. * qla2x00 local function return status code.
  895. *
  896. * Context:
  897. * Kernel context.
  898. */
  899. int
  900. qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
  901. uint8_t *area, uint8_t *domain, uint16_t *top)
  902. {
  903. int rval;
  904. mbx_cmd_t mc;
  905. mbx_cmd_t *mcp = &mc;
  906. DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n",
  907. ha->host_no);)
  908. mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
  909. mcp->out_mb = MBX_0;
  910. mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
  911. mcp->tov = 30;
  912. mcp->flags = 0;
  913. rval = qla2x00_mailbox_command(ha, mcp);
  914. /* Return data. */
  915. *id = mcp->mb[1];
  916. *al_pa = LSB(mcp->mb[2]);
  917. *area = MSB(mcp->mb[2]);
  918. *domain = LSB(mcp->mb[3]);
  919. *top = mcp->mb[6];
  920. if (rval != QLA_SUCCESS) {
  921. /*EMPTY*/
  922. DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n",
  923. ha->host_no, rval);)
  924. } else {
  925. /*EMPTY*/
  926. DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n",
  927. ha->host_no);)
  928. }
  929. return rval;
  930. }
  931. /*
  932. * qla2x00_get_retry_cnt
  933. * Get current firmware login retry count and delay.
  934. *
  935. * Input:
  936. * ha = adapter block pointer.
  937. * retry_cnt = pointer to login retry count.
  938. * tov = pointer to login timeout value.
  939. *
  940. * Returns:
  941. * qla2x00 local function return status code.
  942. *
  943. * Context:
  944. * Kernel context.
  945. */
  946. int
  947. qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov,
  948. uint16_t *r_a_tov)
  949. {
  950. int rval;
  951. uint16_t ratov;
  952. mbx_cmd_t mc;
  953. mbx_cmd_t *mcp = &mc;
  954. DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n",
  955. ha->host_no);)
  956. mcp->mb[0] = MBC_GET_RETRY_COUNT;
  957. mcp->out_mb = MBX_0;
  958. mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
  959. mcp->tov = 30;
  960. mcp->flags = 0;
  961. rval = qla2x00_mailbox_command(ha, mcp);
  962. if (rval != QLA_SUCCESS) {
  963. /*EMPTY*/
  964. DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n",
  965. ha->host_no, mcp->mb[0]);)
  966. } else {
  967. /* Convert returned data and check our values. */
  968. *r_a_tov = mcp->mb[3] / 2;
  969. ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
  970. if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
  971. /* Update to the larger values */
  972. *retry_cnt = (uint8_t)mcp->mb[1];
  973. *tov = ratov;
  974. }
  975. DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d "
  976. "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov);)
  977. }
  978. return rval;
  979. }
  980. /*
  981. * qla2x00_init_firmware
  982. * Initialize adapter firmware.
  983. *
  984. * Input:
  985. * ha = adapter block pointer.
  986. * dptr = Initialization control block pointer.
  987. * size = size of initialization control block.
  988. * TARGET_QUEUE_LOCK must be released.
  989. * ADAPTER_STATE_LOCK must be released.
  990. *
  991. * Returns:
  992. * qla2x00 local function return status code.
  993. *
  994. * Context:
  995. * Kernel context.
  996. */
  997. int
  998. qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
  999. {
  1000. int rval;
  1001. mbx_cmd_t mc;
  1002. mbx_cmd_t *mcp = &mc;
  1003. DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n",
  1004. ha->host_no);)
  1005. mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
  1006. mcp->mb[2] = MSW(ha->init_cb_dma);
  1007. mcp->mb[3] = LSW(ha->init_cb_dma);
  1008. mcp->mb[4] = 0;
  1009. mcp->mb[5] = 0;
  1010. mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
  1011. mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
  1012. mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
  1013. mcp->in_mb = MBX_5|MBX_4|MBX_0;
  1014. mcp->buf_size = size;
  1015. mcp->flags = MBX_DMA_OUT;
  1016. mcp->tov = 30;
  1017. rval = qla2x00_mailbox_command(ha, mcp);
  1018. if (rval != QLA_SUCCESS) {
  1019. /*EMPTY*/
  1020. DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x "
  1021. "mb0=%x.\n",
  1022. ha->host_no, rval, mcp->mb[0]);)
  1023. } else {
  1024. /*EMPTY*/
  1025. DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n",
  1026. ha->host_no);)
  1027. }
  1028. return rval;
  1029. }
  1030. /*
  1031. * qla2x00_get_port_database
  1032. * Issue normal/enhanced get port database mailbox command
  1033. * and copy device name as necessary.
  1034. *
  1035. * Input:
  1036. * ha = adapter state pointer.
  1037. * dev = structure pointer.
  1038. * opt = enhanced cmd option byte.
  1039. *
  1040. * Returns:
  1041. * qla2x00 local function return status code.
  1042. *
  1043. * Context:
  1044. * Kernel context.
  1045. */
  1046. int
  1047. qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
  1048. {
  1049. int rval;
  1050. mbx_cmd_t mc;
  1051. mbx_cmd_t *mcp = &mc;
  1052. port_database_t *pd;
  1053. dma_addr_t pd_dma;
  1054. DEBUG11(printk("qla2x00_get_port_database(%ld): entered.\n",
  1055. ha->host_no);)
  1056. pd = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pd_dma);
  1057. if (pd == NULL) {
  1058. DEBUG2_3_11(printk("qla2x00_get_port_database(%ld): **** "
  1059. "Mem Alloc Failed ****", ha->host_no);)
  1060. return QLA_MEMORY_ALLOC_FAILED;
  1061. }
  1062. memset(pd, 0, PORT_DATABASE_SIZE);
  1063. if (opt != 0)
  1064. mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
  1065. else
  1066. mcp->mb[0] = MBC_GET_PORT_DATABASE;
  1067. mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
  1068. if (HAS_EXTENDED_IDS(ha)) {
  1069. mcp->mb[1] = fcport->loop_id;
  1070. mcp->mb[10] = opt;
  1071. mcp->out_mb |= MBX_10;
  1072. } else {
  1073. mcp->mb[1] = fcport->loop_id << 8 | opt;
  1074. }
  1075. mcp->mb[2] = MSW(pd_dma);
  1076. mcp->mb[3] = LSW(pd_dma);
  1077. mcp->mb[6] = MSW(MSD(pd_dma));
  1078. mcp->mb[7] = LSW(MSD(pd_dma));
  1079. mcp->in_mb = MBX_0;
  1080. mcp->buf_size = PORT_DATABASE_SIZE;
  1081. mcp->flags = MBX_DMA_IN;
  1082. mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
  1083. rval = qla2x00_mailbox_command(ha, mcp);
  1084. if (rval != QLA_SUCCESS)
  1085. goto gpd_error_out;
  1086. /* Check for logged in state. */
  1087. if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
  1088. pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
  1089. rval = QLA_FUNCTION_FAILED;
  1090. goto gpd_error_out;
  1091. }
  1092. /* Names are little-endian. */
  1093. memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
  1094. memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
  1095. /* Get port_id of device. */
  1096. fcport->d_id.b.al_pa = pd->port_id[2];
  1097. fcport->d_id.b.area = pd->port_id[3];
  1098. fcport->d_id.b.domain = pd->port_id[0];
  1099. fcport->d_id.b.rsvd_1 = 0;
  1100. /* Check for device require authentication. */
  1101. pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
  1102. (fcport->flags &= ~FCF_AUTH_REQ);
  1103. /* If not target must be initiator or unknown type. */
  1104. if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
  1105. fcport->port_type = FCT_INITIATOR;
  1106. else
  1107. fcport->port_type = FCT_TARGET;
  1108. gpd_error_out:
  1109. dma_pool_free(ha->s_dma_pool, pd, pd_dma);
  1110. if (rval != QLA_SUCCESS) {
  1111. /*EMPTY*/
  1112. DEBUG2_3_11(printk("qla2x00_get_port_database(%ld): "
  1113. "failed=%x.\n", ha->host_no, rval);)
  1114. } else {
  1115. /*EMPTY*/
  1116. DEBUG11(printk("qla2x00_get_port_database(%ld): done.\n",
  1117. ha->host_no);)
  1118. }
  1119. return rval;
  1120. }
  1121. /*
  1122. * qla2x00_get_firmware_state
  1123. * Get adapter firmware state.
  1124. *
  1125. * Input:
  1126. * ha = adapter block pointer.
  1127. * dptr = pointer for firmware state.
  1128. * TARGET_QUEUE_LOCK must be released.
  1129. * ADAPTER_STATE_LOCK must be released.
  1130. *
  1131. * Returns:
  1132. * qla2x00 local function return status code.
  1133. *
  1134. * Context:
  1135. * Kernel context.
  1136. */
  1137. int
  1138. qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr)
  1139. {
  1140. int rval;
  1141. mbx_cmd_t mc;
  1142. mbx_cmd_t *mcp = &mc;
  1143. DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n",
  1144. ha->host_no);)
  1145. mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
  1146. mcp->out_mb = MBX_0;
  1147. mcp->in_mb = MBX_2|MBX_1|MBX_0;
  1148. mcp->tov = 30;
  1149. mcp->flags = 0;
  1150. rval = qla2x00_mailbox_command(ha, mcp);
  1151. /* Return firmware state. */
  1152. *dptr = mcp->mb[1];
  1153. if (rval != QLA_SUCCESS) {
  1154. /*EMPTY*/
  1155. DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): "
  1156. "failed=%x.\n", ha->host_no, rval);)
  1157. } else {
  1158. /*EMPTY*/
  1159. DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n",
  1160. ha->host_no);)
  1161. }
  1162. return rval;
  1163. }
  1164. /*
  1165. * qla2x00_get_port_name
  1166. * Issue get port name mailbox command.
  1167. * Returned name is in big endian format.
  1168. *
  1169. * Input:
  1170. * ha = adapter block pointer.
  1171. * loop_id = loop ID of device.
  1172. * name = pointer for name.
  1173. * TARGET_QUEUE_LOCK must be released.
  1174. * ADAPTER_STATE_LOCK must be released.
  1175. *
  1176. * Returns:
  1177. * qla2x00 local function return status code.
  1178. *
  1179. * Context:
  1180. * Kernel context.
  1181. */
  1182. int
  1183. qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name,
  1184. uint8_t opt)
  1185. {
  1186. int rval;
  1187. mbx_cmd_t mc;
  1188. mbx_cmd_t *mcp = &mc;
  1189. DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n",
  1190. ha->host_no);)
  1191. mcp->mb[0] = MBC_GET_PORT_NAME;
  1192. mcp->out_mb = MBX_1|MBX_0;
  1193. if (HAS_EXTENDED_IDS(ha)) {
  1194. mcp->mb[1] = loop_id;
  1195. mcp->mb[10] = opt;
  1196. mcp->out_mb |= MBX_10;
  1197. } else {
  1198. mcp->mb[1] = loop_id << 8 | opt;
  1199. }
  1200. mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
  1201. mcp->tov = 30;
  1202. mcp->flags = 0;
  1203. rval = qla2x00_mailbox_command(ha, mcp);
  1204. if (rval != QLA_SUCCESS) {
  1205. /*EMPTY*/
  1206. DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n",
  1207. ha->host_no, rval);)
  1208. } else {
  1209. if (name != NULL) {
  1210. /* This function returns name in big endian. */
  1211. name[0] = LSB(mcp->mb[2]);
  1212. name[1] = MSB(mcp->mb[2]);
  1213. name[2] = LSB(mcp->mb[3]);
  1214. name[3] = MSB(mcp->mb[3]);
  1215. name[4] = LSB(mcp->mb[6]);
  1216. name[5] = MSB(mcp->mb[6]);
  1217. name[6] = LSB(mcp->mb[7]);
  1218. name[7] = MSB(mcp->mb[7]);
  1219. }
  1220. DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n",
  1221. ha->host_no);)
  1222. }
  1223. return rval;
  1224. }
  1225. /*
  1226. * qla2x00_lip_reset
  1227. * Issue LIP reset mailbox command.
  1228. *
  1229. * Input:
  1230. * ha = adapter block pointer.
  1231. * TARGET_QUEUE_LOCK must be released.
  1232. * ADAPTER_STATE_LOCK must be released.
  1233. *
  1234. * Returns:
  1235. * qla2x00 local function return status code.
  1236. *
  1237. * Context:
  1238. * Kernel context.
  1239. */
  1240. int
  1241. qla2x00_lip_reset(scsi_qla_host_t *ha)
  1242. {
  1243. int rval;
  1244. mbx_cmd_t mc;
  1245. mbx_cmd_t *mcp = &mc;
  1246. DEBUG11(printk("qla2x00_lip_reset(%ld): entered.\n",
  1247. ha->host_no);)
  1248. mcp->mb[0] = MBC_LIP_RESET;
  1249. mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
  1250. if (HAS_EXTENDED_IDS(ha)) {
  1251. mcp->mb[1] = 0x00ff;
  1252. mcp->mb[10] = 0;
  1253. mcp->out_mb |= MBX_10;
  1254. } else {
  1255. mcp->mb[1] = 0xff00;
  1256. }
  1257. mcp->mb[2] = ha->loop_reset_delay;
  1258. mcp->mb[3] = 0;
  1259. mcp->in_mb = MBX_0;
  1260. mcp->tov = 30;
  1261. mcp->flags = 0;
  1262. rval = qla2x00_mailbox_command(ha, mcp);
  1263. if (rval != QLA_SUCCESS) {
  1264. /*EMPTY*/
  1265. DEBUG2_3_11(printk("qla2x00_lip_reset(%ld): failed=%x.\n",
  1266. ha->host_no, rval);)
  1267. } else {
  1268. /*EMPTY*/
  1269. DEBUG11(printk("qla2x00_lip_reset(%ld): done.\n", ha->host_no);)
  1270. }
  1271. return rval;
  1272. }
  1273. /*
  1274. * qla2x00_send_sns
  1275. * Send SNS command.
  1276. *
  1277. * Input:
  1278. * ha = adapter block pointer.
  1279. * sns = pointer for command.
  1280. * cmd_size = command size.
  1281. * buf_size = response/command size.
  1282. * TARGET_QUEUE_LOCK must be released.
  1283. * ADAPTER_STATE_LOCK must be released.
  1284. *
  1285. * Returns:
  1286. * qla2x00 local function return status code.
  1287. *
  1288. * Context:
  1289. * Kernel context.
  1290. */
  1291. int
  1292. qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address,
  1293. uint16_t cmd_size, size_t buf_size)
  1294. {
  1295. int rval;
  1296. mbx_cmd_t mc;
  1297. mbx_cmd_t *mcp = &mc;
  1298. DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n",
  1299. ha->host_no);)
  1300. DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total "
  1301. "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov);)
  1302. mcp->mb[0] = MBC_SEND_SNS_COMMAND;
  1303. mcp->mb[1] = cmd_size;
  1304. mcp->mb[2] = MSW(sns_phys_address);
  1305. mcp->mb[3] = LSW(sns_phys_address);
  1306. mcp->mb[6] = MSW(MSD(sns_phys_address));
  1307. mcp->mb[7] = LSW(MSD(sns_phys_address));
  1308. mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
  1309. mcp->in_mb = MBX_0|MBX_1;
  1310. mcp->buf_size = buf_size;
  1311. mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
  1312. mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
  1313. rval = qla2x00_mailbox_command(ha, mcp);
  1314. if (rval != QLA_SUCCESS) {
  1315. /*EMPTY*/
  1316. DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
  1317. "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);)
  1318. DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
  1319. "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);)
  1320. } else {
  1321. /*EMPTY*/
  1322. DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no);)
  1323. }
  1324. return rval;
  1325. }
  1326. /*
  1327. * qla2x00_login_fabric
  1328. * Issue login fabric port mailbox command.
  1329. *
  1330. * Input:
  1331. * ha = adapter block pointer.
  1332. * loop_id = device loop ID.
  1333. * domain = device domain.
  1334. * area = device area.
  1335. * al_pa = device AL_PA.
  1336. * status = pointer for return status.
  1337. * opt = command options.
  1338. * TARGET_QUEUE_LOCK must be released.
  1339. * ADAPTER_STATE_LOCK must be released.
  1340. *
  1341. * Returns:
  1342. * qla2x00 local function return status code.
  1343. *
  1344. * Context:
  1345. * Kernel context.
  1346. */
  1347. int
  1348. qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
  1349. uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
  1350. {
  1351. int rval;
  1352. mbx_cmd_t mc;
  1353. mbx_cmd_t *mcp = &mc;
  1354. DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no);)
  1355. mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
  1356. mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
  1357. if (HAS_EXTENDED_IDS(ha)) {
  1358. mcp->mb[1] = loop_id;
  1359. mcp->mb[10] = opt;
  1360. mcp->out_mb |= MBX_10;
  1361. } else {
  1362. mcp->mb[1] = (loop_id << 8) | opt;
  1363. }
  1364. mcp->mb[2] = domain;
  1365. mcp->mb[3] = area << 8 | al_pa;
  1366. mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
  1367. mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
  1368. mcp->flags = 0;
  1369. rval = qla2x00_mailbox_command(ha, mcp);
  1370. /* Return mailbox statuses. */
  1371. if (mb != NULL) {
  1372. mb[0] = mcp->mb[0];
  1373. mb[1] = mcp->mb[1];
  1374. mb[2] = mcp->mb[2];
  1375. mb[6] = mcp->mb[6];
  1376. mb[7] = mcp->mb[7];
  1377. }
  1378. if (rval != QLA_SUCCESS) {
  1379. /* RLU tmp code: need to change main mailbox_command function to
  1380. * return ok even when the mailbox completion value is not
  1381. * SUCCESS. The caller needs to be responsible to interpret
  1382. * the return values of this mailbox command if we're not
  1383. * to change too much of the existing code.
  1384. */
  1385. if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
  1386. mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
  1387. mcp->mb[0] == 0x4006)
  1388. rval = QLA_SUCCESS;
  1389. /*EMPTY*/
  1390. DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x "
  1391. "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval,
  1392. mcp->mb[0], mcp->mb[1], mcp->mb[2]);)
  1393. } else {
  1394. /*EMPTY*/
  1395. DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n",
  1396. ha->host_no);)
  1397. }
  1398. return rval;
  1399. }
  1400. /*
  1401. * qla2x00_login_local_device
  1402. * Issue login loop port mailbox command.
  1403. *
  1404. * Input:
  1405. * ha = adapter block pointer.
  1406. * loop_id = device loop ID.
  1407. * opt = command options.
  1408. *
  1409. * Returns:
  1410. * Return status code.
  1411. *
  1412. * Context:
  1413. * Kernel context.
  1414. *
  1415. */
  1416. int
  1417. qla2x00_login_local_device(scsi_qla_host_t *ha, uint16_t loop_id,
  1418. uint16_t *mb_ret, uint8_t opt)
  1419. {
  1420. int rval;
  1421. mbx_cmd_t mc;
  1422. mbx_cmd_t *mcp = &mc;
  1423. DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
  1424. mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
  1425. if (HAS_EXTENDED_IDS(ha))
  1426. mcp->mb[1] = loop_id;
  1427. else
  1428. mcp->mb[1] = loop_id << 8;
  1429. mcp->mb[2] = opt;
  1430. mcp->out_mb = MBX_2|MBX_1|MBX_0;
  1431. mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
  1432. mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
  1433. mcp->flags = 0;
  1434. rval = qla2x00_mailbox_command(ha, mcp);
  1435. /* Return mailbox statuses. */
  1436. if (mb_ret != NULL) {
  1437. mb_ret[0] = mcp->mb[0];
  1438. mb_ret[1] = mcp->mb[1];
  1439. mb_ret[6] = mcp->mb[6];
  1440. mb_ret[7] = mcp->mb[7];
  1441. }
  1442. if (rval != QLA_SUCCESS) {
  1443. /* AV tmp code: need to change main mailbox_command function to
  1444. * return ok even when the mailbox completion value is not
  1445. * SUCCESS. The caller needs to be responsible to interpret
  1446. * the return values of this mailbox command if we're not
  1447. * to change too much of the existing code.
  1448. */
  1449. if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
  1450. rval = QLA_SUCCESS;
  1451. DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
  1452. "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval,
  1453. mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);)
  1454. DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
  1455. "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval,
  1456. mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);)
  1457. } else {
  1458. /*EMPTY*/
  1459. DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no);)
  1460. }
  1461. return (rval);
  1462. }
  1463. /*
  1464. * qla2x00_fabric_logout
  1465. * Issue logout fabric port mailbox command.
  1466. *
  1467. * Input:
  1468. * ha = adapter block pointer.
  1469. * loop_id = device loop ID.
  1470. * TARGET_QUEUE_LOCK must be released.
  1471. * ADAPTER_STATE_LOCK must be released.
  1472. *
  1473. * Returns:
  1474. * qla2x00 local function return status code.
  1475. *
  1476. * Context:
  1477. * Kernel context.
  1478. */
  1479. int
  1480. qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id)
  1481. {
  1482. int rval;
  1483. mbx_cmd_t mc;
  1484. mbx_cmd_t *mcp = &mc;
  1485. DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n",
  1486. ha->host_no);)
  1487. mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
  1488. mcp->out_mb = MBX_1|MBX_0;
  1489. if (HAS_EXTENDED_IDS(ha)) {
  1490. mcp->mb[1] = loop_id;
  1491. mcp->mb[10] = 0;
  1492. mcp->out_mb |= MBX_10;
  1493. } else {
  1494. mcp->mb[1] = loop_id << 8;
  1495. }
  1496. mcp->in_mb = MBX_1|MBX_0;
  1497. mcp->tov = 30;
  1498. mcp->flags = 0;
  1499. rval = qla2x00_mailbox_command(ha, mcp);
  1500. if (rval != QLA_SUCCESS) {
  1501. /*EMPTY*/
  1502. DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x "
  1503. "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]);)
  1504. } else {
  1505. /*EMPTY*/
  1506. DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n",
  1507. ha->host_no);)
  1508. }
  1509. return rval;
  1510. }
  1511. /*
  1512. * qla2x00_full_login_lip
  1513. * Issue full login LIP mailbox command.
  1514. *
  1515. * Input:
  1516. * ha = adapter block pointer.
  1517. * TARGET_QUEUE_LOCK must be released.
  1518. * ADAPTER_STATE_LOCK must be released.
  1519. *
  1520. * Returns:
  1521. * qla2x00 local function return status code.
  1522. *
  1523. * Context:
  1524. * Kernel context.
  1525. */
  1526. int
  1527. qla2x00_full_login_lip(scsi_qla_host_t *ha)
  1528. {
  1529. int rval;
  1530. mbx_cmd_t mc;
  1531. mbx_cmd_t *mcp = &mc;
  1532. DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n",
  1533. ha->host_no);)
  1534. mcp->mb[0] = MBC_LIP_FULL_LOGIN;
  1535. mcp->mb[1] = 0;
  1536. mcp->mb[2] = 0;
  1537. mcp->mb[3] = 0;
  1538. mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
  1539. mcp->in_mb = MBX_0;
  1540. mcp->tov = 30;
  1541. mcp->flags = 0;
  1542. rval = qla2x00_mailbox_command(ha, mcp);
  1543. if (rval != QLA_SUCCESS) {
  1544. /*EMPTY*/
  1545. DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n",
  1546. ha->instance, rval);)
  1547. } else {
  1548. /*EMPTY*/
  1549. DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n",
  1550. ha->host_no);)
  1551. }
  1552. return rval;
  1553. }
  1554. /*
  1555. * qla2x00_get_id_list
  1556. *
  1557. * Input:
  1558. * ha = adapter block pointer.
  1559. *
  1560. * Returns:
  1561. * qla2x00 local function return status code.
  1562. *
  1563. * Context:
  1564. * Kernel context.
  1565. */
  1566. int
  1567. qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
  1568. uint16_t *entries)
  1569. {
  1570. int rval;
  1571. mbx_cmd_t mc;
  1572. mbx_cmd_t *mcp = &mc;
  1573. DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n",
  1574. ha->host_no);)
  1575. if (id_list == NULL)
  1576. return QLA_FUNCTION_FAILED;
  1577. mcp->mb[0] = MBC_GET_ID_LIST;
  1578. mcp->mb[1] = MSW(id_list_dma);
  1579. mcp->mb[2] = LSW(id_list_dma);
  1580. mcp->mb[3] = MSW(MSD(id_list_dma));
  1581. mcp->mb[6] = LSW(MSD(id_list_dma));
  1582. mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
  1583. mcp->in_mb = MBX_1|MBX_0;
  1584. mcp->tov = 30;
  1585. mcp->flags = 0;
  1586. rval = qla2x00_mailbox_command(ha, mcp);
  1587. if (rval != QLA_SUCCESS) {
  1588. /*EMPTY*/
  1589. DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n",
  1590. ha->host_no, rval);)
  1591. } else {
  1592. *entries = mcp->mb[1];
  1593. DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n",
  1594. ha->host_no);)
  1595. }
  1596. return rval;
  1597. }
  1598. /*
  1599. * qla2x00_get_resource_cnts
  1600. * Get current firmware resource counts.
  1601. *
  1602. * Input:
  1603. * ha = adapter block pointer.
  1604. *
  1605. * Returns:
  1606. * qla2x00 local function return status code.
  1607. *
  1608. * Context:
  1609. * Kernel context.
  1610. */
  1611. int
  1612. qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt,
  1613. uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, uint16_t *orig_iocb_cnt)
  1614. {
  1615. int rval;
  1616. mbx_cmd_t mc;
  1617. mbx_cmd_t *mcp = &mc;
  1618. DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
  1619. mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
  1620. mcp->out_mb = MBX_0;
  1621. mcp->in_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
  1622. mcp->tov = 30;
  1623. mcp->flags = 0;
  1624. rval = qla2x00_mailbox_command(ha, mcp);
  1625. if (rval != QLA_SUCCESS) {
  1626. /*EMPTY*/
  1627. DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__,
  1628. ha->host_no, mcp->mb[0]);)
  1629. } else {
  1630. DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
  1631. "mb7=%x mb10=%x.\n", __func__, ha->host_no,
  1632. mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7],
  1633. mcp->mb[10]));
  1634. if (cur_xchg_cnt)
  1635. *cur_xchg_cnt = mcp->mb[3];
  1636. if (orig_xchg_cnt)
  1637. *orig_xchg_cnt = mcp->mb[6];
  1638. if (cur_iocb_cnt)
  1639. *cur_iocb_cnt = mcp->mb[7];
  1640. if (orig_iocb_cnt)
  1641. *orig_iocb_cnt = mcp->mb[10];
  1642. }
  1643. return (rval);
  1644. }
  1645. #if defined(QL_DEBUG_LEVEL_3)
  1646. /*
  1647. * qla2x00_get_fcal_position_map
  1648. * Get FCAL (LILP) position map using mailbox command
  1649. *
  1650. * Input:
  1651. * ha = adapter state pointer.
  1652. * pos_map = buffer pointer (can be NULL).
  1653. *
  1654. * Returns:
  1655. * qla2x00 local function return status code.
  1656. *
  1657. * Context:
  1658. * Kernel context.
  1659. */
  1660. int
  1661. qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map)
  1662. {
  1663. int rval;
  1664. mbx_cmd_t mc;
  1665. mbx_cmd_t *mcp = &mc;
  1666. char *pmap;
  1667. dma_addr_t pmap_dma;
  1668. pmap = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pmap_dma);
  1669. if (pmap == NULL) {
  1670. DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****",
  1671. __func__, ha->host_no));
  1672. return QLA_MEMORY_ALLOC_FAILED;
  1673. }
  1674. memset(pmap, 0, FCAL_MAP_SIZE);
  1675. mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
  1676. mcp->mb[2] = MSW(pmap_dma);
  1677. mcp->mb[3] = LSW(pmap_dma);
  1678. mcp->mb[6] = MSW(MSD(pmap_dma));
  1679. mcp->mb[7] = LSW(MSD(pmap_dma));
  1680. mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
  1681. mcp->in_mb = MBX_1|MBX_0;
  1682. mcp->buf_size = FCAL_MAP_SIZE;
  1683. mcp->flags = MBX_DMA_IN;
  1684. mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
  1685. rval = qla2x00_mailbox_command(ha, mcp);
  1686. if (rval == QLA_SUCCESS) {
  1687. DEBUG11(printk("%s(%ld): (mb0=%x/mb1=%x) FC/AL Position Map "
  1688. "size (%x)\n", __func__, ha->host_no, mcp->mb[0],
  1689. mcp->mb[1], (unsigned)pmap[0]));
  1690. DEBUG11(qla2x00_dump_buffer(pmap, pmap[0] + 1));
  1691. if (pos_map)
  1692. memcpy(pos_map, pmap, FCAL_MAP_SIZE);
  1693. }
  1694. dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
  1695. if (rval != QLA_SUCCESS) {
  1696. DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
  1697. ha->host_no, rval));
  1698. } else {
  1699. DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
  1700. }
  1701. return rval;
  1702. }
  1703. #endif