ql4_mbx.c 28 KB

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