ql4_mbx.c 28 KB

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