168 * Returns:
169 * SYS_ERRNO
170 *
171 * Context:
172 * Kernel context.
173 */
174 int
175 ql_alloc_xioctl_resource(ql_adapter_state_t *ha)
176 {
177 ql_xioctl_t *xp;
178
179 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
180
181 if (ha->xioctl != NULL) {
182 QL_PRINT_9(CE_CONT, "(%d): already allocated done\n",
183 ha->instance);
184 return (0);
185 }
186
187 xp = kmem_zalloc(sizeof (ql_xioctl_t), KM_SLEEP);
188 if (xp == NULL) {
189 EL(ha, "failed, kmem_zalloc\n");
190 return (ENOMEM);
191 }
192 ha->xioctl = xp;
193
194 /* Allocate AEN tracking buffer */
195 xp->aen_tracking_queue = kmem_zalloc(EXT_DEF_MAX_AEN_QUEUE *
196 sizeof (EXT_ASYNC_EVENT), KM_SLEEP);
197 if (xp->aen_tracking_queue == NULL) {
198 EL(ha, "failed, kmem_zalloc-2\n");
199 ql_free_xioctl_resource(ha);
200 return (ENOMEM);
201 }
202
203 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
204
205 return (0);
206 }
207
208 /*
209 * ql_free_xioctl_resource
210 * Frees resources used by module code.
211 *
212 * Input:
213 * ha: adapter state pointer.
214 *
215 * Context:
216 * Kernel context.
217 */
218 void
219 ql_free_xioctl_resource(ql_adapter_state_t *ha)
220 {
221 ql_xioctl_t *xp = ha->xioctl;
1513 QL_DUMP_9(cmd, 8, sizeof (EXT_IOCTL));
1514
1515 /* Allocate a DMA Memory Descriptor */
1516 dma_mem = (dma_mem_t *)kmem_zalloc(sizeof (dma_mem_t), KM_SLEEP);
1517 if (dma_mem == NULL) {
1518 EL(ha, "failed, kmem_zalloc\n");
1519 cmd->Status = EXT_STATUS_NO_MEMORY;
1520 cmd->ResponseLen = 0;
1521 return;
1522 }
1523 /* Determine maximum buffer size. */
1524 if (cmd->RequestLen < cmd->ResponseLen) {
1525 pld_byte_cnt = cmd->ResponseLen;
1526 } else {
1527 pld_byte_cnt = cmd->RequestLen;
1528 }
1529
1530 /* Allocate command block. */
1531 pkt_size = (uint32_t)(sizeof (ql_mbx_iocb_t) + pld_byte_cnt);
1532 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1533 if (pkt == NULL) {
1534 EL(ha, "failed, kmem_zalloc\n");
1535 cmd->Status = EXT_STATUS_NO_MEMORY;
1536 cmd->ResponseLen = 0;
1537 return;
1538 }
1539 pld = (caddr_t)pkt + sizeof (ql_mbx_iocb_t);
1540
1541 /* Get command payload data. */
1542 if (ql_get_buffer_data((caddr_t)(uintptr_t)cmd->RequestAdr, pld,
1543 cmd->RequestLen, mode) != cmd->RequestLen) {
1544 EL(ha, "failed, get_buffer_data\n");
1545 kmem_free(pkt, pkt_size);
1546 cmd->Status = EXT_STATUS_COPY_ERR;
1547 cmd->ResponseLen = 0;
1548 return;
1549 }
1550
1551 /* Get DMA memory for the IOCB */
1552 if (ql_get_dma_mem(ha, dma_mem, pkt_size, LITTLE_ENDIAN_DMA,
1553 QL_DMA_RING_ALIGN) != QL_SUCCESS) {
1554 cmn_err(CE_WARN, "%s(%d): DMA memory "
1555 "alloc failed", QL_NAME, ha->instance);
1556 kmem_free(pkt, pkt_size);
1557 kmem_free(dma_mem, sizeof (dma_mem_t));
1558 cmd->Status = EXT_STATUS_MS_NO_RESPONSE;
2123 EL(ha, "failed, fc_port not found\n");
2124 cmd->Status = EXT_STATUS_DEV_NOT_FOUND;
2125 cmd->ResponseLen = 0;
2126 return;
2127 }
2128
2129 if (tq->flags & TQF_NEED_AUTHENTICATION) {
2130 EL(ha, "target not available; loopid=%xh\n", tq->loop_id);
2131 cmd->Status = EXT_STATUS_DEVICE_OFFLINE;
2132 cmd->ResponseLen = 0;
2133 return;
2134 }
2135
2136 /* Allocate command block. */
2137 if ((scsi_req.direction == EXT_DEF_SCSI_PASSTHRU_DATA_IN ||
2138 scsi_req.direction == EXT_DEF_SCSI_PASSTHRU_DATA_OUT) &&
2139 cmd->ResponseLen) {
2140 pld_size = cmd->ResponseLen;
2141 pkt_size = (uint32_t)(sizeof (ql_mbx_iocb_t) + pld_size);
2142 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
2143 if (pkt == NULL) {
2144 EL(ha, "failed, kmem_zalloc\n");
2145 cmd->Status = EXT_STATUS_NO_MEMORY;
2146 cmd->ResponseLen = 0;
2147 return;
2148 }
2149 pld = (caddr_t)pkt + sizeof (ql_mbx_iocb_t);
2150
2151 /* Get DMA memory for the IOCB */
2152 if (ql_get_dma_mem(ha, dma_mem, pld_size, LITTLE_ENDIAN_DMA,
2153 QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
2154 cmn_err(CE_WARN, "%s(%d): request queue DMA memory "
2155 "alloc failed", QL_NAME, ha->instance);
2156 kmem_free(pkt, pkt_size);
2157 cmd->Status = EXT_STATUS_MS_NO_RESPONSE;
2158 cmd->ResponseLen = 0;
2159 return;
2160 }
2161
2162 if (scsi_req.direction == EXT_DEF_SCSI_PASSTHRU_DATA_IN) {
2163 scsi_req.direction = (uint8_t)
2164 (CFG_IST(ha, CFG_CTRL_24258081) ?
2165 CF_RD : CF_DATA_IN | CF_STAG);
2166 } else {
2167 scsi_req.direction = (uint8_t)
2168 (CFG_IST(ha, CFG_CTRL_24258081) ?
2181 kmem_free(dma_mem, sizeof (dma_mem_t));
2182 return;
2183 }
2184
2185 /* Copy out going data to DMA buffer. */
2186 ddi_rep_put8(dma_mem->acc_handle, (uint8_t *)pld,
2187 (uint8_t *)dma_mem->bp, pld_size,
2188 DDI_DEV_AUTOINCR);
2189
2190 /* Sync DMA buffer. */
2191 (void) ddi_dma_sync(dma_mem->dma_handle, 0,
2192 dma_mem->size, DDI_DMA_SYNC_FORDEV);
2193 }
2194 } else {
2195 scsi_req.direction = (uint8_t)
2196 (CFG_IST(ha, CFG_CTRL_24258081) ? 0 : CF_STAG);
2197 cmd->ResponseLen = 0;
2198
2199 pkt_size = sizeof (ql_mbx_iocb_t);
2200 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
2201 if (pkt == NULL) {
2202 EL(ha, "failed, kmem_zalloc-2\n");
2203 cmd->Status = EXT_STATUS_NO_MEMORY;
2204 return;
2205 }
2206 pld = NULL;
2207 pld_size = 0;
2208 }
2209
2210 /* retries = ha->port_down_retry_count; */
2211 retries = 1;
2212 cmd->Status = EXT_STATUS_OK;
2213 cmd->DetailStatus = EXT_DSTATUS_NOADNL_INFO;
2214
2215 QL_PRINT_9(CE_CONT, "(%d): SCSI cdb\n", ha->instance);
2216 QL_DUMP_9(scsi_req.cdbp, 8, scsi_req.cdb_len);
2217
2218 do {
2219 if (DRIVER_SUSPENDED(ha)) {
2220 sts.comp_status = CS_LOOP_DOWN_ABORT;
2221 break;
2222 }
2223
2224 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2225 pkt->cmd24.entry_type = IOCB_CMD_TYPE_7;
3345 cmd->Status = EXT_STATUS_COPY_ERR;
3346 cmd->ResponseLen = 0;
3347 return;
3348 }
3349
3350 opt = (uint16_t)(plbreq.Options & MBC_LOOPBACK_POINT_MASK);
3351
3352 /* Check transfer length fits in buffer. */
3353 if (plbreq.BufferLength < plbreq.TransferCount &&
3354 plbreq.TransferCount < MAILBOX_BUFFER_SIZE) {
3355 EL(ha, "failed, BufferLength=%d, xfercnt=%d, "
3356 "mailbox_buffer_size=%d\n", plbreq.BufferLength,
3357 plbreq.TransferCount, MAILBOX_BUFFER_SIZE);
3358 cmd->Status = EXT_STATUS_INVALID_PARAM;
3359 cmd->ResponseLen = 0;
3360 return;
3361 }
3362
3363 /* Allocate command memory. */
3364 bp = kmem_zalloc(plbreq.TransferCount, KM_SLEEP);
3365 if (bp == NULL) {
3366 EL(ha, "failed, kmem_zalloc\n");
3367 cmd->Status = EXT_STATUS_NO_MEMORY;
3368 cmd->ResponseLen = 0;
3369 return;
3370 }
3371
3372 /* Get loopback data. */
3373 if (ql_get_buffer_data((caddr_t)(uintptr_t)plbreq.BufferAddress,
3374 bp, plbreq.TransferCount, mode) != plbreq.TransferCount) {
3375 EL(ha, "failed, ddi_copyin-2\n");
3376 kmem_free(bp, plbreq.TransferCount);
3377 cmd->Status = EXT_STATUS_COPY_ERR;
3378 cmd->ResponseLen = 0;
3379 return;
3380 }
3381
3382 if ((ha->task_daemon_flags & (QL_LOOP_TRANSITION | DRIVER_STALL)) ||
3383 ql_stall_driver(ha, 0) != QL_SUCCESS) {
3384 EL(ha, "failed, LOOP_NOT_READY\n");
3385 kmem_free(bp, plbreq.TransferCount);
3386 cmd->Status = EXT_STATUS_BUSY;
3387 cmd->ResponseLen = 0;
3388 return;
3389 }
3390
3643 }
3644 } else if (tmp_rnid.Addr.Type == EXT_DEF_TYPE_PORTID) {
3645 /*
3646 * Copy caller's d_id to tmp space.
3647 */
3648 bcopy(&tmp_rnid.Addr.FcAddr.Id[1], tmp_fcid.r.d_id,
3649 EXT_DEF_PORTID_SIZE_ACTUAL);
3650 BIG_ENDIAN_24(&tmp_fcid.r.d_id[0]);
3651
3652 if (bcmp((void *)&ha->d_id, (void *)tmp_fcid.r.d_id,
3653 EXT_DEF_PORTID_SIZE_ACTUAL) == 0) {
3654 local_hba = 1;
3655 } else {
3656 tq = ql_find_port(ha, (uint8_t *)tmp_fcid.r.d_id,
3657 QLNT_PID);
3658 }
3659 }
3660
3661 /* Allocate memory for command. */
3662 tmp_buf = kmem_zalloc(SEND_RNID_RSP_SIZE, KM_SLEEP);
3663 if (tmp_buf == NULL) {
3664 EL(ha, "failed, kmem_zalloc\n");
3665 cmd->Status = EXT_STATUS_NO_MEMORY;
3666 cmd->ResponseLen = 0;
3667 return;
3668 }
3669
3670 if (local_hba) {
3671 rval = ql_get_rnid_params(ha, SEND_RNID_RSP_SIZE, tmp_buf);
3672 if (rval != QL_SUCCESS) {
3673 EL(ha, "failed, get_rnid_params_mbx=%xh\n", rval);
3674 kmem_free(tmp_buf, SEND_RNID_RSP_SIZE);
3675 cmd->Status = EXT_STATUS_ERR;
3676 cmd->ResponseLen = 0;
3677 return;
3678 }
3679
3680 /* Save gotten RNID data. */
3681 bcopy(tmp_buf, &rnid_data, sizeof (EXT_RNID_DATA));
3682
3683 /* Now build the Send RNID response */
3684 tmp_buf[0] = (char)(EXT_DEF_RNID_DFORMAT_TOPO_DISC);
3685 tmp_buf[1] = (2 * EXT_DEF_WWN_NAME_SIZE);
3686 tmp_buf[2] = 0;
3687 tmp_buf[3] = sizeof (EXT_RNID_DATA);
3688
4014 ql_report_lun(ql_adapter_state_t *ha, ql_tgt_t *tq)
4015 {
4016 int rval;
4017 uint8_t retries;
4018 ql_mbx_iocb_t *pkt;
4019 ql_rpt_lun_lst_t *rpt;
4020 dma_mem_t dma_mem;
4021 uint32_t pkt_size, cnt;
4022 uint16_t comp_status;
4023 uint8_t scsi_status_h, scsi_status_l, *reqs;
4024
4025 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
4026
4027 if (DRIVER_SUSPENDED(ha)) {
4028 EL(ha, "failed, LOOP_NOT_READY\n");
4029 return (0);
4030 }
4031
4032 pkt_size = sizeof (ql_mbx_iocb_t) + sizeof (ql_rpt_lun_lst_t);
4033 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
4034 if (pkt == NULL) {
4035 EL(ha, "failed, kmem_zalloc\n");
4036 return (0);
4037 }
4038 rpt = (ql_rpt_lun_lst_t *)((caddr_t)pkt + sizeof (ql_mbx_iocb_t));
4039
4040 /* Get DMA memory for the IOCB */
4041 if (ql_get_dma_mem(ha, &dma_mem, sizeof (ql_rpt_lun_lst_t),
4042 LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN) != QL_SUCCESS) {
4043 cmn_err(CE_WARN, "%s(%d): DMA memory "
4044 "alloc failed", QL_NAME, ha->instance);
4045 kmem_free(pkt, pkt_size);
4046 return (0);
4047 }
4048
4049 for (retries = 0; retries < 4; retries++) {
4050 if (CFG_IST(ha, CFG_CTRL_24258081)) {
4051 pkt->cmd24.entry_type = IOCB_CMD_TYPE_7;
4052 pkt->cmd24.entry_count = 1;
4053
4054 /* Set N_port handle */
4055 pkt->cmd24.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
4056
4057 /* Set target ID */
4258 * count: scan for the number of existing LUNs.
4259 *
4260 * Returns:
4261 * Number of LUNs.
4262 *
4263 * Context:
4264 * Kernel context.
4265 */
4266 static int
4267 ql_inq_scan(ql_adapter_state_t *ha, ql_tgt_t *tq, int count)
4268 {
4269 int lun, cnt, rval;
4270 ql_mbx_iocb_t *pkt;
4271 uint8_t *inq;
4272 uint32_t pkt_size;
4273
4274 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
4275
4276 pkt_size = sizeof (ql_mbx_iocb_t) + INQ_DATA_SIZE;
4277 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
4278 if (pkt == NULL) {
4279 EL(ha, "failed, kmem_zalloc\n");
4280 return (0);
4281 }
4282 inq = (uint8_t *)((caddr_t)pkt + sizeof (ql_mbx_iocb_t));
4283
4284 cnt = 0;
4285 for (lun = 0; lun < MAX_LUNS; lun++) {
4286
4287 if (DRIVER_SUSPENDED(ha)) {
4288 rval = QL_LOOP_DOWN;
4289 cnt = 0;
4290 break;
4291 }
4292
4293 rval = ql_inq(ha, tq, lun, pkt, INQ_DATA_SIZE);
4294 if (rval == QL_SUCCESS) {
4295 switch (*inq) {
4296 case DTYPE_DIRECT:
4297 case DTYPE_PROCESSOR: /* Appliance. */
4298 case DTYPE_WORM:
4299 case DTYPE_RODIRECT:
4300 case DTYPE_SCANNER:
4301 case DTYPE_OPTICAL:
4681 *
4682 * Context:
4683 * Kernel context.
4684 */
4685 static int
4686 ql_24xx_flash_desc(ql_adapter_state_t *ha)
4687 {
4688 uint32_t cnt;
4689 uint16_t chksum, *bp, data;
4690 int rval;
4691 flash_desc_t *fdesc;
4692 ql_xioctl_t *xp = ha->xioctl;
4693
4694 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
4695
4696 if (ha->flash_desc_addr == 0) {
4697 QL_PRINT_9(CE_CONT, "(%d): desc ptr=0\n", ha->instance);
4698 return (QL_FUNCTION_FAILED);
4699 }
4700
4701 if ((fdesc = kmem_zalloc(sizeof (flash_desc_t), KM_SLEEP)) == NULL) {
4702 EL(ha, "kmem_zalloc=null\n");
4703 return (QL_MEMORY_ALLOC_FAILED);
4704 }
4705 rval = ql_dump_fcode(ha, (uint8_t *)fdesc, sizeof (flash_desc_t),
4706 ha->flash_desc_addr << 2);
4707 if (rval != QL_SUCCESS) {
4708 EL(ha, "read status=%xh\n", rval);
4709 kmem_free(fdesc, sizeof (flash_desc_t));
4710 return (rval);
4711 }
4712
4713 chksum = 0;
4714 bp = (uint16_t *)fdesc;
4715 for (cnt = 0; cnt < (sizeof (flash_desc_t)) / 2; cnt++) {
4716 data = *bp++;
4717 LITTLE_ENDIAN_16(&data);
4718 chksum += data;
4719 }
4720
4721 LITTLE_ENDIAN_32(&fdesc->flash_valid);
4722 LITTLE_ENDIAN_16(&fdesc->flash_version);
4723 LITTLE_ENDIAN_16(&fdesc->flash_len);
4724 LITTLE_ENDIAN_16(&fdesc->flash_checksum);
5418 /* parameter error */
5419 EL(ha, "failed, RequestLen < EXT_SET_RNID_REQ, Len=%xh\n",
5420 cmd->RequestLen);
5421 cmd->Status = EXT_STATUS_INVALID_PARAM;
5422 cmd->DetailStatus = EXT_DSTATUS_REQUEST_LEN;
5423 cmd->ResponseLen = 0;
5424 return;
5425 }
5426
5427 rval = ddi_copyin((void*)(uintptr_t)cmd->RequestAdr, &tmp_set,
5428 cmd->RequestLen, mode);
5429 if (rval != 0) {
5430 EL(ha, "failed, ddi_copyin\n");
5431 cmd->Status = EXT_STATUS_COPY_ERR;
5432 cmd->ResponseLen = 0;
5433 return;
5434 }
5435
5436 /* Allocate memory for command. */
5437 tmp_buf = kmem_zalloc(sizeof (EXT_RNID_DATA), KM_SLEEP);
5438 if (tmp_buf == NULL) {
5439 EL(ha, "failed, kmem_zalloc\n");
5440 cmd->Status = EXT_STATUS_NO_MEMORY;
5441 cmd->ResponseLen = 0;
5442 return;
5443 }
5444
5445 rval = ql_get_rnid_params(ha, sizeof (EXT_RNID_DATA),
5446 (caddr_t)tmp_buf);
5447 if (rval != QL_SUCCESS) {
5448 /* error */
5449 EL(ha, "failed, get_rnid_params_mbx=%xh\n", rval);
5450 kmem_free(tmp_buf, sizeof (EXT_RNID_DATA));
5451 cmd->Status = EXT_STATUS_ERR;
5452 cmd->ResponseLen = 0;
5453 return;
5454 }
5455
5456 /* Now set the requested params. */
5457 bcopy(tmp_set.IPVersion, tmp_buf->IPVersion, 2);
5458 bcopy(tmp_set.UDPPortNumber, tmp_buf->UDPPortNumber, 2);
5459 bcopy(tmp_set.IPAddress, tmp_buf->IPAddress, 16);
5460
5461 rval = ql_set_rnid_params(ha, sizeof (EXT_RNID_DATA),
5462 (caddr_t)tmp_buf);
5463 if (rval != QL_SUCCESS) {
5481 * cmd: User space CT arguments pointer.
5482 * mode: flags.
5483 */
5484 static void
5485 ql_get_rnid_parameters(ql_adapter_state_t *ha, EXT_IOCTL *cmd, int mode)
5486 {
5487 EXT_RNID_DATA *tmp_buf;
5488 uint32_t rval;
5489
5490 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
5491
5492 if (DRIVER_SUSPENDED(ha)) {
5493 EL(ha, "failed, LOOP_NOT_READY\n");
5494 cmd->Status = EXT_STATUS_BUSY;
5495 cmd->ResponseLen = 0;
5496 return;
5497 }
5498
5499 /* Allocate memory for command. */
5500 tmp_buf = kmem_zalloc(sizeof (EXT_RNID_DATA), KM_SLEEP);
5501 if (tmp_buf == NULL) {
5502 EL(ha, "failed, kmem_zalloc\n");
5503 cmd->Status = EXT_STATUS_NO_MEMORY;
5504 cmd->ResponseLen = 0;
5505 return;
5506 }
5507
5508 /* Send command */
5509 rval = ql_get_rnid_params(ha, sizeof (EXT_RNID_DATA),
5510 (caddr_t)tmp_buf);
5511 if (rval != QL_SUCCESS) {
5512 /* error */
5513 EL(ha, "failed, get_rnid_params_mbx=%xh\n", rval);
5514 kmem_free(tmp_buf, sizeof (EXT_RNID_DATA));
5515 cmd->Status = EXT_STATUS_ERR;
5516 cmd->ResponseLen = 0;
5517 return;
5518 }
5519
5520 /* Copy the response */
5521 if (ql_send_buffer_data((caddr_t)tmp_buf,
5522 (caddr_t)(uintptr_t)cmd->ResponseAdr,
5523 sizeof (EXT_RNID_DATA), mode) != sizeof (EXT_RNID_DATA)) {
5524 EL(ha, "failed, ddi_copyout\n");
5525 cmd->Status = EXT_STATUS_COPY_ERR;
5526 cmd->ResponseLen = 0;
5618 int retry = 10;
5619
5620 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
5621
5622 while (ha->task_daemon_flags &
5623 (ABORT_ISP_ACTIVE | LOOP_RESYNC_ACTIVE | DRIVER_STALL)) {
5624 ql_delay(ha, 10000000); /* 10 second delay */
5625
5626 retry--;
5627
5628 if (retry == 0) { /* effectively 100 seconds */
5629 EL(ha, "failed, LOOP_NOT_READY\n");
5630 cmd->Status = EXT_STATUS_BUSY;
5631 cmd->ResponseLen = 0;
5632 return;
5633 }
5634 }
5635
5636 /* Allocate memory for command. */
5637 ls = kmem_zalloc(sizeof (ql_link_stats_t), KM_SLEEP);
5638 if (ls == NULL) {
5639 EL(ha, "failed, kmem_zalloc\n");
5640 cmd->Status = EXT_STATUS_NO_MEMORY;
5641 cmd->ResponseLen = 0;
5642 return;
5643 }
5644
5645 /*
5646 * I think these are supposed to be port statistics
5647 * the loop ID or port ID should be in cmd->Instance.
5648 */
5649 rval = ql_get_status_counts(ha, (uint16_t)
5650 (ha->task_daemon_flags & LOOP_DOWN ? 0xFF : ha->loop_id),
5651 sizeof (ql_link_stats_t), (caddr_t)ls, 0);
5652 if (rval != QL_SUCCESS) {
5653 EL(ha, "failed, get_link_status=%xh, id=%xh\n", rval,
5654 ha->loop_id);
5655 cmd->Status = EXT_STATUS_MAILBOX;
5656 cmd->DetailStatus = rval;
5657 cmd->ResponseLen = 0;
5658 } else {
5659 ps.ControllerErrorCount = xp->ControllerErrorCount;
5660 ps.DeviceErrorCount = xp->DeviceErrorCount;
5661 ps.IoCount = (uint32_t)(xp->IOInputRequests +
5662 xp->IOOutputRequests + xp->IOControlRequests);
5663 ps.MBytesCount = (uint32_t)(xp->IOInputMByteCnt +
5740 cmd->ResponseLen = 0;
5741 return;
5742 }
5743
5744 while (ha->task_daemon_flags &
5745 (ABORT_ISP_ACTIVE | LOOP_RESYNC_ACTIVE | DRIVER_STALL)) {
5746 ql_delay(ha, 10000000); /* 10 second delay */
5747
5748 retry--;
5749
5750 if (retry == 0) { /* effectively 100 seconds */
5751 EL(ha, "failed, LOOP_NOT_READY\n");
5752 cmd->Status = EXT_STATUS_BUSY;
5753 cmd->ResponseLen = 0;
5754 return;
5755 }
5756 }
5757
5758 /* Allocate memory for command. */
5759 ls = kmem_zalloc(sizeof (ql_link_stats_t), KM_SLEEP);
5760 if (ls == NULL) {
5761 EL(ha, "failed, kmem_zalloc\n");
5762 cmd->Status = EXT_STATUS_NO_MEMORY;
5763 cmd->ResponseLen = 0;
5764 return;
5765 }
5766
5767 rval = ql_get_link_status(ha, tq->loop_id, sizeof (ql_link_stats_t),
5768 (caddr_t)ls, 0);
5769 if (rval != QL_SUCCESS) {
5770 EL(ha, "failed, get_link_status=%xh, d_id=%xh\n", rval,
5771 tq->d_id.b24);
5772 cmd->Status = EXT_STATUS_MAILBOX;
5773 cmd->DetailStatus = rval;
5774 cmd->ResponseLen = 0;
5775 } else {
5776 ps.LinkFailureCount = LE_32(ls->link_fail_cnt);
5777 ps.LossOfSyncCount = LE_32(ls->sync_loss_cnt);
5778 ps.LossOfSignalsCount = LE_32(ls->signal_loss_cnt);
5779 ps.PrimitiveSeqProtocolErrorCount = LE_32(ls->prot_err_cnt);
5780 ps.InvalidTransmissionWordCount = LE_32(ls->inv_xmit_cnt);
5781 ps.InvalidCRCCount = LE_32(ls->inv_crc_cnt);
5782
5783 rval = ddi_copyout((void *)&ps,
5784 (void *)(uintptr_t)cmd->ResponseAdr,
5785 sizeof (EXT_HBA_PORT_STAT), mode);
6955 * Input:
6956 * ha: adapter state pointer.
6957 * flt_paddr: flash layout pointer address.
6958 *
6959 * Context:
6960 * Kernel context.
6961 */
6962 static void
6963 ql_flash_layout_table(ql_adapter_state_t *ha, uint32_t flt_paddr)
6964 {
6965 ql_flt_ptr_t *fptr;
6966 uint8_t *bp;
6967 int rval;
6968 uint32_t len, faddr, cnt;
6969 uint16_t chksum, w16;
6970
6971 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
6972
6973 /* Process flash layout table header */
6974 len = sizeof (ql_flt_ptr_t);
6975 if ((bp = kmem_zalloc(len, KM_SLEEP)) == NULL) {
6976 EL(ha, "kmem_zalloc=null\n");
6977 return;
6978 }
6979
6980 /* Process pointer to flash layout table */
6981 if ((rval = ql_dump_fcode(ha, bp, len, flt_paddr)) != QL_SUCCESS) {
6982 EL(ha, "fptr dump_flash pos=%xh, status=%xh\n", flt_paddr,
6983 rval);
6984 kmem_free(bp, len);
6985 return;
6986 }
6987 fptr = (ql_flt_ptr_t *)bp;
6988
6989 /* Verify pointer to flash layout table. */
6990 for (chksum = 0, cnt = 0; cnt < len; cnt += 2) {
6991 w16 = (uint16_t)CHAR_TO_SHORT(bp[cnt], bp[cnt + 1]);
6992 chksum += w16;
6993 }
6994 if (chksum != 0 || fptr->sig[0] != 'Q' || fptr->sig[1] != 'F' ||
6995 fptr->sig[2] != 'L' || fptr->sig[3] != 'T') {
6996 EL(ha, "ptr chksum=%xh, sig=%c%c%c%c\n", chksum, fptr->sig[0],
6997 fptr->sig[1], fptr->sig[2], fptr->sig[3]);
6998 kmem_free(bp, len);
7015 * Input:
7016 * ha: adapter state pointer.
7017 * faddr: flash layout table byte address.
7018 *
7019 * Context:
7020 * Kernel context.
7021 */
7022 static void
7023 ql_process_flt(ql_adapter_state_t *ha, uint32_t faddr)
7024 {
7025 ql_flt_hdr_t *fhdr;
7026 ql_flt_region_t *frgn;
7027 uint8_t *bp, *eaddr, nv_rg, vpd_rg;
7028 int rval;
7029 uint32_t len, cnt, fe_addr;
7030 uint16_t chksum, w16;
7031
7032 QL_PRINT_9(CE_CONT, "(%d): started faddr=%xh\n", ha->instance, faddr);
7033
7034 /* Process flash layout table header */
7035 if ((bp = kmem_zalloc(FLASH_LAYOUT_TABLE_SIZE, KM_SLEEP)) == NULL) {
7036 EL(ha, "kmem_zalloc=null\n");
7037 return;
7038 }
7039 fhdr = (ql_flt_hdr_t *)bp;
7040
7041 /* Process flash layout table. */
7042 if ((rval = ql_dump_fcode(ha, bp, FLASH_LAYOUT_TABLE_SIZE, faddr)) !=
7043 QL_SUCCESS) {
7044 EL(ha, "fhdr dump_flash pos=%xh, status=%xh\n", faddr, rval);
7045 kmem_free(bp, FLASH_LAYOUT_TABLE_SIZE);
7046 return;
7047 }
7048
7049 /* Verify flash layout table. */
7050 len = (uint32_t)(CHAR_TO_SHORT(fhdr->len[0], fhdr->len[1]) +
7051 sizeof (ql_flt_hdr_t) + sizeof (ql_flt_region_t));
7052 if (len > FLASH_LAYOUT_TABLE_SIZE) {
7053 chksum = 0xffff;
7054 } else {
7055 for (chksum = 0, cnt = 0; cnt < len; cnt += 2) {
7056 w16 = (uint16_t)CHAR_TO_SHORT(bp[cnt], bp[cnt + 1]);
7057 chksum += w16;
7058 }
7694 rval = ql_fw_etrace(ha, &ha->fwexttracebuf, FTO_INSERT_TIME_STAMP);
7695 if (rval != QL_SUCCESS) {
7696 EL(ha, "f/w extended trace insert"
7697 "time stamp failed: %xh\n", rval);
7698 cmd->Status = EXT_STATUS_ERR;
7699 cmd->ResponseLen = 0;
7700 return;
7701 }
7702
7703 /* Disable Tracing */
7704 rval = ql_fw_etrace(ha, &ha->fwexttracebuf, FTO_EXT_TRACE_DISABLE);
7705 if (rval != QL_SUCCESS) {
7706 EL(ha, "f/w extended trace disable failed: %xh\n", rval);
7707 cmd->Status = EXT_STATUS_ERR;
7708 cmd->ResponseLen = 0;
7709 return;
7710 }
7711
7712 /* Allocate payload buffer */
7713 payload = kmem_zalloc(FWEXTSIZE, KM_SLEEP);
7714 if (payload == NULL) {
7715 EL(ha, "failed, kmem_zalloc\n");
7716 cmd->Status = EXT_STATUS_NO_MEMORY;
7717 cmd->ResponseLen = 0;
7718 return;
7719 }
7720
7721 /* Sync DMA buffer. */
7722 (void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
7723 FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
7724
7725 /* Copy trace buffer data. */
7726 ddi_rep_get8(ha->fwexttracebuf.acc_handle, (uint8_t *)payload,
7727 (uint8_t *)ha->fwexttracebuf.bp, FWEXTSIZE,
7728 DDI_DEV_AUTOINCR);
7729
7730 /* Send payload to application. */
7731 if (ql_send_buffer_data(payload, (caddr_t)(uintptr_t)cmd->ResponseAdr,
7732 cmd->ResponseLen, mode) != cmd->ResponseLen) {
7733 EL(ha, "failed, send_buffer_data\n");
7734 cmd->Status = EXT_STATUS_COPY_ERR;
7735 cmd->ResponseLen = 0;
7736 } else {
7737 cmd->Status = EXT_STATUS_OK;
7738 }
7739
7783 if (cmd->ResponseLen < FWFCESIZE) {
7784 cmd->Status = EXT_STATUS_BUFFER_TOO_SMALL;
7785 cmd->DetailStatus = FWFCESIZE;
7786 EL(ha, "failed, ResponseLen (%xh) < %xh (FWFCESIZE)\n",
7787 cmd->ResponseLen, FWFCESIZE);
7788 cmd->ResponseLen = 0;
7789 return;
7790 }
7791
7792 /* Disable Tracing */
7793 rval = ql_fw_etrace(ha, &ha->fwfcetracebuf, FTO_FCE_TRACE_DISABLE);
7794 if (rval != QL_SUCCESS) {
7795 EL(ha, "f/w FCE trace disable failed: %xh\n", rval);
7796 cmd->Status = EXT_STATUS_ERR;
7797 cmd->ResponseLen = 0;
7798 return;
7799 }
7800
7801 /* Allocate payload buffer */
7802 payload = kmem_zalloc(FWEXTSIZE, KM_SLEEP);
7803 if (payload == NULL) {
7804 EL(ha, "failed, kmem_zalloc\n");
7805 cmd->Status = EXT_STATUS_NO_MEMORY;
7806 cmd->ResponseLen = 0;
7807 return;
7808 }
7809
7810 /* Sync DMA buffer. */
7811 (void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
7812 FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
7813
7814 /* Copy trace buffer data. */
7815 ddi_rep_get8(ha->fwfcetracebuf.acc_handle, (uint8_t *)payload,
7816 (uint8_t *)ha->fwfcetracebuf.bp, FWFCESIZE,
7817 DDI_DEV_AUTOINCR);
7818
7819 /* Send payload to application. */
7820 if (ql_send_buffer_data(payload, (caddr_t)(uintptr_t)cmd->ResponseAdr,
7821 cmd->ResponseLen, mode) != cmd->ResponseLen) {
7822 EL(ha, "failed, send_buffer_data\n");
7823 cmd->Status = EXT_STATUS_COPY_ERR;
7824 cmd->ResponseLen = 0;
7825 } else {
7826 cmd->Status = EXT_STATUS_OK;
7827 }
7828
7905 * Dumps PCI config data to application buffer.
7906 *
7907 * Input:
7908 * ha = adapter state pointer.
7909 * bp = user buffer address.
7910 *
7911 * Returns:
7912 *
7913 * Context:
7914 * Kernel context.
7915 */
7916 int
7917 ql_pci_dump(ql_adapter_state_t *ha, uint32_t *bp, uint32_t pci_size, int mode)
7918 {
7919 uint32_t pci_os;
7920 uint32_t *ptr32, *org_ptr32;
7921
7922 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
7923
7924 ptr32 = kmem_zalloc(pci_size, KM_SLEEP);
7925 if (ptr32 == NULL) {
7926 EL(ha, "failed kmem_zalloc\n");
7927 return (ENOMEM);
7928 }
7929
7930 /* store the initial value of ptr32 */
7931 org_ptr32 = ptr32;
7932 for (pci_os = 0; pci_os < pci_size; pci_os += 4) {
7933 *ptr32 = (uint32_t)ql_pci_config_get32(ha, pci_os);
7934 LITTLE_ENDIAN_32(ptr32);
7935 ptr32++;
7936 }
7937
7938 if (ddi_copyout((void *)org_ptr32, (void *)bp, pci_size, mode) !=
7939 0) {
7940 EL(ha, "failed ddi_copyout\n");
7941 kmem_free(org_ptr32, pci_size);
7942 return (EFAULT);
7943 }
7944
7945 QL_DUMP_9(org_ptr32, 8, pci_size);
7946
7947 kmem_free(org_ptr32, pci_size);
7948
8056 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
8057
8058 if ((CFG_IST(ha, CFG_CTRL_MENLO)) == 0) {
8059 EL(ha, "failed, invalid request for HBA\n");
8060 cmd->Status = EXT_STATUS_INVALID_REQUEST;
8061 cmd->ResponseLen = 0;
8062 return;
8063 }
8064
8065 if (cmd->ResponseLen < sizeof (EXT_MENLO_GET_FW_VERSION)) {
8066 cmd->Status = EXT_STATUS_BUFFER_TOO_SMALL;
8067 cmd->DetailStatus = sizeof (EXT_MENLO_GET_FW_VERSION);
8068 EL(ha, "ResponseLen=%d < %d\n", cmd->ResponseLen,
8069 sizeof (EXT_MENLO_GET_FW_VERSION));
8070 cmd->ResponseLen = 0;
8071 return;
8072 }
8073
8074 /* Allocate packet. */
8075 pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
8076 if (pkt == NULL) {
8077 EL(ha, "failed, kmem_zalloc\n");
8078 cmd->Status = EXT_STATUS_NO_MEMORY;
8079 cmd->ResponseLen = 0;
8080 return;
8081 }
8082
8083 pkt->mvfy.entry_type = VERIFY_MENLO_TYPE;
8084 pkt->mvfy.entry_count = 1;
8085 pkt->mvfy.options_status = LE_16(VMF_DO_NOT_UPDATE_FW);
8086
8087 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, sizeof (ql_mbx_iocb_t));
8088 LITTLE_ENDIAN_16(&pkt->mvfy.options_status);
8089 LITTLE_ENDIAN_16(&pkt->mvfy.failure_code);
8090 ver.FwVersion = LE_32(pkt->mvfy.fw_version);
8091
8092 if (rval != QL_SUCCESS || (pkt->mvfy.entry_status & 0x3c) != 0 ||
8093 pkt->mvfy.options_status != CS_COMPLETE) {
8094 /* Command error */
8095 EL(ha, "failed, status=%xh, es=%xh, cs=%xh, fc=%xh\n", rval,
8096 pkt->mvfy.entry_status & 0x3c, pkt->mvfy.options_status,
8097 pkt->mvfy.failure_code);
8098 cmd->Status = EXT_STATUS_ERR;
8099 cmd->DetailStatus = rval != QL_SUCCESS ? rval :
8100 QL_FUNCTION_FAILED;
8101 cmd->ResponseLen = 0;
8171 }
8172
8173 /* Wait for I/O to stop and daemon to stall. */
8174 if (ql_suspend_hba(ha, 0) != QL_SUCCESS) {
8175 EL(ha, "ql_stall_driver failed\n");
8176 ql_restart_hba(ha);
8177 cmd->Status = EXT_STATUS_BUSY;
8178 cmd->ResponseLen = 0;
8179 return;
8180 }
8181
8182 /* Allocate packet. */
8183 dma_mem = (dma_mem_t *)kmem_zalloc(sizeof (dma_mem_t), KM_SLEEP);
8184 if (dma_mem == NULL) {
8185 EL(ha, "failed, kmem_zalloc\n");
8186 cmd->Status = EXT_STATUS_NO_MEMORY;
8187 cmd->ResponseLen = 0;
8188 return;
8189 }
8190 pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
8191 if (pkt == NULL) {
8192 EL(ha, "failed, kmem_zalloc\n");
8193 kmem_free(dma_mem, sizeof (dma_mem_t));
8194 ql_restart_hba(ha);
8195 cmd->Status = EXT_STATUS_NO_MEMORY;
8196 cmd->ResponseLen = 0;
8197 return;
8198 }
8199
8200 /* Get DMA memory for the IOCB */
8201 if (ql_get_dma_mem(ha, dma_mem, fw.TotalByteCount, LITTLE_ENDIAN_DMA,
8202 QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
8203 cmn_err(CE_WARN, "%s(%d): request queue DMA memory "
8204 "alloc failed", QL_NAME, ha->instance);
8205 kmem_free(pkt, sizeof (ql_mbx_iocb_t));
8206 kmem_free(dma_mem, sizeof (dma_mem_t));
8207 ql_restart_hba(ha);
8208 cmd->Status = EXT_STATUS_MS_NO_RESPONSE;
8209 cmd->ResponseLen = 0;
8210 return;
8211 }
8212
8213 /* Get firmware data. */
8214 if (ql_get_buffer_data((caddr_t)(uintptr_t)fw.pFwDataBytes, dma_mem->bp,
8215 fw.TotalByteCount, mode) != fw.TotalByteCount) {
8216 EL(ha, "failed, get_buffer_data\n");
8217 ql_free_dma_resource(ha, dma_mem);
8218 kmem_free(pkt, sizeof (ql_mbx_iocb_t));
8310 /* Return error */
8311 EL(ha, "RequestLen=%d < %d\n", cmd->RequestLen,
8312 sizeof (EXT_MENLO_MANAGE_INFO));
8313 cmd->Status = EXT_STATUS_INVALID_PARAM;
8314 cmd->DetailStatus = EXT_DSTATUS_REQUEST_LEN;
8315 cmd->ResponseLen = 0;
8316 return;
8317 }
8318
8319 /* Get manage info request. */
8320 if (ddi_copyin((caddr_t)(uintptr_t)cmd->RequestAdr,
8321 (caddr_t)&info, sizeof (EXT_MENLO_MANAGE_INFO), mode) != 0) {
8322 EL(ha, "failed, ddi_copyin\n");
8323 cmd->Status = EXT_STATUS_COPY_ERR;
8324 cmd->ResponseLen = 0;
8325 return;
8326 }
8327
8328 /* Allocate packet. */
8329 pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
8330 if (pkt == NULL) {
8331 EL(ha, "failed, kmem_zalloc\n");
8332 ql_restart_driver(ha);
8333 cmd->Status = EXT_STATUS_NO_MEMORY;
8334 cmd->ResponseLen = 0;
8335 return;
8336 }
8337
8338 pkt->mdata.entry_type = MENLO_DATA_TYPE;
8339 pkt->mdata.entry_count = 1;
8340 pkt->mdata.options_status = (uint16_t)LE_16(info.Operation);
8341
8342 /* Get DMA memory for the IOCB */
8343 if (info.Operation == MENLO_OP_READ_MEM ||
8344 info.Operation == MENLO_OP_WRITE_MEM) {
8345 pkt->mdata.total_byte_count = LE_32(info.TotalByteCount);
8346 pkt->mdata.parameter_1 =
8347 LE_32(info.Parameters.ap.MenloMemory.StartingAddr);
8348 dma_mem = (dma_mem_t *)kmem_zalloc(sizeof (dma_mem_t),
8349 KM_SLEEP);
8350 if (dma_mem == NULL) {
8351 EL(ha, "failed, kmem_zalloc\n");
8352 kmem_free(pkt, sizeof (ql_mbx_iocb_t));
8353 cmd->Status = EXT_STATUS_NO_MEMORY;
8354 cmd->ResponseLen = 0;
8355 return;
8356 }
8806 * cmd: User space CT arguments pointer.
8807 * mode: flags.
8808 */
8809 static void
8810 ql_get_dcbx_parameters(ql_adapter_state_t *ha, EXT_IOCTL *cmd, int mode)
8811 {
8812 uint8_t *tmp_buf;
8813 int rval;
8814
8815 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
8816
8817 if (!(CFG_IST(ha, CFG_CTRL_8081))) {
8818 EL(ha, "invalid request for HBA\n");
8819 cmd->Status = EXT_STATUS_INVALID_REQUEST;
8820 cmd->ResponseLen = 0;
8821 return;
8822 }
8823
8824 /* Allocate memory for command. */
8825 tmp_buf = kmem_zalloc(EXT_DEF_DCBX_PARAM_BUF_SIZE, KM_SLEEP);
8826 if (tmp_buf == NULL) {
8827 EL(ha, "failed, kmem_zalloc\n");
8828 cmd->Status = EXT_STATUS_NO_MEMORY;
8829 cmd->ResponseLen = 0;
8830 return;
8831 }
8832 /* Send command */
8833 rval = ql_get_dcbx_params(ha, EXT_DEF_DCBX_PARAM_BUF_SIZE,
8834 (caddr_t)tmp_buf);
8835 if (rval != QL_SUCCESS) {
8836 /* error */
8837 EL(ha, "failed, get_dcbx_params_mbx=%xh\n", rval);
8838 kmem_free(tmp_buf, EXT_DEF_DCBX_PARAM_BUF_SIZE);
8839 cmd->Status = EXT_STATUS_ERR;
8840 cmd->ResponseLen = 0;
8841 return;
8842 }
8843
8844 /* Copy the response */
8845 if (ql_send_buffer_data((caddr_t)tmp_buf,
8846 (caddr_t)(uintptr_t)cmd->ResponseAdr,
8847 EXT_DEF_DCBX_PARAM_BUF_SIZE, mode) != EXT_DEF_DCBX_PARAM_BUF_SIZE) {
8848 EL(ha, "failed, ddi_copyout\n");
8849 cmd->Status = EXT_STATUS_COPY_ERR;
8850 cmd->ResponseLen = 0;
8851 } else {
9054 if (ddi_copyin((caddr_t)(uintptr_t)cmd->RequestAdr,
9055 (caddr_t)&info, sizeof (EXT_MENLO_MANAGE_INFO), mode) != 0) {
9056 EL(ha, "failed, ddi_copyin\n");
9057 cmd->Status = EXT_STATUS_COPY_ERR;
9058 cmd->ResponseLen = 0;
9059 return;
9060 }
9061
9062 size = info.TotalByteCount;
9063 if (!size) {
9064 /* parameter error */
9065 cmd->Status = EXT_STATUS_INVALID_PARAM;
9066 cmd->DetailStatus = 0;
9067 EL(ha, "failed, size=%xh\n", size);
9068 cmd->ResponseLen = 0;
9069 return;
9070 }
9071
9072 /* Allocate memory for command. */
9073 tmp_buf = kmem_zalloc(size, KM_SLEEP);
9074 if (tmp_buf == NULL) {
9075 EL(ha, "failed, kmem_zalloc\n");
9076 cmd->Status = EXT_STATUS_NO_MEMORY;
9077 cmd->ResponseLen = 0;
9078 return;
9079 }
9080
9081 if (!(info.Operation & MENLO_OP_GET_INFO)) {
9082 EL(ha, "Invalid request for 81XX\n");
9083 kmem_free(tmp_buf, size);
9084 cmd->Status = EXT_STATUS_ERR;
9085 cmd->ResponseLen = 0;
9086 return;
9087 }
9088
9089 rval = ql_get_xgmac_stats(ha, size, (caddr_t)tmp_buf);
9090
9091 if (rval != QL_SUCCESS) {
9092 /* error */
9093 EL(ha, "failed, get_xgmac_stats =%xh\n", rval);
9094 kmem_free(tmp_buf, size);
9095 cmd->Status = EXT_STATUS_ERR;
9096 cmd->ResponseLen = 0;
9097 return;
9098 }
9099
9137 }
9138 /* Get manage info request. */
9139 if (ddi_copyin((caddr_t)(uintptr_t)cmd->RequestAdr,
9140 (caddr_t)&fcf_list, sizeof (EXT_FCF_LIST), mode) != 0) {
9141 EL(ha, "failed, ddi_copyin\n");
9142 cmd->Status = EXT_STATUS_COPY_ERR;
9143 cmd->ResponseLen = 0;
9144 return;
9145 }
9146
9147 if (!(fcf_list.BufSize)) {
9148 /* Return error */
9149 EL(ha, "failed, fcf_list BufSize is=%xh\n",
9150 fcf_list.BufSize);
9151 cmd->Status = EXT_STATUS_INVALID_PARAM;
9152 cmd->ResponseLen = 0;
9153 return;
9154 }
9155 /* Allocate memory for command. */
9156 tmp_buf = kmem_zalloc(fcf_list.BufSize, KM_SLEEP);
9157 if (tmp_buf == NULL) {
9158 EL(ha, "failed, kmem_zalloc\n");
9159 cmd->Status = EXT_STATUS_NO_MEMORY;
9160 cmd->ResponseLen = 0;
9161 return;
9162 }
9163 /* build the descriptor */
9164 if (fcf_list.Options) {
9165 mb_fcf_list.options = FCF_LIST_RETURN_ONE;
9166 } else {
9167 mb_fcf_list.options = FCF_LIST_RETURN_ALL;
9168 }
9169 mb_fcf_list.fcf_index = (uint16_t)fcf_list.FcfIndex;
9170 mb_fcf_list.buffer_size = fcf_list.BufSize;
9171
9172 /* Send command */
9173 rval = ql_get_fcf_list_mbx(ha, &mb_fcf_list, (caddr_t)tmp_buf);
9174 if (rval != QL_SUCCESS) {
9175 /* error */
9176 EL(ha, "failed, get_fcf_list_mbx=%xh\n", rval);
9177 kmem_free(tmp_buf, fcf_list.BufSize);
9178 cmd->Status = EXT_STATUS_ERR;
9179 cmd->ResponseLen = 0;
9180 return;
9181 }
9182
|
168 * Returns:
169 * SYS_ERRNO
170 *
171 * Context:
172 * Kernel context.
173 */
174 int
175 ql_alloc_xioctl_resource(ql_adapter_state_t *ha)
176 {
177 ql_xioctl_t *xp;
178
179 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
180
181 if (ha->xioctl != NULL) {
182 QL_PRINT_9(CE_CONT, "(%d): already allocated done\n",
183 ha->instance);
184 return (0);
185 }
186
187 xp = kmem_zalloc(sizeof (ql_xioctl_t), KM_SLEEP);
188 ha->xioctl = xp;
189
190 /* Allocate AEN tracking buffer */
191 xp->aen_tracking_queue = kmem_zalloc(EXT_DEF_MAX_AEN_QUEUE *
192 sizeof (EXT_ASYNC_EVENT), KM_SLEEP);
193
194 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
195
196 return (0);
197 }
198
199 /*
200 * ql_free_xioctl_resource
201 * Frees resources used by module code.
202 *
203 * Input:
204 * ha: adapter state pointer.
205 *
206 * Context:
207 * Kernel context.
208 */
209 void
210 ql_free_xioctl_resource(ql_adapter_state_t *ha)
211 {
212 ql_xioctl_t *xp = ha->xioctl;
1504 QL_DUMP_9(cmd, 8, sizeof (EXT_IOCTL));
1505
1506 /* Allocate a DMA Memory Descriptor */
1507 dma_mem = (dma_mem_t *)kmem_zalloc(sizeof (dma_mem_t), KM_SLEEP);
1508 if (dma_mem == NULL) {
1509 EL(ha, "failed, kmem_zalloc\n");
1510 cmd->Status = EXT_STATUS_NO_MEMORY;
1511 cmd->ResponseLen = 0;
1512 return;
1513 }
1514 /* Determine maximum buffer size. */
1515 if (cmd->RequestLen < cmd->ResponseLen) {
1516 pld_byte_cnt = cmd->ResponseLen;
1517 } else {
1518 pld_byte_cnt = cmd->RequestLen;
1519 }
1520
1521 /* Allocate command block. */
1522 pkt_size = (uint32_t)(sizeof (ql_mbx_iocb_t) + pld_byte_cnt);
1523 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1524 pld = (caddr_t)pkt + sizeof (ql_mbx_iocb_t);
1525
1526 /* Get command payload data. */
1527 if (ql_get_buffer_data((caddr_t)(uintptr_t)cmd->RequestAdr, pld,
1528 cmd->RequestLen, mode) != cmd->RequestLen) {
1529 EL(ha, "failed, get_buffer_data\n");
1530 kmem_free(pkt, pkt_size);
1531 cmd->Status = EXT_STATUS_COPY_ERR;
1532 cmd->ResponseLen = 0;
1533 return;
1534 }
1535
1536 /* Get DMA memory for the IOCB */
1537 if (ql_get_dma_mem(ha, dma_mem, pkt_size, LITTLE_ENDIAN_DMA,
1538 QL_DMA_RING_ALIGN) != QL_SUCCESS) {
1539 cmn_err(CE_WARN, "%s(%d): DMA memory "
1540 "alloc failed", QL_NAME, ha->instance);
1541 kmem_free(pkt, pkt_size);
1542 kmem_free(dma_mem, sizeof (dma_mem_t));
1543 cmd->Status = EXT_STATUS_MS_NO_RESPONSE;
2108 EL(ha, "failed, fc_port not found\n");
2109 cmd->Status = EXT_STATUS_DEV_NOT_FOUND;
2110 cmd->ResponseLen = 0;
2111 return;
2112 }
2113
2114 if (tq->flags & TQF_NEED_AUTHENTICATION) {
2115 EL(ha, "target not available; loopid=%xh\n", tq->loop_id);
2116 cmd->Status = EXT_STATUS_DEVICE_OFFLINE;
2117 cmd->ResponseLen = 0;
2118 return;
2119 }
2120
2121 /* Allocate command block. */
2122 if ((scsi_req.direction == EXT_DEF_SCSI_PASSTHRU_DATA_IN ||
2123 scsi_req.direction == EXT_DEF_SCSI_PASSTHRU_DATA_OUT) &&
2124 cmd->ResponseLen) {
2125 pld_size = cmd->ResponseLen;
2126 pkt_size = (uint32_t)(sizeof (ql_mbx_iocb_t) + pld_size);
2127 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
2128 pld = (caddr_t)pkt + sizeof (ql_mbx_iocb_t);
2129
2130 /* Get DMA memory for the IOCB */
2131 if (ql_get_dma_mem(ha, dma_mem, pld_size, LITTLE_ENDIAN_DMA,
2132 QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
2133 cmn_err(CE_WARN, "%s(%d): request queue DMA memory "
2134 "alloc failed", QL_NAME, ha->instance);
2135 kmem_free(pkt, pkt_size);
2136 cmd->Status = EXT_STATUS_MS_NO_RESPONSE;
2137 cmd->ResponseLen = 0;
2138 return;
2139 }
2140
2141 if (scsi_req.direction == EXT_DEF_SCSI_PASSTHRU_DATA_IN) {
2142 scsi_req.direction = (uint8_t)
2143 (CFG_IST(ha, CFG_CTRL_24258081) ?
2144 CF_RD : CF_DATA_IN | CF_STAG);
2145 } else {
2146 scsi_req.direction = (uint8_t)
2147 (CFG_IST(ha, CFG_CTRL_24258081) ?
2160 kmem_free(dma_mem, sizeof (dma_mem_t));
2161 return;
2162 }
2163
2164 /* Copy out going data to DMA buffer. */
2165 ddi_rep_put8(dma_mem->acc_handle, (uint8_t *)pld,
2166 (uint8_t *)dma_mem->bp, pld_size,
2167 DDI_DEV_AUTOINCR);
2168
2169 /* Sync DMA buffer. */
2170 (void) ddi_dma_sync(dma_mem->dma_handle, 0,
2171 dma_mem->size, DDI_DMA_SYNC_FORDEV);
2172 }
2173 } else {
2174 scsi_req.direction = (uint8_t)
2175 (CFG_IST(ha, CFG_CTRL_24258081) ? 0 : CF_STAG);
2176 cmd->ResponseLen = 0;
2177
2178 pkt_size = sizeof (ql_mbx_iocb_t);
2179 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
2180 pld = NULL;
2181 pld_size = 0;
2182 }
2183
2184 /* retries = ha->port_down_retry_count; */
2185 retries = 1;
2186 cmd->Status = EXT_STATUS_OK;
2187 cmd->DetailStatus = EXT_DSTATUS_NOADNL_INFO;
2188
2189 QL_PRINT_9(CE_CONT, "(%d): SCSI cdb\n", ha->instance);
2190 QL_DUMP_9(scsi_req.cdbp, 8, scsi_req.cdb_len);
2191
2192 do {
2193 if (DRIVER_SUSPENDED(ha)) {
2194 sts.comp_status = CS_LOOP_DOWN_ABORT;
2195 break;
2196 }
2197
2198 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2199 pkt->cmd24.entry_type = IOCB_CMD_TYPE_7;
3319 cmd->Status = EXT_STATUS_COPY_ERR;
3320 cmd->ResponseLen = 0;
3321 return;
3322 }
3323
3324 opt = (uint16_t)(plbreq.Options & MBC_LOOPBACK_POINT_MASK);
3325
3326 /* Check transfer length fits in buffer. */
3327 if (plbreq.BufferLength < plbreq.TransferCount &&
3328 plbreq.TransferCount < MAILBOX_BUFFER_SIZE) {
3329 EL(ha, "failed, BufferLength=%d, xfercnt=%d, "
3330 "mailbox_buffer_size=%d\n", plbreq.BufferLength,
3331 plbreq.TransferCount, MAILBOX_BUFFER_SIZE);
3332 cmd->Status = EXT_STATUS_INVALID_PARAM;
3333 cmd->ResponseLen = 0;
3334 return;
3335 }
3336
3337 /* Allocate command memory. */
3338 bp = kmem_zalloc(plbreq.TransferCount, KM_SLEEP);
3339
3340 /* Get loopback data. */
3341 if (ql_get_buffer_data((caddr_t)(uintptr_t)plbreq.BufferAddress,
3342 bp, plbreq.TransferCount, mode) != plbreq.TransferCount) {
3343 EL(ha, "failed, ddi_copyin-2\n");
3344 kmem_free(bp, plbreq.TransferCount);
3345 cmd->Status = EXT_STATUS_COPY_ERR;
3346 cmd->ResponseLen = 0;
3347 return;
3348 }
3349
3350 if ((ha->task_daemon_flags & (QL_LOOP_TRANSITION | DRIVER_STALL)) ||
3351 ql_stall_driver(ha, 0) != QL_SUCCESS) {
3352 EL(ha, "failed, LOOP_NOT_READY\n");
3353 kmem_free(bp, plbreq.TransferCount);
3354 cmd->Status = EXT_STATUS_BUSY;
3355 cmd->ResponseLen = 0;
3356 return;
3357 }
3358
3611 }
3612 } else if (tmp_rnid.Addr.Type == EXT_DEF_TYPE_PORTID) {
3613 /*
3614 * Copy caller's d_id to tmp space.
3615 */
3616 bcopy(&tmp_rnid.Addr.FcAddr.Id[1], tmp_fcid.r.d_id,
3617 EXT_DEF_PORTID_SIZE_ACTUAL);
3618 BIG_ENDIAN_24(&tmp_fcid.r.d_id[0]);
3619
3620 if (bcmp((void *)&ha->d_id, (void *)tmp_fcid.r.d_id,
3621 EXT_DEF_PORTID_SIZE_ACTUAL) == 0) {
3622 local_hba = 1;
3623 } else {
3624 tq = ql_find_port(ha, (uint8_t *)tmp_fcid.r.d_id,
3625 QLNT_PID);
3626 }
3627 }
3628
3629 /* Allocate memory for command. */
3630 tmp_buf = kmem_zalloc(SEND_RNID_RSP_SIZE, KM_SLEEP);
3631
3632 if (local_hba) {
3633 rval = ql_get_rnid_params(ha, SEND_RNID_RSP_SIZE, tmp_buf);
3634 if (rval != QL_SUCCESS) {
3635 EL(ha, "failed, get_rnid_params_mbx=%xh\n", rval);
3636 kmem_free(tmp_buf, SEND_RNID_RSP_SIZE);
3637 cmd->Status = EXT_STATUS_ERR;
3638 cmd->ResponseLen = 0;
3639 return;
3640 }
3641
3642 /* Save gotten RNID data. */
3643 bcopy(tmp_buf, &rnid_data, sizeof (EXT_RNID_DATA));
3644
3645 /* Now build the Send RNID response */
3646 tmp_buf[0] = (char)(EXT_DEF_RNID_DFORMAT_TOPO_DISC);
3647 tmp_buf[1] = (2 * EXT_DEF_WWN_NAME_SIZE);
3648 tmp_buf[2] = 0;
3649 tmp_buf[3] = sizeof (EXT_RNID_DATA);
3650
3976 ql_report_lun(ql_adapter_state_t *ha, ql_tgt_t *tq)
3977 {
3978 int rval;
3979 uint8_t retries;
3980 ql_mbx_iocb_t *pkt;
3981 ql_rpt_lun_lst_t *rpt;
3982 dma_mem_t dma_mem;
3983 uint32_t pkt_size, cnt;
3984 uint16_t comp_status;
3985 uint8_t scsi_status_h, scsi_status_l, *reqs;
3986
3987 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
3988
3989 if (DRIVER_SUSPENDED(ha)) {
3990 EL(ha, "failed, LOOP_NOT_READY\n");
3991 return (0);
3992 }
3993
3994 pkt_size = sizeof (ql_mbx_iocb_t) + sizeof (ql_rpt_lun_lst_t);
3995 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
3996 rpt = (ql_rpt_lun_lst_t *)((caddr_t)pkt + sizeof (ql_mbx_iocb_t));
3997
3998 /* Get DMA memory for the IOCB */
3999 if (ql_get_dma_mem(ha, &dma_mem, sizeof (ql_rpt_lun_lst_t),
4000 LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN) != QL_SUCCESS) {
4001 cmn_err(CE_WARN, "%s(%d): DMA memory "
4002 "alloc failed", QL_NAME, ha->instance);
4003 kmem_free(pkt, pkt_size);
4004 return (0);
4005 }
4006
4007 for (retries = 0; retries < 4; retries++) {
4008 if (CFG_IST(ha, CFG_CTRL_24258081)) {
4009 pkt->cmd24.entry_type = IOCB_CMD_TYPE_7;
4010 pkt->cmd24.entry_count = 1;
4011
4012 /* Set N_port handle */
4013 pkt->cmd24.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
4014
4015 /* Set target ID */
4216 * count: scan for the number of existing LUNs.
4217 *
4218 * Returns:
4219 * Number of LUNs.
4220 *
4221 * Context:
4222 * Kernel context.
4223 */
4224 static int
4225 ql_inq_scan(ql_adapter_state_t *ha, ql_tgt_t *tq, int count)
4226 {
4227 int lun, cnt, rval;
4228 ql_mbx_iocb_t *pkt;
4229 uint8_t *inq;
4230 uint32_t pkt_size;
4231
4232 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
4233
4234 pkt_size = sizeof (ql_mbx_iocb_t) + INQ_DATA_SIZE;
4235 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
4236 inq = (uint8_t *)((caddr_t)pkt + sizeof (ql_mbx_iocb_t));
4237
4238 cnt = 0;
4239 for (lun = 0; lun < MAX_LUNS; lun++) {
4240
4241 if (DRIVER_SUSPENDED(ha)) {
4242 rval = QL_LOOP_DOWN;
4243 cnt = 0;
4244 break;
4245 }
4246
4247 rval = ql_inq(ha, tq, lun, pkt, INQ_DATA_SIZE);
4248 if (rval == QL_SUCCESS) {
4249 switch (*inq) {
4250 case DTYPE_DIRECT:
4251 case DTYPE_PROCESSOR: /* Appliance. */
4252 case DTYPE_WORM:
4253 case DTYPE_RODIRECT:
4254 case DTYPE_SCANNER:
4255 case DTYPE_OPTICAL:
4635 *
4636 * Context:
4637 * Kernel context.
4638 */
4639 static int
4640 ql_24xx_flash_desc(ql_adapter_state_t *ha)
4641 {
4642 uint32_t cnt;
4643 uint16_t chksum, *bp, data;
4644 int rval;
4645 flash_desc_t *fdesc;
4646 ql_xioctl_t *xp = ha->xioctl;
4647
4648 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
4649
4650 if (ha->flash_desc_addr == 0) {
4651 QL_PRINT_9(CE_CONT, "(%d): desc ptr=0\n", ha->instance);
4652 return (QL_FUNCTION_FAILED);
4653 }
4654
4655 fdesc = kmem_zalloc(sizeof (flash_desc_t), KM_SLEEP);
4656 rval = ql_dump_fcode(ha, (uint8_t *)fdesc, sizeof (flash_desc_t),
4657 ha->flash_desc_addr << 2);
4658 if (rval != QL_SUCCESS) {
4659 EL(ha, "read status=%xh\n", rval);
4660 kmem_free(fdesc, sizeof (flash_desc_t));
4661 return (rval);
4662 }
4663
4664 chksum = 0;
4665 bp = (uint16_t *)fdesc;
4666 for (cnt = 0; cnt < (sizeof (flash_desc_t)) / 2; cnt++) {
4667 data = *bp++;
4668 LITTLE_ENDIAN_16(&data);
4669 chksum += data;
4670 }
4671
4672 LITTLE_ENDIAN_32(&fdesc->flash_valid);
4673 LITTLE_ENDIAN_16(&fdesc->flash_version);
4674 LITTLE_ENDIAN_16(&fdesc->flash_len);
4675 LITTLE_ENDIAN_16(&fdesc->flash_checksum);
5369 /* parameter error */
5370 EL(ha, "failed, RequestLen < EXT_SET_RNID_REQ, Len=%xh\n",
5371 cmd->RequestLen);
5372 cmd->Status = EXT_STATUS_INVALID_PARAM;
5373 cmd->DetailStatus = EXT_DSTATUS_REQUEST_LEN;
5374 cmd->ResponseLen = 0;
5375 return;
5376 }
5377
5378 rval = ddi_copyin((void*)(uintptr_t)cmd->RequestAdr, &tmp_set,
5379 cmd->RequestLen, mode);
5380 if (rval != 0) {
5381 EL(ha, "failed, ddi_copyin\n");
5382 cmd->Status = EXT_STATUS_COPY_ERR;
5383 cmd->ResponseLen = 0;
5384 return;
5385 }
5386
5387 /* Allocate memory for command. */
5388 tmp_buf = kmem_zalloc(sizeof (EXT_RNID_DATA), KM_SLEEP);
5389
5390 rval = ql_get_rnid_params(ha, sizeof (EXT_RNID_DATA),
5391 (caddr_t)tmp_buf);
5392 if (rval != QL_SUCCESS) {
5393 /* error */
5394 EL(ha, "failed, get_rnid_params_mbx=%xh\n", rval);
5395 kmem_free(tmp_buf, sizeof (EXT_RNID_DATA));
5396 cmd->Status = EXT_STATUS_ERR;
5397 cmd->ResponseLen = 0;
5398 return;
5399 }
5400
5401 /* Now set the requested params. */
5402 bcopy(tmp_set.IPVersion, tmp_buf->IPVersion, 2);
5403 bcopy(tmp_set.UDPPortNumber, tmp_buf->UDPPortNumber, 2);
5404 bcopy(tmp_set.IPAddress, tmp_buf->IPAddress, 16);
5405
5406 rval = ql_set_rnid_params(ha, sizeof (EXT_RNID_DATA),
5407 (caddr_t)tmp_buf);
5408 if (rval != QL_SUCCESS) {
5426 * cmd: User space CT arguments pointer.
5427 * mode: flags.
5428 */
5429 static void
5430 ql_get_rnid_parameters(ql_adapter_state_t *ha, EXT_IOCTL *cmd, int mode)
5431 {
5432 EXT_RNID_DATA *tmp_buf;
5433 uint32_t rval;
5434
5435 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
5436
5437 if (DRIVER_SUSPENDED(ha)) {
5438 EL(ha, "failed, LOOP_NOT_READY\n");
5439 cmd->Status = EXT_STATUS_BUSY;
5440 cmd->ResponseLen = 0;
5441 return;
5442 }
5443
5444 /* Allocate memory for command. */
5445 tmp_buf = kmem_zalloc(sizeof (EXT_RNID_DATA), KM_SLEEP);
5446
5447 /* Send command */
5448 rval = ql_get_rnid_params(ha, sizeof (EXT_RNID_DATA),
5449 (caddr_t)tmp_buf);
5450 if (rval != QL_SUCCESS) {
5451 /* error */
5452 EL(ha, "failed, get_rnid_params_mbx=%xh\n", rval);
5453 kmem_free(tmp_buf, sizeof (EXT_RNID_DATA));
5454 cmd->Status = EXT_STATUS_ERR;
5455 cmd->ResponseLen = 0;
5456 return;
5457 }
5458
5459 /* Copy the response */
5460 if (ql_send_buffer_data((caddr_t)tmp_buf,
5461 (caddr_t)(uintptr_t)cmd->ResponseAdr,
5462 sizeof (EXT_RNID_DATA), mode) != sizeof (EXT_RNID_DATA)) {
5463 EL(ha, "failed, ddi_copyout\n");
5464 cmd->Status = EXT_STATUS_COPY_ERR;
5465 cmd->ResponseLen = 0;
5557 int retry = 10;
5558
5559 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
5560
5561 while (ha->task_daemon_flags &
5562 (ABORT_ISP_ACTIVE | LOOP_RESYNC_ACTIVE | DRIVER_STALL)) {
5563 ql_delay(ha, 10000000); /* 10 second delay */
5564
5565 retry--;
5566
5567 if (retry == 0) { /* effectively 100 seconds */
5568 EL(ha, "failed, LOOP_NOT_READY\n");
5569 cmd->Status = EXT_STATUS_BUSY;
5570 cmd->ResponseLen = 0;
5571 return;
5572 }
5573 }
5574
5575 /* Allocate memory for command. */
5576 ls = kmem_zalloc(sizeof (ql_link_stats_t), KM_SLEEP);
5577
5578 /*
5579 * I think these are supposed to be port statistics
5580 * the loop ID or port ID should be in cmd->Instance.
5581 */
5582 rval = ql_get_status_counts(ha, (uint16_t)
5583 (ha->task_daemon_flags & LOOP_DOWN ? 0xFF : ha->loop_id),
5584 sizeof (ql_link_stats_t), (caddr_t)ls, 0);
5585 if (rval != QL_SUCCESS) {
5586 EL(ha, "failed, get_link_status=%xh, id=%xh\n", rval,
5587 ha->loop_id);
5588 cmd->Status = EXT_STATUS_MAILBOX;
5589 cmd->DetailStatus = rval;
5590 cmd->ResponseLen = 0;
5591 } else {
5592 ps.ControllerErrorCount = xp->ControllerErrorCount;
5593 ps.DeviceErrorCount = xp->DeviceErrorCount;
5594 ps.IoCount = (uint32_t)(xp->IOInputRequests +
5595 xp->IOOutputRequests + xp->IOControlRequests);
5596 ps.MBytesCount = (uint32_t)(xp->IOInputMByteCnt +
5673 cmd->ResponseLen = 0;
5674 return;
5675 }
5676
5677 while (ha->task_daemon_flags &
5678 (ABORT_ISP_ACTIVE | LOOP_RESYNC_ACTIVE | DRIVER_STALL)) {
5679 ql_delay(ha, 10000000); /* 10 second delay */
5680
5681 retry--;
5682
5683 if (retry == 0) { /* effectively 100 seconds */
5684 EL(ha, "failed, LOOP_NOT_READY\n");
5685 cmd->Status = EXT_STATUS_BUSY;
5686 cmd->ResponseLen = 0;
5687 return;
5688 }
5689 }
5690
5691 /* Allocate memory for command. */
5692 ls = kmem_zalloc(sizeof (ql_link_stats_t), KM_SLEEP);
5693
5694 rval = ql_get_link_status(ha, tq->loop_id, sizeof (ql_link_stats_t),
5695 (caddr_t)ls, 0);
5696 if (rval != QL_SUCCESS) {
5697 EL(ha, "failed, get_link_status=%xh, d_id=%xh\n", rval,
5698 tq->d_id.b24);
5699 cmd->Status = EXT_STATUS_MAILBOX;
5700 cmd->DetailStatus = rval;
5701 cmd->ResponseLen = 0;
5702 } else {
5703 ps.LinkFailureCount = LE_32(ls->link_fail_cnt);
5704 ps.LossOfSyncCount = LE_32(ls->sync_loss_cnt);
5705 ps.LossOfSignalsCount = LE_32(ls->signal_loss_cnt);
5706 ps.PrimitiveSeqProtocolErrorCount = LE_32(ls->prot_err_cnt);
5707 ps.InvalidTransmissionWordCount = LE_32(ls->inv_xmit_cnt);
5708 ps.InvalidCRCCount = LE_32(ls->inv_crc_cnt);
5709
5710 rval = ddi_copyout((void *)&ps,
5711 (void *)(uintptr_t)cmd->ResponseAdr,
5712 sizeof (EXT_HBA_PORT_STAT), mode);
6882 * Input:
6883 * ha: adapter state pointer.
6884 * flt_paddr: flash layout pointer address.
6885 *
6886 * Context:
6887 * Kernel context.
6888 */
6889 static void
6890 ql_flash_layout_table(ql_adapter_state_t *ha, uint32_t flt_paddr)
6891 {
6892 ql_flt_ptr_t *fptr;
6893 uint8_t *bp;
6894 int rval;
6895 uint32_t len, faddr, cnt;
6896 uint16_t chksum, w16;
6897
6898 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
6899
6900 /* Process flash layout table header */
6901 len = sizeof (ql_flt_ptr_t);
6902 bp = kmem_zalloc(len, KM_SLEEP);
6903
6904 /* Process pointer to flash layout table */
6905 if ((rval = ql_dump_fcode(ha, bp, len, flt_paddr)) != QL_SUCCESS) {
6906 EL(ha, "fptr dump_flash pos=%xh, status=%xh\n", flt_paddr,
6907 rval);
6908 kmem_free(bp, len);
6909 return;
6910 }
6911 fptr = (ql_flt_ptr_t *)bp;
6912
6913 /* Verify pointer to flash layout table. */
6914 for (chksum = 0, cnt = 0; cnt < len; cnt += 2) {
6915 w16 = (uint16_t)CHAR_TO_SHORT(bp[cnt], bp[cnt + 1]);
6916 chksum += w16;
6917 }
6918 if (chksum != 0 || fptr->sig[0] != 'Q' || fptr->sig[1] != 'F' ||
6919 fptr->sig[2] != 'L' || fptr->sig[3] != 'T') {
6920 EL(ha, "ptr chksum=%xh, sig=%c%c%c%c\n", chksum, fptr->sig[0],
6921 fptr->sig[1], fptr->sig[2], fptr->sig[3]);
6922 kmem_free(bp, len);
6939 * Input:
6940 * ha: adapter state pointer.
6941 * faddr: flash layout table byte address.
6942 *
6943 * Context:
6944 * Kernel context.
6945 */
6946 static void
6947 ql_process_flt(ql_adapter_state_t *ha, uint32_t faddr)
6948 {
6949 ql_flt_hdr_t *fhdr;
6950 ql_flt_region_t *frgn;
6951 uint8_t *bp, *eaddr, nv_rg, vpd_rg;
6952 int rval;
6953 uint32_t len, cnt, fe_addr;
6954 uint16_t chksum, w16;
6955
6956 QL_PRINT_9(CE_CONT, "(%d): started faddr=%xh\n", ha->instance, faddr);
6957
6958 /* Process flash layout table header */
6959 bp = kmem_zalloc(FLASH_LAYOUT_TABLE_SIZE, KM_SLEEP);
6960 fhdr = (ql_flt_hdr_t *)bp;
6961
6962 /* Process flash layout table. */
6963 if ((rval = ql_dump_fcode(ha, bp, FLASH_LAYOUT_TABLE_SIZE, faddr)) !=
6964 QL_SUCCESS) {
6965 EL(ha, "fhdr dump_flash pos=%xh, status=%xh\n", faddr, rval);
6966 kmem_free(bp, FLASH_LAYOUT_TABLE_SIZE);
6967 return;
6968 }
6969
6970 /* Verify flash layout table. */
6971 len = (uint32_t)(CHAR_TO_SHORT(fhdr->len[0], fhdr->len[1]) +
6972 sizeof (ql_flt_hdr_t) + sizeof (ql_flt_region_t));
6973 if (len > FLASH_LAYOUT_TABLE_SIZE) {
6974 chksum = 0xffff;
6975 } else {
6976 for (chksum = 0, cnt = 0; cnt < len; cnt += 2) {
6977 w16 = (uint16_t)CHAR_TO_SHORT(bp[cnt], bp[cnt + 1]);
6978 chksum += w16;
6979 }
7615 rval = ql_fw_etrace(ha, &ha->fwexttracebuf, FTO_INSERT_TIME_STAMP);
7616 if (rval != QL_SUCCESS) {
7617 EL(ha, "f/w extended trace insert"
7618 "time stamp failed: %xh\n", rval);
7619 cmd->Status = EXT_STATUS_ERR;
7620 cmd->ResponseLen = 0;
7621 return;
7622 }
7623
7624 /* Disable Tracing */
7625 rval = ql_fw_etrace(ha, &ha->fwexttracebuf, FTO_EXT_TRACE_DISABLE);
7626 if (rval != QL_SUCCESS) {
7627 EL(ha, "f/w extended trace disable failed: %xh\n", rval);
7628 cmd->Status = EXT_STATUS_ERR;
7629 cmd->ResponseLen = 0;
7630 return;
7631 }
7632
7633 /* Allocate payload buffer */
7634 payload = kmem_zalloc(FWEXTSIZE, KM_SLEEP);
7635
7636 /* Sync DMA buffer. */
7637 (void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
7638 FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
7639
7640 /* Copy trace buffer data. */
7641 ddi_rep_get8(ha->fwexttracebuf.acc_handle, (uint8_t *)payload,
7642 (uint8_t *)ha->fwexttracebuf.bp, FWEXTSIZE,
7643 DDI_DEV_AUTOINCR);
7644
7645 /* Send payload to application. */
7646 if (ql_send_buffer_data(payload, (caddr_t)(uintptr_t)cmd->ResponseAdr,
7647 cmd->ResponseLen, mode) != cmd->ResponseLen) {
7648 EL(ha, "failed, send_buffer_data\n");
7649 cmd->Status = EXT_STATUS_COPY_ERR;
7650 cmd->ResponseLen = 0;
7651 } else {
7652 cmd->Status = EXT_STATUS_OK;
7653 }
7654
7698 if (cmd->ResponseLen < FWFCESIZE) {
7699 cmd->Status = EXT_STATUS_BUFFER_TOO_SMALL;
7700 cmd->DetailStatus = FWFCESIZE;
7701 EL(ha, "failed, ResponseLen (%xh) < %xh (FWFCESIZE)\n",
7702 cmd->ResponseLen, FWFCESIZE);
7703 cmd->ResponseLen = 0;
7704 return;
7705 }
7706
7707 /* Disable Tracing */
7708 rval = ql_fw_etrace(ha, &ha->fwfcetracebuf, FTO_FCE_TRACE_DISABLE);
7709 if (rval != QL_SUCCESS) {
7710 EL(ha, "f/w FCE trace disable failed: %xh\n", rval);
7711 cmd->Status = EXT_STATUS_ERR;
7712 cmd->ResponseLen = 0;
7713 return;
7714 }
7715
7716 /* Allocate payload buffer */
7717 payload = kmem_zalloc(FWEXTSIZE, KM_SLEEP);
7718
7719 /* Sync DMA buffer. */
7720 (void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
7721 FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
7722
7723 /* Copy trace buffer data. */
7724 ddi_rep_get8(ha->fwfcetracebuf.acc_handle, (uint8_t *)payload,
7725 (uint8_t *)ha->fwfcetracebuf.bp, FWFCESIZE,
7726 DDI_DEV_AUTOINCR);
7727
7728 /* Send payload to application. */
7729 if (ql_send_buffer_data(payload, (caddr_t)(uintptr_t)cmd->ResponseAdr,
7730 cmd->ResponseLen, mode) != cmd->ResponseLen) {
7731 EL(ha, "failed, send_buffer_data\n");
7732 cmd->Status = EXT_STATUS_COPY_ERR;
7733 cmd->ResponseLen = 0;
7734 } else {
7735 cmd->Status = EXT_STATUS_OK;
7736 }
7737
7814 * Dumps PCI config data to application buffer.
7815 *
7816 * Input:
7817 * ha = adapter state pointer.
7818 * bp = user buffer address.
7819 *
7820 * Returns:
7821 *
7822 * Context:
7823 * Kernel context.
7824 */
7825 int
7826 ql_pci_dump(ql_adapter_state_t *ha, uint32_t *bp, uint32_t pci_size, int mode)
7827 {
7828 uint32_t pci_os;
7829 uint32_t *ptr32, *org_ptr32;
7830
7831 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
7832
7833 ptr32 = kmem_zalloc(pci_size, KM_SLEEP);
7834
7835 /* store the initial value of ptr32 */
7836 org_ptr32 = ptr32;
7837 for (pci_os = 0; pci_os < pci_size; pci_os += 4) {
7838 *ptr32 = (uint32_t)ql_pci_config_get32(ha, pci_os);
7839 LITTLE_ENDIAN_32(ptr32);
7840 ptr32++;
7841 }
7842
7843 if (ddi_copyout((void *)org_ptr32, (void *)bp, pci_size, mode) !=
7844 0) {
7845 EL(ha, "failed ddi_copyout\n");
7846 kmem_free(org_ptr32, pci_size);
7847 return (EFAULT);
7848 }
7849
7850 QL_DUMP_9(org_ptr32, 8, pci_size);
7851
7852 kmem_free(org_ptr32, pci_size);
7853
7961 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
7962
7963 if ((CFG_IST(ha, CFG_CTRL_MENLO)) == 0) {
7964 EL(ha, "failed, invalid request for HBA\n");
7965 cmd->Status = EXT_STATUS_INVALID_REQUEST;
7966 cmd->ResponseLen = 0;
7967 return;
7968 }
7969
7970 if (cmd->ResponseLen < sizeof (EXT_MENLO_GET_FW_VERSION)) {
7971 cmd->Status = EXT_STATUS_BUFFER_TOO_SMALL;
7972 cmd->DetailStatus = sizeof (EXT_MENLO_GET_FW_VERSION);
7973 EL(ha, "ResponseLen=%d < %d\n", cmd->ResponseLen,
7974 sizeof (EXT_MENLO_GET_FW_VERSION));
7975 cmd->ResponseLen = 0;
7976 return;
7977 }
7978
7979 /* Allocate packet. */
7980 pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
7981
7982 pkt->mvfy.entry_type = VERIFY_MENLO_TYPE;
7983 pkt->mvfy.entry_count = 1;
7984 pkt->mvfy.options_status = LE_16(VMF_DO_NOT_UPDATE_FW);
7985
7986 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, sizeof (ql_mbx_iocb_t));
7987 LITTLE_ENDIAN_16(&pkt->mvfy.options_status);
7988 LITTLE_ENDIAN_16(&pkt->mvfy.failure_code);
7989 ver.FwVersion = LE_32(pkt->mvfy.fw_version);
7990
7991 if (rval != QL_SUCCESS || (pkt->mvfy.entry_status & 0x3c) != 0 ||
7992 pkt->mvfy.options_status != CS_COMPLETE) {
7993 /* Command error */
7994 EL(ha, "failed, status=%xh, es=%xh, cs=%xh, fc=%xh\n", rval,
7995 pkt->mvfy.entry_status & 0x3c, pkt->mvfy.options_status,
7996 pkt->mvfy.failure_code);
7997 cmd->Status = EXT_STATUS_ERR;
7998 cmd->DetailStatus = rval != QL_SUCCESS ? rval :
7999 QL_FUNCTION_FAILED;
8000 cmd->ResponseLen = 0;
8070 }
8071
8072 /* Wait for I/O to stop and daemon to stall. */
8073 if (ql_suspend_hba(ha, 0) != QL_SUCCESS) {
8074 EL(ha, "ql_stall_driver failed\n");
8075 ql_restart_hba(ha);
8076 cmd->Status = EXT_STATUS_BUSY;
8077 cmd->ResponseLen = 0;
8078 return;
8079 }
8080
8081 /* Allocate packet. */
8082 dma_mem = (dma_mem_t *)kmem_zalloc(sizeof (dma_mem_t), KM_SLEEP);
8083 if (dma_mem == NULL) {
8084 EL(ha, "failed, kmem_zalloc\n");
8085 cmd->Status = EXT_STATUS_NO_MEMORY;
8086 cmd->ResponseLen = 0;
8087 return;
8088 }
8089 pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
8090
8091 /* Get DMA memory for the IOCB */
8092 if (ql_get_dma_mem(ha, dma_mem, fw.TotalByteCount, LITTLE_ENDIAN_DMA,
8093 QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
8094 cmn_err(CE_WARN, "%s(%d): request queue DMA memory "
8095 "alloc failed", QL_NAME, ha->instance);
8096 kmem_free(pkt, sizeof (ql_mbx_iocb_t));
8097 kmem_free(dma_mem, sizeof (dma_mem_t));
8098 ql_restart_hba(ha);
8099 cmd->Status = EXT_STATUS_MS_NO_RESPONSE;
8100 cmd->ResponseLen = 0;
8101 return;
8102 }
8103
8104 /* Get firmware data. */
8105 if (ql_get_buffer_data((caddr_t)(uintptr_t)fw.pFwDataBytes, dma_mem->bp,
8106 fw.TotalByteCount, mode) != fw.TotalByteCount) {
8107 EL(ha, "failed, get_buffer_data\n");
8108 ql_free_dma_resource(ha, dma_mem);
8109 kmem_free(pkt, sizeof (ql_mbx_iocb_t));
8201 /* Return error */
8202 EL(ha, "RequestLen=%d < %d\n", cmd->RequestLen,
8203 sizeof (EXT_MENLO_MANAGE_INFO));
8204 cmd->Status = EXT_STATUS_INVALID_PARAM;
8205 cmd->DetailStatus = EXT_DSTATUS_REQUEST_LEN;
8206 cmd->ResponseLen = 0;
8207 return;
8208 }
8209
8210 /* Get manage info request. */
8211 if (ddi_copyin((caddr_t)(uintptr_t)cmd->RequestAdr,
8212 (caddr_t)&info, sizeof (EXT_MENLO_MANAGE_INFO), mode) != 0) {
8213 EL(ha, "failed, ddi_copyin\n");
8214 cmd->Status = EXT_STATUS_COPY_ERR;
8215 cmd->ResponseLen = 0;
8216 return;
8217 }
8218
8219 /* Allocate packet. */
8220 pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
8221
8222 pkt->mdata.entry_type = MENLO_DATA_TYPE;
8223 pkt->mdata.entry_count = 1;
8224 pkt->mdata.options_status = (uint16_t)LE_16(info.Operation);
8225
8226 /* Get DMA memory for the IOCB */
8227 if (info.Operation == MENLO_OP_READ_MEM ||
8228 info.Operation == MENLO_OP_WRITE_MEM) {
8229 pkt->mdata.total_byte_count = LE_32(info.TotalByteCount);
8230 pkt->mdata.parameter_1 =
8231 LE_32(info.Parameters.ap.MenloMemory.StartingAddr);
8232 dma_mem = (dma_mem_t *)kmem_zalloc(sizeof (dma_mem_t),
8233 KM_SLEEP);
8234 if (dma_mem == NULL) {
8235 EL(ha, "failed, kmem_zalloc\n");
8236 kmem_free(pkt, sizeof (ql_mbx_iocb_t));
8237 cmd->Status = EXT_STATUS_NO_MEMORY;
8238 cmd->ResponseLen = 0;
8239 return;
8240 }
8690 * cmd: User space CT arguments pointer.
8691 * mode: flags.
8692 */
8693 static void
8694 ql_get_dcbx_parameters(ql_adapter_state_t *ha, EXT_IOCTL *cmd, int mode)
8695 {
8696 uint8_t *tmp_buf;
8697 int rval;
8698
8699 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
8700
8701 if (!(CFG_IST(ha, CFG_CTRL_8081))) {
8702 EL(ha, "invalid request for HBA\n");
8703 cmd->Status = EXT_STATUS_INVALID_REQUEST;
8704 cmd->ResponseLen = 0;
8705 return;
8706 }
8707
8708 /* Allocate memory for command. */
8709 tmp_buf = kmem_zalloc(EXT_DEF_DCBX_PARAM_BUF_SIZE, KM_SLEEP);
8710 /* Send command */
8711 rval = ql_get_dcbx_params(ha, EXT_DEF_DCBX_PARAM_BUF_SIZE,
8712 (caddr_t)tmp_buf);
8713 if (rval != QL_SUCCESS) {
8714 /* error */
8715 EL(ha, "failed, get_dcbx_params_mbx=%xh\n", rval);
8716 kmem_free(tmp_buf, EXT_DEF_DCBX_PARAM_BUF_SIZE);
8717 cmd->Status = EXT_STATUS_ERR;
8718 cmd->ResponseLen = 0;
8719 return;
8720 }
8721
8722 /* Copy the response */
8723 if (ql_send_buffer_data((caddr_t)tmp_buf,
8724 (caddr_t)(uintptr_t)cmd->ResponseAdr,
8725 EXT_DEF_DCBX_PARAM_BUF_SIZE, mode) != EXT_DEF_DCBX_PARAM_BUF_SIZE) {
8726 EL(ha, "failed, ddi_copyout\n");
8727 cmd->Status = EXT_STATUS_COPY_ERR;
8728 cmd->ResponseLen = 0;
8729 } else {
8932 if (ddi_copyin((caddr_t)(uintptr_t)cmd->RequestAdr,
8933 (caddr_t)&info, sizeof (EXT_MENLO_MANAGE_INFO), mode) != 0) {
8934 EL(ha, "failed, ddi_copyin\n");
8935 cmd->Status = EXT_STATUS_COPY_ERR;
8936 cmd->ResponseLen = 0;
8937 return;
8938 }
8939
8940 size = info.TotalByteCount;
8941 if (!size) {
8942 /* parameter error */
8943 cmd->Status = EXT_STATUS_INVALID_PARAM;
8944 cmd->DetailStatus = 0;
8945 EL(ha, "failed, size=%xh\n", size);
8946 cmd->ResponseLen = 0;
8947 return;
8948 }
8949
8950 /* Allocate memory for command. */
8951 tmp_buf = kmem_zalloc(size, KM_SLEEP);
8952
8953 if (!(info.Operation & MENLO_OP_GET_INFO)) {
8954 EL(ha, "Invalid request for 81XX\n");
8955 kmem_free(tmp_buf, size);
8956 cmd->Status = EXT_STATUS_ERR;
8957 cmd->ResponseLen = 0;
8958 return;
8959 }
8960
8961 rval = ql_get_xgmac_stats(ha, size, (caddr_t)tmp_buf);
8962
8963 if (rval != QL_SUCCESS) {
8964 /* error */
8965 EL(ha, "failed, get_xgmac_stats =%xh\n", rval);
8966 kmem_free(tmp_buf, size);
8967 cmd->Status = EXT_STATUS_ERR;
8968 cmd->ResponseLen = 0;
8969 return;
8970 }
8971
9009 }
9010 /* Get manage info request. */
9011 if (ddi_copyin((caddr_t)(uintptr_t)cmd->RequestAdr,
9012 (caddr_t)&fcf_list, sizeof (EXT_FCF_LIST), mode) != 0) {
9013 EL(ha, "failed, ddi_copyin\n");
9014 cmd->Status = EXT_STATUS_COPY_ERR;
9015 cmd->ResponseLen = 0;
9016 return;
9017 }
9018
9019 if (!(fcf_list.BufSize)) {
9020 /* Return error */
9021 EL(ha, "failed, fcf_list BufSize is=%xh\n",
9022 fcf_list.BufSize);
9023 cmd->Status = EXT_STATUS_INVALID_PARAM;
9024 cmd->ResponseLen = 0;
9025 return;
9026 }
9027 /* Allocate memory for command. */
9028 tmp_buf = kmem_zalloc(fcf_list.BufSize, KM_SLEEP);
9029 /* build the descriptor */
9030 if (fcf_list.Options) {
9031 mb_fcf_list.options = FCF_LIST_RETURN_ONE;
9032 } else {
9033 mb_fcf_list.options = FCF_LIST_RETURN_ALL;
9034 }
9035 mb_fcf_list.fcf_index = (uint16_t)fcf_list.FcfIndex;
9036 mb_fcf_list.buffer_size = fcf_list.BufSize;
9037
9038 /* Send command */
9039 rval = ql_get_fcf_list_mbx(ha, &mb_fcf_list, (caddr_t)tmp_buf);
9040 if (rval != QL_SUCCESS) {
9041 /* error */
9042 EL(ha, "failed, get_fcf_list_mbx=%xh\n", rval);
9043 kmem_free(tmp_buf, fcf_list.BufSize);
9044 cmd->Status = EXT_STATUS_ERR;
9045 cmd->ResponseLen = 0;
9046 return;
9047 }
9048
|