ql4_mbx.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907
  1. /*
  2. * QLogic iSCSI HBA Driver
  3. * Copyright (c) 2003-2006 QLogic Corporation
  4. *
  5. * See LICENSE.qla4xxx for copyright and licensing details.
  6. */
  7. #include "ql4_def.h"
  8. #include "ql4_glbl.h"
  9. #include "ql4_dbg.h"
  10. #include "ql4_inline.h"
  11. /**
  12. * qla4xxx_mailbox_command - issues mailbox commands
  13. * @ha: Pointer to host adapter structure.
  14. * @inCount: number of mailbox registers to load.
  15. * @outCount: number of mailbox registers to return.
  16. * @mbx_cmd: data pointer for mailbox in registers.
  17. * @mbx_sts: data pointer for mailbox out registers.
  18. *
  19. * This routine sssue mailbox commands and waits for completion.
  20. * If outCount is 0, this routine completes successfully WITHOUT waiting
  21. * for the mailbox command to complete.
  22. **/
  23. static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
  24. uint8_t outCount, uint32_t *mbx_cmd,
  25. uint32_t *mbx_sts)
  26. {
  27. int status = QLA_ERROR;
  28. uint8_t i;
  29. u_long wait_count;
  30. uint32_t intr_status;
  31. unsigned long flags = 0;
  32. /* Make sure that pointers are valid */
  33. if (!mbx_cmd || !mbx_sts) {
  34. DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
  35. "pointer\n", ha->host_no, __func__));
  36. return status;
  37. }
  38. /* Mailbox code active */
  39. wait_count = MBOX_TOV * 100;
  40. while (wait_count--) {
  41. mutex_lock(&ha->mbox_sem);
  42. if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {
  43. set_bit(AF_MBOX_COMMAND, &ha->flags);
  44. mutex_unlock(&ha->mbox_sem);
  45. break;
  46. }
  47. mutex_unlock(&ha->mbox_sem);
  48. if (!wait_count) {
  49. DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n",
  50. ha->host_no, __func__));
  51. return status;
  52. }
  53. msleep(10);
  54. }
  55. /* To prevent overwriting mailbox registers for a command that has
  56. * not yet been serviced, check to see if a previously issued
  57. * mailbox command is interrupting.
  58. * -----------------------------------------------------------------
  59. */
  60. spin_lock_irqsave(&ha->hardware_lock, flags);
  61. intr_status = readl(&ha->reg->ctrl_status);
  62. if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
  63. /* Service existing interrupt */
  64. qla4xxx_interrupt_service_routine(ha, intr_status);
  65. clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
  66. }
  67. /* Send the mailbox command to the firmware */
  68. ha->mbox_status_count = outCount;
  69. for (i = 0; i < outCount; i++)
  70. ha->mbox_status[i] = 0;
  71. /* Load all mailbox registers, except mailbox 0. */
  72. for (i = 1; i < inCount; i++)
  73. writel(mbx_cmd[i], &ha->reg->mailbox[i]);
  74. /* Wakeup firmware */
  75. writel(mbx_cmd[0], &ha->reg->mailbox[0]);
  76. readl(&ha->reg->mailbox[0]);
  77. writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
  78. readl(&ha->reg->ctrl_status);
  79. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  80. /* Wait for completion */
  81. /*
  82. * If we don't want status, don't wait for the mailbox command to
  83. * complete. For example, MBOX_CMD_RESET_FW doesn't return status,
  84. * you must poll the inbound Interrupt Mask for completion.
  85. */
  86. if (outCount == 0) {
  87. status = QLA_SUCCESS;
  88. goto mbox_exit;
  89. }
  90. /* Wait for command to complete */
  91. wait_count = jiffies + MBOX_TOV * HZ;
  92. while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
  93. if (time_after_eq(jiffies, wait_count))
  94. break;
  95. spin_lock_irqsave(&ha->hardware_lock, flags);
  96. intr_status = readl(&ha->reg->ctrl_status);
  97. if (intr_status & INTR_PENDING) {
  98. /*
  99. * Service the interrupt.
  100. * The ISR will save the mailbox status registers
  101. * to a temporary storage location in the adapter
  102. * structure.
  103. */
  104. ha->mbox_status_count = outCount;
  105. qla4xxx_interrupt_service_routine(ha, intr_status);
  106. }
  107. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  108. msleep(10);
  109. }
  110. /* Check for mailbox timeout. */
  111. if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
  112. DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...,"
  113. " Scheduling Adapter Reset\n", ha->host_no,
  114. mbx_cmd[0]));
  115. ha->mailbox_timeout_count++;
  116. mbx_sts[0] = (-1);
  117. set_bit(DPC_RESET_HA, &ha->dpc_flags);
  118. goto mbox_exit;
  119. }
  120. /*
  121. * Copy the mailbox out registers to the caller's mailbox in/out
  122. * structure.
  123. */
  124. spin_lock_irqsave(&ha->hardware_lock, flags);
  125. for (i = 0; i < outCount; i++)
  126. mbx_sts[i] = ha->mbox_status[i];
  127. /* Set return status and error flags (if applicable). */
  128. switch (ha->mbox_status[0]) {
  129. case MBOX_STS_COMMAND_COMPLETE:
  130. status = QLA_SUCCESS;
  131. break;
  132. case MBOX_STS_INTERMEDIATE_COMPLETION:
  133. status = QLA_SUCCESS;
  134. break;
  135. case MBOX_STS_BUSY:
  136. DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n",
  137. ha->host_no, __func__, mbx_cmd[0]));
  138. ha->mailbox_timeout_count++;
  139. break;
  140. default:
  141. DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, "
  142. "sts = %08X ****\n", ha->host_no, __func__,
  143. mbx_cmd[0], mbx_sts[0]));
  144. break;
  145. }
  146. spin_unlock_irqrestore(&ha->hardware_lock, flags);
  147. mbox_exit:
  148. mutex_lock(&ha->mbox_sem);
  149. clear_bit(AF_MBOX_COMMAND, &ha->flags);
  150. mutex_unlock(&ha->mbox_sem);
  151. clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
  152. return status;
  153. }
  154. /**
  155. * qla4xxx_initialize_fw_cb - initializes firmware control block.
  156. * @ha: Pointer to host adapter structure.
  157. **/
  158. int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
  159. {
  160. struct init_fw_ctrl_blk *init_fw_cb;
  161. dma_addr_t init_fw_cb_dma;
  162. uint32_t mbox_cmd[MBOX_REG_COUNT];
  163. uint32_t mbox_sts[MBOX_REG_COUNT];
  164. int status = QLA_ERROR;
  165. init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
  166. sizeof(struct init_fw_ctrl_blk),
  167. &init_fw_cb_dma, GFP_KERNEL);
  168. if (init_fw_cb == NULL) {
  169. DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n",
  170. ha->host_no, __func__));
  171. return 10;
  172. }
  173. memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk));
  174. /* Get Initialize Firmware Control Block. */
  175. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  176. memset(&mbox_sts, 0, sizeof(mbox_sts));
  177. mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
  178. mbox_cmd[2] = LSDW(init_fw_cb_dma);
  179. mbox_cmd[3] = MSDW(init_fw_cb_dma);
  180. mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk);
  181. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
  182. QLA_SUCCESS) {
  183. dma_free_coherent(&ha->pdev->dev,
  184. sizeof(struct init_fw_ctrl_blk),
  185. init_fw_cb, init_fw_cb_dma);
  186. return status;
  187. }
  188. /* Initialize request and response queues. */
  189. qla4xxx_init_rings(ha);
  190. /* Fill in the request and response queue information. */
  191. init_fw_cb->pri.rqq_consumer_idx = cpu_to_le16(ha->request_out);
  192. init_fw_cb->pri.compq_producer_idx = cpu_to_le16(ha->response_in);
  193. init_fw_cb->pri.rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
  194. init_fw_cb->pri.compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
  195. init_fw_cb->pri.rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma));
  196. init_fw_cb->pri.rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma));
  197. init_fw_cb->pri.compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma));
  198. init_fw_cb->pri.compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma));
  199. init_fw_cb->pri.shdwreg_addr_lo =
  200. cpu_to_le32(LSDW(ha->shadow_regs_dma));
  201. init_fw_cb->pri.shdwreg_addr_hi =
  202. cpu_to_le32(MSDW(ha->shadow_regs_dma));
  203. /* Set up required options. */
  204. init_fw_cb->pri.fw_options |=
  205. __constant_cpu_to_le16(FWOPT_SESSION_MODE |
  206. FWOPT_INITIATOR_MODE);
  207. init_fw_cb->pri.fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
  208. /* Save some info in adapter structure. */
  209. ha->firmware_options = le16_to_cpu(init_fw_cb->pri.fw_options);
  210. ha->tcp_options = le16_to_cpu(init_fw_cb->pri.ipv4_tcp_opts);
  211. ha->heartbeat_interval = init_fw_cb->pri.hb_interval;
  212. memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr,
  213. min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr)));
  214. memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet,
  215. min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet)));
  216. memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr,
  217. min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr)));
  218. memcpy(ha->name_string, init_fw_cb->pri.iscsi_name,
  219. min(sizeof(ha->name_string),
  220. sizeof(init_fw_cb->pri.iscsi_name)));
  221. /*memcpy(ha->alias, init_fw_cb->Alias,
  222. min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/
  223. /* Save Command Line Paramater info */
  224. ha->port_down_retry_count = le16_to_cpu(init_fw_cb->pri.conn_ka_timeout);
  225. ha->discovery_wait = ql4xdiscoverywait;
  226. /* Send Initialize Firmware Control Block. */
  227. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  228. memset(&mbox_sts, 0, sizeof(mbox_sts));
  229. mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
  230. mbox_cmd[1] = 0;
  231. mbox_cmd[2] = LSDW(init_fw_cb_dma);
  232. mbox_cmd[3] = MSDW(init_fw_cb_dma);
  233. mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk);
  234. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) ==
  235. QLA_SUCCESS)
  236. status = QLA_SUCCESS;
  237. else {
  238. DEBUG2(printk("scsi%ld: %s: MBOX_CMD_INITIALIZE_FIRMWARE "
  239. "failed w/ status %04X\n", ha->host_no, __func__,
  240. mbox_sts[0]));
  241. }
  242. dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk),
  243. init_fw_cb, init_fw_cb_dma);
  244. return status;
  245. }
  246. /**
  247. * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP
  248. * @ha: Pointer to host adapter structure.
  249. **/
  250. int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
  251. {
  252. struct init_fw_ctrl_blk *init_fw_cb;
  253. dma_addr_t init_fw_cb_dma;
  254. uint32_t mbox_cmd[MBOX_REG_COUNT];
  255. uint32_t mbox_sts[MBOX_REG_COUNT];
  256. init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
  257. sizeof(struct init_fw_ctrl_blk),
  258. &init_fw_cb_dma, GFP_KERNEL);
  259. if (init_fw_cb == NULL) {
  260. printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no,
  261. __func__);
  262. return 10;
  263. }
  264. /* Get Initialize Firmware Control Block. */
  265. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  266. memset(&mbox_sts, 0, sizeof(mbox_sts));
  267. memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk));
  268. mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
  269. mbox_cmd[2] = LSDW(init_fw_cb_dma);
  270. mbox_cmd[3] = MSDW(init_fw_cb_dma);
  271. mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk);
  272. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
  273. QLA_SUCCESS) {
  274. DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
  275. ha->host_no, __func__));
  276. dma_free_coherent(&ha->pdev->dev,
  277. sizeof(struct init_fw_ctrl_blk),
  278. init_fw_cb, init_fw_cb_dma);
  279. return QLA_ERROR;
  280. }
  281. /* Save IP Address. */
  282. memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr,
  283. min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr)));
  284. memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet,
  285. min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet)));
  286. memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr,
  287. min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr)));
  288. dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk),
  289. init_fw_cb, init_fw_cb_dma);
  290. return QLA_SUCCESS;
  291. }
  292. /**
  293. * qla4xxx_get_firmware_state - gets firmware state of HBA
  294. * @ha: Pointer to host adapter structure.
  295. **/
  296. int qla4xxx_get_firmware_state(struct scsi_qla_host * ha)
  297. {
  298. uint32_t mbox_cmd[MBOX_REG_COUNT];
  299. uint32_t mbox_sts[MBOX_REG_COUNT];
  300. /* Get firmware version */
  301. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  302. memset(&mbox_sts, 0, sizeof(mbox_sts));
  303. mbox_cmd[0] = MBOX_CMD_GET_FW_STATE;
  304. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) !=
  305. QLA_SUCCESS) {
  306. DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ "
  307. "status %04X\n", ha->host_no, __func__,
  308. mbox_sts[0]));
  309. return QLA_ERROR;
  310. }
  311. ha->firmware_state = mbox_sts[1];
  312. ha->board_id = mbox_sts[2];
  313. ha->addl_fw_state = mbox_sts[3];
  314. DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n",
  315. ha->host_no, __func__, ha->firmware_state);)
  316. return QLA_SUCCESS;
  317. }
  318. /**
  319. * qla4xxx_get_firmware_status - retrieves firmware status
  320. * @ha: Pointer to host adapter structure.
  321. **/
  322. int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
  323. {
  324. uint32_t mbox_cmd[MBOX_REG_COUNT];
  325. uint32_t mbox_sts[MBOX_REG_COUNT];
  326. /* Get firmware version */
  327. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  328. memset(&mbox_sts, 0, sizeof(mbox_sts));
  329. mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS;
  330. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
  331. QLA_SUCCESS) {
  332. DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ "
  333. "status %04X\n", ha->host_no, __func__,
  334. mbox_sts[0]));
  335. return QLA_ERROR;
  336. }
  337. return QLA_SUCCESS;
  338. }
  339. /**
  340. * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry
  341. * @ha: Pointer to host adapter structure.
  342. * @fw_ddb_index: Firmware's device database index
  343. * @fw_ddb_entry: Pointer to firmware's device database entry structure
  344. * @num_valid_ddb_entries: Pointer to number of valid ddb entries
  345. * @next_ddb_index: Pointer to next valid device database index
  346. * @fw_ddb_device_state: Pointer to device state
  347. **/
  348. int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
  349. uint16_t fw_ddb_index,
  350. struct dev_db_entry *fw_ddb_entry,
  351. dma_addr_t fw_ddb_entry_dma,
  352. uint32_t *num_valid_ddb_entries,
  353. uint32_t *next_ddb_index,
  354. uint32_t *fw_ddb_device_state,
  355. uint32_t *conn_err_detail,
  356. uint16_t *tcp_source_port_num,
  357. uint16_t *connection_id)
  358. {
  359. int status = QLA_ERROR;
  360. uint32_t mbox_cmd[MBOX_REG_COUNT];
  361. uint32_t mbox_sts[MBOX_REG_COUNT];
  362. /* Make sure the device index is valid */
  363. if (fw_ddb_index >= MAX_DDB_ENTRIES) {
  364. DEBUG2(printk("scsi%ld: %s: index [%d] out of range.\n",
  365. ha->host_no, __func__, fw_ddb_index));
  366. goto exit_get_fwddb;
  367. }
  368. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  369. memset(&mbox_sts, 0, sizeof(mbox_sts));
  370. mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
  371. mbox_cmd[1] = (uint32_t) fw_ddb_index;
  372. mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
  373. mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
  374. mbox_cmd[4] = sizeof(struct dev_db_entry);
  375. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) ==
  376. QLA_ERROR) {
  377. DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"
  378. " with status 0x%04X\n", ha->host_no, __func__,
  379. mbox_sts[0]));
  380. goto exit_get_fwddb;
  381. }
  382. if (fw_ddb_index != mbox_sts[1]) {
  383. DEBUG2(printk("scsi%ld: %s: index mismatch [%d] != [%d].\n",
  384. ha->host_no, __func__, fw_ddb_index,
  385. mbox_sts[1]));
  386. goto exit_get_fwddb;
  387. }
  388. if (fw_ddb_entry) {
  389. dev_info(&ha->pdev->dev, "DDB[%d] MB0 %04x Tot %d Next %d "
  390. "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n",
  391. fw_ddb_index, mbox_sts[0], mbox_sts[2], mbox_sts[3],
  392. mbox_sts[4], mbox_sts[5], fw_ddb_entry->ip_addr[0],
  393. fw_ddb_entry->ip_addr[1], fw_ddb_entry->ip_addr[2],
  394. fw_ddb_entry->ip_addr[3],
  395. le16_to_cpu(fw_ddb_entry->port),
  396. fw_ddb_entry->iscsi_name);
  397. }
  398. if (num_valid_ddb_entries)
  399. *num_valid_ddb_entries = mbox_sts[2];
  400. if (next_ddb_index)
  401. *next_ddb_index = mbox_sts[3];
  402. if (fw_ddb_device_state)
  403. *fw_ddb_device_state = mbox_sts[4];
  404. /*
  405. * RA: This mailbox has been changed to pass connection error and
  406. * details. Its true for ISP4010 as per Version E - Not sure when it
  407. * was changed. Get the time2wait from the fw_dd_entry field :
  408. * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY
  409. * struct.
  410. */
  411. if (conn_err_detail)
  412. *conn_err_detail = mbox_sts[5];
  413. if (tcp_source_port_num)
  414. *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16;
  415. if (connection_id)
  416. *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
  417. status = QLA_SUCCESS;
  418. exit_get_fwddb:
  419. return status;
  420. }
  421. /**
  422. * qla4xxx_set_fwddb_entry - sets a ddb entry.
  423. * @ha: Pointer to host adapter structure.
  424. * @fw_ddb_index: Firmware's device database index
  425. * @fw_ddb_entry: Pointer to firmware's ddb entry structure, or NULL.
  426. *
  427. * This routine initializes or updates the adapter's device database
  428. * entry for the specified device. It also triggers a login for the
  429. * specified device. Therefore, it may also be used as a secondary
  430. * login routine when a NULL pointer is specified for the fw_ddb_entry.
  431. **/
  432. int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
  433. dma_addr_t fw_ddb_entry_dma)
  434. {
  435. uint32_t mbox_cmd[MBOX_REG_COUNT];
  436. uint32_t mbox_sts[MBOX_REG_COUNT];
  437. /* Do not wait for completion. The firmware will send us an
  438. * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
  439. */
  440. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  441. memset(&mbox_sts, 0, sizeof(mbox_sts));
  442. mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY;
  443. mbox_cmd[1] = (uint32_t) fw_ddb_index;
  444. mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
  445. mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
  446. mbox_cmd[4] = sizeof(struct dev_db_entry);
  447. return qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
  448. }
  449. /**
  450. * qla4xxx_get_crash_record - retrieves crash record.
  451. * @ha: Pointer to host adapter structure.
  452. *
  453. * This routine retrieves a crash record from the QLA4010 after an 8002h aen.
  454. **/
  455. void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
  456. {
  457. uint32_t mbox_cmd[MBOX_REG_COUNT];
  458. uint32_t mbox_sts[MBOX_REG_COUNT];
  459. struct crash_record *crash_record = NULL;
  460. dma_addr_t crash_record_dma = 0;
  461. uint32_t crash_record_size = 0;
  462. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  463. memset(&mbox_sts, 0, sizeof(mbox_cmd));
  464. /* Get size of crash record. */
  465. mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
  466. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  467. QLA_SUCCESS) {
  468. DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",
  469. ha->host_no, __func__));
  470. goto exit_get_crash_record;
  471. }
  472. crash_record_size = mbox_sts[4];
  473. if (crash_record_size == 0) {
  474. DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n",
  475. ha->host_no, __func__));
  476. goto exit_get_crash_record;
  477. }
  478. /* Alloc Memory for Crash Record. */
  479. crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size,
  480. &crash_record_dma, GFP_KERNEL);
  481. if (crash_record == NULL)
  482. goto exit_get_crash_record;
  483. /* Get Crash Record. */
  484. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  485. memset(&mbox_sts, 0, sizeof(mbox_cmd));
  486. mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
  487. mbox_cmd[2] = LSDW(crash_record_dma);
  488. mbox_cmd[3] = MSDW(crash_record_dma);
  489. mbox_cmd[4] = crash_record_size;
  490. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  491. QLA_SUCCESS)
  492. goto exit_get_crash_record;
  493. /* Dump Crash Record. */
  494. exit_get_crash_record:
  495. if (crash_record)
  496. dma_free_coherent(&ha->pdev->dev, crash_record_size,
  497. crash_record, crash_record_dma);
  498. }
  499. /**
  500. * qla4xxx_get_conn_event_log - retrieves connection event log
  501. * @ha: Pointer to host adapter structure.
  502. **/
  503. void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
  504. {
  505. uint32_t mbox_cmd[MBOX_REG_COUNT];
  506. uint32_t mbox_sts[MBOX_REG_COUNT];
  507. struct conn_event_log_entry *event_log = NULL;
  508. dma_addr_t event_log_dma = 0;
  509. uint32_t event_log_size = 0;
  510. uint32_t num_valid_entries;
  511. uint32_t oldest_entry = 0;
  512. uint32_t max_event_log_entries;
  513. uint8_t i;
  514. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  515. memset(&mbox_sts, 0, sizeof(mbox_cmd));
  516. /* Get size of crash record. */
  517. mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
  518. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  519. QLA_SUCCESS)
  520. goto exit_get_event_log;
  521. event_log_size = mbox_sts[4];
  522. if (event_log_size == 0)
  523. goto exit_get_event_log;
  524. /* Alloc Memory for Crash Record. */
  525. event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size,
  526. &event_log_dma, GFP_KERNEL);
  527. if (event_log == NULL)
  528. goto exit_get_event_log;
  529. /* Get Crash Record. */
  530. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  531. memset(&mbox_sts, 0, sizeof(mbox_cmd));
  532. mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
  533. mbox_cmd[2] = LSDW(event_log_dma);
  534. mbox_cmd[3] = MSDW(event_log_dma);
  535. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  536. QLA_SUCCESS) {
  537. DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "
  538. "log!\n", ha->host_no, __func__));
  539. goto exit_get_event_log;
  540. }
  541. /* Dump Event Log. */
  542. num_valid_entries = mbox_sts[1];
  543. max_event_log_entries = event_log_size /
  544. sizeof(struct conn_event_log_entry);
  545. if (num_valid_entries > max_event_log_entries)
  546. oldest_entry = num_valid_entries % max_event_log_entries;
  547. DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
  548. ha->host_no, num_valid_entries));
  549. if (ql4xextended_error_logging == 3) {
  550. if (oldest_entry == 0) {
  551. /* Circular Buffer has not wrapped around */
  552. for (i=0; i < num_valid_entries; i++) {
  553. qla4xxx_dump_buffer((uint8_t *)event_log+
  554. (i*sizeof(*event_log)),
  555. sizeof(*event_log));
  556. }
  557. }
  558. else {
  559. /* Circular Buffer has wrapped around -
  560. * display accordingly*/
  561. for (i=oldest_entry; i < max_event_log_entries; i++) {
  562. qla4xxx_dump_buffer((uint8_t *)event_log+
  563. (i*sizeof(*event_log)),
  564. sizeof(*event_log));
  565. }
  566. for (i=0; i < oldest_entry; i++) {
  567. qla4xxx_dump_buffer((uint8_t *)event_log+
  568. (i*sizeof(*event_log)),
  569. sizeof(*event_log));
  570. }
  571. }
  572. }
  573. exit_get_event_log:
  574. if (event_log)
  575. dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,
  576. event_log_dma);
  577. }
  578. /**
  579. * qla4xxx_reset_lun - issues LUN Reset
  580. * @ha: Pointer to host adapter structure.
  581. * @db_entry: Pointer to device database entry
  582. * @un_entry: Pointer to lun entry structure
  583. *
  584. * This routine performs a LUN RESET on the specified target/lun.
  585. * The caller must ensure that the ddb_entry and lun_entry pointers
  586. * are valid before calling this routine.
  587. **/
  588. int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
  589. int lun)
  590. {
  591. uint32_t mbox_cmd[MBOX_REG_COUNT];
  592. uint32_t mbox_sts[MBOX_REG_COUNT];
  593. int status = QLA_SUCCESS;
  594. DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no,
  595. ddb_entry->os_target_id, lun));
  596. /*
  597. * Send lun reset command to ISP, so that the ISP will return all
  598. * outstanding requests with RESET status
  599. */
  600. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  601. memset(&mbox_sts, 0, sizeof(mbox_sts));
  602. mbox_cmd[0] = MBOX_CMD_LUN_RESET;
  603. mbox_cmd[1] = ddb_entry->fw_ddb_index;
  604. mbox_cmd[2] = lun << 8;
  605. mbox_cmd[5] = 0x01; /* Immediate Command Enable */
  606. qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
  607. if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
  608. mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
  609. status = QLA_ERROR;
  610. return status;
  611. }
  612. /**
  613. * qla4xxx_reset_target - issues target Reset
  614. * @ha: Pointer to host adapter structure.
  615. * @db_entry: Pointer to device database entry
  616. * @un_entry: Pointer to lun entry structure
  617. *
  618. * This routine performs a TARGET RESET on the specified target.
  619. * The caller must ensure that the ddb_entry pointers
  620. * are valid before calling this routine.
  621. **/
  622. int qla4xxx_reset_target(struct scsi_qla_host *ha,
  623. struct ddb_entry *ddb_entry)
  624. {
  625. uint32_t mbox_cmd[MBOX_REG_COUNT];
  626. uint32_t mbox_sts[MBOX_REG_COUNT];
  627. int status = QLA_SUCCESS;
  628. DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no,
  629. ddb_entry->os_target_id));
  630. /*
  631. * Send target reset command to ISP, so that the ISP will return all
  632. * outstanding requests with RESET status
  633. */
  634. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  635. memset(&mbox_sts, 0, sizeof(mbox_sts));
  636. mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET;
  637. mbox_cmd[1] = ddb_entry->fw_ddb_index;
  638. mbox_cmd[5] = 0x01; /* Immediate Command Enable */
  639. qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
  640. &mbox_sts[0]);
  641. if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
  642. mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
  643. status = QLA_ERROR;
  644. return status;
  645. }
  646. int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
  647. uint32_t offset, uint32_t len)
  648. {
  649. uint32_t mbox_cmd[MBOX_REG_COUNT];
  650. uint32_t mbox_sts[MBOX_REG_COUNT];
  651. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  652. memset(&mbox_sts, 0, sizeof(mbox_sts));
  653. mbox_cmd[0] = MBOX_CMD_READ_FLASH;
  654. mbox_cmd[1] = LSDW(dma_addr);
  655. mbox_cmd[2] = MSDW(dma_addr);
  656. mbox_cmd[3] = offset;
  657. mbox_cmd[4] = len;
  658. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) !=
  659. QLA_SUCCESS) {
  660. DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "
  661. "status %04X %04X, offset %08x, len %08x\n", ha->host_no,
  662. __func__, mbox_sts[0], mbox_sts[1], offset, len));
  663. return QLA_ERROR;
  664. }
  665. return QLA_SUCCESS;
  666. }
  667. /**
  668. * qla4xxx_get_fw_version - gets firmware version
  669. * @ha: Pointer to host adapter structure.
  670. *
  671. * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may
  672. * hold an address for data. Make sure that we write 0 to those mailboxes,
  673. * if unused.
  674. **/
  675. int qla4xxx_get_fw_version(struct scsi_qla_host * ha)
  676. {
  677. uint32_t mbox_cmd[MBOX_REG_COUNT];
  678. uint32_t mbox_sts[MBOX_REG_COUNT];
  679. /* Get firmware version. */
  680. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  681. memset(&mbox_sts, 0, sizeof(mbox_sts));
  682. mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
  683. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  684. QLA_SUCCESS) {
  685. DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ "
  686. "status %04X\n", ha->host_no, __func__, mbox_sts[0]));
  687. return QLA_ERROR;
  688. }
  689. /* Save firmware version information. */
  690. ha->firmware_version[0] = mbox_sts[1];
  691. ha->firmware_version[1] = mbox_sts[2];
  692. ha->patch_number = mbox_sts[3];
  693. ha->build_number = mbox_sts[4];
  694. return QLA_SUCCESS;
  695. }
  696. static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha,
  697. dma_addr_t dma_addr)
  698. {
  699. uint32_t mbox_cmd[MBOX_REG_COUNT];
  700. uint32_t mbox_sts[MBOX_REG_COUNT];
  701. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  702. memset(&mbox_sts, 0, sizeof(mbox_sts));
  703. mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS;
  704. mbox_cmd[2] = LSDW(dma_addr);
  705. mbox_cmd[3] = MSDW(dma_addr);
  706. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
  707. QLA_SUCCESS) {
  708. DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
  709. ha->host_no, __func__, mbox_sts[0]));
  710. return QLA_ERROR;
  711. }
  712. return QLA_SUCCESS;
  713. }
  714. static int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index)
  715. {
  716. uint32_t mbox_cmd[MBOX_REG_COUNT];
  717. uint32_t mbox_sts[MBOX_REG_COUNT];
  718. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  719. memset(&mbox_sts, 0, sizeof(mbox_sts));
  720. mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;
  721. mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES;
  722. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
  723. QLA_SUCCESS) {
  724. if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) {
  725. *ddb_index = mbox_sts[2];
  726. } else {
  727. DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
  728. ha->host_no, __func__, mbox_sts[0]));
  729. return QLA_ERROR;
  730. }
  731. } else {
  732. *ddb_index = MAX_PRST_DEV_DB_ENTRIES;
  733. }
  734. return QLA_SUCCESS;
  735. }
  736. int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port)
  737. {
  738. struct dev_db_entry *fw_ddb_entry;
  739. dma_addr_t fw_ddb_entry_dma;
  740. uint32_t ddb_index;
  741. int ret_val = QLA_SUCCESS;
  742. fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
  743. sizeof(*fw_ddb_entry),
  744. &fw_ddb_entry_dma, GFP_KERNEL);
  745. if (!fw_ddb_entry) {
  746. DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
  747. ha->host_no, __func__));
  748. ret_val = QLA_ERROR;
  749. goto qla4xxx_send_tgts_exit;
  750. }
  751. ret_val = qla4xxx_get_default_ddb(ha, fw_ddb_entry_dma);
  752. if (ret_val != QLA_SUCCESS)
  753. goto qla4xxx_send_tgts_exit;
  754. ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index);
  755. if (ret_val != QLA_SUCCESS)
  756. goto qla4xxx_send_tgts_exit;
  757. memset(fw_ddb_entry->iscsi_alias, 0,
  758. sizeof(fw_ddb_entry->iscsi_alias));
  759. memset(fw_ddb_entry->iscsi_name, 0,
  760. sizeof(fw_ddb_entry->iscsi_name));
  761. memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr));
  762. memset(fw_ddb_entry->tgt_addr, 0,
  763. sizeof(fw_ddb_entry->tgt_addr));
  764. fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET);
  765. fw_ddb_entry->port = cpu_to_le16(ntohs(port));
  766. fw_ddb_entry->ip_addr[0] = *ip;
  767. fw_ddb_entry->ip_addr[1] = *(ip + 1);
  768. fw_ddb_entry->ip_addr[2] = *(ip + 2);
  769. fw_ddb_entry->ip_addr[3] = *(ip + 3);
  770. ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma);
  771. qla4xxx_send_tgts_exit:
  772. dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
  773. fw_ddb_entry, fw_ddb_entry_dma);
  774. return ret_val;
  775. }