ql4_mbx.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  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. /* High-water mark of IOCBs */
  338. ha->iocb_hiwat = mbox_sts[2];
  339. if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION)
  340. ha->iocb_hiwat -= IOCB_HIWAT_CUSHION;
  341. else
  342. dev_info(&ha->pdev->dev, "WARNING!!! You have less than %d "
  343. "firmare IOCBs available (%d).\n",
  344. IOCB_HIWAT_CUSHION, ha->iocb_hiwat);
  345. return QLA_SUCCESS;
  346. }
  347. /**
  348. * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry
  349. * @ha: Pointer to host adapter structure.
  350. * @fw_ddb_index: Firmware's device database index
  351. * @fw_ddb_entry: Pointer to firmware's device database entry structure
  352. * @num_valid_ddb_entries: Pointer to number of valid ddb entries
  353. * @next_ddb_index: Pointer to next valid device database index
  354. * @fw_ddb_device_state: Pointer to device state
  355. **/
  356. int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
  357. uint16_t fw_ddb_index,
  358. struct dev_db_entry *fw_ddb_entry,
  359. dma_addr_t fw_ddb_entry_dma,
  360. uint32_t *num_valid_ddb_entries,
  361. uint32_t *next_ddb_index,
  362. uint32_t *fw_ddb_device_state,
  363. uint32_t *conn_err_detail,
  364. uint16_t *tcp_source_port_num,
  365. uint16_t *connection_id)
  366. {
  367. int status = QLA_ERROR;
  368. uint32_t mbox_cmd[MBOX_REG_COUNT];
  369. uint32_t mbox_sts[MBOX_REG_COUNT];
  370. /* Make sure the device index is valid */
  371. if (fw_ddb_index >= MAX_DDB_ENTRIES) {
  372. DEBUG2(printk("scsi%ld: %s: index [%d] out of range.\n",
  373. ha->host_no, __func__, fw_ddb_index));
  374. goto exit_get_fwddb;
  375. }
  376. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  377. memset(&mbox_sts, 0, sizeof(mbox_sts));
  378. mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
  379. mbox_cmd[1] = (uint32_t) fw_ddb_index;
  380. mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
  381. mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
  382. mbox_cmd[4] = sizeof(struct dev_db_entry);
  383. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) ==
  384. QLA_ERROR) {
  385. DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"
  386. " with status 0x%04X\n", ha->host_no, __func__,
  387. mbox_sts[0]));
  388. goto exit_get_fwddb;
  389. }
  390. if (fw_ddb_index != mbox_sts[1]) {
  391. DEBUG2(printk("scsi%ld: %s: index mismatch [%d] != [%d].\n",
  392. ha->host_no, __func__, fw_ddb_index,
  393. mbox_sts[1]));
  394. goto exit_get_fwddb;
  395. }
  396. if (fw_ddb_entry) {
  397. dev_info(&ha->pdev->dev, "DDB[%d] MB0 %04x Tot %d Next %d "
  398. "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n",
  399. fw_ddb_index, mbox_sts[0], mbox_sts[2], mbox_sts[3],
  400. mbox_sts[4], mbox_sts[5], fw_ddb_entry->ip_addr[0],
  401. fw_ddb_entry->ip_addr[1], fw_ddb_entry->ip_addr[2],
  402. fw_ddb_entry->ip_addr[3],
  403. le16_to_cpu(fw_ddb_entry->port),
  404. fw_ddb_entry->iscsi_name);
  405. }
  406. if (num_valid_ddb_entries)
  407. *num_valid_ddb_entries = mbox_sts[2];
  408. if (next_ddb_index)
  409. *next_ddb_index = mbox_sts[3];
  410. if (fw_ddb_device_state)
  411. *fw_ddb_device_state = mbox_sts[4];
  412. /*
  413. * RA: This mailbox has been changed to pass connection error and
  414. * details. Its true for ISP4010 as per Version E - Not sure when it
  415. * was changed. Get the time2wait from the fw_dd_entry field :
  416. * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY
  417. * struct.
  418. */
  419. if (conn_err_detail)
  420. *conn_err_detail = mbox_sts[5];
  421. if (tcp_source_port_num)
  422. *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16;
  423. if (connection_id)
  424. *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
  425. status = QLA_SUCCESS;
  426. exit_get_fwddb:
  427. return status;
  428. }
  429. /**
  430. * qla4xxx_set_fwddb_entry - sets a ddb entry.
  431. * @ha: Pointer to host adapter structure.
  432. * @fw_ddb_index: Firmware's device database index
  433. * @fw_ddb_entry: Pointer to firmware's ddb entry structure, or NULL.
  434. *
  435. * This routine initializes or updates the adapter's device database
  436. * entry for the specified device. It also triggers a login for the
  437. * specified device. Therefore, it may also be used as a secondary
  438. * login routine when a NULL pointer is specified for the fw_ddb_entry.
  439. **/
  440. int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
  441. dma_addr_t fw_ddb_entry_dma)
  442. {
  443. uint32_t mbox_cmd[MBOX_REG_COUNT];
  444. uint32_t mbox_sts[MBOX_REG_COUNT];
  445. /* Do not wait for completion. The firmware will send us an
  446. * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
  447. */
  448. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  449. memset(&mbox_sts, 0, sizeof(mbox_sts));
  450. mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY;
  451. mbox_cmd[1] = (uint32_t) fw_ddb_index;
  452. mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
  453. mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
  454. mbox_cmd[4] = sizeof(struct dev_db_entry);
  455. return qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
  456. }
  457. /**
  458. * qla4xxx_get_crash_record - retrieves crash record.
  459. * @ha: Pointer to host adapter structure.
  460. *
  461. * This routine retrieves a crash record from the QLA4010 after an 8002h aen.
  462. **/
  463. void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
  464. {
  465. uint32_t mbox_cmd[MBOX_REG_COUNT];
  466. uint32_t mbox_sts[MBOX_REG_COUNT];
  467. struct crash_record *crash_record = NULL;
  468. dma_addr_t crash_record_dma = 0;
  469. uint32_t crash_record_size = 0;
  470. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  471. memset(&mbox_sts, 0, sizeof(mbox_cmd));
  472. /* Get size of crash record. */
  473. mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
  474. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  475. QLA_SUCCESS) {
  476. DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",
  477. ha->host_no, __func__));
  478. goto exit_get_crash_record;
  479. }
  480. crash_record_size = mbox_sts[4];
  481. if (crash_record_size == 0) {
  482. DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n",
  483. ha->host_no, __func__));
  484. goto exit_get_crash_record;
  485. }
  486. /* Alloc Memory for Crash Record. */
  487. crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size,
  488. &crash_record_dma, GFP_KERNEL);
  489. if (crash_record == NULL)
  490. goto exit_get_crash_record;
  491. /* Get Crash Record. */
  492. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  493. memset(&mbox_sts, 0, sizeof(mbox_cmd));
  494. mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
  495. mbox_cmd[2] = LSDW(crash_record_dma);
  496. mbox_cmd[3] = MSDW(crash_record_dma);
  497. mbox_cmd[4] = crash_record_size;
  498. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  499. QLA_SUCCESS)
  500. goto exit_get_crash_record;
  501. /* Dump Crash Record. */
  502. exit_get_crash_record:
  503. if (crash_record)
  504. dma_free_coherent(&ha->pdev->dev, crash_record_size,
  505. crash_record, crash_record_dma);
  506. }
  507. /**
  508. * qla4xxx_get_conn_event_log - retrieves connection event log
  509. * @ha: Pointer to host adapter structure.
  510. **/
  511. void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
  512. {
  513. uint32_t mbox_cmd[MBOX_REG_COUNT];
  514. uint32_t mbox_sts[MBOX_REG_COUNT];
  515. struct conn_event_log_entry *event_log = NULL;
  516. dma_addr_t event_log_dma = 0;
  517. uint32_t event_log_size = 0;
  518. uint32_t num_valid_entries;
  519. uint32_t oldest_entry = 0;
  520. uint32_t max_event_log_entries;
  521. uint8_t i;
  522. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  523. memset(&mbox_sts, 0, sizeof(mbox_cmd));
  524. /* Get size of crash record. */
  525. mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
  526. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  527. QLA_SUCCESS)
  528. goto exit_get_event_log;
  529. event_log_size = mbox_sts[4];
  530. if (event_log_size == 0)
  531. goto exit_get_event_log;
  532. /* Alloc Memory for Crash Record. */
  533. event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size,
  534. &event_log_dma, GFP_KERNEL);
  535. if (event_log == NULL)
  536. goto exit_get_event_log;
  537. /* Get Crash Record. */
  538. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  539. memset(&mbox_sts, 0, sizeof(mbox_cmd));
  540. mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
  541. mbox_cmd[2] = LSDW(event_log_dma);
  542. mbox_cmd[3] = MSDW(event_log_dma);
  543. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  544. QLA_SUCCESS) {
  545. DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "
  546. "log!\n", ha->host_no, __func__));
  547. goto exit_get_event_log;
  548. }
  549. /* Dump Event Log. */
  550. num_valid_entries = mbox_sts[1];
  551. max_event_log_entries = event_log_size /
  552. sizeof(struct conn_event_log_entry);
  553. if (num_valid_entries > max_event_log_entries)
  554. oldest_entry = num_valid_entries % max_event_log_entries;
  555. DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
  556. ha->host_no, num_valid_entries));
  557. if (ql4xextended_error_logging == 3) {
  558. if (oldest_entry == 0) {
  559. /* Circular Buffer has not wrapped around */
  560. for (i=0; i < num_valid_entries; i++) {
  561. qla4xxx_dump_buffer((uint8_t *)event_log+
  562. (i*sizeof(*event_log)),
  563. sizeof(*event_log));
  564. }
  565. }
  566. else {
  567. /* Circular Buffer has wrapped around -
  568. * display accordingly*/
  569. for (i=oldest_entry; i < max_event_log_entries; i++) {
  570. qla4xxx_dump_buffer((uint8_t *)event_log+
  571. (i*sizeof(*event_log)),
  572. sizeof(*event_log));
  573. }
  574. for (i=0; i < oldest_entry; i++) {
  575. qla4xxx_dump_buffer((uint8_t *)event_log+
  576. (i*sizeof(*event_log)),
  577. sizeof(*event_log));
  578. }
  579. }
  580. }
  581. exit_get_event_log:
  582. if (event_log)
  583. dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,
  584. event_log_dma);
  585. }
  586. /**
  587. * qla4xxx_reset_lun - issues LUN Reset
  588. * @ha: Pointer to host adapter structure.
  589. * @db_entry: Pointer to device database entry
  590. * @un_entry: Pointer to lun entry structure
  591. *
  592. * This routine performs a LUN RESET on the specified target/lun.
  593. * The caller must ensure that the ddb_entry and lun_entry pointers
  594. * are valid before calling this routine.
  595. **/
  596. int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
  597. int lun)
  598. {
  599. uint32_t mbox_cmd[MBOX_REG_COUNT];
  600. uint32_t mbox_sts[MBOX_REG_COUNT];
  601. int status = QLA_SUCCESS;
  602. DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no,
  603. ddb_entry->os_target_id, lun));
  604. /*
  605. * Send lun reset command to ISP, so that the ISP will return all
  606. * outstanding requests with RESET status
  607. */
  608. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  609. memset(&mbox_sts, 0, sizeof(mbox_sts));
  610. mbox_cmd[0] = MBOX_CMD_LUN_RESET;
  611. mbox_cmd[1] = ddb_entry->fw_ddb_index;
  612. mbox_cmd[2] = lun << 8;
  613. mbox_cmd[5] = 0x01; /* Immediate Command Enable */
  614. qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
  615. if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
  616. mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
  617. status = QLA_ERROR;
  618. return status;
  619. }
  620. /**
  621. * qla4xxx_reset_target - issues target Reset
  622. * @ha: Pointer to host adapter structure.
  623. * @db_entry: Pointer to device database entry
  624. * @un_entry: Pointer to lun entry structure
  625. *
  626. * This routine performs a TARGET RESET on the specified target.
  627. * The caller must ensure that the ddb_entry pointers
  628. * are valid before calling this routine.
  629. **/
  630. int qla4xxx_reset_target(struct scsi_qla_host *ha,
  631. struct ddb_entry *ddb_entry)
  632. {
  633. uint32_t mbox_cmd[MBOX_REG_COUNT];
  634. uint32_t mbox_sts[MBOX_REG_COUNT];
  635. int status = QLA_SUCCESS;
  636. DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no,
  637. ddb_entry->os_target_id));
  638. /*
  639. * Send target reset command to ISP, so that the ISP will return all
  640. * outstanding requests with RESET status
  641. */
  642. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  643. memset(&mbox_sts, 0, sizeof(mbox_sts));
  644. mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET;
  645. mbox_cmd[1] = ddb_entry->fw_ddb_index;
  646. mbox_cmd[5] = 0x01; /* Immediate Command Enable */
  647. qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
  648. &mbox_sts[0]);
  649. if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
  650. mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
  651. status = QLA_ERROR;
  652. return status;
  653. }
  654. int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
  655. uint32_t offset, uint32_t len)
  656. {
  657. uint32_t mbox_cmd[MBOX_REG_COUNT];
  658. uint32_t mbox_sts[MBOX_REG_COUNT];
  659. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  660. memset(&mbox_sts, 0, sizeof(mbox_sts));
  661. mbox_cmd[0] = MBOX_CMD_READ_FLASH;
  662. mbox_cmd[1] = LSDW(dma_addr);
  663. mbox_cmd[2] = MSDW(dma_addr);
  664. mbox_cmd[3] = offset;
  665. mbox_cmd[4] = len;
  666. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) !=
  667. QLA_SUCCESS) {
  668. DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "
  669. "status %04X %04X, offset %08x, len %08x\n", ha->host_no,
  670. __func__, mbox_sts[0], mbox_sts[1], offset, len));
  671. return QLA_ERROR;
  672. }
  673. return QLA_SUCCESS;
  674. }
  675. /**
  676. * qla4xxx_get_fw_version - gets firmware version
  677. * @ha: Pointer to host adapter structure.
  678. *
  679. * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may
  680. * hold an address for data. Make sure that we write 0 to those mailboxes,
  681. * if unused.
  682. **/
  683. int qla4xxx_get_fw_version(struct scsi_qla_host * ha)
  684. {
  685. uint32_t mbox_cmd[MBOX_REG_COUNT];
  686. uint32_t mbox_sts[MBOX_REG_COUNT];
  687. /* Get firmware version. */
  688. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  689. memset(&mbox_sts, 0, sizeof(mbox_sts));
  690. mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
  691. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
  692. QLA_SUCCESS) {
  693. DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ "
  694. "status %04X\n", ha->host_no, __func__, mbox_sts[0]));
  695. return QLA_ERROR;
  696. }
  697. /* Save firmware version information. */
  698. ha->firmware_version[0] = mbox_sts[1];
  699. ha->firmware_version[1] = mbox_sts[2];
  700. ha->patch_number = mbox_sts[3];
  701. ha->build_number = mbox_sts[4];
  702. return QLA_SUCCESS;
  703. }
  704. static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha,
  705. dma_addr_t dma_addr)
  706. {
  707. uint32_t mbox_cmd[MBOX_REG_COUNT];
  708. uint32_t mbox_sts[MBOX_REG_COUNT];
  709. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  710. memset(&mbox_sts, 0, sizeof(mbox_sts));
  711. mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS;
  712. mbox_cmd[2] = LSDW(dma_addr);
  713. mbox_cmd[3] = MSDW(dma_addr);
  714. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
  715. QLA_SUCCESS) {
  716. DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
  717. ha->host_no, __func__, mbox_sts[0]));
  718. return QLA_ERROR;
  719. }
  720. return QLA_SUCCESS;
  721. }
  722. static int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index)
  723. {
  724. uint32_t mbox_cmd[MBOX_REG_COUNT];
  725. uint32_t mbox_sts[MBOX_REG_COUNT];
  726. memset(&mbox_cmd, 0, sizeof(mbox_cmd));
  727. memset(&mbox_sts, 0, sizeof(mbox_sts));
  728. mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;
  729. mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES;
  730. if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
  731. QLA_SUCCESS) {
  732. if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) {
  733. *ddb_index = mbox_sts[2];
  734. } else {
  735. DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
  736. ha->host_no, __func__, mbox_sts[0]));
  737. return QLA_ERROR;
  738. }
  739. } else {
  740. *ddb_index = MAX_PRST_DEV_DB_ENTRIES;
  741. }
  742. return QLA_SUCCESS;
  743. }
  744. int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port)
  745. {
  746. struct dev_db_entry *fw_ddb_entry;
  747. dma_addr_t fw_ddb_entry_dma;
  748. uint32_t ddb_index;
  749. int ret_val = QLA_SUCCESS;
  750. fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
  751. sizeof(*fw_ddb_entry),
  752. &fw_ddb_entry_dma, GFP_KERNEL);
  753. if (!fw_ddb_entry) {
  754. DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
  755. ha->host_no, __func__));
  756. ret_val = QLA_ERROR;
  757. goto qla4xxx_send_tgts_exit;
  758. }
  759. ret_val = qla4xxx_get_default_ddb(ha, fw_ddb_entry_dma);
  760. if (ret_val != QLA_SUCCESS)
  761. goto qla4xxx_send_tgts_exit;
  762. ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index);
  763. if (ret_val != QLA_SUCCESS)
  764. goto qla4xxx_send_tgts_exit;
  765. memset(fw_ddb_entry->iscsi_alias, 0,
  766. sizeof(fw_ddb_entry->iscsi_alias));
  767. memset(fw_ddb_entry->iscsi_name, 0,
  768. sizeof(fw_ddb_entry->iscsi_name));
  769. memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr));
  770. memset(fw_ddb_entry->tgt_addr, 0,
  771. sizeof(fw_ddb_entry->tgt_addr));
  772. fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET);
  773. fw_ddb_entry->port = cpu_to_le16(ntohs(port));
  774. fw_ddb_entry->ip_addr[0] = *ip;
  775. fw_ddb_entry->ip_addr[1] = *(ip + 1);
  776. fw_ddb_entry->ip_addr[2] = *(ip + 2);
  777. fw_ddb_entry->ip_addr[3] = *(ip + 3);
  778. ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma);
  779. qla4xxx_send_tgts_exit:
  780. dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
  781. fw_ddb_entry, fw_ddb_entry_dma);
  782. return ret_val;
  783. }