1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /* Copyright 2010 QLogic Corporation */
23
24 /*
25 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26 */
27
28 #pragma ident "Copyright 2010 QLogic Corporation; ql_iocb.c"
29
30 /*
31 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
32 *
33 * ***********************************************************************
34 * * **
35 * * NOTICE **
36 * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION **
37 * * ALL RIGHTS RESERVED **
38 * * **
39 * ***********************************************************************
40 *
41 */
42
43 #include <ql_apps.h>
44 #include <ql_api.h>
45 #include <ql_debug.h>
46 #include <ql_iocb.h>
47 #include <ql_isr.h>
48 #include <ql_xioctl.h>
49
50 /*
51 * Local Function Prototypes.
52 */
53 static int ql_req_pkt(ql_adapter_state_t *, request_t **);
54 static void ql_continuation_iocb(ql_adapter_state_t *, ddi_dma_cookie_t *,
55 uint16_t, boolean_t);
56 static void ql_isp24xx_rcvbuf(ql_adapter_state_t *);
57 static void ql_cmd_24xx_type_6_iocb(ql_adapter_state_t *, ql_srb_t *, void *);
58
59 /*
60 * ql_start_iocb
61 * The start IOCB is responsible for building request packets
62 * on request ring and modifying ISP input pointer.
63 *
64 * Input:
65 * ha: adapter state pointer.
66 * sp: srb structure pointer.
67 *
68 * Context:
69 * Interrupt or Kernel context, no mailbox commands allowed.
70 */
71 void
ql_start_iocb(ql_adapter_state_t * vha,ql_srb_t * sp)72 ql_start_iocb(ql_adapter_state_t *vha, ql_srb_t *sp)
73 {
74 ql_link_t *link;
75 request_t *pkt;
76 uint64_t *ptr64;
77 uint32_t cnt;
78 ql_adapter_state_t *ha = vha->pha;
79
80 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
81
82 /* Acquire ring lock. */
83 REQUEST_RING_LOCK(ha);
84
85 if (sp != NULL) {
86 /*
87 * If the pending queue is not empty maintain order
88 * by puting this srb at the tail and geting the head.
89 */
90 if ((link = ha->pending_cmds.first) != NULL) {
91 ql_add_link_b(&ha->pending_cmds, &sp->cmd);
92 /* Remove command from pending command queue */
93 sp = link->base_address;
94 ql_remove_link(&ha->pending_cmds, &sp->cmd);
95 }
96 } else {
97 /* Get command from pending command queue if not empty. */
98 if ((link = ha->pending_cmds.first) == NULL) {
99 /* Release ring specific lock */
100 REQUEST_RING_UNLOCK(ha);
101 QL_PRINT_3(CE_CONT, "(%d): empty done\n",
102 ha->instance);
103 return;
104 }
105 /* Remove command from pending command queue */
106 sp = link->base_address;
107 ql_remove_link(&ha->pending_cmds, &sp->cmd);
108 }
109
110 /* start this request and as many others as possible */
111 for (;;) {
112 if (ha->req_q_cnt < sp->req_cnt) {
113 /* Calculate number of free request entries. */
114 cnt = RD16_IO_REG(ha, req_out);
115 if (ha->req_ring_index < cnt) {
116 ha->req_q_cnt = (uint16_t)
117 (cnt - ha->req_ring_index);
118 } else {
119 ha->req_q_cnt = (uint16_t)(REQUEST_ENTRY_CNT -
120 (ha->req_ring_index - cnt));
121 }
122 if (ha->req_q_cnt != 0) {
123 ha->req_q_cnt--;
124 }
125
126 /*
127 * If no room in request ring put this srb at
128 * the head of the pending queue and exit.
129 */
130 if (ha->req_q_cnt < sp->req_cnt) {
131 QL_PRINT_8(CE_CONT, "(%d): request ring full,"
132 " req_q_cnt=%d, req_ring_index=%d\n",
133 ha->instance, ha->req_q_cnt,
134 ha->req_ring_index);
135 ql_add_link_t(&ha->pending_cmds, &sp->cmd);
136 break;
137 }
138 }
139
140 /* Check for room in outstanding command list. */
141 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
142 ha->osc_index++;
143 if (ha->osc_index == MAX_OUTSTANDING_COMMANDS) {
144 ha->osc_index = 1;
145 }
146 if (ha->outstanding_cmds[ha->osc_index] == NULL) {
147 break;
148 }
149 }
150 /*
151 * If no room in outstanding array put this srb at
152 * the head of the pending queue and exit.
153 */
154 if (cnt == MAX_OUTSTANDING_COMMANDS) {
155 QL_PRINT_8(CE_CONT, "(%d): no room in outstanding "
156 "array\n", ha->instance);
157 ql_add_link_t(&ha->pending_cmds, &sp->cmd);
158 break;
159 }
160
161 /* nothing to stop us now. */
162 ha->outstanding_cmds[ha->osc_index] = sp;
163 /* create and save a unique response identifier in the srb */
164 sp->handle = ha->adapter_stats->ncmds << OSC_INDEX_SHIFT |
165 ha->osc_index;
166 ha->req_q_cnt -= sp->req_cnt;
167
168 /* build the iocb in the request ring */
169 pkt = ha->request_ring_ptr;
170 sp->request_ring_ptr = pkt;
171 sp->flags |= SRB_IN_TOKEN_ARRAY;
172
173 /* Zero out packet. */
174 ptr64 = (uint64_t *)pkt;
175 *ptr64++ = 0; *ptr64++ = 0;
176 *ptr64++ = 0; *ptr64++ = 0;
177 *ptr64++ = 0; *ptr64++ = 0;
178 *ptr64++ = 0; *ptr64 = 0;
179
180 /* Setup IOCB common data. */
181 pkt->entry_count = (uint8_t)sp->req_cnt;
182 pkt->sys_define = (uint8_t)ha->req_ring_index;
183 /* mark the iocb with the response identifier */
184 ddi_put32(ha->hba_buf.acc_handle, &pkt->handle,
185 (uint32_t)sp->handle);
186
187 /* Setup IOCB unique data. */
188 (sp->iocb)(vha, sp, pkt);
189
190 sp->flags |= SRB_ISP_STARTED;
191
192 QL_PRINT_5(CE_CONT, "(%d,%d): req packet, sp=%p\n",
193 ha->instance, vha->vp_index, (void *)sp);
194 QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE);
195
196 /* Sync DMA buffer. */
197 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
198 (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE +
199 REQUEST_Q_BUFFER_OFFSET), (size_t)REQUEST_ENTRY_SIZE,
200 DDI_DMA_SYNC_FORDEV);
201
202 /* Adjust ring index. */
203 ha->req_ring_index++;
204 if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
205 ha->req_ring_index = 0;
206 ha->request_ring_ptr = ha->request_ring_bp;
207 } else {
208 ha->request_ring_ptr++;
209 }
210
211 /* Reset watchdog timer */
212 sp->wdg_q_time = sp->init_wdg_q_time;
213
214 /*
215 * Send it by setting the new ring index in the ISP Request
216 * Ring In Pointer register. This is the mechanism
217 * used to notify the isp that a new iocb has been
218 * placed on the request ring.
219 */
220 if (CFG_IST(ha, CFG_CTRL_8021)) {
221 uint32_t w32;
222
223 w32 = ha->req_ring_index << 16 |
224 ha->function_number << 5 | 4;
225 do {
226 ddi_put32(ha->db_dev_handle, ha->nx_req_in,
227 w32);
228 } while (RD_REG_DWORD(ha, ha->db_read) != w32);
229
230 } else {
231 WRT16_IO_REG(ha, req_in, ha->req_ring_index);
232 }
233
234 /* Update outstanding command count statistic. */
235 ha->adapter_stats->ncmds++;
236
237 /* if there is a pending command, try to start it. */
238 if ((link = ha->pending_cmds.first) == NULL) {
239 break;
240 }
241
242 /* Remove command from pending command queue */
243 sp = link->base_address;
244 ql_remove_link(&ha->pending_cmds, &sp->cmd);
245 }
246
247 /* Release ring specific lock */
248 REQUEST_RING_UNLOCK(ha);
249
250 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
251 }
252
253 /*
254 * ql_req_pkt
255 * Function is responsible for locking ring and
256 * getting a zeroed out request packet.
257 *
258 * Input:
259 * ha: adapter state pointer.
260 * pkt: address for packet pointer.
261 *
262 * Returns:
263 * ql local function return status code.
264 *
265 * Context:
266 * Interrupt or Kernel context, no mailbox commands allowed.
267 */
268 static int
ql_req_pkt(ql_adapter_state_t * vha,request_t ** pktp)269 ql_req_pkt(ql_adapter_state_t *vha, request_t **pktp)
270 {
271 uint16_t cnt;
272 uint32_t *long_ptr;
273 uint32_t timer;
274 int rval = QL_FUNCTION_TIMEOUT;
275 ql_adapter_state_t *ha = vha->pha;
276
277 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
278
279 /* Wait for 30 seconds for slot. */
280 for (timer = 30000; timer != 0; timer--) {
281 /* Acquire ring lock. */
282 REQUEST_RING_LOCK(ha);
283
284 if (ha->req_q_cnt == 0) {
285 /* Calculate number of free request entries. */
286 cnt = RD16_IO_REG(ha, req_out);
287 if (ha->req_ring_index < cnt) {
288 ha->req_q_cnt = (uint16_t)
289 (cnt - ha->req_ring_index);
290 } else {
291 ha->req_q_cnt = (uint16_t)
292 (REQUEST_ENTRY_CNT -
293 (ha->req_ring_index - cnt));
294 }
295 if (ha->req_q_cnt != 0) {
296 ha->req_q_cnt--;
297 }
298 }
299
300 /* Found empty request ring slot? */
301 if (ha->req_q_cnt != 0) {
302 ha->req_q_cnt--;
303 *pktp = ha->request_ring_ptr;
304
305 /* Zero out packet. */
306 long_ptr = (uint32_t *)ha->request_ring_ptr;
307 for (cnt = 0; cnt < REQUEST_ENTRY_SIZE/4; cnt++) {
308 *long_ptr++ = 0;
309 }
310
311 /* Setup IOCB common data. */
312 ha->request_ring_ptr->entry_count = 1;
313 ha->request_ring_ptr->sys_define =
314 (uint8_t)ha->req_ring_index;
315 ddi_put32(ha->hba_buf.acc_handle,
316 &ha->request_ring_ptr->handle,
317 (uint32_t)QL_FCA_BRAND);
318
319 rval = QL_SUCCESS;
320
321 break;
322 }
323
324 /* Release request queue lock. */
325 REQUEST_RING_UNLOCK(ha);
326
327 drv_usecwait(MILLISEC);
328
329 /* Check for pending interrupts. */
330 /*
331 * XXX protect interrupt routine from calling itself.
332 * Need to revisit this routine. So far we never
333 * hit this case as req slot was available
334 */
335 if ((!(curthread->t_flag & T_INTR_THREAD)) &&
336 INTERRUPT_PENDING(ha)) {
337 (void) ql_isr((caddr_t)ha);
338 INTR_LOCK(ha);
339 ha->intr_claimed = TRUE;
340 INTR_UNLOCK(ha);
341 }
342 }
343
344 if (rval != QL_SUCCESS) {
345 ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 0);
346 EL(ha, "failed, rval = %xh, isp_abort_needed\n", rval);
347 } else {
348 /*EMPTY*/
349 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
350 }
351 return (rval);
352 }
353
354 /*
355 * ql_isp_cmd
356 * Function is responsible for modifying ISP input pointer.
357 * This action notifies the isp that a new request has been
358 * added to the request ring.
359 *
360 * Releases ring lock.
361 *
362 * Input:
363 * ha: adapter state pointer.
364 *
365 * Context:
366 * Interrupt or Kernel context, no mailbox commands allowed.
367 */
368 void
ql_isp_cmd(ql_adapter_state_t * vha)369 ql_isp_cmd(ql_adapter_state_t *vha)
370 {
371 ql_adapter_state_t *ha = vha->pha;
372
373 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
374
375 QL_PRINT_5(CE_CONT, "(%d): req packet:\n", ha->instance);
376 QL_DUMP_5((uint8_t *)ha->request_ring_ptr, 8, REQUEST_ENTRY_SIZE);
377
378 /* Sync DMA buffer. */
379 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
380 (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE +
381 REQUEST_Q_BUFFER_OFFSET), (size_t)REQUEST_ENTRY_SIZE,
382 DDI_DMA_SYNC_FORDEV);
383
384 /* Adjust ring index. */
385 ha->req_ring_index++;
386 if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
387 ha->req_ring_index = 0;
388 ha->request_ring_ptr = ha->request_ring_bp;
389 } else {
390 ha->request_ring_ptr++;
391 }
392
393 /* Set chip new ring index. */
394 if (CFG_IST(ha, CFG_CTRL_8021)) {
395 uint32_t w32;
396
397 w32 = ha->req_ring_index << 16 |
398 ha->function_number << 5 | 4;
399 do {
400 ddi_put32(ha->db_dev_handle, ha->nx_req_in, w32);
401 } while (RD_REG_DWORD(ha, ha->db_read) != w32);
402
403 } else {
404 WRT16_IO_REG(ha, req_in, ha->req_ring_index);
405 }
406
407 /* Release ring lock. */
408 REQUEST_RING_UNLOCK(ha);
409
410 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
411 }
412
413 /*
414 * ql_command_iocb
415 * Setup of command IOCB.
416 *
417 * Input:
418 * ha: adapter state pointer.
419 * sp: srb structure pointer.
420 *
421 * arg: request queue packet.
422 *
423 * Context:
424 * Interrupt or Kernel context, no mailbox commands allowed.
425 */
426 void
ql_command_iocb(ql_adapter_state_t * ha,ql_srb_t * sp,void * arg)427 ql_command_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
428 {
429 ddi_dma_cookie_t *cp;
430 uint32_t *ptr32, cnt;
431 uint16_t seg_cnt;
432 fcp_cmd_t *fcp = sp->fcp;
433 ql_tgt_t *tq = sp->lun_queue->target_queue;
434 cmd_entry_t *pkt = arg;
435
436 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
437
438 /* Set LUN number */
439 pkt->lun_l = LSB(sp->lun_queue->lun_no);
440 pkt->lun_h = MSB(sp->lun_queue->lun_no);
441
442 /* Set target ID */
443 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
444 pkt->target_l = LSB(tq->loop_id);
445 pkt->target_h = MSB(tq->loop_id);
446 } else {
447 pkt->target_h = LSB(tq->loop_id);
448 }
449
450 /* Set tag queue control flags */
451 if (fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_HEAD_OF_Q) {
452 pkt->control_flags_l = (uint8_t)
453 (pkt->control_flags_l | CF_HTAG);
454 } else if (fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_ORDERED) {
455 pkt->control_flags_l = (uint8_t)
456 (pkt->control_flags_l | CF_OTAG);
457 /* else if (fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_SIMPLE) */
458 } else {
459 pkt->control_flags_l = (uint8_t)
460 (pkt->control_flags_l | CF_STAG);
461 }
462
463 /* Set ISP command timeout. */
464 ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout);
465
466 /* Load SCSI CDB */
467 ddi_rep_put8(ha->hba_buf.acc_handle, fcp->fcp_cdb,
468 pkt->scsi_cdb, MAX_CMDSZ, DDI_DEV_AUTOINCR);
469
470 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
471 pkt->entry_type = IOCB_CMD_TYPE_3;
472 cnt = CMD_TYPE_3_DATA_SEGMENTS;
473 } else {
474 pkt->entry_type = IOCB_CMD_TYPE_2;
475 cnt = CMD_TYPE_2_DATA_SEGMENTS;
476 }
477
478 if (fcp->fcp_data_len == 0) {
479 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
480 ha->xioctl->IOControlRequests++;
481 return;
482 }
483
484 /*
485 * Set transfer direction. Load Data segments.
486 */
487 if (fcp->fcp_cntl.cntl_write_data) {
488 pkt->control_flags_l = (uint8_t)
489 (pkt->control_flags_l | CF_DATA_OUT);
490 ha->xioctl->IOOutputRequests++;
491 ha->xioctl->IOOutputByteCnt += fcp->fcp_data_len;
492 } else if (fcp->fcp_cntl.cntl_read_data) {
493 pkt->control_flags_l = (uint8_t)
494 (pkt->control_flags_l | CF_DATA_IN);
495 ha->xioctl->IOInputRequests++;
496 ha->xioctl->IOInputByteCnt += fcp->fcp_data_len;
497 }
498
499 /* Set data segment count. */
500 seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt;
501 ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt);
502
503 /* Load total byte count. */
504 ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count, fcp->fcp_data_len);
505
506 /* Load command data segment. */
507 ptr32 = (uint32_t *)&pkt->dseg_0_address;
508 cp = sp->pkt->pkt_data_cookie;
509 while (cnt && seg_cnt) {
510 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
511 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
512 ddi_put32(ha->hba_buf.acc_handle, ptr32++,
513 cp->dmac_notused);
514 }
515 ddi_put32(ha->hba_buf.acc_handle, ptr32++,
516 (uint32_t)cp->dmac_size);
517 seg_cnt--;
518 cnt--;
519 cp++;
520 }
521
522 /*
523 * Build continuation packets.
524 */
525 if (seg_cnt) {
526 ql_continuation_iocb(ha, cp, seg_cnt,
527 (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)));
528 }
529
530 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
531 }
532
533 /*
534 * ql_continuation_iocb
535 * Setup of continuation IOCB.
536 *
537 * Input:
538 * ha: adapter state pointer.
539 * cp: cookie list pointer.
540 * seg_cnt: number of segments.
541 * addr64: 64 bit addresses.
542 *
543 * Context:
544 * Interrupt or Kernel context, no mailbox commands allowed.
545 */
546 static void
ql_continuation_iocb(ql_adapter_state_t * ha,ddi_dma_cookie_t * cp,uint16_t seg_cnt,boolean_t addr64)547 ql_continuation_iocb(ql_adapter_state_t *ha, ddi_dma_cookie_t *cp,
548 uint16_t seg_cnt, boolean_t addr64)
549 {
550 cont_entry_t *pkt;
551 uint64_t *ptr64;
552 uint32_t *ptr32, cnt;
553
554 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
555
556 /*
557 * Build continuation packets.
558 */
559 while (seg_cnt) {
560 /* Sync DMA buffer. */
561 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
562 (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE +
563 REQUEST_Q_BUFFER_OFFSET), REQUEST_ENTRY_SIZE,
564 DDI_DMA_SYNC_FORDEV);
565
566 /* Adjust ring pointer, and deal with wrap. */
567 ha->req_ring_index++;
568 if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
569 ha->req_ring_index = 0;
570 ha->request_ring_ptr = ha->request_ring_bp;
571 } else {
572 ha->request_ring_ptr++;
573 }
574 pkt = (cont_entry_t *)ha->request_ring_ptr;
575
576 /* Zero out packet. */
577 ptr64 = (uint64_t *)pkt;
578 *ptr64++ = 0; *ptr64++ = 0;
579 *ptr64++ = 0; *ptr64++ = 0;
580 *ptr64++ = 0; *ptr64++ = 0;
581 *ptr64++ = 0; *ptr64 = 0;
582
583 /*
584 * Build continuation packet.
585 */
586 pkt->entry_count = 1;
587 pkt->sys_define = (uint8_t)ha->req_ring_index;
588 if (addr64) {
589 pkt->entry_type = CONTINUATION_TYPE_1;
590 cnt = CONT_TYPE_1_DATA_SEGMENTS;
591 ptr32 = (uint32_t *)
592 &((cont_type_1_entry_t *)pkt)->dseg_0_address;
593 while (cnt && seg_cnt) {
594 ddi_put32(ha->hba_buf.acc_handle, ptr32++,
595 cp->dmac_address);
596 ddi_put32(ha->hba_buf.acc_handle, ptr32++,
597 cp->dmac_notused);
598 ddi_put32(ha->hba_buf.acc_handle, ptr32++,
599 (uint32_t)cp->dmac_size);
600 seg_cnt--;
601 cnt--;
602 cp++;
603 }
604 } else {
605 pkt->entry_type = CONTINUATION_TYPE_0;
606 cnt = CONT_TYPE_0_DATA_SEGMENTS;
607 ptr32 = (uint32_t *)&pkt->dseg_0_address;
608 while (cnt && seg_cnt) {
609 ddi_put32(ha->hba_buf.acc_handle, ptr32++,
610 cp->dmac_address);
611 ddi_put32(ha->hba_buf.acc_handle, ptr32++,
612 (uint32_t)cp->dmac_size);
613 seg_cnt--;
614 cnt--;
615 cp++;
616 }
617 }
618
619 QL_PRINT_5(CE_CONT, "(%d): packet:\n", ha->instance);
620 QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE);
621 }
622
623 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
624 }
625
626 /*
627 * ql_command_24xx_iocb
628 * Setup of ISP24xx command IOCB.
629 *
630 * Input:
631 * ha: adapter state pointer.
632 * sp: srb structure pointer.
633 * arg: request queue packet.
634 *
635 * Context:
636 * Interrupt or Kernel context, no mailbox commands allowed.
637 */
638 void
ql_command_24xx_iocb(ql_adapter_state_t * ha,ql_srb_t * sp,void * arg)639 ql_command_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
640 {
641 ddi_dma_cookie_t *cp;
642 uint32_t *ptr32, cnt;
643 uint16_t seg_cnt;
644 fcp_cmd_t *fcp = sp->fcp;
645 ql_tgt_t *tq = sp->lun_queue->target_queue;
646 cmd7_24xx_entry_t *pkt = arg;
647 ql_adapter_state_t *pha = ha->pha;
648
649 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
650
651 if (fcp->fcp_data_len != 0 && sp->sg_dma.dma_handle != NULL &&
652 sp->pkt->pkt_data_cookie_cnt > 1) {
653 ql_cmd_24xx_type_6_iocb(ha, sp, arg);
654 QL_PRINT_3(CE_CONT, "(%d): cmd6 exit\n", ha->instance);
655 return;
656 }
657
658 pkt->entry_type = IOCB_CMD_TYPE_7;
659
660 /* Set LUN number */
661 pkt->fcp_lun[2] = LSB(sp->lun_queue->lun_no);
662 pkt->fcp_lun[3] = MSB(sp->lun_queue->lun_no);
663
664 /* Set N_port handle */
665 ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id);
666
667 /* Set target ID */
668 pkt->target_id[0] = tq->d_id.b.al_pa;
669 pkt->target_id[1] = tq->d_id.b.area;
670 pkt->target_id[2] = tq->d_id.b.domain;
671
672 pkt->vp_index = ha->vp_index;
673
674 /* Set ISP command timeout. */
675 if (sp->isp_timeout < 0x1999) {
676 ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout,
677 sp->isp_timeout);
678 }
679
680 /* Load SCSI CDB */
681 ddi_rep_put8(pha->hba_buf.acc_handle, fcp->fcp_cdb, pkt->scsi_cdb,
682 MAX_CMDSZ, DDI_DEV_AUTOINCR);
683 for (cnt = 0; cnt < MAX_CMDSZ; cnt += 4) {
684 ql_chg_endian((uint8_t *)&pkt->scsi_cdb + cnt, 4);
685 }
686
687 /*
688 * Set tag queue control flags
689 * Note:
690 * Cannot copy fcp->fcp_cntl.cntl_qtype directly,
691 * problem with x86 in 32bit kernel mode
692 */
693 switch (fcp->fcp_cntl.cntl_qtype) {
694 case FCP_QTYPE_SIMPLE:
695 pkt->task = TA_STAG;
696 break;
697 case FCP_QTYPE_HEAD_OF_Q:
698 pkt->task = TA_HTAG;
699 break;
700 case FCP_QTYPE_ORDERED:
701 pkt->task = TA_OTAG;
702 break;
703 case FCP_QTYPE_ACA_Q_TAG:
704 pkt->task = TA_ACA;
705 break;
706 case FCP_QTYPE_UNTAGGED:
707 pkt->task = TA_UNTAGGED;
708 break;
709 default:
710 break;
711 }
712
713 if (fcp->fcp_data_len == 0) {
714 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
715 pha->xioctl->IOControlRequests++;
716 return;
717 }
718
719 /* Set transfer direction. */
720 if (fcp->fcp_cntl.cntl_write_data) {
721 pkt->control_flags = CF_WR;
722 pha->xioctl->IOOutputRequests++;
723 pha->xioctl->IOOutputByteCnt += fcp->fcp_data_len;
724 } else if (fcp->fcp_cntl.cntl_read_data) {
725 pkt->control_flags = CF_RD;
726 pha->xioctl->IOInputRequests++;
727 pha->xioctl->IOInputByteCnt += fcp->fcp_data_len;
728 }
729
730 /* Set data segment count. */
731 seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt;
732 ddi_put16(pha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt);
733
734 /* Load total byte count. */
735 ddi_put32(pha->hba_buf.acc_handle, &pkt->total_byte_count,
736 fcp->fcp_data_len);
737
738 /* Load command data segment. */
739 ptr32 = (uint32_t *)&pkt->dseg_0_address;
740 cp = sp->pkt->pkt_data_cookie;
741 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
742 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
743 ddi_put32(pha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size);
744 seg_cnt--;
745 cp++;
746
747 /*
748 * Build continuation packets.
749 */
750 if (seg_cnt) {
751 ql_continuation_iocb(pha, cp, seg_cnt, B_TRUE);
752 }
753
754 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
755 }
756
757 /*
758 * ql_cmd_24xx_type_6_iocb
759 * Setup of ISP24xx command type 6 IOCB.
760 *
761 * Input:
762 * ha: adapter state pointer.
763 * sp: srb structure pointer.
764 * arg: request queue packet.
765 *
766 * Context:
767 * Interrupt or Kernel context, no mailbox commands allowed.
768 */
769 static void
ql_cmd_24xx_type_6_iocb(ql_adapter_state_t * ha,ql_srb_t * sp,void * arg)770 ql_cmd_24xx_type_6_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
771 {
772 uint64_t addr;
773 ddi_dma_cookie_t *cp;
774 uint32_t *ptr32;
775 uint16_t seg_cnt;
776 fcp_cmd_t *fcp = sp->fcp;
777 ql_tgt_t *tq = sp->lun_queue->target_queue;
778 cmd6_24xx_entry_t *pkt = arg;
779 ql_adapter_state_t *pha = ha->pha;
780 dma_mem_t *cmem = &sp->sg_dma;
781 cmd6_2400_dma_t *cdma = cmem->bp;
782
783 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
784
785 pkt->entry_type = IOCB_CMD_TYPE_6;
786
787 bzero(cdma, sizeof (cmd6_2400_dma_t));
788
789 /* Set LUN number */
790 pkt->fcp_lun[2] = cdma->cmd.fcp_lun[1] = LSB(sp->lun_queue->lun_no);
791 pkt->fcp_lun[3] = cdma->cmd.fcp_lun[0] = MSB(sp->lun_queue->lun_no);
792
793 /* Set N_port handle */
794 ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id);
795
796 /* Set target ID */
797 pkt->target_id[0] = tq->d_id.b.al_pa;
798 pkt->target_id[1] = tq->d_id.b.area;
799 pkt->target_id[2] = tq->d_id.b.domain;
800
801 pkt->vp_index = ha->vp_index;
802
803 /* Set ISP command timeout. */
804 if (sp->isp_timeout < 0x1999) {
805 ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout,
806 sp->isp_timeout);
807 }
808
809 /* Load SCSI CDB */
810 ddi_rep_put8(cmem->acc_handle, fcp->fcp_cdb, cdma->cmd.scsi_cdb,
811 MAX_CMDSZ, DDI_DEV_AUTOINCR);
812
813 /*
814 * Set tag queue control flags
815 * Note:
816 * Cannot copy fcp->fcp_cntl.cntl_qtype directly,
817 * problem with x86 in 32bit kernel mode
818 */
819 switch (fcp->fcp_cntl.cntl_qtype) {
820 case FCP_QTYPE_SIMPLE:
821 cdma->cmd.task = TA_STAG;
822 break;
823 case FCP_QTYPE_HEAD_OF_Q:
824 cdma->cmd.task = TA_HTAG;
825 break;
826 case FCP_QTYPE_ORDERED:
827 cdma->cmd.task = TA_OTAG;
828 break;
829 case FCP_QTYPE_ACA_Q_TAG:
830 cdma->cmd.task = TA_ACA;
831 break;
832 case FCP_QTYPE_UNTAGGED:
833 cdma->cmd.task = TA_UNTAGGED;
834 break;
835 default:
836 break;
837 }
838
839 /*
840 * FCP_CMND Payload Data Segment
841 */
842 cp = cmem->cookies;
843 ddi_put16(pha->hba_buf.acc_handle, &pkt->cmnd_length,
844 sizeof (fcp_cmnd_t));
845 ddi_put32(pha->hba_buf.acc_handle, &pkt->cmnd_address[0],
846 cp->dmac_address);
847 ddi_put32(pha->hba_buf.acc_handle, &pkt->cmnd_address[1],
848 cp->dmac_notused);
849
850 /* Set transfer direction. */
851 if (fcp->fcp_cntl.cntl_write_data) {
852 pkt->control_flags = (uint8_t)(CF_DSD_PTR | CF_WR);
853 cdma->cmd.control_flags = CF_WR;
854 pha->xioctl->IOOutputRequests++;
855 pha->xioctl->IOOutputByteCnt += fcp->fcp_data_len;
856 } else if (fcp->fcp_cntl.cntl_read_data) {
857 pkt->control_flags = (uint8_t)(CF_DSD_PTR | CF_RD);
858 cdma->cmd.control_flags = CF_RD;
859 pha->xioctl->IOInputRequests++;
860 pha->xioctl->IOInputByteCnt += fcp->fcp_data_len;
861 }
862
863 /*
864 * FCP_DATA Data Segment Descriptor.
865 */
866 addr = cp->dmac_laddress + sizeof (fcp_cmnd_t);
867 ddi_put32(pha->hba_buf.acc_handle, &pkt->dseg_0_address[0], LSD(addr));
868 ddi_put32(pha->hba_buf.acc_handle, &pkt->dseg_0_address[1], MSD(addr));
869
870 /* Set data segment count. */
871 seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt;
872 ddi_put16(pha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt);
873 ddi_put32(pha->hba_buf.acc_handle, &pkt->dseg_0_length,
874 seg_cnt * 12 + 12);
875
876 /* Load total byte count. */
877 ddi_put32(pha->hba_buf.acc_handle, &pkt->total_byte_count,
878 fcp->fcp_data_len);
879 ddi_put32(cmem->acc_handle, &cdma->cmd.dl, (uint32_t)fcp->fcp_data_len);
880 ql_chg_endian((uint8_t *)&cdma->cmd.dl, 4);
881
882 /* Load command data segments. */
883 ptr32 = (uint32_t *)cdma->cookie_list;
884 cp = sp->pkt->pkt_data_cookie;
885 while (seg_cnt--) {
886 ddi_put32(cmem->acc_handle, ptr32++, cp->dmac_address);
887 ddi_put32(cmem->acc_handle, ptr32++, cp->dmac_notused);
888 ddi_put32(cmem->acc_handle, ptr32++, (uint32_t)cp->dmac_size);
889 cp++;
890 }
891
892 /* Sync DMA buffer. */
893 (void) ddi_dma_sync(cmem->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV);
894
895 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
896 }
897
898 /*
899 * ql_marker
900 * Function issues marker IOCB.
901 *
902 * Input:
903 * ha: adapter state pointer.
904 * loop_id: device loop ID
905 * lun: device LUN
906 * type: marker modifier
907 *
908 * Returns:
909 * ql local function return status code.
910 *
911 * Context:
912 * Interrupt or Kernel context, no mailbox commands allowed.
913 */
914 int
ql_marker(ql_adapter_state_t * ha,uint16_t loop_id,uint16_t lun,uint8_t type)915 ql_marker(ql_adapter_state_t *ha, uint16_t loop_id, uint16_t lun,
916 uint8_t type)
917 {
918 mrk_entry_t *pkt;
919 int rval;
920
921 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
922
923 rval = ql_req_pkt(ha, (request_t **)&pkt);
924 if (rval == QL_SUCCESS) {
925 pkt->entry_type = MARKER_TYPE;
926
927 if (CFG_IST(ha, CFG_CTRL_24258081)) {
928 marker_24xx_entry_t *pkt24 =
929 (marker_24xx_entry_t *)pkt;
930
931 pkt24->modifier = type;
932
933 /* Set LUN number */
934 pkt24->fcp_lun[2] = LSB(lun);
935 pkt24->fcp_lun[3] = MSB(lun);
936
937 pkt24->vp_index = ha->vp_index;
938
939 /* Set N_port handle */
940 ddi_put16(ha->pha->hba_buf.acc_handle,
941 &pkt24->n_port_hdl, loop_id);
942
943 } else {
944 pkt->modifier = type;
945
946 pkt->lun_l = LSB(lun);
947 pkt->lun_h = MSB(lun);
948
949 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
950 pkt->target_l = LSB(loop_id);
951 pkt->target_h = MSB(loop_id);
952 } else {
953 pkt->target_h = LSB(loop_id);
954 }
955 }
956
957 /* Issue command to ISP */
958 ql_isp_cmd(ha);
959 }
960
961 if (rval != QL_SUCCESS) {
962 EL(ha, "failed, rval = %xh\n", rval);
963 } else {
964 /*EMPTY*/
965 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
966 }
967 return (rval);
968 }
969
970 /*
971 * ql_ms_iocb
972 * Setup of name/management server IOCB.
973 *
974 * Input:
975 * ha = adapter state pointer.
976 * sp = srb structure pointer.
977 * arg = request queue packet.
978 *
979 * Context:
980 * Interrupt or Kernel context, no mailbox commands allowed.
981 */
982 void
ql_ms_iocb(ql_adapter_state_t * ha,ql_srb_t * sp,void * arg)983 ql_ms_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
984 {
985 ddi_dma_cookie_t *cp;
986 uint32_t *ptr32;
987 uint16_t seg_cnt;
988 ql_tgt_t *tq = sp->lun_queue->target_queue;
989 ms_entry_t *pkt = arg;
990
991 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
992 QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen);
993 /*
994 * Build command packet.
995 */
996 pkt->entry_type = MS_TYPE;
997
998 /* Set loop ID */
999 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1000 pkt->loop_id_l = LSB(tq->loop_id);
1001 pkt->loop_id_h = MSB(tq->loop_id);
1002 } else {
1003 pkt->loop_id_h = LSB(tq->loop_id);
1004 }
1005
1006 /* Set ISP command timeout. */
1007 ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout);
1008
1009 /* Set cmd data segment count. */
1010 pkt->cmd_dseg_count_l = 1;
1011
1012 /* Set total data segment count */
1013 seg_cnt = (uint16_t)(sp->pkt->pkt_resp_cookie_cnt + 1);
1014 ddi_put16(ha->hba_buf.acc_handle, &pkt->total_dseg_count, seg_cnt);
1015
1016 /* Load ct cmd byte count. */
1017 ddi_put32(ha->hba_buf.acc_handle, &pkt->cmd_byte_count,
1018 (uint32_t)sp->pkt->pkt_cmdlen);
1019
1020 /* Load ct rsp byte count. */
1021 ddi_put32(ha->hba_buf.acc_handle, &pkt->resp_byte_count,
1022 (uint32_t)sp->pkt->pkt_rsplen);
1023
1024 /* Load MS command data segments. */
1025 ptr32 = (uint32_t *)&pkt->dseg_0_address;
1026 cp = sp->pkt->pkt_cmd_cookie;
1027 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
1028 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
1029 ddi_put32(ha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size);
1030 seg_cnt--;
1031
1032 /* Load MS response entry data segments. */
1033 cp = sp->pkt->pkt_resp_cookie;
1034 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
1035 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
1036 ddi_put32(ha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size);
1037 seg_cnt--;
1038 cp++;
1039
1040 /*
1041 * Build continuation packets.
1042 */
1043 if (seg_cnt) {
1044 ql_continuation_iocb(ha, cp, seg_cnt, B_TRUE);
1045 }
1046
1047 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1048 }
1049
1050 /*
1051 * ql_ms_24xx_iocb
1052 * Setup of name/management server IOCB.
1053 *
1054 * Input:
1055 * ha: adapter state pointer.
1056 * sp: srb structure pointer.
1057 * arg: request queue packet.
1058 *
1059 * Context:
1060 * Interrupt or Kernel context, no mailbox commands allowed.
1061 */
1062 void
ql_ms_24xx_iocb(ql_adapter_state_t * ha,ql_srb_t * sp,void * arg)1063 ql_ms_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
1064 {
1065 ddi_dma_cookie_t *cp;
1066 uint32_t *ptr32;
1067 uint16_t seg_cnt;
1068 ql_tgt_t *tq = sp->lun_queue->target_queue;
1069 ct_passthru_entry_t *pkt = arg;
1070 ql_adapter_state_t *pha = ha->pha;
1071
1072 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1073 QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen);
1074 /*
1075 * Build command packet.
1076 */
1077 pkt->entry_type = CT_PASSTHRU_TYPE;
1078
1079 /* Set loop ID */
1080 ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id);
1081
1082 pkt->vp_index = ha->vp_index;
1083
1084 /* Set ISP command timeout. */
1085 if (sp->isp_timeout < 0x1999) {
1086 ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout,
1087 sp->isp_timeout);
1088 }
1089
1090 /* Set cmd/response data segment counts. */
1091 ddi_put16(pha->hba_buf.acc_handle, &pkt->cmd_dseg_count, 1);
1092 seg_cnt = (uint16_t)sp->pkt->pkt_resp_cookie_cnt;
1093 ddi_put16(pha->hba_buf.acc_handle, &pkt->resp_dseg_count, seg_cnt);
1094
1095 /* Load ct cmd byte count. */
1096 ddi_put32(pha->hba_buf.acc_handle, &pkt->cmd_byte_count,
1097 (uint32_t)sp->pkt->pkt_cmdlen);
1098
1099 /* Load ct rsp byte count. */
1100 ddi_put32(pha->hba_buf.acc_handle, &pkt->resp_byte_count,
1101 (uint32_t)sp->pkt->pkt_rsplen);
1102
1103 /* Load MS command entry data segments. */
1104 ptr32 = (uint32_t *)&pkt->dseg_0_address;
1105 cp = sp->pkt->pkt_cmd_cookie;
1106 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
1107 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
1108 ddi_put32(pha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size);
1109
1110 /* Load MS response entry data segments. */
1111 cp = sp->pkt->pkt_resp_cookie;
1112 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
1113 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
1114 ddi_put32(pha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size);
1115 seg_cnt--;
1116 cp++;
1117
1118 /*
1119 * Build continuation packets.
1120 */
1121 if (seg_cnt) {
1122 ql_continuation_iocb(pha, cp, seg_cnt, B_TRUE);
1123 }
1124
1125 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1126 }
1127
1128 /*
1129 * ql_ip_iocb
1130 * Setup of IP IOCB.
1131 *
1132 * Input:
1133 * ha: adapter state pointer.
1134 * sp: srb structure pointer.
1135 * arg: request queue packet.
1136 *
1137 * Context:
1138 * Interrupt or Kernel context, no mailbox commands allowed.
1139 */
1140 void
ql_ip_iocb(ql_adapter_state_t * ha,ql_srb_t * sp,void * arg)1141 ql_ip_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
1142 {
1143 ddi_dma_cookie_t *cp;
1144 uint32_t *ptr32, cnt;
1145 uint16_t seg_cnt;
1146 ql_tgt_t *tq = sp->lun_queue->target_queue;
1147 ip_entry_t *pkt = arg;
1148
1149 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1150
1151 /* Set loop ID */
1152 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1153 pkt->loop_id_l = LSB(tq->loop_id);
1154 pkt->loop_id_h = MSB(tq->loop_id);
1155 } else {
1156 pkt->loop_id_h = LSB(tq->loop_id);
1157 }
1158
1159 /* Set control flags */
1160 pkt->control_flags_l = BIT_6;
1161 if (sp->pkt->pkt_tran_flags & FC_TRAN_HI_PRIORITY) {
1162 pkt->control_flags_h = BIT_7;
1163 }
1164
1165 /* Set ISP command timeout. */
1166 ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout);
1167
1168 /* Set data segment count. */
1169 seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt;
1170 /* Load total byte count. */
1171 ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count,
1172 (uint32_t)sp->pkt->pkt_cmdlen);
1173 ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt);
1174
1175 /*
1176 * Build command packet.
1177 */
1178 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
1179 pkt->entry_type = IP_A64_TYPE;
1180 cnt = IP_A64_DATA_SEGMENTS;
1181 } else {
1182 pkt->entry_type = IP_TYPE;
1183 cnt = IP_DATA_SEGMENTS;
1184 }
1185
1186 /* Load command entry data segments. */
1187 ptr32 = (uint32_t *)&pkt->dseg_0_address;
1188 cp = sp->pkt->pkt_cmd_cookie;
1189 while (cnt && seg_cnt) {
1190 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
1191 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
1192 ddi_put32(ha->hba_buf.acc_handle, ptr32++,
1193 cp->dmac_notused);
1194 }
1195 ddi_put32(ha->hba_buf.acc_handle, ptr32++,
1196 (uint32_t)cp->dmac_size);
1197 seg_cnt--;
1198 cnt--;
1199 cp++;
1200 }
1201
1202 /*
1203 * Build continuation packets.
1204 */
1205 if (seg_cnt) {
1206 ql_continuation_iocb(ha, cp, seg_cnt,
1207 (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)));
1208 }
1209
1210 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1211 }
1212
1213 /*
1214 * ql_ip_24xx_iocb
1215 * Setup of IP IOCB for ISP24xx.
1216 *
1217 * Input:
1218 * ha: adapter state pointer.
1219 * sp: srb structure pointer.
1220 * arg: request queue packet.
1221 *
1222 * Context:
1223 * Interrupt or Kernel context, no mailbox commands allowed.
1224 */
1225 void
ql_ip_24xx_iocb(ql_adapter_state_t * ha,ql_srb_t * sp,void * arg)1226 ql_ip_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
1227 {
1228 ddi_dma_cookie_t *cp;
1229 uint32_t *ptr32;
1230 uint16_t seg_cnt;
1231 ql_tgt_t *tq = sp->lun_queue->target_queue;
1232 ip_cmd_entry_t *pkt = arg;
1233
1234 pkt->entry_type = IP_CMD_TYPE;
1235
1236 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1237
1238 /* Set N_port handle */
1239 ddi_put16(ha->hba_buf.acc_handle, &pkt->hdl_status, tq->loop_id);
1240
1241 /* Set ISP command timeout. */
1242 if (sp->isp_timeout < 0x1999) {
1243 ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout_hdl,
1244 sp->isp_timeout);
1245 }
1246
1247 /* Set data segment count. */
1248 seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt;
1249 /* Load total byte count. */
1250 ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count,
1251 (uint32_t)sp->pkt->pkt_cmdlen);
1252 ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt);
1253
1254 /* Set control flags */
1255 ddi_put16(ha->hba_buf.acc_handle, &pkt->control_flags,
1256 (uint16_t)(BIT_0));
1257
1258 /* Set frame header control flags */
1259 ddi_put16(ha->hba_buf.acc_handle, &pkt->frame_hdr_cntrl_flgs,
1260 (uint16_t)(IPCF_LAST_SEQ | IPCF_FIRST_SEQ));
1261
1262 /* Load command data segment. */
1263 ptr32 = (uint32_t *)&pkt->dseg_0_address;
1264 cp = sp->pkt->pkt_cmd_cookie;
1265 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
1266 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
1267 ddi_put32(ha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size);
1268 seg_cnt--;
1269 cp++;
1270
1271 /*
1272 * Build continuation packets.
1273 */
1274 if (seg_cnt) {
1275 ql_continuation_iocb(ha, cp, seg_cnt, B_TRUE);
1276 }
1277
1278 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1279 }
1280
1281 /*
1282 * ql_isp_rcvbuf
1283 * Locates free buffers and places it on the receive buffer queue.
1284 *
1285 * Input:
1286 * ha = adapter state pointer.
1287 *
1288 * Context:
1289 * Interrupt or Kernel context, no mailbox commands allowed.
1290 */
1291 void
ql_isp_rcvbuf(ql_adapter_state_t * ha)1292 ql_isp_rcvbuf(ql_adapter_state_t *ha)
1293 {
1294 rcvbuf_t *container;
1295 uint16_t rcv_q_cnt;
1296 uint16_t index = 0;
1297 uint16_t index1 = 1;
1298 int debounce_count = QL_MAX_DEBOUNCE;
1299 ql_srb_t *sp;
1300 fc_unsol_buf_t *ubp;
1301 int ring_updated = FALSE;
1302
1303 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1304 ql_isp24xx_rcvbuf(ha);
1305 return;
1306 }
1307
1308 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1309
1310 /* Acquire adapter state lock. */
1311 ADAPTER_STATE_LOCK(ha);
1312
1313 /* Calculate number of free receive buffer entries. */
1314 index = RD16_IO_REG(ha, mailbox_out[8]);
1315 do {
1316 index1 = RD16_IO_REG(ha, mailbox_out[8]);
1317 if (index1 == index) {
1318 break;
1319 } else {
1320 index = index1;
1321 }
1322 } while (debounce_count --);
1323
1324 if (debounce_count < 0) {
1325 /* This should never happen */
1326 EL(ha, "max mb8 debounce retries exceeded\n");
1327 }
1328
1329 rcv_q_cnt = (uint16_t)(ha->rcvbuf_ring_index < index ?
1330 index - ha->rcvbuf_ring_index : RCVBUF_CONTAINER_CNT -
1331 (ha->rcvbuf_ring_index - index));
1332
1333 if (rcv_q_cnt == RCVBUF_CONTAINER_CNT) {
1334 rcv_q_cnt--;
1335 }
1336
1337 /* Load all free buffers in ISP receive buffer ring. */
1338 index = 0;
1339 while (rcv_q_cnt > (uint16_t)0 && index < QL_UB_LIMIT) {
1340 /* Locate a buffer to give. */
1341 QL_UB_LOCK(ha);
1342 while (index < QL_UB_LIMIT) {
1343 ubp = ha->ub_array[index];
1344 if (ubp != NULL) {
1345 sp = ubp->ub_fca_private;
1346 if ((sp->ub_type == FC_TYPE_IS8802_SNAP) &&
1347 (ha->flags & IP_INITIALIZED) &&
1348 (sp->flags & SRB_UB_IN_FCA) &&
1349 (!(sp->flags & (SRB_UB_IN_ISP |
1350 SRB_UB_FREE_REQUESTED | SRB_UB_CALLBACK |
1351 SRB_UB_ACQUIRED)))) {
1352 sp->flags |= SRB_UB_IN_ISP;
1353 break;
1354 }
1355 }
1356 index++;
1357 }
1358
1359 if (index < QL_UB_LIMIT) {
1360 rcv_q_cnt--;
1361 index++;
1362 container = ha->rcvbuf_ring_ptr;
1363
1364 /*
1365 * Build container.
1366 */
1367 ddi_put32(ha->hba_buf.acc_handle,
1368 (uint32_t *)(void *)&container->bufp[0],
1369 sp->ub_buffer.cookie.dmac_address);
1370
1371 ddi_put32(ha->hba_buf.acc_handle,
1372 (uint32_t *)(void *)&container->bufp[1],
1373 sp->ub_buffer.cookie.dmac_notused);
1374
1375 ddi_put16(ha->hba_buf.acc_handle, &container->handle,
1376 LSW(sp->handle));
1377
1378 ha->ub_outcnt++;
1379
1380 /* Adjust ring index. */
1381 ha->rcvbuf_ring_index++;
1382 if (ha->rcvbuf_ring_index == RCVBUF_CONTAINER_CNT) {
1383 ha->rcvbuf_ring_index = 0;
1384 ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp;
1385 } else {
1386 ha->rcvbuf_ring_ptr++;
1387 }
1388
1389 ring_updated = TRUE;
1390 }
1391 QL_UB_UNLOCK(ha);
1392 }
1393
1394 if (ring_updated) {
1395 /* Sync queue. */
1396 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
1397 (off_t)RCVBUF_Q_BUFFER_OFFSET, (size_t)RCVBUF_QUEUE_SIZE,
1398 DDI_DMA_SYNC_FORDEV);
1399
1400 /* Set chip new ring index. */
1401 WRT16_IO_REG(ha, mailbox_in[8], ha->rcvbuf_ring_index);
1402 }
1403
1404 /* Release adapter state lock. */
1405 ADAPTER_STATE_UNLOCK(ha);
1406
1407 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1408 }
1409
1410 /*
1411 * ql_isp24xx_rcvbuf
1412 * Locates free buffers and send it to adapter.
1413 *
1414 * Input:
1415 * ha = adapter state pointer.
1416 *
1417 * Context:
1418 * Interrupt or Kernel context, no mailbox commands allowed.
1419 */
1420 static void
ql_isp24xx_rcvbuf(ql_adapter_state_t * ha)1421 ql_isp24xx_rcvbuf(ql_adapter_state_t *ha)
1422 {
1423 rcvbuf_t *container;
1424 uint16_t index;
1425 ql_srb_t *sp;
1426 fc_unsol_buf_t *ubp;
1427 int rval;
1428 ip_buf_pool_entry_t *pkt = NULL;
1429
1430 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1431
1432 for (;;) {
1433 /* Locate a buffer to give. */
1434 QL_UB_LOCK(ha);
1435 for (index = 0; index < QL_UB_LIMIT; index++) {
1436 ubp = ha->ub_array[index];
1437 if (ubp != NULL) {
1438 sp = ubp->ub_fca_private;
1439 if ((sp->ub_type == FC_TYPE_IS8802_SNAP) &&
1440 (ha->flags & IP_INITIALIZED) &&
1441 (sp->flags & SRB_UB_IN_FCA) &&
1442 (!(sp->flags & (SRB_UB_IN_ISP |
1443 SRB_UB_FREE_REQUESTED | SRB_UB_CALLBACK |
1444 SRB_UB_ACQUIRED)))) {
1445 ha->ub_outcnt++;
1446 sp->flags |= SRB_UB_IN_ISP;
1447 break;
1448 }
1449 }
1450 }
1451 QL_UB_UNLOCK(ha);
1452 if (index == QL_UB_LIMIT) {
1453 break;
1454 }
1455
1456 /* Get IOCB packet for buffers. */
1457 if (pkt == NULL) {
1458 rval = ql_req_pkt(ha, (request_t **)&pkt);
1459 if (rval != QL_SUCCESS) {
1460 EL(ha, "failed, ql_req_pkt=%x\n", rval);
1461 QL_UB_LOCK(ha);
1462 ha->ub_outcnt--;
1463 sp->flags &= ~SRB_UB_IN_ISP;
1464 QL_UB_UNLOCK(ha);
1465 break;
1466 }
1467 pkt->entry_type = IP_BUF_POOL_TYPE;
1468 container = &pkt->buffers[0];
1469 }
1470
1471 /*
1472 * Build container.
1473 */
1474 ddi_put32(ha->hba_buf.acc_handle, &container->bufp[0],
1475 sp->ub_buffer.cookie.dmac_address);
1476 ddi_put32(ha->hba_buf.acc_handle, &container->bufp[1],
1477 sp->ub_buffer.cookie.dmac_notused);
1478 ddi_put16(ha->hba_buf.acc_handle, &container->handle,
1479 LSW(sp->handle));
1480
1481 pkt->buffer_count++;
1482 container++;
1483
1484 if (pkt->buffer_count == IP_POOL_BUFFERS) {
1485 ql_isp_cmd(ha);
1486 pkt = NULL;
1487 }
1488 }
1489
1490 if (pkt != NULL) {
1491 ql_isp_cmd(ha);
1492 }
1493
1494 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1495 }
1496